Scaled slope bias and transparent shadows fixes

This commit is contained in:
2026-10-31 01:10:21 -07:00
parent 29f0765864
commit f45ad72056
15 changed files with 126 additions and 48 deletions

View File

@ -636,7 +636,7 @@ void main() {
shadowMap shadowMap
#endif #endif
#endif #endif
, eye, p + n * shadowsBias * 2, shadowsBias , eye, p, n, shadowsBias
#ifdef _ShadowMapTransparent #ifdef _ShadowMapTransparent
, false , false
#endif #endif

View File

@ -259,6 +259,11 @@
"link": "_biasLightWorldViewProjectionMatrixSpotArray", "link": "_biasLightWorldViewProjectionMatrixSpotArray",
"ifdef": ["_Clusters", "_ShadowMap", "_Spot"] "ifdef": ["_Clusters", "_ShadowMap", "_Spot"]
}, },
{
"name": "LWVPSpotArray",
"link": "_biasLightViewProjectionMatrixSpotArray",
"ifdef": ["_SinglePoint", "_ShadowMap", "_Spot"]
},
{ {
"name": "pointLightDataArray", "name": "pointLightDataArray",
"link": "_pointLightsAtlasArray", "link": "_pointLightsAtlasArray",

View File

@ -448,7 +448,7 @@ void main() {
shadowMap shadowMap
#endif #endif
#endif #endif
, eye, p + n * shadowsBias * 2, shadowsBias , eye, p, n, shadowsBias
#ifdef _ShadowMapTransparent #ifdef _ShadowMapTransparent
, false , false
#endif #endif

View File

@ -183,6 +183,11 @@
"link": "_biasLightWorldViewProjectionMatrixSpotArray", "link": "_biasLightWorldViewProjectionMatrixSpotArray",
"ifdef": ["_Clusters", "_ShadowMap", "_Spot"] "ifdef": ["_Clusters", "_ShadowMap", "_Spot"]
}, },
{
"name": "LWVPSpotArray",
"link": "_biasLightViewProjectionMatrixSpotArray",
"ifdef": ["_SinglePoint", "_ShadowMap", "_Spot"]
},
{ {
"name": "pointLightDataArray", "name": "pointLightDataArray",
"link": "_pointLightsAtlasArray", "link": "_pointLightsAtlasArray",

View File

@ -595,3 +595,4 @@ vec3 sampleLightVoxels(const vec3 p, const vec3 n, const vec3 v, const float dot
#endif #endif
#endif #endif

View File

@ -24,7 +24,7 @@ uniform vec2 smSizeUniform;
#ifdef _ShadowMapAtlas #ifdef _ShadowMapAtlas
uniform vec4 tileBoundsSunArray[maxLights * shadowmapCascades]; uniform vec4 tileBoundsSunArray[maxLights * shadowmapCascades];
#if defined(_Clusters) && defined(_Spot) && defined(_ShadowMap) #if defined(_Clusters) && (defined(_Spot) || defined(_LTC)) && defined(_ShadowMap)
uniform vec4 tileBoundsSpotArray[maxLightsCluster]; uniform vec4 tileBoundsSpotArray[maxLightsCluster];
#endif #endif
vec4 tileBounds = vec4(0.0, 0.0, 1.0, 1.0); vec4 tileBounds = vec4(0.0, 0.0, 1.0, 1.0);
@ -180,7 +180,7 @@ vec3 PCFCube(samplerCubeShadow shadowMapCube,
#endif #endif
) { ) {
const float s = shadowmapCubePcfSize; // TODO: incorrect... const float s = shadowmapCubePcfSize; // TODO: incorrect...
float compare = lpToDepth(lp, lightProj) - bias * 1.5; float compare = lpToDepth(lp, lightProj) - bias * 1.5 - 0.0001;
ml = ml + n * bias * 20; ml = ml + n * bias * 20;
#ifdef _InvY #ifdef _InvY
ml.y = -ml.y; ml.y = -ml.y;
@ -321,7 +321,7 @@ vec3 PCFFakeCube(sampler2DShadow shadowMap,
, const bool transparent , const bool transparent
#endif #endif
) { ) {
const float compare = lpToDepth(lp, lightProj) - bias * 1.5; const float compare = lpToDepth(lp, lightProj) - bias * 1.5 - 0.0001;
ml = ml + n * bias * 20; ml = ml + n * bias * 20;
int faceIndex = 0; int faceIndex = 0;
const int lightIndex = index * 6; const int lightIndex = index * 6;
@ -408,10 +408,16 @@ vec3 PCFFakeCube(sampler2DShadow shadowMap,
#ifdef _ShadowMapTransparent #ifdef _ShadowMapTransparent
if (transparent == false) { if (transparent == false) {
vec3 transResult = vec3(0.0); vec3 transResult = vec3(0.0);
vec2 tileMin = pointLightTile.xy;
vec2 tileMax = pointLightTile.xy + pointLightTile.z;
#ifdef _FlipY
tileMin.y = 1.0 - tileMax.y;
tileMax.y = 1.0 - pointLightTile.y;
#endif
for (int x = -1; x <= 1; x++) { for (int x = -1; x <= 1; x++) {
for (int y = -1; y <= 1; y++) { for (int y = -1; y <= 1; y++) {
vec4 smt = texture(shadowMapTransparent, vec4 smt = texture(shadowMapTransparent,
clamp(uvtiled + vec2(x, y) / smSize, 0.0, 1.0)); clamp(uvtiled + vec2(x, y) / smSize, tileMin, tileMax));
transResult += (smt.a < compare) ? smt.rgb : vec3(1.0); transResult += (smt.a < compare) ? smt.rgb : vec3(1.0);
} }
} }
@ -437,15 +443,15 @@ vec3 shadowTest(sampler2DShadow shadowMap,
#ifdef _ShadowMapAtlas #ifdef _ShadowMapAtlas
// use tile PCF // use tile PCF
#ifdef _SMSizeUniform #ifdef _SMSizeUniform
vec2 smSizeAtlas = smSizeUniform * (tileBounds.zw - tileBounds.xy); vec2 smSizeAtlas = smSizeUniform;
#else #else
vec2 smSizeAtlas = shadowmapSize * (tileBounds.zw - tileBounds.xy); vec2 smSizeAtlas = shadowmapSize;
#endif #endif
return PCFTileAware(shadowMap, return PCFTileAware(shadowMap,
#ifdef _ShadowMapTransparent #ifdef _ShadowMapTransparent
shadowMapTransparent, shadowMapTransparent,
#endif #endif
lPos.xy, lPos.z - shadowsBias, smSizeAtlas, lPos.xy, lPos.z - shadowsBias - 0.0001, smSizeAtlas,
tileBounds.xy, tileBounds.zw tileBounds.xy, tileBounds.zw
#ifdef _ShadowMapTransparent #ifdef _ShadowMapTransparent
, transparent , transparent
@ -462,7 +468,7 @@ vec3 shadowTest(sampler2DShadow shadowMap,
#ifdef _ShadowMapTransparent #ifdef _ShadowMapTransparent
shadowMapTransparent, shadowMapTransparent,
#endif #endif
lPos.xy, lPos.z - shadowsBias, smSize lPos.xy, lPos.z - shadowsBias - 0.0001, smSize
#ifdef _ShadowMapTransparent #ifdef _ShadowMapTransparent
, transparent , transparent
#endif #endif
@ -499,11 +505,22 @@ mat4 getCascadeMat(const float d, out int casi, out int casIndex) {
// .. // ..
} }
float worldPerTexel(const mat4 LWVP, const vec2 smSize) {
return max(1.0 / abs(LWVP[0][0]), 1.0 / abs(LWVP[1][1])) / smSize.x;
}
float nlSlopeBias(const vec3 n, const mat4 LWVP, const float wpt) {
vec3 ldir = normalize(vec3(LWVP[0][2], LWVP[1][2], LWVP[2][2]));
float ndotl = max(abs(dot(n, ldir)), 0.05);
float tanTheta = min(sqrt(1.0 - ndotl * ndotl) / ndotl, 1.5);
return wpt * tanTheta * abs(LWVP[2][2]);
}
vec3 shadowTestCascade(sampler2DShadow shadowMap, vec3 shadowTestCascade(sampler2DShadow shadowMap,
#ifdef _ShadowMapTransparent #ifdef _ShadowMapTransparent
sampler2D shadowMapTransparent, sampler2D shadowMapTransparent,
#endif #endif
const vec3 eye, const vec3 p, const float shadowsBias const vec3 eye, const vec3 p, const vec3 n, const float shadowsBias
#ifdef _ShadowMapTransparent #ifdef _ShadowMapTransparent
, const bool transparent , const bool transparent
#endif #endif
@ -522,8 +539,10 @@ vec3 shadowTestCascade(sampler2DShadow shadowMap,
int casi; int casi;
int casIndex; int casIndex;
mat4 LWVP = getCascadeMat(d, casi, casIndex); mat4 LWVP = getCascadeMat(d, casi, casIndex);
vec4 lPos = LWVP * vec4(p, 1.0); float wpt = worldPerTexel(LWVP, smSize);
vec4 lPos = LWVP * vec4(p + n * 0.5 * wpt, 1.0);
lPos.xyz /= lPos.w; lPos.xyz /= lPos.w;
float scaledBias = shadowsBias + nlSlopeBias(n, LWVP, wpt);
#ifdef _ShadowMapAtlas #ifdef _ShadowMapAtlas
tileBounds = tileBoundsSunArray[casi]; tileBounds = tileBoundsSunArray[casi];
@ -536,7 +555,7 @@ vec3 shadowTestCascade(sampler2DShadow shadowMap,
#ifdef _ShadowMapTransparent #ifdef _ShadowMapTransparent
shadowMapTransparent, shadowMapTransparent,
#endif #endif
lPos.xy, lPos.z - shadowsBias, smSize, lPos.xy, lPos.z - scaledBias, smSize,
tileBounds.xy, tileBounds.zw tileBounds.xy, tileBounds.zw
#ifdef _ShadowMapTransparent #ifdef _ShadowMapTransparent
, transparent , transparent
@ -547,7 +566,7 @@ vec3 shadowTestCascade(sampler2DShadow shadowMap,
#ifdef _ShadowMapTransparent #ifdef _ShadowMapTransparent
shadowMapTransparent, shadowMapTransparent,
#endif #endif
lPos.xy, lPos.z - shadowsBias, smSize lPos.xy, lPos.z - scaledBias, smSize
#ifdef _ShadowMapTransparent #ifdef _ShadowMapTransparent
, transparent , transparent
#endif #endif
@ -569,8 +588,10 @@ vec3 shadowTestCascade(sampler2DShadow shadowMap,
casData[casIndex2 + 2], casData[casIndex2 + 2],
casData[casIndex2 + 3]); casData[casIndex2 + 3]);
vec4 lPos2 = LWVP2 * vec4(p, 1.0); float wpt2 = worldPerTexel(LWVP2, smSize);
vec4 lPos2 = LWVP2 * vec4(p + n * 0.5 * wpt2, 1.0);
lPos2.xyz /= lPos2.w; lPos2.xyz /= lPos2.w;
float scaledBias2 = shadowsBias + nlSlopeBias(n, LWVP2, wpt2);
vec3 visibility2 = vec3(1.0); vec3 visibility2 = vec3(1.0);
// use lPos2 coordinates for second cascade, not lPos // use lPos2 coordinates for second cascade, not lPos
#ifdef _ShadowMapAtlas #ifdef _ShadowMapAtlas
@ -582,7 +603,7 @@ vec3 shadowTestCascade(sampler2DShadow shadowMap,
#ifdef _ShadowMapTransparent #ifdef _ShadowMapTransparent
shadowMapTransparent, shadowMapTransparent,
#endif #endif
lPos2.xy, lPos2.z - shadowsBias, smSize, lPos2.xy, lPos2.z - scaledBias2, smSize,
tileBounds.xy, tileBounds.zw tileBounds.xy, tileBounds.zw
#ifdef _ShadowMapTransparent #ifdef _ShadowMapTransparent
, transparent , transparent
@ -593,7 +614,7 @@ vec3 shadowTestCascade(sampler2DShadow shadowMap,
#ifdef _ShadowMapTransparent #ifdef _ShadowMapTransparent
shadowMapTransparent, shadowMapTransparent,
#endif #endif
lPos2.xy, lPos2.z - shadowsBias, smSize lPos2.xy, lPos2.z - scaledBias2, smSize
#ifdef _ShadowMapTransparent #ifdef _ShadowMapTransparent
, transparent , transparent
#endif #endif

View File

@ -674,7 +674,7 @@ class LightObject extends Object {
break; break;
} }
if (discardLightCulled(light)) continue; if (discardLightCulled(light)) continue;
if (light.data.raw.type == type) { if (light.data.raw.type == type || (type == "spot" && light.data.raw.type == "area")) {
m.setFrom(light.VP); m.setFrom(light.VP);
m.multmat(Uniforms.biasMat); m.multmat(Uniforms.biasMat);
#if lnx_shadowmap_atlas #if lnx_shadowmap_atlas
@ -711,8 +711,8 @@ class LightObject extends Object {
LWVPMatrixArray[i * 16 + 13] = m._31; LWVPMatrixArray[i * 16 + 13] = m._31;
LWVPMatrixArray[i * 16 + 14] = m._32; LWVPMatrixArray[i * 16 + 14] = m._32;
LWVPMatrixArray[i * 16 + 15] = m._33; LWVPMatrixArray[i * 16 + 15] = m._33;
i++; // only increment in light type }
} i++;
} }
return LWVPMatrixArray; return LWVPMatrixArray;
} }
@ -791,7 +791,7 @@ class LightObject extends Object {
public static var spotTileBoundsArray: Float32Array = null; public static var spotTileBoundsArray: Float32Array = null;
public static function updateSpotTileBoundsArray(): Float32Array { public static function updateSpotTileBoundsArray(): Float32Array {
var maxLights = getMaxLights(); var maxLights = maxLightsCluster;
if (spotTileBoundsArray == null) { if (spotTileBoundsArray == null) {
spotTileBoundsArray = new Float32Array(maxLights * 4); spotTileBoundsArray = new Float32Array(maxLights * 4);
} }
@ -799,19 +799,20 @@ class LightObject extends Object {
var i = 0; var i = 0;
for (light in Scene.active.lights) { for (light in Scene.active.lights) {
if (i >= maxLights) break; if (i >= maxLights) break;
if (!light.visible || light.data.raw.type != "spot") continue; if (discardLightCulled(light)) continue;
if (!light.data.raw.cast_shadow || light.data.raw.strength == 0.0) continue; if ((light.data.raw.type == "spot" || light.data.raw.type == "area") && light.data.raw.cast_shadow) {
var idx = i * 4; var idx = i * 4;
spotTileBoundsArray[idx ] = light.tileOffsetX[0]; spotTileBoundsArray[idx ] = light.tileOffsetX[0];
spotTileBoundsArray[idx + 2] = light.tileOffsetX[0] + light.tileScale[0]; spotTileBoundsArray[idx + 2] = light.tileOffsetX[0] + light.tileScale[0];
#if (!kha_opengl) #if (!kha_opengl)
// flip bounds // flip bounds
spotTileBoundsArray[idx + 1] = 1.0 - (light.tileOffsetY[0] + light.tileScale[0]); spotTileBoundsArray[idx + 1] = 1.0 - (light.tileOffsetY[0] + light.tileScale[0]);
spotTileBoundsArray[idx + 3] = 1.0 - light.tileOffsetY[0]; spotTileBoundsArray[idx + 3] = 1.0 - light.tileOffsetY[0];
#else #else
spotTileBoundsArray[idx + 1] = light.tileOffsetY[0]; spotTileBoundsArray[idx + 1] = light.tileOffsetY[0];
spotTileBoundsArray[idx + 3] = light.tileOffsetY[0] + light.tileScale[0]; spotTileBoundsArray[idx + 3] = light.tileOffsetY[0] + light.tileScale[0];
#end #end
}
i++; i++;
} }
return spotTileBoundsArray; return spotTileBoundsArray;

View File

@ -928,6 +928,14 @@ class Uniforms {
case "_tileBoundsSunArray": { case "_tileBoundsSunArray": {
fa = LightObject.updateSunTileBoundsArray(); fa = LightObject.updateSunTileBoundsArray();
} }
case "_tileBoundsSpotArray": {
fa = LightObject.updateSpotTileBoundsArray();
}
#end
#if (!lnx_clusters && lnx_spot)
case "_biasLightWorldViewProjectionMatrixSpotArray": {
fa = updateSpotMatrixFloats();
}
#end #end
} }
@ -1387,6 +1395,11 @@ class Uniforms {
fa = LightObject.updateLWVPMatrixArray(object, "spot"); fa = LightObject.updateLWVPMatrixArray(object, "spot");
} }
#end // lnx_clusters #end // lnx_clusters
#if (!lnx_clusters && lnx_spot)
case "_biasLightWorldViewProjectionMatrixSpotArray": {
fa = updateSpotMatrixFloats();
}
#end
#if lnx_morph_target #if lnx_morph_target
case "_morphWeights": { case "_morphWeights": {
fa = cast(object, MeshObject).morphTarget.morphWeights; fa = cast(object, MeshObject).morphTarget.morphWeights;
@ -1473,6 +1486,32 @@ class Uniforms {
} }
return null; return null;
} }
static var spotMatrixFloats: Float32Array = null;
static function updateSpotMatrixFloats(): Float32Array {
var light = getSpot(0);
if (light == null) return null;
if (spotMatrixFloats == null) spotMatrixFloats = new Float32Array(16);
helpMat.setFrom(light.VP);
helpMat.multmat(biasMat);
spotMatrixFloats[0 ] = helpMat._00;
spotMatrixFloats[1 ] = helpMat._01;
spotMatrixFloats[2 ] = helpMat._02;
spotMatrixFloats[3 ] = helpMat._03;
spotMatrixFloats[4 ] = helpMat._10;
spotMatrixFloats[5 ] = helpMat._11;
spotMatrixFloats[6 ] = helpMat._12;
spotMatrixFloats[7 ] = helpMat._13;
spotMatrixFloats[8 ] = helpMat._20;
spotMatrixFloats[9 ] = helpMat._21;
spotMatrixFloats[10] = helpMat._22;
spotMatrixFloats[11] = helpMat._23;
spotMatrixFloats[12] = helpMat._30;
spotMatrixFloats[13] = helpMat._31;
spotMatrixFloats[14] = helpMat._32;
spotMatrixFloats[15] = helpMat._33;
return spotMatrixFloats;
}
#end #end
static function currentMat(object: Object): MaterialData { static function currentMat(object: Object): MaterialData {

View File

@ -171,7 +171,7 @@ class Inc {
var t = new RenderTargetRaw(); var t = new RenderTargetRaw();
t.name = name; t.name = name;
t.width = t.height = size; t.width = t.height = size;
t.format = transparent ? "RGBA64" : "DEPTH16"; t.format = transparent ? "RGBA128" : "DEPTH16";
return path.createRenderTarget(t); return path.createRenderTarget(t);
} }
@ -498,7 +498,7 @@ class Inc {
t.name = target; t.name = target;
t.width = sizew; t.width = sizew;
t.height = sizeh; t.height = sizeh;
t.format = transparent ? "RGBA64" : "DEPTH16"; t.format = transparent ? "RGBA128" : "DEPTH16";
rt = path.createRenderTarget(t); rt = path.createRenderTarget(t);
} }
} }

View File

@ -540,7 +540,7 @@ class RenderPathDeferred {
t2.name = "empty_shadowmap_transparent"; t2.name = "empty_shadowmap_transparent";
t2.width = 1; t2.width = 1;
t2.height = 1; t2.height = 1;
t2.format = "RGBA64"; t2.format = "RGBA128";
path.createRenderTarget(t2); path.createRenderTarget(t2);
path.setTarget("empty_shadowmap_transparent"); path.setTarget("empty_shadowmap_transparent");
path.currentG.clear(0xffffffff, null); path.currentG.clear(0xffffffff, null);

View File

@ -43,7 +43,7 @@ def make(context_id, rpasses, shadowmap=False, shadowmap_transparent=False):
'name': context_id, 'name': context_id,
'vertex_elements': vs, 'vertex_elements': vs,
'depth_write': False, 'depth_write': False,
'depth_read': True, 'depth_read': False,
'compare_mode': 'less', 'compare_mode': 'less',
'cull_mode': 'clockwise', 'cull_mode': 'clockwise',
'blend_source': 'blend_zero', 'blend_source': 'blend_zero',
@ -241,6 +241,7 @@ def make(context_id, rpasses, shadowmap=False, shadowmap_transparent=False):
vert.add_out('vec4 wvpposition') vert.add_out('vec4 wvpposition')
vert.write('wvpposition = gl_Position;') vert.write('wvpposition = gl_Position;')
frag.write('float depth = (wvpposition.z / wvpposition.w) * 0.5 + 0.5;') frag.write('float depth = (wvpposition.z / wvpposition.w) * 0.5 + 0.5;')
frag.write('depth += 0.00002 + min(max(abs(dFdx(gl_FragCoord.z)), abs(dFdy(gl_FragCoord.z))), 0.0005);')
frag.write('vec3 color = mix(vec3(1.0), basecol, opacity);') frag.write('vec3 color = mix(vec3(1.0), basecol, opacity);')
frag.write('fragColor = vec4(color, depth);') frag.write('fragColor = vec4(color, depth);')
@ -248,12 +249,16 @@ def make(context_id, rpasses, shadowmap=False, shadowmap_transparent=False):
if mat_state.material.lnx_discard: if mat_state.material.lnx_discard:
opac = mat_state.material.lnx_discard_opacity_shadows opac = mat_state.material.lnx_discard_opacity_shadows
frag.write('if (opacity < {0}) discard;'.format(opac)) frag.write('if (opacity < {0}) discard;'.format(opac))
elif rpdat.rp_renderer == 'Deferred' and 'translucent' in rpasses and not shadowmap: elif shadowmap or (rpdat.rp_renderer == 'Deferred' and 'translucent' in rpasses):
pass pass
else: else:
opac = '1.0' opac = '1.0'
frag.write('if (opacity < {0}) discard;'.format(opac)) frag.write('if (opacity < {0}) discard;'.format(opac))
if shadowmap and not shadowmap_transparent:
frag.write('vec2 sdz = vec2(dFdx(gl_FragCoord.z), dFdy(gl_FragCoord.z));')
frag.write('gl_FragDepth = gl_FragCoord.z + (0.00002 + min(max(abs(sdz.x), abs(sdz.y)), 0.0005)) * float(gl_FragCoord.w == 1.0);')
make_finalize.make(con_depth) make_finalize.make(con_depth)
assets.vs_equal(con_depth, assets.shader_cons['depth_vert']) assets.vs_equal(con_depth, assets.shader_cons['depth_vert'])

View File

@ -415,9 +415,10 @@ def make_forward_mobile(con_mesh):
frag.write('vec3 svisibility = vec3(1.0);') frag.write('vec3 svisibility = vec3(1.0);')
frag.write('float sdotNL = max(dot(n, sunDir), 0.0);') frag.write('float sdotNL = max(dot(n, sunDir), 0.0);')
if is_shadows: if is_shadows:
vert.add_out('vec4 lightPosition') if not '_CSM' in wrd.world_defs:
vert.add_uniform('mat4 LWVP', '_biasLightWorldViewProjectionMatrixSun') vert.add_out('vec4 lightPosition')
vert.write('lightPosition = LWVP * spos;') vert.add_uniform('mat4 LWVP', '_biasLightWorldViewProjectionMatrixSun')
vert.write('lightPosition = LWVP * spos;')
frag.add_uniform('bool receiveShadow') frag.add_uniform('bool receiveShadow')
frag.add_uniform(f'sampler2DShadow {shadowmap_sun}') frag.add_uniform(f'sampler2DShadow {shadowmap_sun}')
if is_transparent_shadows: if is_transparent_shadows:
@ -435,7 +436,7 @@ def make_forward_mobile(con_mesh):
frag.write(f'svisibility = shadowTestCascade({shadowmap_sun},') frag.write(f'svisibility = shadowTestCascade({shadowmap_sun},')
if is_transparent_shadows: if is_transparent_shadows:
frag.write(f'{shadowmap_sun_tr},') frag.write(f'{shadowmap_sun_tr},')
frag.write('eye, wposition + n * shadowsBias * 10, shadowsBias') frag.write('eye, wposition, n, shadowsBias')
if is_transparent_shadows: if is_transparent_shadows:
frag.write(', opacity != 1.0') frag.write(', opacity != 1.0')
frag.write(');') frag.write(');')
@ -826,7 +827,7 @@ def make_forward_base(con_mesh, parse_opacity=False, transluc_pass=False):
frag.write(f'svisibility = shadowTestCascade({shadowmap_sun},') frag.write(f'svisibility = shadowTestCascade({shadowmap_sun},')
if is_transparent_shadows: if is_transparent_shadows:
frag.write(f'{shadowmap_sun_tr},') frag.write(f'{shadowmap_sun_tr},')
frag.write('eye, wposition + n * shadowsBias * 10, shadowsBias') frag.write('eye, wposition, n, shadowsBias')
if is_transparent_shadows: if is_transparent_shadows:
frag.write(', false') frag.write(', false')
frag.write(');') frag.write(');')

View File

@ -328,7 +328,7 @@ def make_gi(context_id):
frag.write(f'svisibility = shadowTestCascade({shadowmap_sun},') frag.write(f'svisibility = shadowTestCascade({shadowmap_sun},')
if is_transparent_shadows: if is_transparent_shadows:
frag.write(f'{shadowmap_sun_tr},') frag.write(f'{shadowmap_sun_tr},')
frag.write('eye, P + N * shadowsBias * 10, shadowsBias') frag.write('eye, P, N, shadowsBias')
if is_transparent_shadows: if is_transparent_shadows:
frag.write(', false') frag.write(', false')
frag.write(');') frag.write(');')

View File

@ -58,7 +58,7 @@ def get_rpasses(material):
ar.append('depth') ar.append('depth')
if material.lnx_cast_shadow and rpdat.rp_shadows and ('mesh' in ar): if material.lnx_cast_shadow and rpdat.rp_shadows and ('mesh' in ar):
if 'translucent' in ar or 'refraction' in ar: if ('translucent' in ar or 'refraction' in ar) and rpdat.rp_shadowmap_transparent:
ar.append('shadowmap_transparent') ar.append('shadowmap_transparent')
else: else:
ar.append('shadowmap') ar.append('shadowmap')

View File

@ -661,7 +661,7 @@ def init_properties():
bpy.types.Light.lnx_clip_start = FloatProperty(name="Clip Start", default=0.1) bpy.types.Light.lnx_clip_start = FloatProperty(name="Clip Start", default=0.1)
bpy.types.Light.lnx_clip_end = FloatProperty(name="Clip End", default=50.0) bpy.types.Light.lnx_clip_end = FloatProperty(name="Clip End", default=50.0)
bpy.types.Light.lnx_fov = FloatProperty(name="Field of View", default=0.84) bpy.types.Light.lnx_fov = FloatProperty(name="Field of View", default=0.84)
bpy.types.Light.lnx_shadows_bias = FloatProperty(name="Bias", description="Depth offset to fight shadow acne", default=1.0) bpy.types.Light.lnx_shadows_bias = FloatProperty(name="Bias", description="Depth offset to fight shadow acne", default=0.0)
# For world # For world
bpy.types.World.lnx_light_ies_texture = BoolProperty(name="IES Texture (iestexture.png)", default=False, update=assets.invalidate_compiler_cache) bpy.types.World.lnx_light_ies_texture = BoolProperty(name="IES Texture (iestexture.png)", default=False, update=assets.invalidate_compiler_cache)
bpy.types.World.lnx_light_clouds_texture = BoolProperty(name="Clouds Texture (cloudstexture.png)", default=False, update=assets.invalidate_compiler_cache) bpy.types.World.lnx_light_clouds_texture = BoolProperty(name="Clouds Texture (cloudstexture.png)", default=False, update=assets.invalidate_compiler_cache)