static void SimpleRaycast(Texture2D texture) { Raytracer <RayPayload, float3> raycaster = new Raytracer <RayPayload, float3>(); // View and projection matrices float4x4 viewMatrix = Transforms.LookAtLH(float3(2, 1f, 4), float3(0, 0, 0), float3(0, 1, 0)); float4x4 projectionMatrix = Transforms.PerspectiveFovLH(pi_over_4, texture.Height / (float)texture.Width, 0.01f, 20); Scene <float3> scene = new Scene <float3>(); CreateScene(scene); raycaster.OnClosestHit += delegate(IRaycastContext context, float3 attribute, ref RayPayload payload) { payload.Color = attribute; }; for (float px = 0.5f; px < texture.Width; px++) { for (float py = 0.5f; py < texture.Height; py++) { RayDescription ray = RayDescription.FromScreen(px, py, texture.Width, texture.Height, inverse(viewMatrix), inverse(projectionMatrix), 0, 1000); RayPayload coloring = new RayPayload(); raycaster.Trace(scene, ray, ref coloring); texture.Write((int)px, (int)py, float4(coloring.Color, 1)); } } }
static void LitRaycast(Texture2D texture) { // Scene Setup float3 CameraPosition = float3(3, 2f, 4); float3 LightPosition = float3(3, 5, -2); // View and projection matrices float4x4 viewMatrix = Transforms.LookAtLH(CameraPosition, float3(0, 1, 0), float3(0, 1, 0)); float4x4 projectionMatrix = Transforms.PerspectiveFovLH(pi_over_4, texture.Height / (float)texture.Width, 0.01f, 20); Scene <PositionNormal> scene = new Scene <PositionNormal>(); CreateScene(scene); // Raycaster to trace rays and check for shadow rays. Raytracer <ShadowRayPayload, PositionNormal> shadower = new Raytracer <ShadowRayPayload, PositionNormal>(); shadower.OnAnyHit += delegate(IRaycastContext context, PositionNormal attribute, ref ShadowRayPayload payload) { // If any object is found in ray-path to the light, the ray is shadowed. payload.Shadowed = true; // No neccessary to continue checking other objects return(HitResult.Stop); }; // Raycaster to trace rays and lit closest surfaces Raytracer <RayPayload, PositionNormal> raycaster = new Raytracer <RayPayload, PositionNormal>(); raycaster.OnClosestHit += delegate(IRaycastContext context, PositionNormal attribute, ref RayPayload payload) { // Move geometry attribute to world space attribute = attribute.Transform(context.FromGeometryToWorld); float3 V = normalize(CameraPosition - attribute.Position); float3 L = normalize(LightPosition - attribute.Position); float lambertFactor = max(0, dot(attribute.Normal, L)); // Check ray to light... ShadowRayPayload shadow = new ShadowRayPayload(); shadower.Trace(scene, RayDescription.FromTo( attribute.Position + attribute.Normal * 0.001f, // Move an epsilon away from the surface to avoid self-shadowing LightPosition), ref shadow); payload.Color = shadow.Shadowed ? float3(0, 0, 0) : float3(1, 1, 1) * lambertFactor; }; raycaster.OnMiss += delegate(IRaycastContext context, ref RayPayload payload) { payload.Color = float3(0, 0, 1); // Blue, as the sky. }; // Render all points of the screen for (int px = 0; px < texture.Width; px++) { for (int py = 0; py < texture.Height; py++) { RayDescription ray = RayDescription.FromScreen(px + 0.5f, py + 0.5f, texture.Width, texture.Height, inverse(viewMatrix), inverse(projectionMatrix), 0, 1000); RayPayload coloring = new RayPayload(); raycaster.Trace(scene, ray, ref coloring); texture.Write(px, py, float4(coloring.Color, 1)); } } }