diff --git a/packages/wolf_3d_renderer/shaders/wolf_world.frag b/packages/wolf_3d_renderer/shaders/wolf_world.frag index d95e6de..8a23eab 100644 --- a/packages/wolf_3d_renderer/shaders/wolf_world.frag +++ b/packages/wolf_3d_renderer/shaders/wolf_world.frag @@ -1,24 +1,32 @@ #include +// Output surface size in pixels. uniform vec2 uResolution; +// One source-texel step in UV space: (1/width, 1/height). uniform vec2 uTexel; +// Source frame produced by the software renderer. uniform sampler2D uTexture; out vec4 fragColor; +// Perceptual brightness approximation used for edge detection. float luma(vec3 color) { return dot(color, vec3(0.299, 0.587, 0.114)); } void main() { + // Convert fragment coordinates to normalized UV coordinates. vec2 uv = FlutterFragCoord().xy / uResolution; + // Read the base color from the source frame. vec4 centerSample = texture(uTexture, uv); + // Sample 4-neighborhood (N/S/E/W) around the current pixel. vec3 sampleN = texture(uTexture, uv + vec2(0.0, -uTexel.y)).rgb; vec3 sampleS = texture(uTexture, uv + vec2(0.0, uTexel.y)).rgb; vec3 sampleE = texture(uTexture, uv + vec2(uTexel.x, 0.0)).rgb; vec3 sampleW = texture(uTexture, uv + vec2(-uTexel.x, 0.0)).rgb; + // Compute local luma range; wider range means a stronger edge. float lumaCenter = luma(centerSample.rgb); float lumaMin = min( lumaCenter, @@ -30,9 +38,14 @@ void main() { ); float edgeSpan = max(lumaMax - lumaMin, 0.0001); + // Convert raw edge strength into a smooth 0..1 blending amount. float edgeAmount = smoothstep(0.03, 0.18, edgeSpan); + + // Average neighbors and blend toward that average only near edges. + // This acts like a lightweight edge-aware anti-aliasing pass. vec3 neighborhoodAvg = (sampleN + sampleS + sampleE + sampleW) * 0.25; vec3 aaColor = mix(centerSample.rgb, neighborhoodAvg, edgeAmount * 0.45); + // Preserve source alpha and output the anti-aliased color. fragColor = vec4(aaColor, centerSample.a); }