diff --git a/libraries/render-utils/src/DeferredBufferRead.slh b/libraries/render-utils/src/DeferredBufferRead.slh new file mode 100644 index 0000000000..fa166300ae --- /dev/null +++ b/libraries/render-utils/src/DeferredBufferRead.slh @@ -0,0 +1,140 @@ + +<@if not DEFERRED_BUFFER_READ_SLH@> +<@def DEFERRED_BUFFER_READ_SLH@> + +<@include DeferredBuffer.slh@> + +// the albedo texture +uniform sampler2D albedoMap; + +// the normal texture +uniform sampler2D normalMap; + +// the specular texture +uniform sampler2D specularMap; + +// the depth texture +uniform sampler2D depthMap; + +// the obscurance texture +uniform sampler2D obscuranceMap; + +// the lighting texture +uniform sampler2D lightingMap; + + +struct DeferredTransform { + mat4 projection; + mat4 viewInverse; + float stereoSide; + vec3 _spareABC; +}; + +layout(std140) uniform deferredTransformBuffer { + DeferredTransform _deferredTransform; +}; +DeferredTransform getDeferredTransform() { + return _deferredTransform; +} + +bool getStereoMode(DeferredTransform deferredTransform) { + return (deferredTransform.stereoSide != 0.0); +} +float getStereoSide(DeferredTransform deferredTransform) { + return (deferredTransform.stereoSide); +} + +vec4 evalEyePositionFromZ(DeferredTransform deferredTransform, float depthVal, vec2 texcoord) { + vec3 nPos = vec3(texcoord.xy * 2.0f - 1.0f, depthVal * 2.0f - 1.0f); + + // compute the view space position using the depth + // basically manually pick the proj matrix components to do the inverse + float Ze = -deferredTransform.projection[3][2] / (nPos.z + deferredTransform.projection[2][2]); + float Xe = (-Ze * nPos.x - Ze * deferredTransform.projection[2][0] - deferredTransform.projection[3][0]) / deferredTransform.projection[0][0]; + float Ye = (-Ze * nPos.y - Ze * deferredTransform.projection[2][1] - deferredTransform.projection[3][1]) / deferredTransform.projection[1][1]; + return vec4(Xe, Ye, Ze, 1.0f); +} + +struct DeferredFragment { + vec4 normalVal; + vec4 diffuseVal; + vec4 specularVal; + vec4 position; + vec3 normal; + float metallic; + vec3 diffuse; + float obscurance; + vec3 specular; + float roughness; + vec3 emissive; + int mode; + float depthVal; +}; + +vec4 unpackDeferredPosition(DeferredTransform deferredTransform, float depthValue, vec2 texcoord) { + if (getStereoMode(deferredTransform)) { + if (texcoord.x > 0.5) { + texcoord.x -= 0.5; + } + texcoord.x *= 2.0; + } + return evalEyePositionFromZ(deferredTransform, depthValue, texcoord); +} + +DeferredFragment unpackDeferredFragmentNoPosition(vec2 texcoord) { + + DeferredFragment frag; + frag.depthVal = -1; + frag.normalVal = texture(normalMap, texcoord); + frag.diffuseVal = texture(albedoMap, texcoord); + frag.specularVal = texture(specularMap, texcoord); + frag.obscurance = texture(obscuranceMap, texcoord).x; + + // Unpack the normal from the map + frag.normal = normalize(frag.normalVal.xyz * 2.0 - vec3(1.0)); + frag.roughness = 2.0 * frag.normalVal.a; + + // Diffuse color and unpack the mode and the metallicness + frag.diffuse = frag.diffuseVal.xyz; + unpackModeMetallic(frag.diffuseVal.w, frag.mode, frag.metallic); + + + if (frag.metallic <= 0.5) { + frag.metallic = 0.0; + frag.specular = vec3(0.03); // Default Di-electric fresnel value + } else { + frag.specular = vec3(frag.diffuseVal.xyz); + frag.metallic = 1.0; + } + + frag.emissive = frag.specularVal.xyz; + frag.obscurance = min(frag.specularVal.w, frag.obscurance); + + return frag; +} + +DeferredFragment unpackDeferredFragment(DeferredTransform deferredTransform, vec2 texcoord) { + + float depthValue = texture(depthMap, texcoord).r; + + DeferredFragment frag = unpackDeferredFragmentNoPosition(texcoord); + + frag.depthVal = depthValue; + frag.position = unpackDeferredPosition(deferredTransform, frag.depthVal, texcoord); + + return frag; +} + + + + +<@endif@>