Skip to content

Commit 334bae5

Browse files
committed
Parallel raytracing
1 parent 805fd21 commit 334bae5

File tree

1 file changed

+29
-25
lines changed

1 file changed

+29
-25
lines changed

Engine/Raytracer.cs

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,6 @@ namespace Unilight
55
// 1st = Origin, 2nd = Direction
66
using Ray = Tuple<Vector3D, Vector3D>;
77

8-
using IntPair = Tuple<int, int>;
9-
10-
// Eye, LookAt, ViewportWidth, ViewportHeight
11-
using TCamera = Tuple<Vector3D, Vector3D, float, float>;
12-
138
public class Raytracer
149
{
1510
private static int DEFAULT_TRACE_DEPTH = 5;
@@ -37,6 +32,8 @@ private struct RayTraversalResult
3732

3833
private Intersector mIntersector = new Intersector();
3934

35+
private Matrix4? _imageToWorld = null;
36+
4037
public bool GlobalReflection { get; set; } = true;
4138
public bool ComputeSpecular { get; set; } = false;
4239
public bool ComputeDiffuse { get; set; } = false;
@@ -45,7 +42,9 @@ private struct RayTraversalResult
4542

4643
public int TraceDepth { get; set; } = DEFAULT_TRACE_DEPTH;
4744

48-
public Raytracer() { }
45+
public Raytracer()
46+
{
47+
}
4948

5049
private RgbColor computeSpecular(float vDotR, float mGls, RgbColor sourceSpec, float matSpec)
5150
{
@@ -141,38 +140,46 @@ private RgbColor trace(Ray ray, int depth)
141140
return lit;
142141
}
143142

144-
private Matrix4 imageToViewportTransform(int imgWidth, int imgHeight, Camera cam)
143+
private void ComputeImageToViewportTransform(int imageWidth, int imageHeight, out Matrix4 result)
145144
{
146-
float width = cam.ViewportWidth;
147-
float height = cam.ViewportHeight;
148-
if (imgWidth == 0 || imgHeight == 0 || width == 0 || height == 0)
149-
return Matrix4.identity();
145+
float width = Camera.ViewportWidth;
146+
float height = Camera.ViewportHeight;
150147

151-
Matrix4 finalTransform = Matrix4.translate(cam.LookAt.X, cam.LookAt.Y, cam.LookAt.Z);
148+
if (imageWidth == 0 || imageHeight == 0 || width == 0 || height == 0)
149+
{
150+
result = Matrix4.identity();
151+
return;
152+
}
153+
154+
Matrix4 finalTransform = Matrix4.translate(Camera.LookAt.X, Camera.LookAt.Y, Camera.LookAt.Z);
152155

153-
Vector3D invNormal = cam.Eye - cam.LookAt;
156+
Vector3D invNormal = Camera.Eye - Camera.LookAt;
154157
invNormal.Normalize();
155158

156159
Matrix4 scale = Matrix4.identity();
157-
scale.SetAt(0, 0, width / imgWidth);
158-
scale.SetAt(1, 1, height / imgHeight);
160+
scale.SetAt(0, 0, width / imageWidth);
161+
scale.SetAt(1, 1, height / imageHeight);
159162
finalTransform.MultiplyThisBy(scale);
160163

161164
Matrix4 mirror = Matrix4.identity();
162165
mirror.SetAt(1, 1, -1);
163166
finalTransform.MultiplyThisBy(mirror);
164167

165-
Matrix4 center = Matrix4.translate(-imgWidth / 2, -imgHeight / 2, 0);
168+
Matrix4 center = Matrix4.translate(-imageWidth / 2, -imageHeight / 2, 0);
166169
finalTransform.MultiplyThisBy(center);
167170

168-
return finalTransform;
171+
// assign to out parameter
172+
result = finalTransform;
169173
}
170174

171175
public void Render()
172176
{
173177
if (Buffer == null)
174178
return;
175179

180+
// Compute image to world transform
181+
ComputeImageToViewportTransform(Buffer.Width, Buffer.Height, out _imageToWorld);
182+
176183
List<(Point start, Point end)>? chunks = null;
177184
Chunks.CreateRenderChunks(Buffer.Width, Buffer.Height, out chunks);
178185

@@ -191,10 +198,10 @@ public void Render()
191198
//PixelsToPlotCount = Buffer.Width * Buffer.Height;
192199

193200
// Render all chunks in parallel
194-
//Parallel.ForEach(chunks, chunk =>
195-
//{
196-
// RenderChunk(chunk.start, chunk.end, pixels, stride);
197-
//});
201+
Parallel.ForEach(chunks, chunk =>
202+
{
203+
RenderChunk(chunk.start, chunk.end, pixels, stride);
204+
});
198205

199206
RenderChunk(new Point(0, 0), new Point(Buffer.Width, Buffer.Height), pixels, stride);
200207

@@ -217,12 +224,9 @@ private void RenderChunk(Point start, Point end, byte[] pixels, int stride)
217224

218225
PixelIterator iter = new PixelIterator(start, end, TraversalOrder);
219226

220-
// TBD: Compute this only once, not for every thread
221-
Matrix4 i2v = imageToViewportTransform(Buffer.Width, Buffer.Height, Camera);
222-
223227
while (!iter.Done())
224228
{
225-
Vector3D mapped = i2v.Multiply(new Vector3D(iter.Cursor.X, iter.Cursor.Y, 0));
229+
Vector3D mapped = _imageToWorld.Multiply(new Vector3D(iter.Cursor.X, iter.Cursor.Y, 0));
226230
Vector3D dir = mapped - Camera.Eye;
227231
dir.Normalize();
228232
Ray ray = new Ray(Camera.Eye, dir);

0 commit comments

Comments
 (0)