#import bevy_pbr::mesh_vertex_output MeshVertexOutput #import bevy_sprite::mesh2d_view_bindings globals struct DarknessMaterial { color: vec4, }; struct PointLight { position: vec2, radius: f32, } struct SpotLight { position: vec2, radius: f32, rotation: f32, angle: f32, padding1: u32, padding2: u32, padding3: u32, } @group(1) @binding(0) var material: DarknessMaterial; @group(1) @binding(1) var point_light_count: i32; @group(1) @binding(2) var point_lights: array; @group(1) @binding(3) var spot_light_count: i32; @group(1) @binding(4) var spot_lights: array; @group(1) @binding(5) var shadowmap_texture: texture_2d; @group(1) @binding(6) var shadowmap_sampler: sampler; @fragment fn fragment( mesh: MeshVertexOutput, ) -> @location(0) vec4 { let color = material.color; let pos = mesh.world_position.xy; let t = globals.time; let light_edge = 6.0; let light_edge_mult = 0.8; var bright_light = 0.0; var dim_light = 0.0; for (var i: i32 = 0; i < point_light_count; i++) { if (point_lights[i].radius <= 0.0) { continue; } let radius = point_lights[i].radius - (sin(t * 5.0) * 0.5 + 0.5) * 0.2; let diff = pos - point_lights[i].position; let dist = distance(pos, point_lights[i].position); let edge_treshold = radius * light_edge_mult - light_edge; let edge_dist = max(dist - edge_treshold, 0.0); let uv = vec2( (atan2(diff.y, diff.x) + radians(180.0)) / radians(360.0), f32(i) / 128.0 ); let max_range = textureSample(shadowmap_texture, shadowmap_sampler, uv).r; bright_light = bright_light + step(dist, edge_treshold) * step(dist, max_range); dim_light = dim_light + step(dist, radius) * step(dist, max_range); } for (var i: i32 = 0; i < spot_light_count; i++) { if (spot_lights[i].radius <= 0.0 || spot_lights[i].angle <= 0.0) { continue; } let spot = spot_lights[i]; let radius = spot.radius - (sin(t * 5.0) * 0.5 + 0.5) * 0.2; let diff = pos - spot.position; let dist = length(diff); let spot_dir = vec2(cos(spot.rotation), sin(spot.rotation)); let angle_diff = acos(dot(spot_dir, normalize(diff))); let uv = vec2( (atan2(diff.y, diff.x) + radians(180.0)) / radians(360.0), f32(i + 64) / 128.0 ); let max_range = textureSample(shadowmap_texture, shadowmap_sampler, uv).r; let edge_treshold = radius * light_edge_mult - light_edge; let edge_dist = max(dist - edge_treshold, 0.0); let angle_mult = step(angle_diff, spot.angle / 2.0); bright_light = bright_light + step(dist, edge_treshold) * angle_mult * step(dist, max_range); dim_light = dim_light + step(dist, radius) * angle_mult * step(dist, max_range); } let edge1 = step(bright_light, 0.75); let edge2 = step(dim_light, 0.75) * 0.5 + 0.5; return vec4(color.rgb, color.a * edge1 * (edge2 * 0.5 + 0.5)); }