diff options
| author | hachem <im@hachem.wtf> | 2026-08-24 17:07:54 +0200 |
|---|---|---|
| committer | hachem <im@hachem.wtf> | 2026-08-24 17:07:54 +0200 |
| commit | 06398a7a176e123506de6e8851866a8bec0b3427 (patch) | |
| tree | 7167ef4818f2c224840122961882efb5ec26c80b /assets/shaders | |
| parent | 1c85c2ecaa826afd8bf80f93741cf1b2deba5798 (diff) | |
[chore]: cleanup shaders
Diffstat (limited to 'assets/shaders')
| -rw-r--r-- | assets/shaders/blur.slang | 60 | ||||
| -rw-r--r-- | assets/shaders/equirect_to_cubemap.slang | 12 | ||||
| -rw-r--r-- | assets/shaders/geodesic.slang | 148 | ||||
| -rw-r--r-- | assets/shaders/grid.slang | 26 | ||||
| -rw-r--r-- | assets/shaders/skybox.slang | 12 | ||||
| -rw-r--r-- | assets/shaders/sphere.slang | 60 | ||||
| -rw-r--r-- | assets/shaders/textured_quad.slang | 14 | ||||
| -rw-r--r-- | assets/shaders/vk_pipeline_test.slang | 10 |
8 files changed, 137 insertions, 205 deletions
diff --git a/assets/shaders/blur.slang b/assets/shaders/blur.slang deleted file mode 100644 index 17e4eae..0000000 --- a/assets/shaders/blur.slang +++ /dev/null @@ -1,60 +0,0 @@ -struct VSInput -{ - float2 position : POSITION; - float2 texCoord : TEXCOORD0; -}; - -struct VSOutput -{ - float4 position : SV_Position; - float2 texCoord : TEXCOORD0; -}; - -[shader("vertex")] -VSOutput vertexMain(VSInput input) -{ - VSOutput output; - output.position = float4(input.position, 0.0, 1.0); - output.texCoord = input.texCoord; - return output; -} - -Sampler2D u_ScreenTexture; -uniform float2 u_Resolution; -uniform float u_BlurStrength; -uniform float u_GlowIntensity; - -[shader("fragment")] -float4 fragmentMain(VSOutput input) : SV_Target -{ - float2 texelSize = 1.0 / u_Resolution; - float4 centerColor = u_ScreenTexture.Sample(input.texCoord); - - float brightness = (centerColor.r + centerColor.g + centerColor.b) / 3.0; - float glowMask = smoothstep(0.05, 0.3, brightness); - - float4 blurredColor = float4(0.0, 0.0, 0.0, 0.0); - float totalWeight = 0.0; - - for (int x = -8; x <= 8; x++) - { - for (int y = -8; y <= 8; y++) - { - float2 offset = float2(x, y) * texelSize * u_BlurStrength; - float4 sampleColor = u_ScreenTexture.Sample(input.texCoord + offset); - - float weight = exp(-float(x * x + y * y) / (2.0 * 8.0 * 8.0)); - blurredColor += sampleColor * weight; - totalWeight += weight; - } - } - - blurredColor /= totalWeight; - - float3 emissionColor = float3(1.0, 0.8, 0.6); - float3 glowColor = emissionColor * glowMask * u_GlowIntensity * 2.0; - float3 auraColor = blurredColor.rgb * glowMask * u_GlowIntensity * 0.8; - float3 finalColor = centerColor.rgb + glowColor + auraColor; - - return float4(finalColor, centerColor.a); -} diff --git a/assets/shaders/equirect_to_cubemap.slang b/assets/shaders/equirect_to_cubemap.slang index 9b2ea4b..510e6b0 100644 --- a/assets/shaders/equirect_to_cubemap.slang +++ b/assets/shaders/equirect_to_cubemap.slang @@ -1,5 +1,11 @@ -uniform float4x4 u_Projection; -uniform float4x4 u_View; +// Equirectangular HDRI -> cubemap face projection. NOTE: the OpenGL path uses the +// hand-written assets/shaders/EquirectToCubemap.glsl instead; this Slang version +// feeds the Vulkan cubemap bake (vulkan_cubemap.cpp), which binds the view / +// projection as a $Globals UBO. Kept as loose `uniform` globals (not a +// ConstantBuffer) so both paths bind them the same way. + +uniform float4x4 u_projection; +uniform float4x4 u_view; struct VSInput { float3 position : POSITION; }; struct VSOutput { float4 position : SV_Position; float3 worldPos : TEXCOORD0; }; @@ -9,7 +15,7 @@ VSOutput vertexMain(VSInput input) { VSOutput output; output.worldPos = input.position; - output.position = mul(u_Projection, mul(u_View, float4(input.position, 1.0))); + output.position = mul(u_projection, mul(u_view, float4(input.position, 1.0))); return output; } diff --git a/assets/shaders/geodesic.slang b/assets/shaders/geodesic.slang index eee62da..eb536c9 100644 --- a/assets/shaders/geodesic.slang +++ b/assets/shaders/geodesic.slang @@ -1,3 +1,9 @@ +// Ray-traced Schwarzschild black hole: back-traces one null geodesic per pixel +// through curved spacetime, shading the accretion disk, the lensed HDRI +// background, and placed objects. Runs as a full-screen fragment pass. Uniforms +// live in ConstantBuffers (UBOs) driven through the RHI; the HDRI is a cubemap +// sampler. See docs/physics.md for the maths. + struct VSInput { float2 position : POSITION; float2 texCoord : TEXCOORD0; }; struct VSOutput { float4 position : SV_Position; float2 texCoord : TEXCOORD0; }; @@ -12,54 +18,44 @@ VSOutput vertexMain(VSInput input) struct Camera { - float3 camPos; float _pad0; - float3 camRight; float _pad1; - float3 camUp; float _pad2; - float3 camForward; float _pad3; - float tanHalfFov; - float aspect; - bool moving; - int outputChannel; // 0 = colour; 1 = redshift g; 2 = emission T; 3 = impact parameter - int rawOutput; // 0 = display (false-colour / tone-mapped); 1 = raw float value + float3 u_cam_pos; float _pad0; + float3 u_cam_right; float _pad1; + float3 u_cam_up; float _pad2; + float3 u_cam_forward; float _pad3; + float u_tan_half_fov; + float u_aspect; + bool u_moving; + int u_output_channel; // 0 = colour; 1 = redshift g; 2 = emission T; 3 = impact parameter + int u_raw_output; // 0 = display (false-colour / tone-mapped); 1 = raw float value }; - -// A jet-ish false-colour ramp (blue -> cyan -> green -> yellow -> red) for the -// observable export channels. t is expected in [0, 1]. -float3 Falsecolor(float t) -{ - t = clamp(t, 0.0, 1.0); - return clamp(float3(1.5 - abs(4.0 * t - 3.0), - 1.5 - abs(4.0 * t - 2.0), - 1.5 - abs(4.0 * t - 1.0)), 0.0, 1.0); -} ConstantBuffer<Camera> cam; struct Disk { - float disk_r1; // inner edge (clamped to the ISCO, 3 r_s, below) - float disk_r2; // outer edge - float disk_num; // turbulence strength (0 = smooth physical disk) - float thickness; // slab half-height (anti-aliases the edge-on disk) - float disk_density; // disk brightness / exposure - float temperature; // Kelvin at the flux peak (disk colour) + float u_inner_radius; // inner edge (clamped to the ISCO, 3 r_s, below) + float u_outer_radius; // outer edge + float u_turbulence; // turbulence strength (0 = smooth physical disk) + float u_thickness; // slab half-height (anti-aliases the edge-on disk) + float u_brightness; // disk brightness / exposure + float u_temperature; // Kelvin at the flux peak (disk colour) }; ConstantBuffer<Disk> disk; struct Objects { - int numObjects; - float4 objPosRadius[16]; - float4 objColor[16]; - float mass[16]; + int u_num_objects; + float4 u_obj_pos_radius[16]; + float4 u_obj_color[16]; + float u_mass[16]; }; ConstantBuffer<Objects> obj; struct Simulation { - int maxStepsMoving; - int maxStepsStatic; - float earlyExitDistance; - float time; + int u_max_steps_moving; + int u_max_steps_static; + float u_early_exit_distance; + float u_time; }; ConstantBuffer<Simulation> sim; @@ -163,8 +159,8 @@ float3 DiskEmission(float3 P, float3 rayDir, out float outG, out float outTemit) { outG = 0.0; outTemit = 0.0; float rc = length(float2(P.x, P.z)); // cylindrical radius (disk axis = +Y) - float rin = max(disk.disk_r1, R_ISCO); - float rout = disk.disk_r2; + float rin = max(disk.u_inner_radius, R_ISCO); + float rout = disk.u_outer_radius; if (rc < rin || rc > rout) return float3(0.0); @@ -173,7 +169,7 @@ float3 DiskEmission(float3 P, float3 rayDir, out float outG, out float outTemit) float xr = rc / rin; float flux = max((1.0 - sqrt(1.0 / xr)) / (xr * xr * xr), 0.0); float Tn = pow(flux / FLUX_PEAK, 0.25); // normalised temperature, peak ~ 1 - float Temit = disk.temperature * Tn; + float Temit = disk.u_temperature * Tn; // Keplerian orbit (prograde about +Y). Locally-measured orbital speed for a // Schwarzschild circular geodesic: v = sqrt( M / (r - 2M) ) = 0.5 c at ISCO. @@ -198,18 +194,18 @@ float3 DiskEmission(float3 P, float3 rayDir, out float outG, out float outTemit) float edge = smoothstep(rin, rin * 1.12, rc) * (1.0 - smoothstep(rout * 0.88, rout, rc)); bright *= edge; - // Optional turbulence overlay (disk.disk_num = strength; 0 = smooth). - if (disk.disk_num > 0.0) + // Optional turbulence overlay (disk.u_turbulence = strength; 0 = smooth). + if (disk.u_turbulence > 0.0) { - float ang = sim.time * 0.3 / sqrt(xr); + float ang = sim.u_time * 0.3 / sqrt(xr); float3 rp = float3(P.x * cos(ang) - P.z * sin(ang), 0.0, P.x * sin(ang) + P.z * cos(ang)) * 1e-10; - float turb = 1.0 + disk.disk_num * (fbm(rp * 3.0, 3) - 0.5); + float turb = 1.0 + disk.u_turbulence * (fbm(rp * 3.0, 3) - 0.5); bright *= max(turb, 0.0); } - return colour * bright * max(disk.disk_density, 0.0); + return colour * bright * max(disk.u_brightness, 0.0); } struct Ray @@ -255,15 +251,15 @@ bool Intercept(Ray ray, float rs) { return ray.r <= rs; } bool InterceptObject(Ray ray, inout Hit hit) { float3 P = float3(ray.x, ray.y, ray.z); - for (int i = 0; i < obj.numObjects; ++i) + for (int i = 0; i < obj.u_num_objects; ++i) { - float3 center = obj.objPosRadius[i].xyz; - float radius = obj.objPosRadius[i].w; + float3 center = obj.u_obj_pos_radius[i].xyz; + float radius = obj.u_obj_pos_radius[i].w; float distSq = dot(P - center, P - center); if (distSq > radius * radius * 4.0) continue; if (distSq <= radius * radius) { - hit.objectColor = obj.objColor[i]; + hit.objectColor = obj.u_obj_color[i]; hit.hitCenter = center; hit.hitRadius = radius; return true; @@ -317,8 +313,8 @@ float CalculateAdaptiveStepSize(Ray ray, float baseStepSize) // Slow down when near the disk plane (within its radial extent) so the thin // slab is never stepped over -- otherwise grazing rays leak through it. float rc = length(float2(ray.x, ray.z)); - if (rc < disk.disk_r2 * 3.0 && abs(ray.y) < disk.thickness * 8.0) - step = min(step, disk.thickness); + if (rc < disk.u_outer_radius * 3.0 && abs(ray.y) < disk.u_thickness * 8.0) + step = min(step, disk.u_thickness); return clamp(step, MIN_STEP_SIZE, MAX_STEP_SIZE); } @@ -328,15 +324,25 @@ float3 ACESFilm(float3 x) return clamp((x * (2.51 * x + 0.03)) / (x * (2.43 * x + 0.59) + 0.14), 0.0, 1.0); } +// A jet-ish false-colour ramp (blue -> cyan -> green -> yellow -> red) for the +// observable export channels. t is expected in [0, 1]. +float3 Falsecolor(float t) +{ + t = clamp(t, 0.0, 1.0); + return clamp(float3(1.5 - abs(4.0 * t - 3.0), + 1.5 - abs(4.0 * t - 2.0), + 1.5 - abs(4.0 * t - 1.0)), 0.0, 1.0); +} + // Trace one primary ray for the given image UV and return its linear, // pre-tone-map radiance. Called once per sub-sample by fragmentMain. float3 TracePixel(float2 texCoord, out float outG, out float outTemit, out bool outHitDisk) { outG = 0.0; outTemit = 0.0; outHitDisk = false; - float u = (2.0 * texCoord.x - 1.0) * cam.aspect * cam.tanHalfFov; - float v = (1.0 - 2.0 * texCoord.y) * cam.tanHalfFov; - float3 dir = normalize(u * cam.camRight - v * cam.camUp + cam.camForward); - Ray ray = InitRay(cam.camPos, dir); + float u = (2.0 * texCoord.x - 1.0) * cam.u_aspect * cam.u_tan_half_fov; + float v = (1.0 - 2.0 * texCoord.y) * cam.u_tan_half_fov; + float3 dir = normalize(u * cam.u_cam_right - v * cam.u_cam_up + cam.u_cam_forward); + Ray ray = InitRay(cam.u_cam_pos, dir); bool hitBlackHole = false; bool hitObject = false; @@ -348,11 +354,11 @@ float3 TracePixel(float2 texCoord, out float outG, out float outTemit, out bool bool hitDisk = false; float3 diskColor = float3(0.0); // emission of the first (opaque) disk surface hit - int maxSteps = cam.moving ? sim.maxStepsMoving : sim.maxStepsStatic; + int maxSteps = cam.u_moving ? sim.u_max_steps_moving : sim.u_max_steps_static; if (maxSteps <= 0) - maxSteps = cam.moving ? DEFAULT_MAX_STEPS_MOVING : DEFAULT_MAX_STEPS_STATIC; + maxSteps = cam.u_moving ? DEFAULT_MAX_STEPS_MOVING : DEFAULT_MAX_STEPS_STATIC; - float exitDistance = sim.earlyExitDistance > 0.0 ? sim.earlyExitDistance : DEFAULT_EARLY_EXIT_DISTANCE; + float exitDistance = sim.u_early_exit_distance > 0.0 ? sim.u_early_exit_distance : DEFAULT_EARLY_EXIT_DISTANCE; int objectCheckInterval = 5; for (int i = 0; i < maxSteps; ++i) @@ -370,7 +376,7 @@ float3 TracePixel(float2 texCoord, out float outG, out float outTemit, out bool // while grazing along it. Real (nonzero) thickness stops the zero-height // edge-on "razor" from aliasing into a beam streaking across the frame. { - float H = disk.thickness; + float H = disk.u_thickness; bool crossed = prevPos.y * newPos.y < 0.0; bool inSlab = abs(newPos.y) <= H; if (crossed || inSlab) @@ -379,7 +385,7 @@ float3 TracePixel(float2 texCoord, out float outG, out float outTemit, out bool ? lerp(prevPos, newPos, prevPos.y / (prevPos.y - newPos.y)) : newPos; float rc = length(float2(hitP.x, hitP.z)); - if (rc >= max(disk.disk_r1, R_ISCO) && rc <= disk.disk_r2) + if (rc >= max(disk.u_inner_radius, R_ISCO) && rc <= disk.u_outer_radius) { diskColor = DiskEmission(hitP, newPos - prevPos, outG, outTemit); hitDisk = true; @@ -400,7 +406,7 @@ float3 TracePixel(float2 texCoord, out float outG, out float outTemit, out bool // Computed UNCONDITIONALLY (before the branch) so ddx/ddy are valid; strongly // lensed background rays diverge fast, so they read a blurred cubemap mip and // the starfield stops aliasing into a fan along the equatorial plane. - float3 rayDir = normalize(float3(ray.x, ray.y, ray.z) - cam.camPos); + float3 rayDir = normalize(float3(ray.x, ray.y, ray.z) - cam.u_cam_pos); float footprint = max(length(ddx(rayDir)), length(ddy(rayDir))); float envLod = clamp(log2(max(footprint / 0.0015, 1.0)), 0.0, 10.0); @@ -417,7 +423,7 @@ float3 TracePixel(float2 texCoord, out float outG, out float outTemit, out bool { float3 P = float3(ray.x, ray.y, ray.z); float3 N = normalize(P - hit.hitCenter); - float3 V = normalize(cam.camPos - P); + float3 V = normalize(cam.u_cam_pos - P); float intensity = 0.1 + 0.9 * max(dot(N, V), 0.0); shade = hit.objectColor.rgb * intensity; } @@ -438,41 +444,41 @@ float4 fragmentMain(VSOutput input) : SV_Target // ordered grid). Radiance is averaged before tone-mapping; ddx/ddy give the // resolution-correct per-pixel UV footprint. // Observable export channels: the chosen scalar quantity, either as a raw - // float (rawOutput: value in RGB, validity mask in A) or false-coloured. + // float (u_raw_output: value in RGB, validity mask in A) or false-coloured. // Channel 0 is the normal colour image. - if (cam.outputChannel != 0) + if (cam.u_output_channel != 0) { float g, Temit; bool hitDisk; TracePixel(input.texCoord, g, Temit, hitDisk); float value; float valid = 1.0; - if (cam.outputChannel == 3) // impact parameter: a per-ray geometric quantity (r_s) + if (cam.u_output_channel == 3) // impact parameter: a per-ray geometric quantity (r_s) { - float uu = (2.0 * input.texCoord.x - 1.0) * cam.aspect * cam.tanHalfFov; - float vv = (1.0 - 2.0 * input.texCoord.y) * cam.tanHalfFov; - float3 dir = normalize(uu * cam.camRight - vv * cam.camUp + cam.camForward); - value = length(cross(cam.camPos, dir)) / SagA_rs; + float uu = (2.0 * input.texCoord.x - 1.0) * cam.u_aspect * cam.u_tan_half_fov; + float vv = (1.0 - 2.0 * input.texCoord.y) * cam.u_tan_half_fov; + float3 dir = normalize(uu * cam.u_cam_right - vv * cam.u_cam_up + cam.u_cam_forward); + value = length(cross(cam.u_cam_pos, dir)) / SagA_rs; } else // g / T are disk-only { valid = hitDisk ? 1.0 : 0.0; - value = (cam.outputChannel == 1) ? g : Temit; + value = (cam.u_output_channel == 1) ? g : Temit; } - if (cam.rawOutput != 0) + if (cam.u_raw_output != 0) return float4(value, value, value, valid); // raw: physical value + validity if (valid < 0.5) return float4(0.0, 0.0, 0.0, 1.0); - float norm = (cam.outputChannel == 1) ? value / 1.5 - : (cam.outputChannel == 2) ? value / 15000.0 + float norm = (cam.u_output_channel == 1) ? value / 1.5 + : (cam.u_output_channel == 2) ? value / 15000.0 : value / 30.0; return float4(Falsecolor(norm), 1.0); } float _g, _t; bool _hd; - if (cam.rawOutput != 0) // raw colour: linear pre-tone-map radiance (HDR) + if (cam.u_raw_output != 0) // raw colour: linear pre-tone-map radiance (HDR) return float4(TracePixel(input.texCoord, _g, _t, _hd), 1.0); - if (cam.moving) + if (cam.u_moving) return float4(ACESFilm(TracePixel(input.texCoord, _g, _t, _hd)), 1.0); float2 dUV = float2(ddx(input.texCoord.x), ddy(input.texCoord.y)); diff --git a/assets/shaders/grid.slang b/assets/shaders/grid.slang index f549cb1..8dc4362 100644 --- a/assets/shaders/grid.slang +++ b/assets/shaders/grid.slang @@ -1,15 +1,15 @@ // Reference grid on the XZ plane. Uniforms live in a ConstantBuffer (UBO) so both // backends drive it through the same RHI path (bind a uniform buffer at binding 0). -struct GridU +struct Grid { - float4x4 u_ViewProjection; - float4x4 u_Transform; - float u_GridSize; - float3 u_GridColor; - float u_GridAlpha; - float3 u_CameraPos; + float4x4 u_view_projection; + float4x4 u_transform; + float u_grid_size; + float3 u_grid_color; + float u_grid_alpha; + float3 u_camera_pos; }; -ConstantBuffer<GridU> gu; +ConstantBuffer<Grid> gu; struct VSInput { float3 position : POSITION; }; struct VSOutput { float4 position : SV_Position; }; @@ -18,19 +18,19 @@ struct VSOutput { float4 position : SV_Position; }; VSOutput vertexMain(VSInput input) { VSOutput output; - float3 scaledPosition = input.position * (gu.u_GridSize / 50.0); - output.position = mul(gu.u_ViewProjection, mul(gu.u_Transform, float4(scaledPosition, 1.0))); + float3 scaledPosition = input.position * (gu.u_grid_size / 50.0); + output.position = mul(gu.u_view_projection, mul(gu.u_transform, float4(scaledPosition, 1.0))); return output; } [shader("fragment")] float4 fragmentMain(VSOutput input) : SV_Target { - float dist = length(gu.u_CameraPos); + float dist = length(gu.u_camera_pos); float fadeFactor = 1.0 - clamp(dist / 100.0, 0.0, 0.8); - float3 color = gu.u_GridColor; - float alpha = gu.u_GridAlpha * fadeFactor; + float3 color = gu.u_grid_color; + float alpha = gu.u_grid_alpha * fadeFactor; float gridFade = 1.0 - clamp(dist / 50.0, 0.0, 0.9); alpha *= gridFade; diff --git a/assets/shaders/skybox.slang b/assets/shaders/skybox.slang index 6447bea..f7aeb50 100644 --- a/assets/shaders/skybox.slang +++ b/assets/shaders/skybox.slang @@ -1,11 +1,11 @@ -// Fullscreen skybox cube. View/projection in a ConstantBuffer (UBO, binding 0) +// Full-screen skybox cube. View/projection in a ConstantBuffer (UBO, binding 0) // so both backends drive it through the RHI; the cubemap is a sampler at binding 1. -struct SkyboxU +struct Skybox { - float4x4 u_Projection; - float4x4 u_View; + float4x4 u_projection; + float4x4 u_view; }; -ConstantBuffer<SkyboxU> sb; +ConstantBuffer<Skybox> sb; struct VSInput { float3 position : POSITION; }; struct VSOutput { float4 position : SV_Position; float3 texCoords : TEXCOORD0; }; @@ -15,7 +15,7 @@ VSOutput vertexMain(VSInput input) { VSOutput output; output.texCoords = input.position; - float4 pos = mul(sb.u_Projection, mul(sb.u_View, float4(input.position, 1.0))); + float4 pos = mul(sb.u_projection, mul(sb.u_view, float4(input.position, 1.0))); output.position = pos.xyww; // force depth = 1 so the skybox stays behind everything return output; } diff --git a/assets/shaders/sphere.slang b/assets/shaders/sphere.slang index e37700d..41badde 100644 --- a/assets/shaders/sphere.slang +++ b/assets/shaders/sphere.slang @@ -1,42 +1,32 @@ // Lit sphere (Blinn-Phong + HDRI ambient + selection rim). Uniforms in a // ConstantBuffer (UBO, binding 0) so both backends drive it through the RHI; // the environment cubemap is a separate sampler at binding 1. -struct SphereU +struct Sphere { - float4x4 u_ViewProjection; - float4x4 u_Transform; - float3 u_Color; - float u_Specular; - float u_Emission; - float3 u_LightPos; - float3 u_CameraPos; - int u_IsSelected; - float3 u_OutlineColor; - float u_OutlineWidth; + float4x4 u_view_projection; + float4x4 u_transform; + float3 u_color; + float u_specular; + float u_emission; + float3 u_light_pos; + float3 u_camera_pos; + int u_is_selected; + float3 u_outline_color; + float u_outline_width; }; -ConstantBuffer<SphereU> su; +ConstantBuffer<Sphere> su; -struct VSInput -{ - float3 position : POSITION; - float3 normal : NORMAL; -}; - -struct VSOutput -{ - float4 position : SV_Position; - float3 normal : TEXCOORD0; - float3 worldPos : TEXCOORD1; -}; +struct VSInput { float3 position : POSITION; float3 normal : NORMAL; }; +struct VSOutput { float4 position : SV_Position; float3 normal : TEXCOORD0; float3 worldPos : TEXCOORD1; }; [shader("vertex")] VSOutput vertexMain(VSInput input) { VSOutput output; - output.worldPos = mul(su.u_Transform, float4(input.position, 1.0)).xyz; - float3x3 normalMatrix = (float3x3)su.u_Transform; + output.worldPos = mul(su.u_transform, float4(input.position, 1.0)).xyz; + float3x3 normalMatrix = (float3x3)su.u_transform; output.normal = mul(normalMatrix, input.normal); - output.position = mul(su.u_ViewProjection, float4(output.worldPos, 1.0)); + output.position = mul(su.u_view_projection, float4(output.worldPos, 1.0)); return output; } @@ -46,8 +36,8 @@ SamplerCube u_HDRIEnvironment; float4 fragmentMain(VSOutput input) : SV_Target { float3 normal = normalize(input.normal); - float3 lightDir = normalize(su.u_LightPos - input.worldPos); - float3 viewDir = normalize(su.u_CameraPos - input.worldPos); + float3 lightDir = normalize(su.u_light_pos - input.worldPos); + float3 viewDir = normalize(su.u_camera_pos - input.worldPos); float3 reflectDir = reflect(-lightDir, normal); float3 hdriLight = u_HDRIEnvironment.Sample(normal).rgb; @@ -56,18 +46,18 @@ float4 fragmentMain(VSOutput input) : SV_Target float diff = max(dot(normal, lightDir), 0.0); float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32.0); - float3 diffuse = su.u_Color * (diff + hdriIntensity * hdriLight); - float3 specular = float3(su.u_Specular, su.u_Specular, su.u_Specular) * spec; - float3 emission = su.u_Color * su.u_Emission; + float3 diffuse = su.u_color * (diff + hdriIntensity * hdriLight); + float3 specular = float3(su.u_specular, su.u_specular, su.u_specular) * spec; + float3 emission = su.u_color * su.u_emission; float3 result = diffuse + specular + emission; - if (su.u_IsSelected > 0) + if (su.u_is_selected > 0) { float ndotv = max(dot(normal, viewDir), 0.0); float rim = 1.0 - ndotv; - float outlineMask = step(1.0 - su.u_OutlineWidth, rim); - result = lerp(result, su.u_OutlineColor, outlineMask); + float outlineMask = step(1.0 - su.u_outline_width, rim); + result = lerp(result, su.u_outline_color, outlineMask); } return float4(result, 1.0); diff --git a/assets/shaders/textured_quad.slang b/assets/shaders/textured_quad.slang index 52d46ed..b72db81 100644 --- a/assets/shaders/textured_quad.slang +++ b/assets/shaders/textured_quad.slang @@ -1,14 +1,8 @@ -struct VSInput -{ - float2 position : POSITION; - float2 texCoord : TEXCOORD0; -}; +// Full-screen textured quad: samples one 2D texture straight to the target. +// Used to blit an off-screen colour buffer to the swapchain. -struct VSOutput -{ - float4 position : SV_Position; - float2 texCoord : TEXCOORD0; -}; +struct VSInput { float2 position : POSITION; float2 texCoord : TEXCOORD0; }; +struct VSOutput { float4 position : SV_Position; float2 texCoord : TEXCOORD0; }; [shader("vertex")] VSOutput vertexMain(VSInput input) diff --git a/assets/shaders/vk_pipeline_test.slang b/assets/shaders/vk_pipeline_test.slang index f4d1897..453fcd3 100644 --- a/assets/shaders/vk_pipeline_test.slang +++ b/assets/shaders/vk_pipeline_test.slang @@ -1,12 +1,8 @@ // Minimal shader used only to verify the Vulkan graphics-pipeline path (SPIR-V -// module -> pipeline -> draw -> read-back). Draws a full-screen gradient -// triangle from the vertex id, so it needs no vertex buffer, UBO, or sampler. +// module -> pipeline -> draw -> read-back). Draws a full-screen gradient triangle +// from the vertex id, so it needs no vertex buffer, UBO, or sampler. -struct VSOutput -{ - float4 position : SV_Position; - float3 color : COLOR0; -}; +struct VSOutput { float4 position : SV_Position; float3 color : COLOR0; }; [shader("vertex")] VSOutput vertexMain(uint vid : SV_VertexID) |
