سؤال

What I want to achieve: Well, i have a terrain and skybox, and a simple water grid still without anything special. I want to make reflections on the water by using framebuffers, rendered a flipped scene onto a texture and use this texture in the water shader along with bump maps, refraction ect...


water vertex shader:

#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);
}

water fragment shader:

#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);
}

They are still for testing.


rendering the reflection:

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);

framebuffer generation:

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);

My problem: Firstly, i know that I haven't set up properly my texture coordinates. It renders the scene flipped as it should on the 1*1 grid(my texcoords) on the water, but i have no idea how can i scale it along the whole water right, because whaen i scale it the bad way-the corners of the whole water surface are the texcoords - it distort and scale it too much so the reflection is not at the right position.

PICTURE: http://postimg.org/image/br87iuhp3/

As you can see it reflects the flipped screen in the viewing frustum.

Question: Are there other ways to render it as a texture but without specifying maybe complex texture coordinates, or compute them in the fragment shader/in eye or camera space.

هل كانت مفيدة؟

المحلول

In your linked image the texture applied to the water surface looks like that each quad has been rendered with its own {0,1}×{0,1} texture coordinate set. Which is not what you want. You want to apply the screen space position as texture coordinate. This is actually most easily done in the fragment shader by using the expression

vec2 screenspace = vec2(gl_FragCoord.x / viewport.x, gl_FragCoord.y/viewport.y);

where viewport is a vec2 uniform set to the viewport coordinates.

Also don't abuse OpenGL as a matrix math library! Don't use glScale, glTranslate etc.! Especially not if you use shaders. BTW, in OpenGL-3 core and later those functions have been removed. They're not there. Use a real matrix math library like GLM, Eigen or linmath.h

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top