separated bvh primitive and primitivedata;
This commit is contained in:
@@ -14,15 +14,18 @@ CBUFFER(BVHCB, CBSLOT_RENDERER_BVH)
|
||||
uint xTraceBVHMeshVertexPOSStride;
|
||||
};
|
||||
|
||||
|
||||
struct BVHPrimitive
|
||||
{
|
||||
float3 v0;
|
||||
uint n0;
|
||||
|
||||
float3 v1;
|
||||
uint n1;
|
||||
|
||||
float3 v2;
|
||||
};
|
||||
struct BVHPrimitiveData
|
||||
{
|
||||
uint userdata;
|
||||
uint n0;
|
||||
uint n1;
|
||||
uint n2;
|
||||
|
||||
uint2 u0;
|
||||
|
||||
@@ -16,7 +16,8 @@ TYPEDBUFFER(meshVertexBuffer_COL, float4, TEXSLOT_ONDEMAND5);
|
||||
|
||||
RWSTRUCTUREDBUFFER(primitiveIDBuffer, uint, 0);
|
||||
RWSTRUCTUREDBUFFER(primitiveBuffer, BVHPrimitive, 1);
|
||||
RWSTRUCTUREDBUFFER(primitiveMortonBuffer, float, 2); // morton buffer is float because sorting is written for floats!
|
||||
RWSTRUCTUREDBUFFER(primitiveDataBuffer, BVHPrimitiveData, 2);
|
||||
RWSTRUCTUREDBUFFER(primitiveMortonBuffer, float, 3); // morton buffer is float because sorting is written for floats!
|
||||
|
||||
|
||||
// Expands a 10-bit integer into 30 bits
|
||||
@@ -79,9 +80,10 @@ void main(uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex)
|
||||
const uint materialIndex = xTraceBVHMaterialOffset + subsetIndex;
|
||||
TracedRenderingMaterial material = materialBuffer[materialIndex];
|
||||
|
||||
float3 pos0 = mul(WORLD, float4(pos_nor0.xyz, 1)).xyz;
|
||||
float3 pos1 = mul(WORLD, float4(pos_nor1.xyz, 1)).xyz;
|
||||
float3 pos2 = mul(WORLD, float4(pos_nor2.xyz, 1)).xyz;
|
||||
BVHPrimitive prim;
|
||||
prim.v0 = mul(WORLD, float4(pos_nor0.xyz, 1)).xyz;
|
||||
prim.v1 = mul(WORLD, float4(pos_nor1.xyz, 1)).xyz;
|
||||
prim.v2 = mul(WORLD, float4(pos_nor2.xyz, 1)).xyz;
|
||||
nor0 = normalize(mul((float3x3)WORLD, nor0));
|
||||
nor1 = normalize(mul((float3x3)WORLD, nor1));
|
||||
nor2 = normalize(mul((float3x3)WORLD, nor2));
|
||||
@@ -89,7 +91,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex)
|
||||
float4 u1 = float4(meshVertexBuffer_UV0[i1] * material.texMulAdd.xy + material.texMulAdd.zw, meshVertexBuffer_UV1[i1]);
|
||||
float4 u2 = float4(meshVertexBuffer_UV0[i2] * material.texMulAdd.xy + material.texMulAdd.zw, meshVertexBuffer_UV1[i2]);
|
||||
|
||||
float4 color = xTraceBVHInstanceColor * material.baseColor;
|
||||
const float4 color = xTraceBVHInstanceColor * material.baseColor;
|
||||
float4 c0 = color;
|
||||
float4 c1 = color;
|
||||
float4 c2 = color;
|
||||
@@ -108,22 +110,22 @@ void main(uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex)
|
||||
{
|
||||
const float3 facenormal = normalize(nor0 + nor1 + nor2);
|
||||
|
||||
float x1 = pos1.x - pos0.x;
|
||||
float x2 = pos2.x - pos0.x;
|
||||
float y1 = pos1.y - pos0.y;
|
||||
float y2 = pos2.y - pos0.y;
|
||||
float z1 = pos1.z - pos0.z;
|
||||
float z2 = pos2.z - pos0.z;
|
||||
const float x1 = prim.v1.x - prim.v0.x;
|
||||
const float x2 = prim.v2.x - prim.v0.x;
|
||||
const float y1 = prim.v1.y - prim.v0.y;
|
||||
const float y2 = prim.v2.y - prim.v0.y;
|
||||
const float z1 = prim.v1.z - prim.v0.z;
|
||||
const float z2 = prim.v2.z - prim.v0.z;
|
||||
|
||||
float s1 = u1.x - u0.x;
|
||||
float s2 = u2.x - u0.x;
|
||||
float t1 = u1.y - u0.y;
|
||||
float t2 = u2.y - u0.y;
|
||||
const float s1 = u1.x - u0.x;
|
||||
const float s2 = u2.x - u0.x;
|
||||
const float t1 = u1.y - u0.y;
|
||||
const float t2 = u2.y - u0.y;
|
||||
|
||||
float r = 1.0f / (s1 * t2 - s2 * t1);
|
||||
float3 sdir = float3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
|
||||
const float r = 1.0f / (s1 * t2 - s2 * t1);
|
||||
const float3 sdir = float3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
|
||||
(t2 * z1 - t1 * z2) * r);
|
||||
float3 tdir = float3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
|
||||
const float3 tdir = float3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
|
||||
(s1 * z2 - s2 * z1) * r);
|
||||
|
||||
tangent.xyz = normalize(sdir - facenormal * dot(facenormal, sdir));
|
||||
@@ -132,26 +134,25 @@ void main(uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex)
|
||||
binormal = normalize(cross(tangent.xyz, facenormal) * tangent.w);
|
||||
}
|
||||
|
||||
// Pack primitive to store:
|
||||
BVHPrimitive prim = (BVHPrimitive)0;
|
||||
prim.v0 = pos0;
|
||||
prim.v1 = pos1;
|
||||
prim.v2 = pos2;
|
||||
prim.n0 = pack_unitvector(nor0);
|
||||
prim.n1 = pack_unitvector(nor1);
|
||||
prim.n2 = pack_unitvector(nor2);
|
||||
prim.u0 = pack_half4(u0);
|
||||
prim.u1 = pack_half4(u1);
|
||||
prim.u2 = pack_half4(u2);
|
||||
prim.c0 = pack_rgba(c0);
|
||||
prim.c1 = pack_rgba(c1);
|
||||
prim.c2 = pack_rgba(c2);
|
||||
prim.tangent = pack_unitvector(tangent.xyz);
|
||||
prim.binormal = pack_unitvector(binormal);
|
||||
prim.materialIndex = materialIndex;
|
||||
// Pack primitive data:
|
||||
BVHPrimitiveData primdata;
|
||||
primdata.userdata = 0;
|
||||
primdata.n0 = pack_unitvector(nor0);
|
||||
primdata.n1 = pack_unitvector(nor1);
|
||||
primdata.n2 = pack_unitvector(nor2);
|
||||
primdata.u0 = pack_half4(u0);
|
||||
primdata.u1 = pack_half4(u1);
|
||||
primdata.u2 = pack_half4(u2);
|
||||
primdata.c0 = pack_rgba(c0);
|
||||
primdata.c1 = pack_rgba(c1);
|
||||
primdata.c2 = pack_rgba(c2);
|
||||
primdata.tangent = pack_unitvector(tangent.xyz);
|
||||
primdata.binormal = pack_unitvector(binormal);
|
||||
primdata.materialIndex = materialIndex;
|
||||
|
||||
// Store packed primitive:
|
||||
// Store primitive:
|
||||
primitiveBuffer[primitiveID] = prim;
|
||||
primitiveDataBuffer[primitiveID] = primdata;
|
||||
|
||||
primitiveIDBuffer[primitiveID] = primitiveID; // will be sorted by morton so we need this!
|
||||
|
||||
|
||||
@@ -9,10 +9,11 @@
|
||||
|
||||
STRUCTUREDBUFFER(materialBuffer, TracedRenderingMaterial, TEXSLOT_ONDEMAND0);
|
||||
TEXTURE2D(materialTextureAtlas, float4, TEXSLOT_ONDEMAND1);
|
||||
STRUCTUREDBUFFER(primitiveBuffer, BVHPrimitive, TEXSLOT_ONDEMAND2);
|
||||
RAWBUFFER(primitiveCounterBuffer, TEXSLOT_ONDEMAND3);
|
||||
STRUCTUREDBUFFER(primitiveIDBuffer, uint, TEXSLOT_ONDEMAND4);
|
||||
STRUCTUREDBUFFER(bvhNodeBuffer, BVHNode, TEXSLOT_ONDEMAND5);
|
||||
RAWBUFFER(primitiveCounterBuffer, TEXSLOT_ONDEMAND2);
|
||||
STRUCTUREDBUFFER(primitiveIDBuffer, uint, TEXSLOT_ONDEMAND3);
|
||||
STRUCTUREDBUFFER(primitiveBuffer, BVHPrimitive, TEXSLOT_ONDEMAND4);
|
||||
STRUCTUREDBUFFER(primitiveDataBuffer, BVHPrimitiveData, TEXSLOT_ONDEMAND5);
|
||||
STRUCTUREDBUFFER(bvhNodeBuffer, BVHNode, TEXSLOT_ONDEMAND6);
|
||||
|
||||
|
||||
// Returns the closest hit primitive if any (useful for generic trace). If nothing was hit, then rayHit.distance will be equal to INFINITE_RAYHIT
|
||||
@@ -193,7 +194,7 @@ inline float3 Shade(inout Ray ray, inout RayHit hit, inout float seed, in float2
|
||||
{
|
||||
if (hit.distance < INFINITE_RAYHIT)
|
||||
{
|
||||
Primitive_Triangle tri = Primitive_UnpackTriangle(primitiveBuffer[hit.primitiveID]);
|
||||
TriangleData tri = TriangleData_Unpack(primitiveDataBuffer[hit.primitiveID]);
|
||||
|
||||
float u = hit.bary.x;
|
||||
float v = hit.bary.y;
|
||||
|
||||
@@ -34,7 +34,7 @@ void main( uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex)
|
||||
|
||||
float3 finalResult = 0;
|
||||
|
||||
Primitive_Triangle tri = Primitive_UnpackTriangle(primitiveBuffer[ray.primitiveID]);
|
||||
TriangleData tri = TriangleData_Unpack(primitiveDataBuffer[ray.primitiveID]);
|
||||
|
||||
float u = ray.bary.x;
|
||||
float v = ray.bary.y;
|
||||
|
||||
@@ -153,7 +153,7 @@ inline RayHit CreateRayHit()
|
||||
//}
|
||||
|
||||
|
||||
struct Primitive_Triangle
|
||||
struct TriangleData
|
||||
{
|
||||
float3 v0, v1, v2; // positions
|
||||
float3 n0, n1, n2; // normals
|
||||
@@ -163,29 +163,26 @@ struct Primitive_Triangle
|
||||
float3 binormal;
|
||||
uint materialIndex;
|
||||
};
|
||||
inline Primitive_Triangle Primitive_UnpackTriangle(in BVHPrimitive prim)
|
||||
inline TriangleData TriangleData_Unpack(in BVHPrimitiveData primdata)
|
||||
{
|
||||
Primitive_Triangle tri;
|
||||
TriangleData tri;
|
||||
|
||||
tri.v0 = prim.v0;
|
||||
tri.v1 = prim.v1;
|
||||
tri.v2 = prim.v2;
|
||||
tri.materialIndex = prim.materialIndex;
|
||||
tri.n0 = unpack_unitvector(primdata.n0);
|
||||
tri.n1 = unpack_unitvector(primdata.n1);
|
||||
tri.n2 = unpack_unitvector(primdata.n2);
|
||||
|
||||
tri.n0 = unpack_unitvector(prim.n0);
|
||||
tri.n1 = unpack_unitvector(prim.n1);
|
||||
tri.n2 = unpack_unitvector(prim.n2);
|
||||
tri.u0 = unpack_half4(primdata.u0);
|
||||
tri.u1 = unpack_half4(primdata.u1);
|
||||
tri.u2 = unpack_half4(primdata.u2);
|
||||
|
||||
tri.tangent = unpack_unitvector(prim.tangent);
|
||||
tri.binormal = unpack_unitvector(prim.binormal);
|
||||
tri.c0 = unpack_rgba(primdata.c0);
|
||||
tri.c1 = unpack_rgba(primdata.c1);
|
||||
tri.c2 = unpack_rgba(primdata.c2);
|
||||
|
||||
tri.u0 = unpack_half4(prim.u0);
|
||||
tri.u1 = unpack_half4(prim.u1);
|
||||
tri.u2 = unpack_half4(prim.u2);
|
||||
tri.tangent = unpack_unitvector(primdata.tangent);
|
||||
tri.binormal = unpack_unitvector(primdata.binormal);
|
||||
|
||||
tri.c0 = unpack_rgba(prim.c0);
|
||||
tri.c1 = unpack_rgba(prim.c1);
|
||||
tri.c2 = unpack_rgba(prim.c2);
|
||||
tri.materialIndex = primdata.materialIndex;
|
||||
|
||||
return tri;
|
||||
}
|
||||
|
||||
@@ -347,6 +347,17 @@ void wiGPUBVH::Build(const Scene& scene, GRAPHICSTHREAD threadID)
|
||||
assert(SUCCEEDED(hr));
|
||||
device->SetName(&bvhFlagBuffer, "BVHFlagBuffer");
|
||||
|
||||
desc.BindFlags = BIND_SHADER_RESOURCE | BIND_UNORDERED_ACCESS;
|
||||
desc.StructureByteStride = sizeof(uint);
|
||||
desc.ByteWidth = desc.StructureByteStride * maxPrimitiveCount;
|
||||
desc.CPUAccessFlags = 0;
|
||||
desc.Format = FORMAT_UNKNOWN;
|
||||
desc.MiscFlags = RESOURCE_MISC_BUFFER_STRUCTURED;
|
||||
desc.Usage = USAGE_DEFAULT;
|
||||
hr = device->CreateBuffer(&desc, nullptr, &primitiveIDBuffer);
|
||||
assert(SUCCEEDED(hr));
|
||||
device->SetName(&primitiveIDBuffer, "primitiveIDBuffer");
|
||||
|
||||
desc.BindFlags = BIND_SHADER_RESOURCE | BIND_UNORDERED_ACCESS;
|
||||
desc.StructureByteStride = sizeof(BVHPrimitive);
|
||||
desc.ByteWidth = desc.StructureByteStride * maxPrimitiveCount;
|
||||
@@ -359,15 +370,15 @@ void wiGPUBVH::Build(const Scene& scene, GRAPHICSTHREAD threadID)
|
||||
device->SetName(&primitiveBuffer, "primitiveBuffer");
|
||||
|
||||
desc.BindFlags = BIND_SHADER_RESOURCE | BIND_UNORDERED_ACCESS;
|
||||
desc.StructureByteStride = sizeof(uint);
|
||||
desc.StructureByteStride = sizeof(BVHPrimitiveData);
|
||||
desc.ByteWidth = desc.StructureByteStride * maxPrimitiveCount;
|
||||
desc.CPUAccessFlags = 0;
|
||||
desc.Format = FORMAT_UNKNOWN;
|
||||
desc.MiscFlags = RESOURCE_MISC_BUFFER_STRUCTURED;
|
||||
desc.Usage = USAGE_DEFAULT;
|
||||
hr = device->CreateBuffer(&desc, nullptr, &primitiveIDBuffer);
|
||||
hr = device->CreateBuffer(&desc, nullptr, &primitiveDataBuffer);
|
||||
assert(SUCCEEDED(hr));
|
||||
device->SetName(&primitiveIDBuffer, "primitiveIDBuffer");
|
||||
device->SetName(&primitiveDataBuffer, "primitiveDataBuffer");
|
||||
|
||||
desc.BindFlags = BIND_SHADER_RESOURCE | BIND_UNORDERED_ACCESS;
|
||||
desc.ByteWidth = desc.StructureByteStride * maxPrimitiveCount;
|
||||
@@ -413,6 +424,7 @@ void wiGPUBVH::Build(const Scene& scene, GRAPHICSTHREAD threadID)
|
||||
GPUResource* uavs[] = {
|
||||
&primitiveIDBuffer,
|
||||
&primitiveBuffer,
|
||||
&primitiveDataBuffer,
|
||||
&primitiveMortonBuffer,
|
||||
};
|
||||
device->BindUAVs(CS, uavs, 0, ARRAYSIZE(uavs), threadID);
|
||||
@@ -633,9 +645,10 @@ void wiGPUBVH::Bind(SHADERSTAGE stage, GRAPHICSTHREAD threadID) const
|
||||
const GPUResource* res[] = {
|
||||
&globalMaterialBuffer,
|
||||
(globalMaterialAtlas.IsValid() ? &globalMaterialAtlas : wiTextureHelper::getWhite()),
|
||||
&primitiveBuffer,
|
||||
&primitiveCounterBuffer,
|
||||
&primitiveIDBuffer,
|
||||
&primitiveBuffer,
|
||||
&primitiveDataBuffer,
|
||||
&bvhNodeBuffer,
|
||||
};
|
||||
device->BindResources(stage, res, TEXSLOT_ONDEMAND0, ARRAYSIZE(res), threadID);
|
||||
|
||||
@@ -17,9 +17,10 @@ private:
|
||||
// Scene BVH intersection resources:
|
||||
wiGraphics::GPUBuffer bvhNodeBuffer;
|
||||
wiGraphics::GPUBuffer bvhFlagBuffer;
|
||||
wiGraphics::GPUBuffer primitiveBuffer;
|
||||
wiGraphics::GPUBuffer primitiveCounterBuffer;
|
||||
wiGraphics::GPUBuffer primitiveIDBuffer;
|
||||
wiGraphics::GPUBuffer primitiveBuffer;
|
||||
wiGraphics::GPUBuffer primitiveDataBuffer;
|
||||
wiGraphics::GPUBuffer primitiveMortonBuffer;
|
||||
wiGraphics::GPUBuffer primitiveSortedMortonBuffer;
|
||||
uint32_t maxPrimitiveCount = 0;
|
||||
|
||||
Reference in New Issue
Block a user