水反射纹理坐标

时间:2013-09-19 17:36:43

标签: opengl reflection shader framebuffer render-to-texture

我想要实现的目标:嗯,我有一个地形和天空盒,还有一个简单的水网,仍然没有什么特别的。 我想通过使用framebuffers在水面上进行反射,在纹理上渲染一个翻转的场景,并在水着色器中使用此纹理以及凹凸贴图,折射等...


水顶点着色器:

#version 330

uniform mat4 projection_matrix;
uniform mat4 modelview_matrix;

in vec3 a_Vertex;

out vec2 texCoord0;
out vec3 v_pos;

void main() 
{      
gl_Position = projection_matrix * modelview_matrix * vec4(a_Vertex,1.0);
texCoord0 = vec2(gl_Position.x,gl_Position.z);
}

水片段着色器:

#version 330

uniform sampler2D color_texture;

in vec2 texCoord0;
in vec3 v_pos;

void main(void)
{
gl_FragColor = vec4(1,1,1,0.6)*texture(color_texture,texCoord0.st);
}

它们仍在测试中。


渲染反射:

glBindFramebuffer(GL_FRAMEBUFFER,pndheightmap.waterFrameBufferID);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
terrainShader->bindShader();
glScalef(1,-1,1);
GLfloat modelviewMatrix[16];
glGetFloatv(GL_MODELVIEW_MATRIX,modelviewMatrix);
terrainShader->sendUniform4x4("scaling_matrix",modelviewMatrix);
glFrontFace(GL_CW);
pndheightmap.p_rendermap_h();
glFrontFace(GL_CCW);
glScalef(1,-1,1);
glGetFloatv(GL_MODELVIEW_MATRIX,modelviewMatrix);
terrainShader->sendUniform4x4("scaling_matrix",modelviewMatrix);
glEnable(GL_DEPTH_TEST);
glBindFramebuffer(GL_FRAMEBUFFER, 0);

帧缓冲生成:

glGenFramebuffers(1, &waterFrameBufferID);
glBindFramebuffer(GL_FRAMEBUFFER, waterFrameBufferID);

glGenTextures(1, &waterReflectionBufferID);
glBindTexture(GL_TEXTURE_2D, waterReflectionBufferID);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, mapwidth, mapheight,0,GL_RGB, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);

glGenRenderbuffers(1, &depthRenderBufferID);
glBindRenderbuffer(GL_RENDERBUFFER, depthRenderBufferID);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, mapwidth, mapheight);

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,waterReflectionBufferID, 0);

glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderBufferID);
GLenum DrawBuffers[1] = {GL_COLOR_ATTACHMENT0};
glDrawBuffers(1, DrawBuffers);

glBindRenderbuffer(GL_RENDERBUFFER,0);
glBindFramebuffer(GL_FRAMEBUFFER,0);

我的问题: 首先,我知道我没有正确设置我的纹理坐标。 它渲染场景在水面上的1 * 1网格(我的texcoords)上应该翻转,但是我不知道如何沿着整个水域缩放它,因为我可以将它缩小到糟糕的方式 - 角落整个水面是texcoords - 它扭曲和缩放太多,所以反射不在正确的位置。

图片: http://postimg.org/image/br87iuhp3/

正如你所看到的,它反映了观看视锥中的翻转屏幕。

问题还有其他方法可以将其渲染为纹理但不指定可能复杂的纹理坐标,或者在片段着色器/眼睛或相机空间中计算它们

1 个答案:

答案 0 :(得分:1)

在链接的图像中,应用于水面的纹理看起来像每个四边形都使用自己的{0,1}×{0,1}纹理坐标集进行渲染。这不是你想要的。您想要将屏幕空间位置应用为纹理坐标。这实际上最容易通过使用表达式

在片段着色器中完成
vec2 screenspace = vec2(gl_FragCoord.x / viewport.x, gl_FragCoord.y/viewport.y);

其中viewport是设置为视口坐标的vec2制服。

也不要滥用OpenGL作为矩阵数学库!不要使用glScale,glTranslate等!特别是如果你使用着色器。顺便说一下,在OpenGL-3核心中,以后这些功能已被删除。他们不在那里。使用真实的矩阵数学库,如GLM,Eigen或linmath.h

相关问题