hachem.wtf
aboutsummaryrefslogtreecommitdiff
path: root/assets/shaders/geodesic.slang
diff options
context:
space:
mode:
Diffstat (limited to 'assets/shaders/geodesic.slang')
-rw-r--r--assets/shaders/geodesic.slang66
1 files changed, 46 insertions, 20 deletions
diff --git a/assets/shaders/geodesic.slang b/assets/shaders/geodesic.slang
index db450a8..a1b0f46 100644
--- a/assets/shaders/geodesic.slang
+++ b/assets/shaders/geodesic.slang
@@ -78,11 +78,6 @@ struct Hit
float hitRadius;
};
-float3 SampleHDRI(float3 direction)
-{
- return u_HDRIEnvironment.Sample(direction).rgb;
-}
-
float hash(float3 p)
{
p = frac(p * float3(0.1031, 0.1030, 0.0973));
@@ -280,6 +275,11 @@ void RK4Step(inout Ray ray, float dL)
float CalculateAdaptiveStepSize(Ray ray, float baseStepSize)
{
float step = 0.02 * max(ray.r - R_PHOTON, 0.0);
+
+ 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);
+
return clamp(step, MIN_STEP_SIZE, MAX_STEP_SIZE);
}
@@ -288,11 +288,10 @@ float3 ACESFilm(float3 x)
return clamp((x * (2.51 * x + 0.03)) / (x * (2.43 * x + 0.59) + 0.14), 0.0, 1.0);
}
-[shader("fragment")]
-float4 fragmentMain(VSOutput input) : SV_Target
+float3 TracePixel(float2 texCoord)
{
- float u = (2.0 * input.texCoord.x - 1.0) * cam.aspect * cam.tanHalfFov;
- float v = (1.0 - 2.0 * input.texCoord.y) * cam.tanHalfFov;
+ 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);
@@ -323,16 +322,22 @@ float4 fragmentMain(VSOutput input) : SV_Target
RK4Step(ray, stepSize);
float3 newPos = float3(ray.x, ray.y, ray.z);
- if (prevPos.y * newPos.y < 0.0)
{
- float t = prevPos.y / (prevPos.y - newPos.y);
- float3 cross = lerp(prevPos, newPos, t);
- float rc = length(float2(cross.x, cross.z));
- if (rc >= max(disk.disk_r1, R_ISCO) && rc <= disk.disk_r2)
+ float H = disk.thickness;
+ bool crossed = prevPos.y * newPos.y < 0.0;
+ bool inSlab = abs(newPos.y) <= H;
+ if (crossed || inSlab)
{
- diskColor = DiskEmission(cross, newPos - prevPos);
- hitDisk = true;
- break;
+ float3 hitP = crossed
+ ? 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)
+ {
+ diskColor = DiskEmission(hitP, newPos - prevPos);
+ hitDisk = true;
+ break;
+ }
}
}
@@ -341,6 +346,10 @@ float4 fragmentMain(VSOutput input) : SV_Target
if (ray.dr > 0.0 && ray.r > 50.0 * SagA_rs) break;
}
+ float3 rayDir = normalize(float3(ray.x, ray.y, ray.z) - cam.camPos);
+ float footprint = max(length(ddx(rayDir)), length(ddy(rayDir)));
+ float envLod = clamp(log2(max(footprint / 0.0015, 1.0)), 0.0, 10.0);
+
float3 shade;
if (hitDisk)
{
@@ -360,9 +369,26 @@ float4 fragmentMain(VSOutput input) : SV_Target
}
else
{
- float3 rayDir = normalize(float3(ray.x, ray.y, ray.z) - cam.camPos);
- shade = SampleHDRI(rayDir);
+ shade = u_HDRIEnvironment.SampleLevel(rayDir, envLod).rgb;
}
- return float4(ACESFilm(shade), 1.0);
+ return shade;
+}
+
+[shader("fragment")]
+float4 fragmentMain(VSOutput input) : SV_Target
+{
+ if (cam.moving)
+ return float4(ACESFilm(TracePixel(input.texCoord)), 1.0);
+
+ float2 dUV = float2(ddx(input.texCoord.x), ddy(input.texCoord.y));
+ float2 offs[4] = {
+ float2( 0.125, 0.375), float2( 0.375, -0.125),
+ float2(-0.125, -0.375), float2(-0.375, 0.125),
+ };
+ float3 sum = float3(0.0);
+ for (int i = 0; i < 4; ++i)
+ sum += TracePixel(input.texCoord + offs[i] * dUV);
+
+ return float4(ACESFilm(sum * 0.25), 1.0);
}