我试图减少我必须在场景中绘制的后期处理纹理的数量。最终目标是支持SSAO着色器。着色器需要深度,位置和正常数据。目前,我将深度和法线存储在1个浮动纹理中,将位置存储在另一个浮动纹理中。
我一直在做一些阅读,你似乎可以通过简单地使用普通纹理中存储的深度来获得位置。您必须取消投影x和y并将其乘以深度值。我似乎无法做到这一点,这可能是由于我缺乏理解......
所以目前我的位置被绘制到位置纹理。这就是它的样子(目前正在正常工作)
我的新方法也是如此。我传递正常纹理,该纹理存储RGB通道中的法线x,y和z以及w中的深度。在SSAO着色器中,我需要获得位置,所以这就是我正在做的事情:
//viewport is a vec2 of the viewport width and height
//invProj is a mat4 using camera.projectionMatrixInverse (camera.projectionMatrixInverse.getInverse( camera.projectionMatrix );)
vec3 get_eye_normal()
{
vec2 frag_coord = gl_FragCoord.xy/viewport;
frag_coord = (frag_coord-0.5)*2.0;
vec4 device_normal = vec4(frag_coord, 0.0, 1.0);
return normalize((invProj * device_normal).xyz);
}
...
float srcDepth = texture2D(tNormalsTex, vUv).w;
vec3 eye_ray = get_eye_normal();
vec3 srcPosition = vec3( eye_ray.x * srcDepth , eye_ray.y * srcDepth , eye_ray.z * srcDepth );
//Previously was doing this:
//vec3 srcPosition = texture2D(tPositionTex, vUv).xyz;
然而,当我渲染出位置时,它看起来像这样:
使用新方法,SSAO看起来很乱。任何帮助将不胜感激。
答案 0 :(得分:0)
我能够找到解决方案。你需要将相机的光线法线乘以远近(我使用的是标准化的深度值 - 但你需要世界深度值。)
我创建了一个从正常/深度纹理中提取位置的函数,如下所示:
首先在深度捕获过程中(片段着色器)
float ld = length(vPosition) / linearDepth; //linearDepth is cam.far - cam.near
gl_FragColor = vec4( normalize( vNormal ).xyz, ld );
现在在着色器中试图提取位置......
/// <summary>
/// This function will get the 3d world position from the Normal texture containing depth in its w component
/// <summary>
vec3 get_world_pos( vec2 uv )
{
vec2 frag_coord = uv;
float depth = texture2D(tNormals, frag_coord).w;
float unprojDepth = depth * linearDepth - 1.0;
frag_coord = (frag_coord-0.5)*2.0;
vec4 device_normal = vec4(frag_coord, 0.0, 1.0);
vec3 eye_ray = normalize((invProj * device_normal).xyz);
vec3 pos = vec3( eye_ray.x * unprojDepth, eye_ray.y * unprojDepth, eye_ray.z * unprojDepth );
return pos;
}