Faster shadow sample
This commit is contained in:
parent
62b23aa2f0
commit
bf639496e9
|
@ -109,6 +109,7 @@ uniform vec2 cameraPlane;
|
|||
#ifdef _ShadowMap
|
||||
#ifdef _ShadowMapCube
|
||||
uniform vec2 lightProj;
|
||||
// uniform samplerCubeShadow shadowMap0; //arm_dev
|
||||
uniform samplerCube shadowMap0;
|
||||
// uniform samplerCube shadowMap1;
|
||||
// uniform samplerCube shadowMap2;
|
||||
|
@ -140,6 +141,7 @@ uniform vec2 cameraPlane;
|
|||
uniform vec3 sunDir;
|
||||
uniform vec3 sunCol;
|
||||
#ifdef _ShadowMap
|
||||
// uniform sampler2DShadow shadowMap; // arm_dev
|
||||
uniform sampler2D shadowMap;
|
||||
uniform float shadowsBias;
|
||||
#ifdef _CSM
|
||||
|
@ -360,6 +362,9 @@ void main() {
|
|||
#ifdef _Clusters
|
||||
|
||||
float depthl = linearize(depth * 0.5 + 0.5, cameraProj);
|
||||
#ifdef HLSL
|
||||
depthl += texture(clustersData, vec2(0.0)).r * 1e-9; // TODO: krafix bug, needs to generate sampler
|
||||
#endif
|
||||
int clusterI = getClusterI(texCoord, depthl, cameraPlane);
|
||||
int numLights = int(texelFetch(clustersData, ivec2(clusterI, 0), 0).r * 255);
|
||||
|
||||
|
|
|
@ -1,27 +1,17 @@
|
|||
#include "compiled.inc"
|
||||
|
||||
// uniform sampler2D shadowMap;
|
||||
// uniform samplerCube shadowMapCube;
|
||||
// uniform sampler2DShadow shadowMap;
|
||||
// uniform samplerCubeShadow shadowMapCube;
|
||||
|
||||
#ifdef _CSM
|
||||
uniform vec4 casData[shadowmapCascades * 4 + 4];
|
||||
#endif
|
||||
|
||||
float shadowCompare(sampler2D shadowMap, const vec2 uv, const float compare) {
|
||||
float depth = texture(shadowMap, uv).r;
|
||||
return step(compare, depth);
|
||||
}
|
||||
|
||||
float shadowLerp(sampler2D shadowMap, const vec2 uv, const float compare, const vec2 smSize) {
|
||||
const vec2 texelSize = vec2(1.0) / smSize;
|
||||
vec2 f = fract(uv * smSize + 0.5);
|
||||
vec2 centroidUV = floor(uv * smSize + 0.5) / smSize;
|
||||
float lb = shadowCompare(shadowMap, centroidUV, compare);
|
||||
float lt = shadowCompare(shadowMap, centroidUV + texelSize * vec2(0.0, 1.0), compare);
|
||||
float rb = shadowCompare(shadowMap, centroidUV + texelSize * vec2(1.0, 0.0), compare);
|
||||
float rt = shadowCompare(shadowMap, centroidUV + texelSize, compare);
|
||||
float lb = step(compare, texture(shadowMap, centroidUV).r);
|
||||
float lt = step(compare, texture(shadowMap, centroidUV + texelSize * vec2(0.0, 1.0)).r);
|
||||
float rb = step(compare, texture(shadowMap, centroidUV + texelSize * vec2(1.0, 0.0)).r);
|
||||
float rt = step(compare, texture(shadowMap, centroidUV + texelSize).r);
|
||||
float a = mix(lb, lt, f.y);
|
||||
float b = mix(rb, rt, f.y);
|
||||
float c = mix(a, b, f.x);
|
||||
|
@ -41,6 +31,20 @@ float PCF(sampler2D shadowMap, const vec2 uv, const float compare, const vec2 sm
|
|||
return result / 9.0;
|
||||
}
|
||||
|
||||
// arm_dev
|
||||
float PCF(sampler2DShadow shadowMap, const vec2 uv, const float compare, const vec2 smSize) {
|
||||
float result = texture(shadowMap, vec3(uv + (vec2(-1.0, -1.0) / smSize), compare));
|
||||
result += texture(shadowMap, vec3(uv + (vec2(-1.0, 0.0) / smSize), compare));
|
||||
result += texture(shadowMap, vec3(uv + (vec2(-1.0, 1.0) / smSize), compare));
|
||||
result += texture(shadowMap, vec3(uv + (vec2(0.0, -1.0) / smSize), compare));
|
||||
result += texture(shadowMap, vec3(uv, compare));
|
||||
result += texture(shadowMap, vec3(uv + (vec2(0.0, 1.0) / smSize), compare));
|
||||
result += texture(shadowMap, vec3(uv + (vec2(1.0, -1.0) / smSize), compare));
|
||||
result += texture(shadowMap, vec3(uv + (vec2(1.0, 0.0) / smSize), compare));
|
||||
result += texture(shadowMap, vec3(uv + (vec2(1.0, 1.0) / smSize), compare));
|
||||
return result / 9.0;
|
||||
}
|
||||
|
||||
float lpToDepth(vec3 lp, const vec2 lightProj) {
|
||||
lp = abs(lp);
|
||||
float zcomp = max(lp.x, max(lp.y, lp.z));
|
||||
|
@ -62,31 +66,33 @@ float PCFCube(samplerCube shadowMapCube, const vec3 lp, vec3 ml, const float bia
|
|||
result += step(compare, texture(shadowMapCube, ml + vec3(s, -s, -s)).r);
|
||||
result += step(compare, texture(shadowMapCube, ml + vec3(-s, s, -s)).r);
|
||||
result += step(compare, texture(shadowMapCube, ml + vec3(-s, -s, -s)).r);
|
||||
result /= 9.0;
|
||||
return result;
|
||||
return result / 9.0;
|
||||
}
|
||||
|
||||
float PCFCube2(samplerCube shadowMapCube, const vec3 lp, vec3 ml, const float bias, const vec2 lightProj) {
|
||||
const float s = shadowmapCubePcfSize;
|
||||
float compare = lpToDepth(lp, lightProj) - bias * 0.4;
|
||||
float result = step(compare, texture(shadowMapCube, ml).r);
|
||||
result += step(compare, texture(shadowMapCube, ml + vec3(s, s, s)).r);
|
||||
result += step(compare, texture(shadowMapCube, ml + vec3(-s, s, s)).r);
|
||||
result += step(compare, texture(shadowMapCube, ml + vec3(s, -s, s)).r);
|
||||
result += step(compare, texture(shadowMapCube, ml + vec3(s, s, -s)).r);
|
||||
result += step(compare, texture(shadowMapCube, ml + vec3(-s, -s, s)).r);
|
||||
result += step(compare, texture(shadowMapCube, ml + vec3(s, -s, -s)).r);
|
||||
result += step(compare, texture(shadowMapCube, ml + vec3(-s, s, -s)).r);
|
||||
result += step(compare, texture(shadowMapCube, ml + vec3(-s, -s, -s)).r);
|
||||
result /= 9.0;
|
||||
return result;
|
||||
float PCFCube(samplerCubeShadow shadowMapCube, const vec3 lp, vec3 ml, const float bias, const vec2 lightProj, const vec3 n) {
|
||||
const float s = shadowmapCubePcfSize; // TODO: incorrect...
|
||||
float compare = lpToDepth(lp - n * bias * 80, lightProj);
|
||||
ml = ml + n * bias * 80;
|
||||
float result = texture(shadowMapCube, vec4(ml, compare));
|
||||
result += texture(shadowMapCube, vec4(ml + vec3(s, s, s), compare));
|
||||
result += texture(shadowMapCube, vec4(ml + vec3(-s, s, s), compare));
|
||||
result += texture(shadowMapCube, vec4(ml + vec3(s, -s, s), compare));
|
||||
result += texture(shadowMapCube, vec4(ml + vec3(s, s, -s), compare));
|
||||
result += texture(shadowMapCube, vec4(ml + vec3(-s, -s, s), compare));
|
||||
result += texture(shadowMapCube, vec4(ml + vec3(s, -s, -s), compare));
|
||||
result += texture(shadowMapCube, vec4(ml + vec3(-s, s, -s), compare));
|
||||
result += texture(shadowMapCube, vec4(ml + vec3(-s, -s, -s), compare));
|
||||
return result / 9.0;
|
||||
}
|
||||
|
||||
float shadowTest(sampler2D shadowMap, const vec3 lPos, const float shadowsBias, const vec2 smSize) {
|
||||
|
||||
// Out of bounds
|
||||
if (lPos.x < 0.0 || lPos.y < 0.0 || lPos.x > 1.0 || lPos.y > 1.0) return 1.0;
|
||||
return PCF(shadowMap, lPos.xy, lPos.z - shadowsBias, smSize);
|
||||
}
|
||||
|
||||
// arm_dev
|
||||
float shadowTest(sampler2DShadow shadowMap, const vec3 lPos, const float shadowsBias, const vec2 smSize) {
|
||||
if (lPos.x < 0.0 || lPos.y < 0.0 || lPos.x > 1.0 || lPos.y > 1.0) return 1.0;
|
||||
return PCF(shadowMap, lPos.xy, lPos.z - shadowsBias, smSize);
|
||||
}
|
||||
|
||||
|
@ -165,4 +171,48 @@ float shadowTestCascade(sampler2D shadowMap, const vec3 eye, const vec3 p, const
|
|||
// if (ci == 8) albedo.rgb = vec3(0.0, 0.0, 1.0);
|
||||
// if (ci == 12) albedo.rgb = vec3(1.0, 1.0, 0.0);
|
||||
}
|
||||
|
||||
// arm_dev
|
||||
float shadowTestCascade(sampler2DShadow shadowMap, const vec3 eye, const vec3 p, const float shadowsBias, const vec2 smSize) {
|
||||
const int c = shadowmapCascades;
|
||||
float d = distance(eye, p);
|
||||
|
||||
int casi;
|
||||
int casIndex;
|
||||
mat4 LWVP = getCascadeMat(d, casi, casIndex);
|
||||
|
||||
vec4 lPos = LWVP * vec4(p, 1.0);
|
||||
|
||||
float visibility = 1.0;
|
||||
if (lPos.w > 0.0) visibility = shadowTest(shadowMap, lPos.xyz / lPos.w, shadowsBias, smSize);
|
||||
|
||||
// Blend cascade
|
||||
// https://github.com/TheRealMJP/Shadows
|
||||
const float blendThres = 0.15;
|
||||
float nextSplit = casData[c * 4][casi];
|
||||
float splitSize = casi == 0 ? nextSplit : nextSplit - casData[c * 4][casi - 1];
|
||||
float splitDist = (nextSplit - d) / splitSize;
|
||||
if (splitDist <= blendThres && casi != c - 1) {
|
||||
int casIndex2 = casIndex + 4;
|
||||
mat4 LWVP2 = mat4(
|
||||
casData[casIndex2 + 0],
|
||||
casData[casIndex2 + 1],
|
||||
casData[casIndex2 + 2],
|
||||
casData[casIndex2 + 3]);
|
||||
|
||||
vec4 lPos2 = LWVP2 * vec4(p, 1.0);
|
||||
float visibility2 = 1.0;
|
||||
if (lPos2.w > 0.0) visibility2 = shadowTest(shadowMap, lPos2.xyz / lPos2.w, shadowsBias, smSize);
|
||||
|
||||
float lerpAmt = smoothstep(0.0, blendThres, splitDist);
|
||||
return mix(visibility2, visibility, lerpAmt);
|
||||
}
|
||||
return visibility;
|
||||
|
||||
// Visualize cascades
|
||||
// if (ci == 0) albedo.rgb = vec3(1.0, 0.0, 0.0);
|
||||
// if (ci == 4) albedo.rgb = vec3(0.0, 1.0, 0.0);
|
||||
// if (ci == 8) albedo.rgb = vec3(0.0, 0.0, 1.0);
|
||||
// if (ci == 12) albedo.rgb = vec3(1.0, 1.0, 0.0);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -429,9 +429,19 @@ class RenderPathDeferred {
|
|||
|
||||
#if rp_decals
|
||||
{
|
||||
// path.setTarget("gbuffer0", ["gbuffer1"]);
|
||||
#if arm_dev
|
||||
path.setDepthFrom("gbuffer0", "gbuffer1"); // Unbind depth so we can read it
|
||||
path.depthToRenderTarget.set("main", path.renderTargets.get("tex"));
|
||||
path.setTarget("gbuffer0", ["gbuffer1"]);
|
||||
#end
|
||||
|
||||
path.bindTarget("_main", "gbufferD");
|
||||
path.drawDecals("decal");
|
||||
|
||||
#if arm_dev
|
||||
path.setDepthFrom("gbuffer0", "tex"); // Re-bind depth
|
||||
path.depthToRenderTarget.set("main", path.renderTargets.get("gbuffer0"));
|
||||
#end
|
||||
}
|
||||
#end
|
||||
|
||||
|
@ -553,7 +563,7 @@ class RenderPathDeferred {
|
|||
Inc.drawShadowMap();
|
||||
#end
|
||||
|
||||
path.setDepthFrom("tex", "gbuffer1"); // Unbind depth form tex so we can read it
|
||||
path.setDepthFrom("tex", "gbuffer1"); // Unbind depth so we can read it
|
||||
path.setTarget("tex");
|
||||
path.bindTarget("_main", "gbufferD");
|
||||
path.bindTarget("gbuffer0", "gbuffer0");
|
||||
|
|
|
@ -142,7 +142,7 @@ def parse_shader(sres, c, con, defs, lines, parse_attributes):
|
|||
cid = cid[:-1]
|
||||
|
||||
found = False # Unique check
|
||||
if ctype == 'sampler2D' or ctype == 'sampler2DShadow' or ctype == 'sampler3D' or ctype == 'samplerCube' or ctype == 'image2D' or ctype == 'uimage2D' or ctype == 'image3D' or ctype == 'uimage3D': # Texture unit
|
||||
if ctype.startswith('sampler') or ctype.startswith('image') or ctype.startswith('uimage'): # Texture unit
|
||||
for tu in con['texture_units']: # Texture already present
|
||||
if tu['name'] == cid:
|
||||
found = True
|
||||
|
@ -151,7 +151,7 @@ def parse_shader(sres, c, con, defs, lines, parse_attributes):
|
|||
tu = {}
|
||||
tu['name'] = cid
|
||||
# sampler2D / image2D
|
||||
if ctype == 'image2D' or ctype == 'uimage2D' or ctype == 'image3D' or ctype == 'uimage3D':
|
||||
if ctype.startswith('image') or ctype.startswith('uimage'):
|
||||
tu['is_image'] = True
|
||||
# Check for link
|
||||
for l in c['links']:
|
||||
|
|
|
@ -5,7 +5,8 @@ import arm.material.make_mesh as make_mesh
|
|||
import arm.utils
|
||||
|
||||
def make(context_id):
|
||||
con_decal = mat_state.data.add_context({ 'name': context_id, 'depth_write': False, 'compare_mode': 'less', 'cull_mode': 'clockwise',
|
||||
# 'compare_mode': 'less' needs read-only depth view
|
||||
con_decal = mat_state.data.add_context({ 'name': context_id, 'depth_write': False, 'compare_mode': 'always', 'cull_mode': 'clockwise',
|
||||
'blend_source': 'source_alpha',
|
||||
'blend_destination': 'inverse_source_alpha',
|
||||
'blend_operation': 'add',
|
||||
|
@ -39,6 +40,9 @@ def make(context_id):
|
|||
|
||||
frag.write_attrib(' vec2 screenPosition = wvpposition.xy / wvpposition.w;')
|
||||
frag.write_attrib(' vec2 depthCoord = screenPosition * 0.5 + 0.5;')
|
||||
frag.write_attrib('#ifdef HLSL')
|
||||
frag.write_attrib(' depthCoord.y = 1.0 - depthCoord.y;')
|
||||
frag.write_attrib('#endif')
|
||||
frag.write_attrib(' float depth = texture(gbufferD, depthCoord).r * 2.0 - 1.0;')
|
||||
|
||||
frag.write_attrib(' vec3 wpos = getPos2(invVP, depth, depthCoord);')
|
||||
|
|
|
@ -736,10 +736,13 @@ def make_forward_base(con_mesh, parse_opacity=False):
|
|||
vert.write('wvpposition = gl_Position;')
|
||||
# wvpposition.z / wvpposition.w
|
||||
frag.write('float depthl = linearize(gl_FragCoord.z, cameraProj);')
|
||||
frag.write('#ifdef HLSL')
|
||||
frag.write('depthl += texture(clustersData, vec2(0.0)).r * 1e-9;') # TODO: krafix bug, needs to generate sampler
|
||||
frag.write('#endif')
|
||||
frag.write('int clusterI = getClusterI((wvpposition.xy / wvpposition.w) * 0.5 + 0.5, depthl, cameraPlane);')
|
||||
frag.write('int numLights = int(texelFetch(clustersData, ivec2(clusterI, 0), 0).r * 255);')
|
||||
|
||||
frag.write('for (int i = 0; i < numLights; i++) {')
|
||||
frag.write('for (int i = 0; i < min(numLights, maxLightsCluster); i++) {')
|
||||
frag.write('int li = int(texelFetch(clustersData, ivec2(clusterI, i + 1), 0).r * 255);')
|
||||
frag.write('vec3 lp = lightsArray[li * 2].xyz;')
|
||||
frag.write('vec3 ld = lp - wposition;')
|
||||
|
|
Loading…
Reference in a new issue