在进行延迟照明时,会出现3个工件。
奇怪的带子[至少在我看来是这样]
如果你看一看带圆圈的圆柱体的顶部,你会看到它是如何扭曲地延伸,模糊了它后面的场景。我不知道发生了什么事
剥离线
如果你看圆柱体,你会看到一条奇怪的线,它会出现在所有的物体上,这取决于你看它的Angular 。
3.屏幕撕裂
只观察球体
现在,当我向下旋转相机,使球体移动到屏幕的顶部边缘时,它开始拉伸
因为我的程序是相当大的,我不知道哪里出了问题,我将张贴什么,我觉得是项目的相关部分在这里。如果需要更多的信息,请告诉我。
让我们从最重要的帧缓冲区开始
public class FrameBuffer
{
private final int fboID;
private final int Width;
private final int Height;
private final Texture2D colorBuffers[];
private final RenderBuffer depthStencil;
private RenderingAttributes render;
public FrameBuffer(int width,int height)
{
Width=width;
Height=height;
fboID=GL30.glGenFramebuffers();
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER,fboID);
{
colorBuffers=new Texture2D[3]; // create 3 textures
colorBuffers[0]=new Texture2D(GL30.GL_RGB32F,GL11.GL_RGB,GL11.GL_NEAREST,width,height,GL30.GL_COLOR_ATTACHMENT0); //used to store scene vertex positions in worldSpace
colorBuffers[1]=new Texture2D(GL30.GL_RGB32F,GL11.GL_RGB,GL11.GL_NEAREST,width,height,GL30.GL_COLOR_ATTACHMENT1); //used to store scene normals in worldSpace
colorBuffers[2]=new Texture2D(GL11.GL_RGB,GL11.GL_RGB,GL11.GL_LINEAR,width,height,GL30.GL_COLOR_ATTACHMENT2); //final output image blitted to screen
depthStencil=new RenderBuffer(GL30.GL_DEPTH24_STENCIL8,width,height); //used in gBuffer pass for depth testing
}
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER,0);
}
//Attach/Detach frameBuffer for each pass
//RenderingAttributes is a class used to set and unset glParameters like blending,depth testing
//etc based on what pass im rendering i will show the details in a minute
public void bind(RenderingAttributes binding,boolean enable)
{
if(enable)
{
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER,fboID);
GL11.glViewport(0,0,Width,Height);
if(binding!=null){(render=binding).setOps();} //what operations to perform before rendering
}
else
{
GL11.glViewport(0,0,Display.getWidth(),Display.getHeight());
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER,0);
if(render!=null){render.disableOps();} //what operations to perform after rendering
}
}
//Used by pointLight pass to read vertexPositions and normals from the gBuffer Textures
public void attachTexture(int textureID,int textureBank)
{
Texture2D texture=colorBuffers[textureID];
texture.bindTexture(textureBank);
}
//Used to resolve COLOR_ATTACHMENT_2[final output] to screen
public void resolveToScreen(int attachment)
{
GL30.glBindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER,0);
GL30.glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER,fboID);
GL11.glDrawBuffer(GL11.GL_BACK);
GL11.glReadBuffer(attachment);
GL30.glBlitFramebuffer(0,0,Width,Height
,0,0,Display.getWidth(),Display.getHeight()
,GL11.GL_COLOR_BUFFER_BIT,GL11.GL_LINEAR);
GL30.glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER,0);
GL30.glBindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER,0);
}
//CalnUp
public void release()
{
for(Texture2D tex:colorBuffers){tex.release();}
depthStencil.release();
GL30.glDeleteFramebuffers(fboID);
}
private static final class Texture2D
{
private final int textureID;
private Texture2D(int textureFormat,int imageFormat,int filter,int width,int height,int attachment)
{
GL11.glBindTexture(GL11.GL_TEXTURE_2D,textureID=GL11.glGenTextures());
GL11.glTexImage2D(GL11.GL_TEXTURE_2D,0
,textureFormat,width,height,0
,imageFormat,GL11.GL_FLOAT,(FloatBuffer)null);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D,GL11.GL_TEXTURE_MIN_FILTER,filter);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D,GL11.GL_TEXTURE_MAG_FILTER,filter);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D,GL11.GL_TEXTURE_WRAP_S,GL11.GL_CLAMP);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D,GL11.GL_TEXTURE_WRAP_T,GL11.GL_CLAMP);
GL11.glBindTexture(GL11.GL_TEXTURE_2D,0);
GL32.glFramebufferTexture(GL30.GL_FRAMEBUFFER,attachment,textureID,0);
}
private void bindTexture(int textureBank)
{
GL13.glActiveTexture(textureBank);
GL11.glBindTexture(GL11.GL_TEXTURE_2D,textureID);
}
private void release(){GL11.glDeleteTextures(textureID);}
}
//DepthBuffer used for gBuffer pass
private static final class RenderBuffer
{
private final int bufferID;
private RenderBuffer(int format,int width,int height)
{
GL30.glBindRenderbuffer(GL30.GL_RENDERBUFFER,bufferID=GL30.glGenRenderbuffers());
GL30.glRenderbufferStorage(GL30.GL_RENDERBUFFER,format,width,height);
GL30.glFramebufferRenderbuffer(GL30.GL_FRAMEBUFFER,GL30.GL_DEPTH_STENCIL_ATTACHMENT,GL30.GL_RENDERBUFFER,bufferID);
GL30.glBindRenderbuffer(GL30.GL_RENDERBUFFER,0);
}
private void release(){GL30.glDeleteRenderbuffers(bufferID);}
}
}
现在每个通道有3个主要组件
渲染属性:-在附加和分离帧缓冲区以进行渲染时执行的操作集
着色器
写入帧缓冲区的实际渲染器
1) g缓冲通行证
下面是我的gbuffer过程的渲染属性
private static final class Rendering implements RenderingAttributes
{
private final IntBuffer colorTargets;
private Rendering()
{
colorTargets=BufferUtils.createIntBuffer(3);
colorTargets.put(GL30.GL_COLOR_ATTACHMENT0).put(GL30.GL_COLOR_ATTACHMENT1).put(GL30.GL_COLOR_ATTACHMENT2);
colorTargets.flip();
}
@Override
public void setOps()
{
GL11.glEnable(GL11.GL_CULL_FACE); //cull backside of all geometry we don't need those vertices in the gBuffer
GL11.glCullFace(GL11.GL_BACK);
GL20.glDrawBuffers(colorTargets); //enable all 3 colorTargets, we won't draw to the last one we only clear it
GL11.glEnable(GL11.GL_DEPTH_TEST); //enable depth test for proper results
GL11.glDepthMask(true); //allow writing to depth buffer
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); //clear current color and depth of all attachments
}
@Override
public void disableOps() //called when attach(null,false) is called on frameBuffer basically the exact opposite operations of setOps
{
GL11.glDisable(GL11.GL_CULL_FACE); //disable culling
GL20.glDrawBuffers(GL11.GL_NONE); //don't draw to anything
GL11.glDepthMask(false); //don't write to depth Buffer
GL11.glDisable(GL11.GL_DEPTH_TEST); //disable depth testing
}
}
这是我的gbuffer过程顶点和片段着色器
Vertex Shader
# version 430 core
uniform mat4 P,V,M; //P Perspective , V view ,M model matrices
in vec3 vertex;
out vec3 vertexMap;
in vec3 normal;
out vec3 normalMap;
void main()
{
vec4 worldVertex=M*vec4(vertex,1.0);
gl_Position=P*V*worldVertex;
vertexMap=worldVertex.xyz; //output vertexPosition in worldSpace
normalMap=normalize(vec3((M*vec4(normal,0.0)).xyz)); //output normal in worldSpace
}
My fragment shader
# version 430 core
in vec3 vertexMap;
in vec3 normalMap;
layout(location=0) out vec4 vertexBuffer; //output to color_attachment_0
layout(location=1) out vec4 normalBuffer; //output to color_attachment_1
void main()
{
vertexBuffer=vec4(vertexMap,0);
normalBuffer=vec4(normalMap,0);
}
最后我把这个交给我的朋友
public void render(Camera cam)
{
fbo.bind(gRenderer,true); //begin
sceneRenderer.renderGlobal(cam,gShader); //gives every entity my gBuffer shader for rendering
fbo.bind(null,false); //end
}
下面是包含vertexpositions的彩色附件0的外观
下面是包含顶点法线的颜色附件1的外观
2) 点光通
从这篇文章我读到它有两个子过程
a) 模板传递
这是我的模具渲染属性
private static final class StencilRendering implements RenderingAttributes
{
@Override
public void setOps()
{
GL20.glDrawBuffers(GL11.GL_NONE); //no draw buffers
GL11.glDisable(GL11.GL_CULL_FACE); //no cull face for reasons explained in the article
GL11.glEnable(GL11.GL_DEPTH_TEST); //enable depth test cause stencil test depends on it
GL11.glEnable(GL11.GL_STENCIL_TEST); //set the stencil ops
GL11.glStencilMask(0xff);
GL11.glClear(GL11.GL_STENCIL_BUFFER_BIT);
GL11.glStencilFunc(GL11.GL_ALWAYS,0,0xFF); //as explained in the article
GL20.glStencilOpSeparate(GL11.GL_FRONT,GL11.GL_KEEP,GL14.GL_DECR_WRAP,GL11.GL_KEEP);
GL20.glStencilOpSeparate(GL11.GL_BACK,GL11.GL_KEEP,GL14.GL_INCR_WRAP,GL11.GL_KEEP);
}
@Override
public void disableOps()
{
GL11.glDisable(GL11.GL_DEPTH_TEST);
GL11.glDisable(GL11.GL_STENCIL_TEST);
}
}
这是我的模板着色器。这里什么都没发生
Vertex shader
# version 430 core
uniform mat4 P,V,M;
in vec3 vertex;
void main(){gl_Position=P*V*M*vec4(vertex,1.0);}
Fragment shader
# version 430 core
out vec4 pixelColor;
void main(){pixelColor=vec4(1,1,1,0f);}
b) 浅色通行证
以下是我的灯光渲染属性
private static final class ColorRendering implements RenderingAttributes
{
@Override
public void setOps()
{
GL20.glDrawBuffers(GL30.GL_COLOR_ATTACHMENT2); //draw to final output buffer
GL11.glDisable(GL11.GL_DEPTH_TEST);
GL11.glEnable(GL11.GL_CULL_FACE);
GL11.glCullFace(GL11.GL_FRONT);
GL11.glEnable(GL11.GL_BLEND); //enable blending to add lightOutput for multiple lights
GL11.glBlendFunc(GL11.GL_ONE,GL11.GL_ONE);
GL14.glBlendEquation(GL14.GL_FUNC_ADD);
GL11.glEnable(GL11.GL_STENCIL_TEST); //enable stencil test so only pixels within the lights bounding sphere gets rendered
GL11.glStencilFunc(GL11.GL_EQUAL,1,0xFF);
}
@Override
public void disableOps()
{
GL20.glDrawBuffers(GL11.GL_NONE);
GL11.glDisable(GL11.GL_CULL_FACE);
GL11.glDisable(GL11.GL_BLEND);
GL11.glDisable(GL11.GL_STENCIL_TEST);
GL11.glEnable(GL11.GL_DEPTH_TEST);
}
}
这是我的着色器
Vertex Shader
# version 430 core
uniform mat4 P,V,M;
in vec3 vertex;
void main(){gl_Position=P*V*M*vec4(vertex,1.0);}
Fragment Shader
# version 430 core
uniform sampler2D vertexBuffer;
uniform sampler2D normalBuffer;
uniform int ScreenWidth;
uniform int ScreenHeight;
uniform vec3 color;
uniform vec3 position;
uniform vec3 attenuation;
out vec4 pixelColor;
vec2 genTexCoord()
{
vec2 texCoord=vec2(0.0);
texCoord.x=gl_FragCoord.x/ScreenWidth;
texCoord.y=gl_FragCoord.y/ScreenHeight;
return texCoord;
}
float getAtten(float length)
{
float intencity=0;
intencity+=attenuation.x;
intencity+=attenuation.y*(length);
intencity+=attenuation.z*(length*length);
return intencity;
}
void main()
{
vec3 finalColor=vec3(0);
vec2 vertexTexCoord=genTexCoord();
vec3 actualVertex=texture(vertexBuffer,vertexTexCoord).xyz;
vec3 actualNormal=normalize(texture(normalBuffer,vertexTexCoord).xyz);
vec3 lightDir=position-actualVertex;
float atten=getAtten(length(lightDir));
float maxIntencity=(max(dot(normalize(lightDir),actualNormal),0f));
finalColor+=(color*maxIntencity)/atten;
pixelColor=vec4(finalColor,0.0);
}
这里是我如何渲染我的点光通行证
public void render(Camera cam)
{
fbo.bind(null,true); // i don't use the ops for my frameBuffer cause it has 2 passes
for(PointLight pLight:lights)
{
light.translate(pLight.getPosition()); //light is an sphere entity having sphere geometry and modelMatrix for position and scale
light.scale((float)pLight.getRadius());
stencil.setOps(); //Stencil Pass
light.setShader(stencilShader);
light.render(cam);
stencil.disableOps();
color.setOps(); //Color pass
light.setShader(colorShader);
light.render(cam);
color.disableOps();
}
fbo.bind(null,false);
}
c) 最终管道
class PipeLine
{
private final FrameBuffer fbo;
private final GBufferPass pass1;
private final PLightPass pass2;
PipeLine()throws IOException
{
fbo=new FrameBuffer(Display.getWidth(),Display.getHeight());
pass1=new GBufferPass(fbo);
pass2=new PLightPass(fbo);
}
void render(Camera cam)
{
pass1.render(cam);
pass2.render(cam);
fbo.resolveToScreen(GL30.GL_COLOR_ATTACHMENT2); //output final image to screen
}
void cleanUp()
{
fbo.release();
pass1.cleanUp();
pass2.cleanUp();
}
}
即使是一个猜测或可能性,为什么我得到上述人工制品将是很大的帮助。
暂无答案!
目前还没有任何答案,快来回答吧!