1/**************************************************************************** 2** 3** Copyright (C) 2014 NVIDIA Corporation. 4** Copyright (C) 2019 The Qt Company Ltd. 5** Contact: https://www.qt.io/licensing/ 6** 7** This file is part of Qt 3D Studio. 8** 9** $QT_BEGIN_LICENSE:GPL$ 10** Commercial License Usage 11** Licensees holding valid commercial Qt licenses may use this file in 12** accordance with the commercial license agreement provided with the 13** Software or, alternatively, in accordance with the terms contained in 14** a written agreement between you and The Qt Company. For licensing terms 15** and conditions see https://www.qt.io/terms-conditions. For further 16** information use the contact form at https://www.qt.io/contact-us. 17** 18** GNU General Public License Usage 19** Alternatively, this file may be used under the terms of the GNU 20** General Public License version 3 or (at your option) any later version 21** approved by the KDE Free Qt Foundation. The licenses are as published by 22** the Free Software Foundation and appearing in the file LICENSE.GPL3 23** included in the packaging of this file. Please review the following 24** information to ensure the GNU General Public License requirements will 25** be met: https://www.gnu.org/licenses/gpl-3.0.html. 26** 27** $QT_END_LICENSE$ 28** 29****************************************************************************/ 30 31#ifndef SCREEN_SPACE_DO_GLSLLIB 32#define SCREEN_SPACE_DO_GLSLLIB 1 33 34#include "depthpass.glsllib" 35 36vec3 getViewSpacePos( sampler2D depthSampler, vec2 camProps, vec2 UV, vec4 UvToEye ) 37{ 38 float sampleDepth = getDepthValue( texture(depthSampler, UV), camProps ); 39 sampleDepth = depthValueToLinearDistance( sampleDepth, camProps ); 40 41 vec2 scaledUV = (UV * UvToEye.xy) + UvToEye.zw; 42 return vec3(scaledUV * sampleDepth, sampleDepth); 43} 44 45float shadowOcclusion(sampler2D depthSampler, vec3 lightDir, vec3 worldPos, mat4 viewMat, mat4 viewProj, vec4 shadowParams, vec2 camProps, vec4 aoScreen, vec4 UvToEye) 46{ 47 vec3 viewPos = getViewSpacePos( depthSampler, camProps, ( gl_FragCoord.xy * aoScreen.zw ), UvToEye ); 48 float depth = viewPos.z; 49 50 // Get the screen-space UV 51 vec2 centerUV = gl_FragCoord.xy * aoScreen.zw; 52 53 float screenDist = shadowParams.y * 3.1415926535 * aoScreen.y / viewPos.z; 54 if (screenDist < 1.0) { return 1.0; } 55 56 vec3 viewL = normalize( (viewMat * vec4(lightDir, 0)).xyz ); 57 58 float steps = min( screenDist, 20.0 ); 59 int maxCt = int(steps); 60 float step = 3.1415926535 * shadowParams.y / float(maxCt); 61 float ret = float(maxCt); 62 63 for( int i = 0; i < maxCt; ++i ) 64 { 65 vec3 ray = lightDir * step * float(i); 66 vec3 samplePos = worldPos - ray; 67 68 vec4 smpUV = viewProj * vec4(samplePos, 1.0); 69 smpUV /= smpUV.w; 70 smpUV.xy = (smpUV.xy + 1.0) * 0.5; 71 72 vec3 testPos = getViewSpacePos( depthSampler, camProps, smpUV.xy, UvToEye ); 73 testPos.z += shadowParams.w; 74 vec3 testVec = normalize(viewPos - testPos); 75 testVec -= viewL; 76 float isBehind = clamp( testVec.z, 0.0, 1.0 ); 77 float diff = (testPos.z - depth) / shadowParams.y; 78 ret -= isBehind * (1.0 / (1.0 + diff * diff)); 79 } 80 81 ret /= float(maxCt); // divide by number of samples; 82 // Blend between soft and hard based on softness param 83 // NOTE : the 0.72974 is actually an gamma-inverted 0.5 (assuming gamma 2.2) 84 // Would not need this if we linearized color instead. 85 float hardCut = (ret <= 0.72974) ? 0.0 : 1.0; 86 ret = shadowParams.z * ret + (1.0 - shadowParams.z) * hardCut; 87 88 // Blend between full and no occlusion based on strength param 89 ret = shadowParams.x * ret + (1.0 - shadowParams.x); 90 91 return ret; 92} 93 94// For reference 95/* 96float glossyOcclusionBasis(sampler2D depthSampler, mat3 tanFrame, vec3 worldPos, mat4 viewProj, vec3 viewDir, vec4 shadowParams, vec2 camProps, float roughness) 97{ 98 float ret = 16.0; 99 100 float kernel[16]; 101 kernel[0] = 0.5; kernel[1] = 0.25; 102 kernel[2] = 0.75; kernel[3] = 0.125; 103 kernel[4] = 0.625; kernel[5] = 0.375; 104 kernel[6] = 0.875; kernel[7] = 0.0625; 105 kernel[8] = 0.5625; kernel[9] = 0.3125; 106 kernel[10] = 0.8125; kernel[11] = 0.1875; 107 kernel[12] = 0.6875; kernel[13] = 0.4375; 108 kernel[14] = 0.9375; kernel[15] = 0.03125; 109 110 float rough = clamp(roughness, 0.0001, 1.0); 111 float normFac = 1.0 / (rough); 112 113 float phiShift = hashRot( gl_FragCoord.xy ); 114 ivec2 iCoords = ivec2( gl_FragCoord.xy ); 115 float depth = getDepthValue( texelFetch(depthSampler, iCoords, 0) ); 116 depth = depthValueToLinearDistance( depth, camProps ); 117 118 for( int i = 0; i < 16; ++i ) 119 { 120 vec3 localDir; 121 float phi = 6.28318530718 * (kernel[i] + phiShift); 122 float cosTheta = sqrt( float(i+1) / 33.0); 123 localDir.z = sqrt(1.0 - cosTheta*cosTheta) * normFac; 124 localDir.x = cos(phi) * cosTheta; 125 localDir.y = sin(phi) * cosTheta; 126 127 localDir = normalize(localDir); 128 129 vec3 halfDir = tanFrame[0]*localDir.x + tanFrame[1]*localDir.y + tanFrame[2]*localDir.z; 130 vec3 ray = reflect( -viewDir, halfDir ) * shadowParams.x; 131 132 vec4 samplePos = vec4( worldPos + ray, 1.0 ); 133 134 vec4 sampleProj = viewProj * samplePos; 135 sampleProj /= sampleProj.w; 136 sampleProj.xy = (sampleProj.xy + 1.0) * 0.5; 137 float sampleDepth = getDepthValue( texture(depthSampler, sampleProj.xy) ); 138 139 sampleDepth = depthValueToLinearDistance( sampleDepth, camProps ); 140 141 // Occlusion is applied based on a Cauchy distribution filter 142 // But with a "dead zone" for the very close samples. By subtracting it from 16, 143 // which represents no occlusion (16/16 = 1), we let nearby occluders have a 144 // lot of effect, but far away occluders do not. Furthermore, the "dead zone" 145 // in the filter means that the extremely near (which we assume to be part of the 146 // same surface) are also excluded to try and limit self-occlusion. 147 float occlDist = 4.0 * max(depth - sampleDepth - shadowParams.y, 0.0) / shadowParams.x; 148 float occlFactor = 1.0 / ( 1.0 + occlDist*occlDist*0.04 ); 149 occlFactor -= 1.0 / ( 1.0 + occlDist*occlDist*4.0 ); 150 ret -= min(2.0 * occlFactor, 1.0); 151 } 152 153 ret /= 16.0; // divide by number of samples; 154 return ret; 155} 156*/ 157 158#endif 159