summaryrefslogtreecommitdiffstats
path: root/res/effectlib/sampleProbe.glsllib
diff options
context:
space:
mode:
authorAntti Määttä <antti.maatta@qt.io>2019-12-12 14:40:21 +0200
committerAntti Määttä <antti.maatta@qt.io>2019-12-27 11:21:24 +0200
commitc4ed0d6acfc2cb444a5260cbd509a427208f7ac5 (patch)
tree6ceba81778153e8a28f0fa4ef918c2498cb40b51 /res/effectlib/sampleProbe.glsllib
parent71190e5a059eba4c911abcfdd599c2a98d674ed0 (diff)
Optimize and cleanup shaders
Change-Id: Ia27680e20f73ffe645d5a336fad7024e67a8389b Reviewed-by: Janne Kangas <janne.kangas@qt.io> Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io>
Diffstat (limited to 'res/effectlib/sampleProbe.glsllib')
-rw-r--r--res/effectlib/sampleProbe.glsllib206
1 files changed, 67 insertions, 139 deletions
diff --git a/res/effectlib/sampleProbe.glsllib b/res/effectlib/sampleProbe.glsllib
index 361aad5..4846ee3 100644
--- a/res/effectlib/sampleProbe.glsllib
+++ b/res/effectlib/sampleProbe.glsllib
@@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2014 NVIDIA Corporation.
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt 3D Studio.
@@ -31,6 +31,8 @@
#ifndef SAMPLE_PROBE_GLSLLIB
#define SAMPLE_PROBE_GLSLLIB 1
+#include "sampleProbePre.glsllib"
+
#define USE_RGBE
uniform sampler2D light_probe;
@@ -49,37 +51,37 @@ uniform vec4 light_probe_opts;
float noise1d(vec2 n)
{
- return 0.5 + 0.5 * fract(sin(dot(n.xy, vec2(12.9898, 78.233)))* 43758.5453);
+ return 0.5 + 0.5 * fract(sin(dot(n.xy, vec2(12.9898, 78.233))) * 43758.5453);
}
-mat3 orthoNormalize( in mat3 tanFrame )
+mat3 orthoNormalize(in mat3 tanFrame)
{
mat3 outMat;
- outMat[0] = normalize( cross( tanFrame[1], tanFrame[2] ) );
- outMat[1] = normalize( cross( tanFrame[2], outMat[0] ) );
+ 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 )
+mat3 tangentFrame(vec3 N, vec3 p)
{
// get edge vectors of the pixel triangle
- vec3 dp1 = dFdx( p );
- vec3 dp2 = dFdy( p );
+ vec3 dp1 = dFdx(p);
+ vec3 dp2 = dFdy(p);
// solve the linear system
- vec3 dp2perp = cross( dp2, N );
- vec3 dp1perp = cross( N, dp1 );
+ vec3 dp2perp = cross(dp2, N);
+ vec3 dp1perp = cross(N, dp1);
vec3 T = normalize(dp1perp);
vec3 B = normalize(dp2perp);
- return mat3( T , B , N );
+ return mat3(T, B, N);
}
-vec2 transformSample( vec2 origUV, vec4 probeRot, vec2 probeOfs )
+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) );
+ 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;
}
@@ -96,7 +98,7 @@ vec3 textureProbe(sampler2D lightProbe, vec2 coord, float lod)
// 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 getProbeSampleUV(vec3 smpDir, vec4 probeRot, vec2 probeOfs)
{
vec2 smpUV;
@@ -118,86 +120,83 @@ vec2 getProbeSampleUV( vec3 smpDir, vec4 probeRot, vec2 probeOfs )
return smpUV;
}
-vec4 getTopLayerSample( vec3 inDir, float lodShift, vec3 lodOffsets )
+vec4 getTopLayerSample(vec3 inDir, float lodShift, vec3 lodOffsets)
{
#if QT3DS_ENABLE_LIGHT_PROBE_2
- if ( light_probe2_props.w < 0.5 )
+ 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 );
+ 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 );
+ 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 )
+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 );
+ 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 )
+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 );
+ 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));
+ 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) );
+ 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 = textureSize(light_probe, 0);
- 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);
+ ivec2 iSize = lightProbeSize(light_probe, 0);
+ vec3 ddx = dFdx(smpDir) * float(iSize.x);
+ vec3 ddy = dFdy(smpDir) * 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);
+ deriv.x = max(dot(ddx, ddx), dot(ddy, ddy));
+
+ 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 );
+ 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 );
+ 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 );
+ 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 );
+ 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 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;
}
@@ -205,111 +204,40 @@ vec3 getProbeWeightedSample( vec3 smpDir, float lodShift, float roughness, vec3
return retVal * wt;
}
-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 = vec2( textureSize( light_probe, 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 )
+vec4 sampleDiffuse(mat3 tanFrame)
{
- if ( light_probe_props.w < 0.005 )
- return vec4( 0.0 );
+ 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 );
+ 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 )
+vec4 sampleDiffuseCustomMaterial(vec3 normal, vec3 worldPos, float aoFactor)
{
-
- mat3 tanFrame = tangentFrame( normal, worldPos );
- return sampleDiffuse( tanFrame );
+ mat3 tanFrame = tangentFrame(normal, worldPos);
+ return sampleDiffuse(tanFrame);
}
-vec4 sampleGlossyAniso( mat3 tanFrame, vec3 viewDir, float roughU, float roughV )
+vec4 sampleGlossy(mat3 tanFrame, vec3 viewDir, float roughness)
{
- if ( light_probe_props.w < 0.005 )
- return vec4( 0.0 );
+ 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) );
+ float sigma = smoothstep(0.0, 1.0, clamp(roughness, 0.0001, 1.0));
vec3 ret = vec3(0, 0, 0);
- vec3 smpDir = reflect( -viewDir, tanFrame[2] );
- float sigma = sqrt(sigmaU * sigmaV);
+ vec3 smpDir = reflect(-viewDir, tanFrame[2]);
// Compute the Geometric occlusion/self-shadowing term
- float NdotL = clamp( dot( smpDir, tanFrame[2] ), 0.0, 0.999995);
+ 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 );
+ 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 );
-}
+ outColor = getProbeSample(smpDir, sigma, tanFrame[2]);
-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 );
+ return vec4(light_probe_props.w * Gl * outColor, 1.0);
}
#endif