0

私が達成したいこと:まあ、私は地形とスカイボックス、そして特別なことはまだ何もない単純な水グリッドを持っています. フレーム バッファを使用して水面に反射を作成し、反転したシーンをテクスチャにレンダリングし、このテクスチャをバンプ マップ、屈折などとともにウォーター シェーダで使用したいと考えています。


水頂点シェーダ:

#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/

ご覧のとおり、反転した画面が視錐台に反映されています。

質問:複雑なテクスチャ座標を指定せずにテクスチャとしてレンダリングする方法や、フラグメント シェーダ/目またはカメラ空間でそれらを計算する方法は他にありますか?

4

1 に答える 1

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 などの実数行列数学ライブラリを使用する

于 2013-09-20T11:40:09.203 に答える