Hello All,
I am writing a compute shader that calculating Grid frustum for my tiled forwarding rendering demo using Directx12. However, I am having a very strange issue of writing results to my RWStructedBuffer with a Frustum type, where all planes of a frustum share the exactly the same plane information. (I am pretty sure I can correctly calculate the plane information for left, right, top, and bottom planes of a frustum.)
My Frustum structure declaration is the following:
struct Plane
{
float3 N; // Plane normal.
float d; // Distance to origin.
};
// Four planes of a view frustum (in view space).
// The planes are:
// * Left,
// * Right,
// * Top,
// * Bottom.
// The back and/or front planes can be computed from depth values in the
// light culling compute shader.
struct Frustum
{
Plane planes[4]; // left, right, top, bottom frustum planes.
};
These two structures are declared in CommonIncl.hlsl file.
In the actual hlsl file that compute the grid frustum, I wrote a few lines of codes that just try to assign four planes of a frustum different values and store the frustum in my RWStructuredBuffer using the following codes:
#include "CommonIncl.hlsl"
// ...skip some extra codes
struct test2
{
float4 p[4];
};
RWStructuredBuffer<Frustum> out_Frustums : register(u0);
RWStructuredBuffer<test2> debugUAV : register(u1);
// Calculate the view frustum for each tiled in the view space
[numthreads(BLOCK_SIZE, BLOCK_SIZE, 1)]
void CS_GridFrustumPass(ComputeShaderInput Input)
{
const float3 eyePos = float3(0.0f, 0.0f, 0.0f);
uint tiledBlockSize = BLOCK_SIZE;
// Compute 4 points on the far clipping plane to use as the frustum vertices
float4 tiledVerticesInScreenSpace[4];
tiledVerticesInScreenSpace[0] = float4(Input.dispatchThreadID.xy * tiledBlockSize, -1.0f, 1.0f);
tiledVerticesInScreenSpace[1] = float4(float2(Input.dispatchThreadID.x + 1, Input.dispatchThreadID.y) * tiledBlockSize, -1.0f, 1.0f);
tiledVerticesInScreenSpace[2] = float4(float2(Input.dispatchThreadID.x, Input.dispatchThreadID.y + 1) * tiledBlockSize, -1.0f, 1.0f);
tiledVerticesInScreenSpace[3] = float4(float2(Input.dispatchThreadID.x + 1, Input.dispatchThreadID.y + 1) * tiledBlockSize, -1.0f, 1.0f);
float3 tiledVerticesInViewSpace[4];
[unroll]
for (int i = 0; i < 4; ++i)
{
tiledVerticesInViewSpace[i] = ScreenToView(tiledVerticesInScreenSpace[i]).xyz;
}
// Build the frustum planes from the view space points
Frustum frustum;
frustum.planes[0].N = float3(0.0f, 1.0f, 0.0f);
frustum.planes[0].d = 0;
frustum.planes[1].N = float3(0.0f, 2.0f, 0.0f);
frustum.planes[1].d = 0;
frustum.planes[2].N = float3(0.0f, 3.0f, 0.0f);
frustum.planes[2].d = 0;
frustum.planes[3].N = float3(0.0f, 4.0f, 0.0f);
frustum.planes[3].d = 0;
// Store the computed frustum in the output buffer
if (Input.dispatchThreadID.x < numThreads.x && Input.dispatchThreadID.y < numThreads.y)
{
uint idx = Input.dispatchThreadID.x + (Input.dispatchThreadID.y * numThreads.x);
out_Frustums[idx] = frustum;
// Another case when the type of RWStructuredBuffer is test2
//test2 tt;
//tt.p[0] = float4(1, 1, 1, 1);
//tt.p[1] = float4(2, 2, 2, 2);
//tt.p[2] = float4(3, 3, 3, 3);
//tt.p[3] = float4(4, 4, 4, 4);
//debugUAV[idx] = tt;
}
}
With the RWStructuredBuffer<Frustum>, the RenderDoc shows that all planes have the same result as plane[0] in a frustum. However, with the RWStructuredBuffer<test2>, the RenderDoc shows that all planes have the desired values, which is p[0] = {1,1,1,1}, p[1]={2,2,2,2},p[2]={3,3,3,3} and p[3]={4,4,4,4}.
I am very confused about what I just observed and I am not sure what cause this issue. Does that means we cannot use a nested structure for the type of my RWStructuredBuffer?
(PS: I think the creation of this RWStructuredBuffer should be correct in my code.)
Best,
Nullptr