Implement receive shadow setting for mobile path + all light types

This commit is contained in:
Moritz Brückner 2020-07-13 23:20:58 +02:00
parent c765561ca6
commit 9a47d77594
3 changed files with 80 additions and 64 deletions

View file

@ -70,7 +70,7 @@ uniform sampler2D sltcMag;
vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, const vec3 lp, const vec3 lightCol,
const vec3 albedo, const float rough, const float spec, const vec3 f0
#ifdef _ShadowMap
, int index, float bias
, int index, float bias, bool receiveShadow
#endif
#ifdef _Spot
, bool isSpot, float spotA, float spotB, vec3 spotDir
@ -130,28 +130,30 @@ vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, co
#ifdef _LTC
#ifdef _ShadowMap
#ifdef _SinglePoint
vec4 lPos = LWVPSpot0 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[0], lPos.xyz / lPos.w, bias);
#endif
#ifdef _Clusters
if (index == 0) {
vec4 lPos = LWVPSpot0 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[0], lPos.xyz / lPos.w, bias);
}
else if (index == 1) {
vec4 lPos = LWVPSpot1 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[1], lPos.xyz / lPos.w, bias);
}
else if (index == 2) {
vec4 lPos = LWVPSpot2 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[2], lPos.xyz / lPos.w, bias);
}
else if (index == 3) {
vec4 lPos = LWVPSpot3 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[3], lPos.xyz / lPos.w, bias);
}
#endif
if (receiveShadow) {
#ifdef _SinglePoint
vec4 lPos = LWVPSpot0 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[0], lPos.xyz / lPos.w, bias);
#endif
#ifdef _Clusters
if (index == 0) {
vec4 lPos = LWVPSpot0 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[0], lPos.xyz / lPos.w, bias);
}
else if (index == 1) {
vec4 lPos = LWVPSpot1 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[1], lPos.xyz / lPos.w, bias);
}
else if (index == 2) {
vec4 lPos = LWVPSpot2 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[2], lPos.xyz / lPos.w, bias);
}
else if (index == 3) {
vec4 lPos = LWVPSpot3 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[3], lPos.xyz / lPos.w, bias);
}
#endif
}
#endif
return direct;
#endif
@ -164,28 +166,30 @@ vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, co
direct *= smoothstep(spotB, spotA, spotEffect);
}
#ifdef _ShadowMap
#ifdef _SinglePoint
vec4 lPos = LWVPSpot0 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[0], lPos.xyz / lPos.w, bias);
#endif
#ifdef _Clusters
if (index == 0) {
vec4 lPos = LWVPSpot0 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[0], lPos.xyz / lPos.w, bias);
}
else if (index == 1) {
vec4 lPos = LWVPSpot1 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[1], lPos.xyz / lPos.w, bias);
}
else if (index == 2) {
vec4 lPos = LWVPSpot2 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[2], lPos.xyz / lPos.w, bias);
}
else if (index == 3) {
vec4 lPos = LWVPSpot3 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[3], lPos.xyz / lPos.w, bias);
}
#endif
if (receiveShadow) {
#ifdef _SinglePoint
vec4 lPos = LWVPSpot0 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[0], lPos.xyz / lPos.w, bias);
#endif
#ifdef _Clusters
if (index == 0) {
vec4 lPos = LWVPSpot0 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[0], lPos.xyz / lPos.w, bias);
}
else if (index == 1) {
vec4 lPos = LWVPSpot1 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[1], lPos.xyz / lPos.w, bias);
}
else if (index == 2) {
vec4 lPos = LWVPSpot2 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[2], lPos.xyz / lPos.w, bias);
}
else if (index == 3) {
vec4 lPos = LWVPSpot3 * vec4(p + n * bias * 10, 1.0);
direct *= shadowTest(shadowMapSpot[3], lPos.xyz / lPos.w, bias);
}
#endif
}
#endif
return direct;
}
@ -196,17 +200,19 @@ vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, co
#endif
#ifdef _ShadowMap
#ifdef _SinglePoint
#ifndef _Spot
direct *= PCFCube(shadowMapPoint[0], ld, -l, bias, lightProj, n);
#endif
#endif
#ifdef _Clusters
if (index == 0) direct *= PCFCube(shadowMapPoint[0], ld, -l, bias, lightProj, n);
else if (index == 1) direct *= PCFCube(shadowMapPoint[1], ld, -l, bias, lightProj, n);
else if (index == 2) direct *= PCFCube(shadowMapPoint[2], ld, -l, bias, lightProj, n);
else if (index == 3) direct *= PCFCube(shadowMapPoint[3], ld, -l, bias, lightProj, n);
#endif
if (receiveShadow) {
#ifdef _SinglePoint
#ifndef _Spot
direct *= PCFCube(shadowMapPoint[0], ld, -l, bias, lightProj, n);
#endif
#endif
#ifdef _Clusters
if (index == 0) direct *= PCFCube(shadowMapPoint[0], ld, -l, bias, lightProj, n);
else if (index == 1) direct *= PCFCube(shadowMapPoint[1], ld, -l, bias, lightProj, n);
else if (index == 2) direct *= PCFCube(shadowMapPoint[2], ld, -l, bias, lightProj, n);
else if (index == 3) direct *= PCFCube(shadowMapPoint[3], ld, -l, bias, lightProj, n);
#endif
}
#endif
return direct;

View file

@ -3,13 +3,14 @@ import bpy
def write(vert, frag):
wrd = bpy.data.worlds['Arm']
is_shadows = '_ShadowMap' in wrd.world_defs
frag.add_include('std/clusters.glsl')
frag.add_uniform('vec2 cameraProj', link='_cameraPlaneProj')
frag.add_uniform('vec2 cameraPlane', link='_cameraPlane')
frag.add_uniform('vec4 lightsArray[maxLights * 2]', link='_lightsArray')
frag.add_uniform('sampler2D clustersData', link='_clustersData')
if is_shadows:
frag.add_uniform('bool receiveShadow')
frag.add_uniform('vec2 lightProj', link='_lightPlaneProj', included=True)
frag.add_uniform('samplerCubeShadow shadowMapPoint[4]', included=True)
vert.add_out('vec4 wvpposition')
@ -36,7 +37,7 @@ def write(vert, frag):
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('direct += sampleLight(')
frag.write(' wposition,')
frag.write(' n,')
@ -49,7 +50,7 @@ def write(vert, frag):
frag.write(' specular,')
frag.write(' f0')
if is_shadows:
frag.write(' , li, lightsArray[li * 2].w') # bias
frag.write(' , li, lightsArray[li * 2].w, receiveShadow') # bias
if '_Spot' in wrd.world_defs:
frag.write(' , li > numPoints - 1')
frag.write(' , lightsArray[li * 2 + 1].w') # cutoff
@ -59,4 +60,4 @@ def write(vert, frag):
frag.write(' , voxels, voxpos')
frag.write(');')
frag.write('}') # for numLights
frag.write('}') # for numLights

View file

@ -366,8 +366,11 @@ def make_forward_mobile(con_mesh):
vert.add_out('vec4 lightPosition')
vert.add_uniform('mat4 LWVP', '_biasLightWorldViewProjectionMatrix')
vert.write('lightPosition = LWVP * spos;')
frag.add_uniform('bool receiveShadow')
frag.add_uniform('sampler2DShadow shadowMap')
frag.add_uniform('float shadowsBias', '_sunShadowsBias')
frag.write('if (receiveShadow) {')
if '_CSM' in wrd.world_defs:
frag.add_include('std/shadows.glsl')
frag.add_uniform('vec4 casData[shadowmapCascades * 4 + 4]', '_cascadeData', included=True)
@ -381,6 +384,7 @@ def make_forward_mobile(con_mesh):
else:
frag.write(' svisibility = texture(shadowMap, vec3(lPos.xy, lPos.z - shadowsBias)).r;')
frag.write('}')
frag.write('}') # receiveShadow
frag.write('direct += basecol * sdotNL * sunCol * svisibility;')
if '_SinglePoint' in wrd.world_defs:
@ -394,8 +398,11 @@ def make_forward_mobile(con_mesh):
frag.write('vec3 l = normalize(ld);')
frag.write('float dotNL = max(dot(n, l), 0.0);')
if is_shadows:
frag.add_uniform('bool receiveShadow')
frag.add_uniform('float pointBias', link='_pointShadowsBias')
frag.add_include('std/shadows.glsl')
frag.write('if (receiveShadow) {')
if '_Spot' in wrd.world_defs:
vert.add_out('vec4 spotPosition')
vert.add_uniform('mat4 LWVPSpot0', link='_biasLightWorldViewProjectionMatrixSpot0')
@ -420,6 +427,7 @@ def make_forward_mobile(con_mesh):
frag.write('visibility = float(texture(shadowMapPoint[0], vec3(-l + n * pointBias * 20)).r > compare);')
else:
frag.write('visibility = texture(shadowMapPoint[0], vec4(-l + n * pointBias * 20, compare)).r;')
frag.write('}') # receiveShadow
frag.write('direct += basecol * dotNL * pointCol * attenuate(distance(wposition, pointPos)) * visibility;')
@ -593,7 +601,7 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
float dotNV = max(dot(n, vVec), 0.0);
""")
sh = tese if tese != None else vert
sh = tese if tese is not None else vert
sh.add_out('vec3 eyeDir')
sh.add_uniform('vec3 eye', '_cameraPosition')
sh.write('eyeDir = eye - wposition;')
@ -645,7 +653,6 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
frag.write('indirect *= vec3(1.0 - traceAO(voxpos, n, voxels));')
frag.write('vec3 direct = vec3(0.0);')
frag.add_uniform('bool receiveShadow')
if '_Sun' in wrd.world_defs:
frag.add_uniform('vec3 sunCol', '_sunColor')
@ -656,6 +663,7 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
frag.write('float sdotNH = dot(n, sh);')
frag.write('float sdotVH = dot(vVec, sh);')
if is_shadows:
frag.add_uniform('bool receiveShadow')
frag.add_uniform('sampler2DShadow shadowMap')
frag.add_uniform('float shadowsBias', '_sunShadowsBias')
frag.write('if (receiveShadow) {')
@ -665,7 +673,7 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
frag.add_uniform('vec3 eye', '_cameraPosition')
frag.write('svisibility = shadowTestCascade(shadowMap, eye, wposition + n * shadowsBias * 10, shadowsBias);')
else:
if tese != None:
if tese is not None:
tese.add_out('vec4 lightPosition')
tese.add_uniform('mat4 LVP', '_biasLightViewProjectionMatrix')
tese.write('lightPosition = LVP * vec4(wposition, 1.0);')
@ -694,6 +702,7 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
frag.add_uniform('vec3 spotDir', link='_spotDirection')
frag.add_uniform('vec2 spotData', link='_spotData')
if is_shadows:
frag.add_uniform('bool receiveShadow')
frag.add_uniform('float pointBias', link='_pointShadowsBias')
if '_Spot' in wrd.world_defs:
# Skip world matrix, already in world-space
@ -705,7 +714,7 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
frag.write('direct += sampleLight(')
frag.write(' wposition, n, vVec, dotNV, pointPos, pointCol, albedo, roughness, specular, f0')
if is_shadows:
frag.write(' , 0, pointBias')
frag.write(' , 0, pointBias, receiveShadow')
if '_Spot' in wrd.world_defs:
frag.write(' , true, spotData.x, spotData.y, spotDir')
if '_VoxelShadow' in wrd.world_defs and '_VoxelAOvar' in wrd.world_defs: