feat(postfx): afegir push constants i efectes chromatic aberration + scanlines
- PostFXUniforms struct (vignette_strength, chroma_strength, scanline_strength, time) - Shader MSL actualitzat: aberració cromàtica RGB + scanlines sin-wave + vinyeta paramètrica - Pipeline postfx declara num_uniform_buffers=1 (buffer(0) en MSL) - Engine acumula temps i fa SDL_PushGPUFragmentUniformData cada frame - Valors per defecte: vignette=1.5, chroma=0, scanlines=0 (comportament idèntic a l'anterior) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -85,7 +85,12 @@ vertex PostVOut postfx_vs(uint vid [[vertex_id]]) {
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// PostFX fragment shader
|
||||
// Samples the offscreen scene texture and applies a subtle vignette.
|
||||
// Effects driven by PostFXUniforms (uniform buffer slot 0):
|
||||
// - Chromatic aberration: RGB channel UV offset
|
||||
// - Scanlines: sin-wave intensity modulation
|
||||
// - Vignette: radial edge darkening
|
||||
// MSL binding for fragment uniform buffer 0 with 1 sampler, 0 storage:
|
||||
// constant PostFXUniforms& u [[buffer(0)]]
|
||||
// ---------------------------------------------------------------------------
|
||||
static const char* kPostFXFragMSL = R"(
|
||||
#include <metal_stdlib>
|
||||
@@ -96,14 +101,32 @@ struct PostVOut {
|
||||
float2 uv;
|
||||
};
|
||||
|
||||
fragment float4 postfx_fs(PostVOut in [[stage_in]],
|
||||
texture2d<float> scene [[texture(0)]],
|
||||
sampler samp [[sampler(0)]]) {
|
||||
float4 color = scene.sample(samp, in.uv);
|
||||
struct PostFXUniforms {
|
||||
float vignette_strength;
|
||||
float chroma_strength;
|
||||
float scanline_strength;
|
||||
float time;
|
||||
};
|
||||
|
||||
// Subtle vignette: darkens edges proportionally to distance from centre
|
||||
fragment float4 postfx_fs(PostVOut in [[stage_in]],
|
||||
texture2d<float> scene [[texture(0)]],
|
||||
sampler samp [[sampler(0)]],
|
||||
constant PostFXUniforms& u [[buffer(0)]]) {
|
||||
// Chromatic aberration: offset R and B channels horizontally
|
||||
float ca = u.chroma_strength * 0.005;
|
||||
float4 color;
|
||||
color.r = scene.sample(samp, in.uv + float2( ca, 0.0)).r;
|
||||
color.g = scene.sample(samp, in.uv ).g;
|
||||
color.b = scene.sample(samp, in.uv - float2( ca, 0.0)).b;
|
||||
color.a = scene.sample(samp, in.uv ).a;
|
||||
|
||||
// Scanlines: horizontal sine-wave at ~360 lines (one dark band per 2 px at 720p)
|
||||
float scan = 0.85 + 0.15 * sin(in.uv.y * 3.14159265 * 720.0);
|
||||
color.rgb *= mix(1.0, scan, u.scanline_strength);
|
||||
|
||||
// Vignette: radial edge darkening
|
||||
float2 d = in.uv - float2(0.5, 0.5);
|
||||
float vignette = 1.0 - dot(d, d) * 1.5;
|
||||
float vignette = 1.0 - dot(d, d) * u.vignette_strength;
|
||||
color.rgb *= clamp(vignette, 0.0, 1.0);
|
||||
|
||||
return color;
|
||||
@@ -215,7 +238,7 @@ bool GpuPipeline::init(SDL_GPUDevice* device,
|
||||
SDL_GPUShader* postfx_vert = createShader(device, kPostFXVertMSL, "postfx_vs",
|
||||
SDL_GPU_SHADERSTAGE_VERTEX, 0, 0);
|
||||
SDL_GPUShader* postfx_frag = createShader(device, kPostFXFragMSL, "postfx_fs",
|
||||
SDL_GPU_SHADERSTAGE_FRAGMENT, 1, 0);
|
||||
SDL_GPU_SHADERSTAGE_FRAGMENT, 1, 1);
|
||||
if (!postfx_vert || !postfx_frag) {
|
||||
SDL_Log("GpuPipeline: failed to create postfx shaders");
|
||||
if (postfx_vert) SDL_ReleaseGPUShader(device, postfx_vert);
|
||||
|
||||
Reference in New Issue
Block a user