Skip to content

Commit d79d08d

Browse files
authored
Merge pull request #3 from adamstirtan/feature/supersampling
2 parents 1c0df41 + 9c126fb commit d79d08d

File tree

5 files changed

+41
-8
lines changed

5 files changed

+41
-8
lines changed

RayTracer.Core/Engine.cs

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,36 @@ public Image<Rgba32> Render()
9999
float distance = float.MaxValue;
100100
Vector3 color = Vector3.Zero;
101101

102-
Vector3 pixelPos = pixelStart + camRight * (x * deltaX);
103-
Vector3 direction = Vector3.Normalize(pixelPos - camPos);
102+
// Supersampling / stratified jittered sampling
103+
int spp = System.Math.Max(1, _options.SamplesPerPixel);
104+
int side = (int)System.MathF.Round(System.MathF.Sqrt(spp));
105+
if (side * side != spp) side = 1; // fallback to 1 if not perfect square
104106

105-
Ray ray = new(camPos, direction);
106-
Raytrace(_scene, _options, ray, ref color, 1, ref distance);
107+
Vector3 accum = Vector3.Zero;
107108

109+
// simple stratified grid within pixel
110+
for (int sy = 0; sy < side; sy++)
111+
{
112+
for (int sx = 0; sx < side; sx++)
113+
{
114+
// jitter within subpixel
115+
float jitterX = (sx + 0.5f) / side;
116+
float jitterY = (sy + 0.5f) / side;
117+
118+
Vector3 pixelPosSS = pixelStart + camRight * ((x + jitterX) * deltaX) - camUp * ((y + jitterY) * deltaY);
119+
Vector3 dirSS = Vector3.Normalize(pixelPosSS - camPos);
120+
121+
Ray ssRay = new(camPos, dirSS);
122+
float ssDistance = float.MaxValue;
123+
Vector3 ssColor = Vector3.Zero;
124+
125+
Raytrace(_scene, _options, ssRay, ref ssColor, 1, ref ssDistance);
126+
127+
accum += ssColor;
128+
}
129+
}
130+
131+
color = accum / (side * side);
108132
color = Vector3.Clamp(color, Vector3.Zero, Vector3.One);
109133

110134
pixelRowSpan[x] = new Rgba32(color.X, color.Y, color.Z);

RayTracer.Core/Primitives/Torus.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ private float SDF(Vector3 p)
3232
public override RayIntersection Intersects(Ray ray, ref float distance)
3333
{
3434
// Ray-marching using SDF. Not perfect but simple and robust for tests/scenes.
35-
const int maxSteps = 100;
36-
const float hitEps = 1e-3f;
35+
const int maxSteps = 300; // increase steps for finer intersections
36+
const float hitEps = 5e-4f; // tighter hit epsilon for crisper surface
3737
const float maxDist = 100f;
3838

3939
float t = 0f;
@@ -60,7 +60,7 @@ public override RayIntersection Intersects(Ray ray, ref float distance)
6060
private Vector3 EstimateNormal(Vector3 p)
6161
{
6262
// numerical gradient
63-
float eps = 1e-4f;
63+
float eps = 5e-5f;
6464
float dx = SDF(new Vector3(p.X + eps, p.Y, p.Z)) - SDF(new Vector3(p.X - eps, p.Y, p.Z));
6565
float dy = SDF(new Vector3(p.X, p.Y + eps, p.Z)) - SDF(new Vector3(p.X, p.Y - eps, p.Z));
6666
float dz = SDF(new Vector3(p.X, p.Y, p.Z + eps)) - SDF(new Vector3(p.X, p.Y, p.Z - eps));

RayTracer.Core/RenderOptions.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,8 @@ public class RenderOptions
1313
public required bool DisableReflections { get; init; }
1414
public bool DisableDiffuse { get; init; }
1515
public bool DisableSpeculation { get; init; }
16+
17+
// Supersampling: number of samples per pixel (1 = no supersampling).
18+
// Use perfect squares like 1,4,9 (1x1,2x2,3x3 stratified sampling).
19+
public int SamplesPerPixel { get; init; } = 1;
1620
}

Raytracer.Cli/Program.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
int height = 600;
1212
string outPath = "render.png";
1313
int depth = 2;
14+
int samplesPerPixel = 1;
1415

1516
for (int i = 0; i < argsList.Length; i++)
1617
{
@@ -31,6 +32,9 @@
3132
case "--depth":
3233
if (i + 1 < argsList.Length) int.TryParse(argsList[++i], out depth);
3334
break;
35+
case "--spp":
36+
if (i + 1 < argsList.Length) int.TryParse(argsList[++i], out samplesPerPixel);
37+
break;
3438
}
3539
}
3640

@@ -78,7 +82,8 @@
7882
TraceDepth = depth,
7983
CameraPosition = cameraPos,
8084
CameraTarget = cameraTarget,
81-
DisableReflections = false
85+
DisableReflections = false,
86+
SamplesPerPixel = samplesPerPixel
8287
};
8388

8489
var engine = new Engine(scene, options);

assets/torus_render_spp4_tuned.png

194 KB
Loading

0 commit comments

Comments
 (0)