我正在尝试使用LWJGL实现一组着色器来渲染SPH流体模拟,如this presentation from NVidia所示。为此,我需要首先将我的粒子渲染为纹理,并在生成的纹理上应用不同的着色器。
算法的第一部分渲染效果很好,将预期的流体厚度图像保存在GL_COLOR_ATTACHMENT0
纹理处:
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, frameBufferID.get(0));
GL30.glBindRenderbuffer(GL30.GL_RENDERBUFFER, renderBufferID.get(0));
glDisable(GL_DEPTH_TEST);
glDepthMask(false);
glDrawBuffer(GL30.GL_COLOR_ATTACHMENT0);
glClearColor(0.f, 0.f, 0.f, 0.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
drawSpheres();
glEnable(GL_DEPTH_TEST);
glDepthMask(true);
glDisable(GL_BLEND);
第二部分也渲染得很好,将流体颜色图像保存在GL_COLOR_ATTACHMENT4
纹理:
glDrawBuffer(GL30.GL_COLOR_ATTACHMENT4);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
drawSpheres();
但是,我在尝试生成流体法线图像时遇到问题。它应该从渲染缓冲区中获取GL_DEPTH_ATTACHMENT
(写入代码的第一部分)和GL_COLOR_ATTACHMENT4
来自第二部分。
glDrawBuffer(GL30.GL_COLOR_ATTACHMENT5);
GL30.glFramebufferTexture2D(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
depth2.get(0), 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GL13.glActiveTexture(GL13.GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, depth.get(0));
glEnable(GL_TEXTURE_2D);
smooth();
glDisable(GL_TEXTURE_2D);
GL30.glFramebufferTexture2D(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth.get(0), 0);
glDisable(GL_DEPTH_TEST);
glDepthMask(false);
glEnable(GL_BLEND);
我的normal()
方法如下:
private void normal() {
ARBShaderObjects.glUseProgramObjectARB(programNormal);
GL20.glUniform1i(GL20.glGetUniformLocation(programSmooth, "depthTex"), 0);
GL20.glUniform1i(GL20.glGetUniformLocation(programSmooth, "colorTex"), 1);
GL20.glUniform1f(GL20.glGetUniformLocation(programSmooth, "del_x"), 1.0f/620.0f);
GL20.glUniform1f(GL20.glGetUniformLocation(programSmooth, "del_y"), 1.0f/620.0f);
fullscreenQuad();
}
public void fullscreenQuad(){
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
GLU.gluOrtho2D(0, 620, 0, 620);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glBegin(GL_QUADS);
glTexCoord2f(0.f, 0.f);
glVertex2f(0.f, 0.f);
glTexCoord2f(1f, 0.f);
glVertex2f(620.f, 0.f);
glTexCoord2f(1.f, 1.f);
glVertex2f(620.f, 620.f);
glTexCoord2f(0.f, 1.f);
glVertex2f(0.f, 620.f);
glEnd();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
在GL_COLOR_ATTACHMENT5
纹理上生成的渲染只是一个纯黑色图像。因此,最终渲染最终也是纯黑色。
programNormal
方法中使用的normal()
由以下顶点着色器构成:
uniform float pointRadius;
uniform float near;
uniform float far;
varying vec3 posEye;
void main()
{
vec3 n;
n.xy = gl_PointCoord.st*vec2(2.0, -2.0) + vec2(-1.0, 1.0);
float mag = dot(n.xy, n.xy);
if (mag > 1.0) discard;
n.z = sqrt(1.0-mag);
vec4 spherePosEye =vec4(posEye+n*pointRadius,1.0);
vec4 clipSpacePos = gl_ProjectionMatrix*spherePosEye;
float normDepth = clipSpacePos.z/clipSpacePos.w;
gl_FragDepth = (((far-near)/2.)*normDepth)+((far+near)/2.);
gl_FragData[0] = gl_Color;
}
片段着色器:
uniform sampler2D depthTex;
uniform sampler2D colorTex;
uniform float del_x;
uniform float del_y;
vec3 uvToEye(vec2 texCoord,float z)
{
vec2 xyPos = (texCoord*2. -1.);
vec4 clipPos = vec4( xyPos, z, 1.0 );
vec4 viewPos = (gl_ProjectionMatrixInverse * clipPos);
return(viewPos.xyz/viewPos.w);
}
void main(){
float maxDepth = 0.999;
float depth = texture2D(depthTex,gl_TexCoord[0].xy).x;
if(depth>maxDepth)
{
discard;
}
vec3 posEye = uvToEye(gl_TexCoord[0].xy,depth);
vec2 texCoord1 = vec2(gl_TexCoord[0].x+del_x,gl_TexCoord[0].y);
vec2 texCoord2 = vec2(gl_TexCoord[0].x-del_x,gl_TexCoord[0].y);
vec3 ddx = uvToEye(texCoord1, texture2D(depthTex,texCoord1.xy).x)-posEye;
vec3 ddx2 = posEye-uvToEye(texCoord2, texture2D(depthTex,texCoord2.xy).x);
if(abs(ddx.z)>abs(ddx2.z))
{
ddx = ddx2;
}
texCoord1 = vec2(gl_TexCoord[0].x,gl_TexCoord[0].y+del_y);
texCoord2 = vec2(gl_TexCoord[0].x,gl_TexCoord[0].y-del_y);
vec3 ddy = uvToEye(texCoord1, texture2D(depthTex,texCoord1.xy).x)-posEye;
vec3 ddy2 = posEye-uvToEye(texCoord2, texture2D(depthTex,texCoord2.xy).x);
if(abs(ddy.z)>abs(ddy2.z))
{
ddy = ddy2;
}
vec3 n = cross(ddx,ddy);
n = normalize(n);
const vec3 lightDir = vec3(-0.5, 1.5, 5.);
const float shininess = 100.0;
float diffuse = max(0.0,dot(lightDir,n));
vec3 v = normalize(-posEye);
vec3 h = normalize(lightDir + v);
float specular = pow(max(0.0, dot(n, h)), shininess);
gl_FragData[0] = texture2D(colorTex,gl_TexCoord[0].xy)*diffuse+specular;
}
答案 0 :(得分:0)
我知道这是一个老问题,但对于任何想知道你应该在深度纹理中使用GL_DEPTH_ATTACHMENT24的人来说。