Perspective divison without the clipping in stochastic rasterization

Started by
-1 comments, last by pnt1614 7 years, 6 months ago

I am trying to implement the stochastic rasterization based on the paper: "Real-Time Stochastic Rasterization on Conventional GPU Architectures" and provided pseudo code. But I do not understand how they address a problem as a triangle moves to/from a position behind the camera ("crossing z=0" in the paper) in the geometry shader. To handle the "crossing z = 0" problem, they generate a 2D AABB to contain all vertices behind the camera then find an intersection between an edge and the near plane and use this intersection point to update the 2D AABB. As generating a 2D AABB to contain all vertices behind the camera, they perform perspective divison without clipping and I think this yield a incorrect result.

I have implemented the following shader code in the geometry shader using DirectX 11 and HLSL 5.0


void intersectNear(float3 start, float3 end, inout float2 minXY, inout float2 maxXY)
{
    float denom = end.z - start.z;
    if (abs(denom) > 0.0001)
    {
        float a = (nearPlaneZ - start.z) / denom;
        if ((a >= 0.0) && (a < 1.0))
        {
   	     // Intersection point in camera space
	     float3 cs = float3(lerp(start.xy, end.xy, a), nearPlaneZ);

	     // Intersection point in screen space
	     float2 ss = project42(mul(float4(cs, 1.0), g_mProj));
	     minXY = min(minXY, ss);
	     maxXY = max(maxXY, ss);
        }
    }
}

void ST_GS(triangle VS_OUTPUT input[3] : SV_POSITION, inout TriangleStream<GS_OUTPUT_ST> output)
{
        ......

        float4 ssP0A = input[0].Prev_hPos; // A0 in the clip space
	float4 ssP0B = input[1].Prev_hPos; // B0 in the clip space
	float4 ssP0C = input[2].Prev_hPos; // C0 in the clip space

	float4 ssP1A = input[0].Curr_hPos; // A1 in the clip space
	float4 ssP1B = input[1].Curr_hPos; // B1 in the clip space
	float4 ssP1C = input[2].Curr_hPos; // C1 in the clip space


        // scaled depth values in the view space
        float minDepth = min6(input[0].Prev_vPos.z, input[1].Prev_vPos.z, input[2].Prev_vPos.z,
				input[0].Curr_vPos.z, input[1].Curr_vPos.z, input[2].Curr_vPos.z)  / far_plane;
				
        float maxDepth = max6(input[0].Prev_vPos.z, input[1].Prev_vPos.z, input[2].Prev_vPos.z,
				input[0].Curr_vPos.z, input[1].Curr_vPos.z, input[2].Curr_vPos.z) / far_plane;


       
        if (maxDepth < near_plane || minDepth > 1.0f)
        {
            return; // Out of view frustrum
        }		
	else if (minDepth < 0.0f)
	{
   	    float2 clipMin = float2(-1.0f, -1.0f);
	    float2 clipMax = float2(1.0f, 1.0f);

	    // Make 2D AABB
	    // Grow the 2D AABB to contain all points with z < z_near
	    if (input[0].Prev_vPos.z < nearPlaneZ)
	    {
		float2 v = project42(ssP0A);
		clipMin = min(clipMin, v);
		clipMax = max(clipMax, v);
			}
	    if (input[1].Prev_vPos.z < nearPlaneZ)
	    {
		float2 v = project42(ssP0B);
		clipMin = min(clipMin, v);
		clipMax = max(clipMax, v);
	    }

	    if (input[2].Prev_vPos.z < nearPlaneZ)
     	    {
		float2 v = project42(ssP0C);
		clipMin = min(clipMin, v);
		clipMax = max(clipMax, v);
	    }


	    if (input[0].Curr_vPos.z < nearPlaneZ)
	    {
		float2 v = project42(ssP1A);
		clipMin = min(clipMin, v);
		clipMax = max(clipMax, v);
	    }
		
  	    if (input[1].Curr_vPos.z < nearPlaneZ)
	    {
		float2 v = project42(ssP1B);
		clipMin = min(clipMin, v);
		clipMax = max(clipMax, v);
	    }

   	    if (input[2].Curr_vPos.z < nearPlaneZ)
	    {
		float2 v = project42(ssP1C);
		clipMin = min(clipMin, v);
		clipMax = max(clipMax, v);
	    }


	    // Viewport clips the generated 2D AABB
	    intersectNear(input[0].Prev_vPos.xyz, input[1].Prev_vPos.xyz, clipMin, clipMax);
	    intersectNear(input[1].Prev_vPos.xyz, input[2].Prev_vPos.xyz, clipMin, clipMax);
	    intersectNear(input[2].Prev_vPos.xyz, input[0].Prev_vPos.xyz, clipMin, clipMax);

	    intersectNear(input[0].Curr_vPos.xyz, input[1].Curr_vPos.xyz, clipMin, clipMax);
	    intersectNear(input[1].Curr_vPos.xyz, input[2].Curr_vPos.xyz, clipMin, clipMax);
	    intersectNear(input[2].Curr_vPos.xyz, input[0].Curr_vPos.xyz, clipMin, clipMax);

	    intersectNear(input[0].Prev_vPos.xyz, input[0].Curr_vPos.xyz, clipMin, clipMax);
	    intersectNear(input[1].Prev_vPos.xyz, input[1].Curr_vPos.xyz, clipMin, clipMax);
	    intersectNear(input[2].Prev_vPos.xyz, input[2].Curr_vPos.xyz, clipMin, clipMax);


	    // Output a quad
	    points[0].posH = float4(clipMax.x, clipMin.y, nearPlaneDepth, 1.0);
	    points[1].posH = float4(clipMax.x, clipMax.y, nearPlaneDepth, 1.0);
	    points[2].posH = float4(clipMin.x, clipMin.y, nearPlaneDepth, 1.0);
	    points[3].posH = float4(clipMin.x, clipMax.y, nearPlaneDepth, 1.0);
					
	
	    output.Append(points[0]);
	    output.Append(points[1]);
	    output.Append(points[2]);
	    output.Append(points[3]);
	    output.RestartStrip();

	    return;
}

I am not sure that this is the limitation of this paper or I do not understand this stage. Is there anyone understood this paper or this stage? Please help me. Thanks in advance.

This topic is closed to new replies.

Advertisement