Jump to content

  • Log In with Google      Sign In   
  • Create Account

steven166

Member Since 22 Nov 2011
Offline Last Active Yesterday, 06:03 AM

#5312951 Perspective divison without the clipping in stochastic rasterization

Posted by on 27 September 2016 - 09:08 PM

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.




#5245946 Texture2DArray and mipmapping

Posted by on 12 August 2015 - 05:39 AM

I fixed it, I just change the MipFilter into D3D11_FILTER_LINEAR when loading image information. But it seems that mipmapping has a problem as bleeding.




#5245455 Backface culling in geometry shader?

Posted by on 10 August 2015 - 07:28 AM

Thanks Kalle_h again, I did it.

 

@phantom: I need to manipulate vertices in the geometry, therefore I must do backface culling manually :(




#5109362 Is there possible to use dynamic index in shader model 5.0?

Posted by on 14 November 2013 - 10:55 PM

However, a Texture2DArray does not allow multiple textures with different resolutions.




#4936017 How to get an value from Byte Address buffer in DX11, HLSL?

Posted by on 30 April 2012 - 02:48 AM

Thank you so much, Tsus, I have tried the Load function before and I got the same error, but maybe there is something wrong, now it is working.


#4936010 How to get an value from Byte Address buffer in DX11, HLSL?

Posted by on 30 April 2012 - 01:55 AM

I try to modidy the shader code of OIT, http://www.yakiimo3d.com/2010/07/25/dx11-order-independent-transparency-with-msaa/, and the source code can be downloaded from http://yakiimo3d.codeplex.com/releases/view/49570. But in StoreFragments.hlsl, when they render into a linked list, they use a byte address buffer for offset.
void StoreFragmentsPS( SceneVS_Output input )
{
    uint x = input.pos.x;	    // [0,g_nFrameWidth]
    uint y = input.pos.y;	    // [0,g_nFrameHeight]
    // Create fragment data.
    uint4 nColor = saturate( input.color ) * 255;
    FragmentLink element;
    element.fragmentData.nColor = (nColor.x) | (nColor.y << 8) | (nColor.z << 16) | (nColor.a << 24);
    element.fragmentData.fDepth = input.pos.z;

    // Increment and get current pixel count.
    uint nPixelCount= FLBuffer.IncrementCounter();


    // Read and update Start Offset Buffer.
    uint nIndex = y * g_nFrameWidth + x;
    uint nStartOffsetAddress = 4 * nIndex;
    uint nOldStartOffset;

    StartOffsetBuffer.InterlockedExchange(
	    nStartOffsetAddress, nPixelCount, nOldStartOffset );


if ( nOldStartOffset != 0xFFFFFFFF  ) {
  //get an error: array, matrix, vector or indexable object.......
  uint index = StartOffsetBuffer[ idx ];
}
    // Store fragment link.
    element.nNext = nOldStartOffset;
    FLBuffer[ nPixelCount ] = element;
}

With the function InterlockedExchange, nPixelCount value will be saved at nStartOffsetAddress position and we can get the old value. Hence, we can use nOldStartOffset value as an index to get the previous/next element, but why did I get that error? and how to solve it?
Anybody help me, please? Thank in advance.


PARTNERS