I’m working on a 64k intro and decided to render scenes, where most of their content is based on triangle meshes. I also want to display some raytraced objects at the same time. Both rendering methods should use multisampling, and the painter’s algorithm should be simulated correctly as expected using Z-Tests. Before we enter into details, here is the picture of the result (click for a larger version): The terrain and the hollow cube are triangle meshes, and the white sphere is raytraced. I want to explain how I set up the rendering pipeline.

First, the entire mesh-based geometry is rendered into a rendertarget with several multisampling textures (In my case I have 3 textures with 4xMSAA), so that I can store amongst other things the color and the depth. I’m not storing the depth value exactly, instead I’m storing the world-space distance between the geometry and the camera. This could be the output struct of a pixel shader rendering the geometry:

```struct PSOUT
{
float4 Color;
float4 Normal;
float4 Depth;
};

// Later, in the pixel shader:
PSOUT r;
r.Color = float4(color, 1);
r.Normal = float4(normalize(normal), 1);
r.Depth = float4(length(worldPos - WorldCameraPosition), 0, 0, 1);
return r;
```

Then I render a fullscreen quad for the raytracing step. For this to work I need to pass the inverse of the ViewProjection matrix to the shader. This is the vertex shader for the fullscreen quad:

```struct VIn
{
float2 Pos: POSITION;
};

struct VOut
{
float4 ProjPos: SV_POSITION;
sample float2 toPos: TEXCOORD0;
float2 texCoords : TEXCOORD1;
};

VOut VS(VIn a)
{
VOut result;
result.ProjPos = float4(a.Pos, 0, 1);
result.texCoords = float2(a.Pos.x, -a.Pos.y) * 0.5 + 0.5;
result.toPos = a.Pos;
return result;
}
```

Notice the “sample” interpolation method introduced with Shader Model 4.1. This forces the pixel shader to run per-sample instead of per-pixel, enabling the nice antialiased raytracing rendering. Setting up the a raytracing framework is a piece of cake now. Here is an excerpt of the fragment shader:

```Texture2DMS<float4,4> tx: register(t0);

float4 PS(VOut a, uint nSampleIndex : SV_SAMPLEINDEX) : SV_TARGET
{
uint x, y, s;
tx.GetDimensions(x, y, s);

float4 toPos = mul(float4(a.toPos, 0, 1), ViewProjInverse);
toPos /= toPos.w;
float3 o = WorldCameraPosition; // ray origin
float3 d = normalize(toPos - WorldCameraPosition); // ray direction

float3 c = float3(1, 3, 1); //sphere center
float r = 1; // sphere radius
INTER i = raySphereIntersect(o, d, c, r); // ray sphere intersection

if (i.hit)
{
float z = tx.Load(a.texCoords * float2(x,y), nSampleIndex).x;
if (z > length(i.p - WorldCameraPosition))
return float4(1, 1, 1, 1);
}

return float4(0,0,0,0);
}
```

First of all you’ll notice that I’m using a multisampling texture to read back the depth values from the previous mesh rendering pass. Then you’ll see that I’m using the SV_SAMPLEINDEX semantic, which is needed for sampling that texture. This way I ensure a perfect sample match between the depth texture reads and raytracing output writes. After reading the depth value from the texture, I do a simple comparison between it and the distance between the raytraced geometry and the camera in world space. If that test passes, I render the sphere, otherwise I return an alpha value of 0. Alpha blending does the rest.

The result is a nice integration between raytracing and mesh-based rendering using multisampling.