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

@ -43,7 +43,7 @@ def make(context_id, rpasses, shadowmap=False, shadowmap_transparent=False):
'name': context_id,
'vertex_elements': vs,
'depth_write': False,
'depth_read': True,
'depth_read': False,
'compare_mode': 'less',
'cull_mode': 'clockwise',
'blend_source': 'blend_zero',
@ -241,6 +241,7 @@ def make(context_id, rpasses, shadowmap=False, shadowmap_transparent=False):
vert.add_out('vec4 wvpposition')
vert.write('wvpposition = gl_Position;')
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('fragColor = vec4(color, depth);')
@ -248,12 +249,16 @@ def make(context_id, rpasses, shadowmap=False, shadowmap_transparent=False):
if mat_state.material.lnx_discard:
opac = mat_state.material.lnx_discard_opacity_shadows
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
else:
opac = '1.0'
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)
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('float sdotNL = max(dot(n, sunDir), 0.0);')
if is_shadows:
vert.add_out('vec4 lightPosition')
vert.add_uniform('mat4 LWVP', '_biasLightWorldViewProjectionMatrixSun')
vert.write('lightPosition = LWVP * spos;')
if not '_CSM' in wrd.world_defs:
vert.add_out('vec4 lightPosition')
vert.add_uniform('mat4 LWVP', '_biasLightWorldViewProjectionMatrixSun')
vert.write('lightPosition = LWVP * spos;')
frag.add_uniform('bool receiveShadow')
frag.add_uniform(f'sampler2DShadow {shadowmap_sun}')
if is_transparent_shadows:
@ -435,7 +436,7 @@ def make_forward_mobile(con_mesh):
frag.write(f'svisibility = shadowTestCascade({shadowmap_sun},')
if is_transparent_shadows:
frag.write(f'{shadowmap_sun_tr},')
frag.write('eye, wposition + n * shadowsBias * 10, shadowsBias')
frag.write('eye, wposition, n, shadowsBias')
if is_transparent_shadows:
frag.write(', opacity != 1.0')
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},')
if is_transparent_shadows:
frag.write(f'{shadowmap_sun_tr},')
frag.write('eye, wposition + n * shadowsBias * 10, shadowsBias')
frag.write('eye, wposition, n, shadowsBias')
if is_transparent_shadows:
frag.write(', false')
frag.write(');')

View File

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

View File

@ -58,7 +58,7 @@ def get_rpasses(material):
ar.append('depth')
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')
else:
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_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_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
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)