瀏覽代碼

Pack linear depth to RGBA manually to comply with FBO specification.

Lasse Öörni 14 年之前
父節點
當前提交
9c40326a8c

+ 3 - 1
Engine/Graphics/OpenGL/OGLGraphics.cpp

@@ -1820,7 +1820,9 @@ unsigned Graphics::GetRGBAFormat()
 
 
 unsigned Graphics::GetDepthFormat()
 unsigned Graphics::GetDepthFormat()
 {
 {
-    return GL_LUMINANCE32F_ARB;
+    // OpenGL FBO specs state that color attachments must have the same format; therefore must pack linear depth to RGBA manually
+    // if not using a readable hardware depth texture
+    return GL_RGBA;
 }
 }
 
 
 unsigned Graphics::GetDepthStencilFormat()
 unsigned Graphics::GetDepthStencilFormat()

+ 1 - 1
SourceAssets/GLSLShaders/GBuffer.frag

@@ -31,5 +31,5 @@ void main()
     float specPower = cMatSpecProperties.y / 255.0;
     float specPower = cMatSpecProperties.y / 255.0;
 
 
     gl_FragData[0] = vec4(normal * 0.5 + 0.5, specPower);
     gl_FragData[0] = vec4(normal * 0.5 + 0.5, specPower);
-    gl_FragData[1] = vec4(vTexCoord.z);
+    gl_FragData[1] = vec4(PackDepth(vTexCoord.z), 0.0);
 }
 }

+ 2 - 2
SourceAssets/GLSLShaders/LightVolume.frag

@@ -16,7 +16,7 @@ void main()
 {
 {
     // If rendering a directional light quad, optimize out the w divide
     // If rendering a directional light quad, optimize out the w divide
     #ifdef DIRLIGHT
     #ifdef DIRLIGHT
-        float depth = texture2D(sDepthBuffer, vScreenPos).r;
+        float depth = UnpackDepth(texture2D(sDepthBuffer, vScreenPos).rgb);
         #ifdef ORTHO
         #ifdef ORTHO
             vec3 worldPos = mix(vNearRay, vFarRay, depth);
             vec3 worldPos = mix(vNearRay, vFarRay, depth);
         #else
         #else
@@ -24,7 +24,7 @@ void main()
         #endif
         #endif
         vec4 normalInput = texture2D(sNormalBuffer, vScreenPos);
         vec4 normalInput = texture2D(sNormalBuffer, vScreenPos);
     #else
     #else
-        float depth = texture2DProj(sDepthBuffer, vScreenPos).r;
+        float depth = UnpackDepth(texture2DProj(sDepthBuffer, vScreenPos).rgb);
         #ifdef ORTHO
         #ifdef ORTHO
             vec3 worldPos = mix(vNearRay, vFarRay, depth) / vScreenPos.w;
             vec3 worldPos = mix(vNearRay, vFarRay, depth) / vScreenPos.w;
         #else
         #else

+ 24 - 0
SourceAssets/GLSLShaders/Samplers.frag

@@ -23,3 +23,27 @@ vec3 DecodeNormal(vec4 normalInput)
     normal.z = sqrt(max(1.0 - dot(normal.xy, normal.xy), 0.0));
     normal.z = sqrt(max(1.0 - dot(normal.xy, normal.xy), 0.0));
     return normal;
     return normal;
 }
 }
+
+vec3 PackDepth(float depth)
+{
+    vec3 ret;
+    depth *= 255;
+    ret.x = floor(depth);
+    depth = (depth - ret.x) * 255;
+    ret.y = floor(depth);
+    ret.z = (depth - ret.y);
+    ret.xy *= 1.0 / 255;
+    return ret;
+}
+
+float UnpackDepth(vec3 depth)
+{
+    const vec3 dotValues = vec3(1.0, 1.0 / 255, 1.0 / (255 * 255));
+    return dot(depth, dotValues);
+}
+
+float ReconstructDepth(float hwDepth)
+{
+    return cDepthReconstruct.y / (hwDepth - cDepthReconstruct.x);
+}
+

+ 1 - 0
SourceAssets/GLSLShaders/Uniforms.frag

@@ -1,3 +1,4 @@
+uniform vec2 cDepthReconstruct;
 uniform vec4 cFogParams;
 uniform vec4 cFogParams;
 uniform vec3 cFogColor;
 uniform vec3 cFogColor;
 uniform vec4 cLightColor;
 uniform vec4 cLightColor;