<@if not DEFERRED_TRANSFORM_SLH@> <@def DEFERRED_TRANSFORM_SLH@> <@include gpu/ShaderConstants.h@> <@include render-utils/ShaderConstants.h@> <@func declareDeferredFrameTransform()@> struct CameraCorrection { mat4 _correction; mat4 _correctionInverse; mat4 _prevView; mat4 _prevViewInverse; }; LAYOUT(binding=GPU_BUFFER_CAMERA_CORRECTION) uniform cameraCorrectionBuffer { CameraCorrection cameraCorrection; }; struct DeferredFrameTransform { vec4 _pixelInfo; vec4 _invPixelInfo; vec4 _depthInfo; vec4 _stereoInfo; mat4 _projection[2]; mat4 _invProjection[2]; mat4 _projectionMono; mat4 _viewInverse; mat4 _view; mat4 _projectionUnJittered[2]; mat4 _invProjectionUnJittered[2]; }; LAYOUT(binding=RENDER_UTILS_BUFFER_DEFERRED_FRAME_TRANSFORM) uniform deferredFrameTransformBuffer { DeferredFrameTransform frameTransform; }; vec2 getWidthHeight(int resolutionLevel) { return vec2(ivec2(frameTransform._pixelInfo.zw) >> resolutionLevel); } vec2 getInvWidthHeight() { return frameTransform._invPixelInfo.xy; } float getProjScaleEye() { return frameTransform._projection[0][1][1]; } float getProjScale(int resolutionLevel) { return getWidthHeight(resolutionLevel).y * frameTransform._projection[0][1][1] * 0.5; } mat4 getProjection(int side) { return frameTransform._projection[side]; } mat4 getProjectionMono() { return frameTransform._projectionMono; } mat4 getUnjitteredProjection(int side) { return frameTransform._projectionUnJittered[side]; } mat4 getUnjitteredInvProjection(int side) { return frameTransform._invProjectionUnJittered[side]; } // positive near distance of the projection float getProjectionNear() { float planeC = frameTransform._projection[0][2][3] + frameTransform._projection[0][2][2]; float planeD = frameTransform._projection[0][3][2]; return planeD / planeC; } // positive far distance of the projection float getPosLinearDepthFar() { return -frameTransform._depthInfo.z; } mat4 getViewInverse() { return frameTransform._viewInverse * cameraCorrection._correctionInverse; } mat4 getView() { return cameraCorrection._correction * frameTransform._view; } mat4 getPreviousView() { return cameraCorrection._prevView; } mat4 getPreviousViewInverse() { return cameraCorrection._prevViewInverse; } DeferredFrameTransform getDeferredFrameTransform() { DeferredFrameTransform result = frameTransform; result._view = getView(); result._viewInverse = getViewInverse(); return result; } bool isStereo() { return frameTransform._stereoInfo.x > 0.0f; } float getStereoSideWidth(int resolutionLevel) { return float(int(frameTransform._stereoInfo.y) >> resolutionLevel); } float getStereoSideHeight(int resolutionLevel) { return float(int(frameTransform._pixelInfo.w) >> resolutionLevel); } vec2 getStereoSideSize(int resolutionLevel) { return vec2(getStereoSideWidth(resolutionLevel), getStereoSideHeight(resolutionLevel)); } ivec4 getStereoSideInfoFromWidth(int xPos, int sideWidth) { return ivec4((1 - int(xPos < sideWidth)) * ivec2(1, sideWidth), sideWidth, isStereo()); } ivec4 getStereoSideInfo(int xPos, int resolutionLevel) { int sideWidth = int(getStereoSideWidth(resolutionLevel)); return getStereoSideInfoFromWidth(xPos, sideWidth); } int getStereoSide(ivec4 sideInfo) { return sideInfo.x; } float evalZeyeFromZdb(float depth) { return frameTransform._depthInfo.x / (depth * frameTransform._depthInfo.y + frameTransform._depthInfo.z); } float evalZdbFromZeye(float Zeye) { return (frameTransform._depthInfo.x - Zeye * frameTransform._depthInfo.z) / (Zeye * frameTransform._depthInfo.y); } vec3 evalEyeNormal(vec3 C) { return normalize(cross(dFdx(C), dFdy(C))); } vec3 evalEyePositionFromZdb(int side, float Zdb, vec2 texcoord) { // compute the view space position using the depth vec3 clipPos; clipPos.xyz = vec3(texcoord.xy, Zdb) * 2.0 - 1.0; vec4 eyePos = frameTransform._invProjection[side] * vec4(clipPos.xyz, 1.0); return eyePos.xyz / eyePos.w; } vec3 evalUnjitteredEyePositionFromZdb(int side, float Zdb, vec2 texcoord) { // compute the view space position using the depth vec3 clipPos; clipPos.xyz = vec3(texcoord.xy, Zdb) * 2.0 - 1.0; vec4 eyePos = frameTransform._invProjectionUnJittered[side] * vec4(clipPos.xyz, 1.0); return eyePos.xyz / eyePos.w; } vec3 evalEyePositionFromZeye(int side, float Zeye, vec2 texcoord) { float Zdb = evalZdbFromZeye(Zeye); return evalEyePositionFromZdb(side, Zdb, texcoord); } ivec2 getPixelPosTexcoordPosAndSide(in vec2 glFragCoord, out ivec2 pixelPos, out vec2 texcoordPos, out ivec4 stereoSide) { ivec2 fragPos = ivec2(glFragCoord.xy); stereoSide = getStereoSideInfo(fragPos.x, 0); pixelPos = fragPos; pixelPos.x -= stereoSide.y; texcoordPos = (vec2(pixelPos) + 0.5) * getInvWidthHeight(); return fragPos; } <@endfunc@> <@endif@>