diff options
Diffstat (limited to 'res/effectlib/gles2/sampleProbe.glsllib')
-rw-r--r-- | res/effectlib/gles2/sampleProbe.glsllib | 324 |
1 files changed, 0 insertions, 324 deletions
diff --git a/res/effectlib/gles2/sampleProbe.glsllib b/res/effectlib/gles2/sampleProbe.glsllib deleted file mode 100644 index fb202e5..0000000 --- a/res/effectlib/gles2/sampleProbe.glsllib +++ /dev/null @@ -1,324 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SAMPLE_PROBE_GLSLLIB -#define SAMPLE_PROBE_GLSLLIB 1 - -#ifndef QT3DS_ENABLE_LIGHT_PROBE_2 -#define QT3DS_ENABLE_LIGHT_PROBE_2 0 -#endif - -#ifndef QT3DS_ENABLE_IBL_FOV -#define QT3DS_ENABLE_IBL_FOV 0 -#endif - -#define USE_RGBE - -uniform sampler2D light_probe; -uniform vec4 light_probe_props; -uniform vec4 light_probe_rotation; -uniform vec4 light_probe_offset; // light_probe_offset.w = number of mipmaps -uniform vec2 light_probe_size; - -#if QT3DS_ENABLE_LIGHT_PROBE_2 -uniform sampler2D light_probe2; -uniform vec4 light_probe2_props; -uniform vec2 light_probe2_size; -#endif - -#if QT3DS_ENABLE_IBL_FOV -uniform vec4 light_probe_opts; -#endif - -float noise1d(vec2 n) -{ - return 0.5 + 0.5 * fract(sin(dot(n.xy, vec2(12.9898, 78.233)))* 43758.5453); -} - -mat3 orthoNormalize( in mat3 tanFrame ) -{ - mat3 outMat; - outMat[0] = normalize( cross( tanFrame[1], tanFrame[2] ) ); - outMat[1] = normalize( cross( tanFrame[2], outMat[0] ) ); - outMat[2] = tanFrame[2]; - - return outMat; -} - -mat3 tangentFrame( vec3 N, vec3 p ) -{ - // get edge vectors of the pixel triangle - vec3 dp1 = dFdx( p ); - vec3 dp2 = dFdy( p ); - // solve the linear system - vec3 dp2perp = cross( dp2, N ); - vec3 dp1perp = cross( N, dp1 ); - vec3 T = normalize(dp1perp); - vec3 B = normalize(dp2perp); - return mat3( T , B , N ); -} - -vec2 transformSample( vec2 origUV, vec4 probeRot, vec2 probeOfs ) -{ - vec2 retUV; - retUV.x = dot( vec3(origUV, 1.0), vec3(probeRot.xy, probeOfs.x) ); - retUV.y = dot( vec3(origUV, 1.0), vec3(probeRot.zw, probeOfs.y) ); - return retUV; -} - -vec3 textureProbe(sampler2D lightProbe, vec2 coord, float lod) -{ -#ifdef USE_RGBE - vec4 ret = textureLod(lightProbe, coord, lod); - return ret.rgb * pow(2.0, ret.a * 255.0 - 128.0); -#else - return textureLod(lightProbe, coord, lod).rgb; -#endif -} - -// This is broken out into its own routine so that if we get some other -// format image than a lat-long, then we can account for that by changing -// the code here alone. -vec2 getProbeSampleUV( vec3 smpDir, vec4 probeRot, vec2 probeOfs ) -{ - vec2 smpUV; - -#if QT3DS_ENABLE_IBL_FOV - smpUV.x = (2.0 * atan(-smpDir.z, smpDir.x) + 3.14159265358 ) / light_probe_opts.x; - smpUV.y = (2.0 * atan(-smpDir.z, smpDir.y) + 3.14159265358 ) / light_probe_opts.x; -#else - smpUV.x = atan( smpDir.x, -smpDir.z) / 3.14159265359; - smpUV.y = 1.0 - (acos(smpDir.y) / 1.57079632679); -#endif - smpUV = transformSample( smpUV.xy * 0.5, probeRot, probeOfs ) + vec2(0.5, 0.5); - - return smpUV; -} - -vec4 getTopLayerSample( vec3 inDir, float lodShift, vec3 lodOffsets ) -{ -#if QT3DS_ENABLE_LIGHT_PROBE_2 - if ( light_probe2_props.w < 0.5 ) - return vec4(0.0, 0.0, 0.0, 0.0); - - vec2 smpUV = getProbeSampleUV( inDir, vec4(1.0, 0.0, 0.0, 1.0), light_probe_props.xy ); - smpUV.x -= 0.5; - smpUV.x *= light_probe2_props.x; - smpUV.x += light_probe2_props.y; - - vec4 retVal = 0.4 * textureLod( light_probe2, smpUV , lodShift ); - retVal += 0.2 * textureLod( light_probe2, smpUV , lodShift+lodOffsets.x ); - retVal += 0.3 * textureLod( light_probe2, smpUV , lodShift+lodOffsets.y ); - retVal += 0.1 * textureLod( light_probe2, smpUV , lodShift+lodOffsets.z ); - return retVal; -#else - return vec4(0.0, 0.0, 0.0, 0.0); -#endif -} - -vec3 getProbeSample( vec3 smpDir, float lodShift, vec3 normal ) -{ - vec2 smpUV = getProbeSampleUV( smpDir, light_probe_rotation, light_probe_offset.xy ); - return textureProbe( light_probe, smpUV , lodShift ); -} - -vec3 getProbeWeightedSample( vec3 smpDir, float lodShift, float roughness, vec3 normal ) -{ - // This gives us a weighted sum that approximates the total filter support - // of the full-blown convolution. - vec2 smpUV = getProbeSampleUV( smpDir, light_probe_rotation, light_probe_offset.xy ); - float wt = 1.0; - -#if QT3DS_ENABLE_IBL_FOV - wt = min(wt, smoothstep(roughness * -0.25, roughness * 0.25, smpUV.x)); - wt = min(wt, smoothstep(roughness * -0.25, roughness * 0.25, smpUV.y)); - wt = min(wt, 1.0 - smoothstep(1.0 - roughness*0.25, 1.0 + roughness*0.25, smpUV.x)); - wt = min(wt, 1.0 - smoothstep(1.0 - roughness*0.25, 1.0 + roughness*0.25, smpUV.y)); -#endif - - vec3 lodOffsets; - lodOffsets.x = mix(-2.0, -0.70710678, roughness); - lodOffsets.y = min( 2.0 * smoothstep(0.0, 0.1, roughness), 2.0 - 1.29289 * smoothstep(0.1, 1.0, roughness) ); - lodOffsets.z = min( 6.0 * smoothstep(0.0, 0.1, roughness), 6.0 - 4.585786 * smoothstep(0.1, 1.0, roughness) ); - - ivec2 iSize = ivec2(light_probe_size); - vec3 ddx = dFdx( smpDir ) * float(iSize.x); - vec3 ddy = dFdy( smpDir ) * float(iSize.y); -// vec2 ddxUV = dFdx( smpUV ) * float(iSize.x); -// vec2 ddyUV = dFdy( smpUV ) * float(iSize.y); - - vec2 deriv; - deriv.x = max( dot(ddx, ddx), dot(ddy, ddy) ); -// deriv.y = max( dot(ddxUV, ddxUV), dot(ddyUV, ddyUV) ); - deriv = clamp( deriv, vec2(1.0), vec2(iSize.x * iSize.y) ); - vec2 lodBound = 0.5 * log2( deriv ) - vec2(1.0); - -// float minLod = 0.5 * (lodBound.x + lodBound.y); - float minLod = lodBound.x; - float maxLod = log2( max(float(iSize.x), float(iSize.y)) ); - minLod = clamp( minLod / maxLod, 0.0, 1.0 ); - minLod *= minLod * maxLod; - - lodShift = max( lodShift, minLod ); - - vec3 retVal = 0.4 * textureProbe( light_probe, smpUV , lodShift ); - retVal += 0.2 * textureProbe( light_probe, smpUV , max(minLod, lodShift+lodOffsets.x) ); - retVal += 0.3 * textureProbe( light_probe, smpUV , lodShift+lodOffsets.y ); - retVal += 0.1 * textureProbe( light_probe, smpUV , lodShift+lodOffsets.z ); - -#if QT3DS_ENABLE_LIGHT_PROBE_2 - vec4 topSmp = getTopLayerSample( smpDir, lodShift, lodOffsets ); - vec3 tempVal = mix( retVal, topSmp.xyz, topSmp.w ); - retVal = mix( retVal, tempVal, light_probe2_props.z ); -#endif - - if (light_probe_props.z > -1.0) { - float ctr = 0.5 + 0.5 * light_probe_props.z; - float vertWt = smoothstep(ctr-roughness*0.25, ctr+roughness*0.25, smpUV.y); - float wtScaled = mix(1.0, vertWt, light_probe_props.z + 1.0); - retVal *= wtScaled; - } - - return retVal * wt; -} - -vec2 textureSizeLod( vec2 size, int level ) -{ - return size / pow(2.0, float(level)); -} - -vec3 getProbeAnisoSample( vec3 smpDir, float roughU, float roughV, mat3 tanFrame ) -{ - float minRough = min(roughU, roughV); - float maxRough = max(roughU, roughV); - - float lodMin = log2( (minRough*3.0 + maxRough)*0.25 ) + (light_probe_offset.w - 2.0); - - float ratio = clamp( maxRough / minRough, 1.01, 27.0); - vec2 texSize = textureSizeLod( light_probe_size, int(floor( lodMin )) ); - texSize = mix( texSize, texSize * 0.5, fract(lodMin) ); - - // Boundary of 1.0..9.0 is just to keep the number of samples to within a - // reasonable number of samples in the filter. Similarly, with the clamping - // of the ratio to a max of 27.0 is just to prevent the step size in the filter - // to be no bigger than 3 texels (beyond which, there are some artifacts at high - // roughness, aka low texture res). - float stepFig = clamp(floor( ratio ), 1.0, 9.0); - - // numSteps is half the number of samples we need to take, which makes it - // the number of steps to take on each side. - int numSteps = int( floor(stepFig * 0.5) ); - - vec2 smpUV = getProbeSampleUV( smpDir, light_probe_rotation, light_probe_offset.xy ); - vec4 result = vec4(0.0); - - vec3 smpDirOfs = (maxRough == roughU) ? 0.01 * tanFrame[0] : 0.01 * tanFrame[1]; - vec2 stepPos = getProbeSampleUV(normalize(smpDir + smpDirOfs), light_probe_rotation, light_probe_offset.xy); - vec2 stepNeg = getProbeSampleUV(normalize(smpDir - smpDirOfs), light_probe_rotation, light_probe_offset.xy); - stepPos -= smpUV; stepNeg -= smpUV; - stepPos *= texSize; stepNeg *= texSize; - - // This ensures that we step along a size that makes sense even if one of the two - // sammpling directions wraps around the edges of the IBL texture. - smpDirOfs /= min( length(stepPos), length(stepNeg) ); - smpDirOfs *= ratio / stepFig; - - float sigma = mix(0.0, 2.0, ratio / 27.0); - sigma *= sigma; - - float wt = (1.0 / (ratio - 1.0)) + 1.0; - result.xyz += wt * getProbeWeightedSample( smpDir, lodMin, minRough, tanFrame[2] ); - result.w += wt; - for (int i = 0; i < numSteps; ++i) - { - wt = sigma / (sigma + float(i * i)); - vec2 uv0 = getProbeSampleUV(normalize(smpDir + smpDirOfs * float(i)), light_probe_rotation, light_probe_offset.xy); - vec2 uv1 = getProbeSampleUV(normalize(smpDir - smpDirOfs * float(i)), light_probe_rotation, light_probe_offset.xy); - result.xyz += wt * textureProbe( light_probe, uv0 , lodMin ); - result.w += wt; - result.xyz += wt * textureProbe( light_probe, uv1 , lodMin ); - result.w += wt; - } - - result /= result.w; - return result.xyz; -} - -vec4 sampleDiffuse( mat3 tanFrame ) -{ - if ( light_probe_props.w < 0.005 ) - return vec4( 0.0 ); - - return vec4( light_probe_props.w * getProbeWeightedSample( tanFrame[2], light_probe_offset.w - 2.65149613, 1.0, tanFrame[2] ), 1.0 ); -} - -vec4 sampleDiffuseCustomMaterial( vec3 normal, vec3 worldPos, float aoFactor ) -{ - - mat3 tanFrame = tangentFrame( normal, worldPos ); - return sampleDiffuse( tanFrame ); -} - -vec4 sampleGlossyAniso( mat3 tanFrame, vec3 viewDir, float roughU, float roughV ) -{ - if ( light_probe_props.w < 0.005 ) - return vec4( 0.0 ); - - float sigmaU = smoothstep( 0.0, 1.0, clamp(roughU, 0.0001, 1.0) ); - float sigmaV = smoothstep( 0.0, 1.0, clamp(roughV, 0.0001, 1.0) ); - vec3 ret = vec3(0, 0, 0); - - vec3 smpDir = reflect( -viewDir, tanFrame[2] ); - float sigma = sqrt(sigmaU * sigmaV); - - // Compute the Geometric occlusion/self-shadowing term - float NdotL = clamp( dot( smpDir, tanFrame[2] ), 0.0, 0.999995); - float k = sigma * 0.31830988618; // roughness / pi - float Gl = clamp( (NdotL / (NdotL*(1.0-k) + k) + (1.0 - k*k)) * 0.5, 0.0, 1.0 ); - - vec3 outColor; - - outColor = getProbeAnisoSample( smpDir, sigmaU, sigmaV, tanFrame ); - - return vec4( light_probe_props.w * Gl * outColor, 1.0 ); -} - -vec4 sampleGlossy( mat3 tanFrame, vec3 viewDir, float roughness ) -{ - return sampleGlossyAniso( tanFrame, viewDir, roughness, roughness ); -} - -vec4 sampleGlossyCustomMaterial( vec3 normal, vec3 worldPos, vec3 viewDir, float roughness ) -{ - mat3 tanFrame = tangentFrame( normal, worldPos ); - return sampleGlossy( tanFrame, viewDir, roughness ); -} - -#endif |