Merge pull request #1770 from MoritzBrueckner/receive-shadow
Implement "receive shadow" setting for mobile path + all light types
This commit is contained in:
commit
ded83d16a1
|
@ -346,7 +346,7 @@ void main() {
|
|||
fragColor.rgb += sampleLight(
|
||||
p, n, v, dotNV, pointPos, pointCol, albedo, roughness, occspec.y, f0
|
||||
#ifdef _ShadowMap
|
||||
, 0, pointBias
|
||||
, 0, pointBias, true
|
||||
#endif
|
||||
#ifdef _Spot
|
||||
, true, spotData.x, spotData.y, spotDir
|
||||
|
@ -400,7 +400,7 @@ void main() {
|
|||
occspec.y,
|
||||
f0
|
||||
#ifdef _ShadowMap
|
||||
, li, lightsArray[li * 2].w // bias
|
||||
, li, lightsArray[li * 2].w, true // bias
|
||||
#endif
|
||||
#ifdef _Spot
|
||||
, li > numPoints - 1
|
||||
|
|
|
@ -182,7 +182,7 @@ void main() {
|
|||
fragColor.rgb += sampleLight(
|
||||
p, n, v, dotNV, pointPos, pointCol, albedo, roughness, occspec.y, f0
|
||||
#ifdef _ShadowMap
|
||||
, 0, pointBias
|
||||
, 0, pointBias, true
|
||||
#endif
|
||||
#ifdef _Spot
|
||||
, true, spotData.x, spotData.y, spotDir
|
||||
|
@ -218,7 +218,7 @@ void main() {
|
|||
occspec.y,
|
||||
f0
|
||||
#ifdef _ShadowMap
|
||||
, li, lightsArray[li * 2].w // bias
|
||||
, li, lightsArray[li * 2].w, true // bias
|
||||
#endif
|
||||
#ifdef _Spot
|
||||
, li > numPoints - 1
|
||||
|
|
|
@ -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,40 +130,7 @@ 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
|
||||
#endif
|
||||
return direct;
|
||||
#endif
|
||||
|
||||
#ifdef _Spot
|
||||
if (isSpot) {
|
||||
float spotEffect = dot(spotDir, l); // lightDir
|
||||
// x - cutoff, y - cutoff - exponent
|
||||
if (spotEffect < spotA) {
|
||||
direct *= smoothstep(spotB, spotA, spotEffect);
|
||||
}
|
||||
#ifdef _ShadowMap
|
||||
if (receiveShadow) {
|
||||
#ifdef _SinglePoint
|
||||
vec4 lPos = LWVPSpot0 * vec4(p + n * bias * 10, 1.0);
|
||||
direct *= shadowTest(shadowMapSpot[0], lPos.xyz / lPos.w, bias);
|
||||
|
@ -186,6 +153,43 @@ vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, co
|
|||
direct *= shadowTest(shadowMapSpot[3], lPos.xyz / lPos.w, bias);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
return direct;
|
||||
#endif
|
||||
|
||||
#ifdef _Spot
|
||||
if (isSpot) {
|
||||
float spotEffect = dot(spotDir, l); // lightDir
|
||||
// x - cutoff, y - cutoff - exponent
|
||||
if (spotEffect < spotA) {
|
||||
direct *= smoothstep(spotB, spotA, spotEffect);
|
||||
}
|
||||
#ifdef _ShadowMap
|
||||
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;
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
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
|
||||
|
@ -60,28 +60,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) {
|
||||
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
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
@ -89,15 +91,17 @@ vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, co
|
|||
|
||||
#ifdef _ShadowMap
|
||||
#ifndef _Spot
|
||||
#ifdef _SinglePoint
|
||||
direct *= PCFCube(shadowMapPoint[0], ld, -l, bias, lightProj, n);
|
||||
#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
|
||||
direct *= PCFCube(shadowMapPoint[0], ld, -l, bias, lightProj, n);
|
||||
#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
|
||||
#endif
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue