• Create Account

# steven166

Member Since 22 Nov 2011
Offline Last Active Oct 20 2016 01:02 AM

### #5312951Perspective 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);

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.

### #5245946Texture2DArray 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.

### #5245455Backface 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

### #5109362Is 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.

### #4936017How 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.

### #4936010How 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;
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(

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