gpt4 book ai didi

OpenGL GBuffer 法线和深度缓冲问题

转载 作者:行者123 更新时间:2023-12-01 09:59:19 26 4
gpt4 key购买 nike

我终于让我的 GBuffer 工作了(当然不是真的),但现在我遇到了一些奇怪的问题,我找不到原因。

当我在屏幕上绘制法线纹理时,法线总是显示给我(蓝色总是指向相机)。我不知道如何正确解释,所以这里有一些屏幕:

(我认为这就是为什么我的光照 channel 看起来很奇怪的问题)

下面是我创建 GBuffer 的方法:

glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);

// generate texture object
glGenTextures(GBUFFER_NUM_TEXTURES, textures);
for (unsigned int i = 0; i < 4; i++)
{
glBindTexture(GL_TEXTURE_2D, textures[i]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_FLOAT, 0);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, textures[i], 0);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}

// generate depth texture object
glGenTextures(1, &depthStencilTexture);
glBindTexture(GL_TEXTURE_2D, depthStencilTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT,NULL);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthStencilTexture, 0);

// generate output texture object
glGenTextures(1, &outputTexture);
glBindTexture(GL_TEXTURE_2D, outputTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, width, height, 0, GL_RGB, GL_FLOAT, NULL);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT4, GL_TEXTURE_2D, outputTexture, 0);

GLenum Status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
assert(Status == GL_FRAMEBUFFER_COMPLETE);

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);

这里是几何 channel :

glEnable(GL_DEPTH_TEST);
glDepthMask(true);
glCullFace(GL_BACK);

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);

GLenum DrawBuffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
glDrawBuffers(GBUFFER_NUM_TEXTURES, DrawBuffers);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glLoadIdentity();
camera.Render();

geoProgram->Use();

GLfloat mat[16];

glPushMatrix();
glTranslatef(0,0,-20);
glRotatef(rot, 1.0, 0, 0);
glGetFloatv(GL_MODELVIEW_MATRIX,mat);
glUniformMatrix4fv(worldMatrixLocation, 1, GL_FALSE, mat);
glutSolidCube(5);
glPopMatrix();

glPushMatrix();
glTranslatef(0,0,0);
glGetFloatv(GL_MODELVIEW_MATRIX,mat);
glUniformMatrix4fv(worldMatrixLocation, 1, GL_FALSE, mat);
gluSphere(sphere, 3.0, 20, 20);
glPopMatrix();

glDepthMask(false);
glDisable(GL_DEPTH_TEST);

这里是几何 channel 着色器:

[Vertex]
varying vec3 normal;
varying vec4 position;
uniform mat4 worldMatrix;

void main( void )
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
position = worldMatrix * gl_Vertex;
normal = (worldMatrix * vec4(gl_Normal, 0.0)).xyz;
gl_TexCoord[0]=gl_MultiTexCoord0;
}


[Fragment]
varying vec3 normal;
varying vec4 position;

void main( void )
{
gl_FragData[0] = vec4(0.5, 0.5, 0.5, 1);//gl_Color;
gl_FragData[1] = position;
gl_FragData[2] = vec4(normalize(normal),0);
gl_FragData[3] = vec4(gl_TexCoord[0].st, 0, 0);
}

很抱歉这个长问题/代码片段,但我不知道下一步该怎么做,我用其他 GBuffer 实现检查了所有内容,但找不到错误。

//编辑:

好吧,看来你是对的,问题不在于 gbuffer,而在于照明 channel 。我玩了很多,但无法让它工作:(

这是光照 channel :

[vs]
void main( void )
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

[fs]
uniform sampler2D colorMap;
uniform sampler2D positionMap;
uniform sampler2D normalMap;
uniform sampler2D texcoordMap;

uniform vec2 screenSize;
uniform vec3 pointLightPostion;
uniform vec3 pointLightColor;
uniform float pointLightRadius;


void main( void )
{
float lightDiffuse = 0.5;
float lightSpecular = 0.7;
vec3 lightAttenuation = vec3(1.4, 0.045, 0.00075);

vec2 TexCoord = gl_FragCoord.xy / screenSize.xy;
vec3 WorldPos = texture2D(positionMap, TexCoord).xyz;
vec3 Color = texture(colorMap, TexCoord).xyz;
vec3 normal = texture(normalMap, TexCoord).xyz;
normal = normalize(normal);

vec3 lightVector = WorldPos - pointLightPostion;
float dist = length(lightVector);
lightVector = normalize(lightVector);

float nDotL = max(dot(normal, lightVector), 0.0);
vec3 halfVector = normalize(lightVector - WorldPos);
float nDotHV = max(dot(normal, halfVector), 0.0);

vec3 lightColor = pointLightColor;
vec3 diffuse = lightDiffuse * nDotL;
vec3 specular = lightSpecular * pow(nDotHV, 1.0) * nDotL;
lightColor += diffuse + specular;

float attenuation = clamp(1.0 / (lightAttenuation.x + lightAttenuation.y * dist + lightAttenuation.z * dist * dist), 0.0, 1.0);


gl_FragColor = vec4(vec3(Color * lightColor * attenuation), 1.0);
}

如有必要,我还可以发布 sencil pass 和/或所有其他处理过程。

最佳答案

我知道这有点过时了,但我想让你知道,经过大量研究后我一切正常!如果有人遇到类似/相同的问题,我只是想在这里发布。

实际上位置图是完全错误的(好吧,我的照明模型也是如此,但那是另一回事了:))。正如您已经说过的,我正在使用固定管道功能(这真的很愚蠢)。实际的失败是我得到了“modelmatrix”

glGetFloatv(GL_MODELVIEW_MATRIX,mat);
glUniformMatrix4fv(worldMatrixLocation, 1, GL_FALSE, mat);

这实际上是模型矩阵 * 固定管道中的 View 矩阵。所以我将所有内容都更改为自定义模型计算,瞧,位置图是正确的。 (好吧,您也可以使用固定功能管道并设置具有匹配值的自定义模型矩阵并将其作为模型矩阵输入到着色器中,但这只是脏)。多亏了你,我走上了正确的道路,并设法理解了矩阵计算和着色器等更多!

顺便说一句:gbuffer 现在看起来像这样(实际上不需要 textureposition :)): enter image description here

关于OpenGL GBuffer 法线和深度缓冲问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18776791/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com