diff --git a/Shaders/std/light.glsl b/Shaders/std/light.glsl index ea3871fc..d5172808 100644 --- a/Shaders/std/light.glsl +++ b/Shaders/std/light.glsl @@ -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; diff --git a/blender/arm/material/make_cluster.py b/blender/arm/material/make_cluster.py index 9428f996..6864386d 100644 --- a/blender/arm/material/make_cluster.py +++ b/blender/arm/material/make_cluster.py @@ -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 \ No newline at end of file + frag.write('}') # for numLights diff --git a/blender/arm/material/make_mesh.py b/blender/arm/material/make_mesh.py index 5965e850..72a93975 100644 --- a/blender/arm/material/make_mesh.py +++ b/blender/arm/material/make_mesh.py @@ -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: