Skip to content

Commit 161733f

Browse files
author
kevyuu
committed
Fix example 71
1 parent 20cc57e commit 161733f

File tree

4 files changed

+134
-122
lines changed

4 files changed

+134
-122
lines changed

71_RayTracingPipeline/app_resources/common.hlsl

Lines changed: 1 addition & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ struct STriangleGeomInfo
9292
MaterialPacked material;
9393
uint64_t vertexBufferAddress;
9494
uint64_t indexBufferAddress;
95+
uint64_t normalBufferAddress;
9596

9697
uint32_t vertexStride : 26;
9798
uint32_t objType: 3;
@@ -238,8 +239,6 @@ enum ObjectType : uint32_t // matches c++
238239
OT_COUNT
239240
};
240241

241-
static uint32_t s_offsetsToNormalBytes[OT_COUNT] = { 18, 24, 24, 20, 20, 24, 16, 12 }; // based on normals data position
242-
243242
float32_t3 computeDiffuse(Material mat, float32_t3 light_dir, float32_t3 normal)
244243
{
245244
float32_t dotNL = max(dot(normal, light_dir), 0.0);
@@ -271,85 +270,6 @@ float3 unpackNormals3x10(uint32_t v)
271270
return clamp(float3(pn) / 511.0, -1.0, 1.0);
272271
}
273272

274-
float32_t3 fetchVertexNormal(int instID, int primID, STriangleGeomInfo geom, float2 bary)
275-
{
276-
uint idxOffset = primID * 3;
277-
278-
const uint indexType = geom.indexType;
279-
const uint vertexStride = geom.vertexStride;
280-
281-
const uint32_t objType = geom.objType;
282-
const uint64_t indexBufferAddress = geom.indexBufferAddress;
283-
284-
uint i0, i1, i2;
285-
switch (indexType)
286-
{
287-
case 0: // EIT_16BIT
288-
{
289-
i0 = uint32_t(vk::RawBufferLoad < uint16_t > (indexBufferAddress + (idxOffset + 0) * sizeof(uint16_t), 2u));
290-
i1 = uint32_t(vk::RawBufferLoad < uint16_t > (indexBufferAddress + (idxOffset + 1) * sizeof(uint16_t), 2u));
291-
i2 = uint32_t(vk::RawBufferLoad < uint16_t > (indexBufferAddress + (idxOffset + 2) * sizeof(uint16_t), 2u));
292-
}
293-
break;
294-
case 1: // EIT_32BIT
295-
{
296-
i0 = vk::RawBufferLoad < uint32_t > (indexBufferAddress + (idxOffset + 0) * sizeof(uint32_t));
297-
i1 = vk::RawBufferLoad < uint32_t > (indexBufferAddress + (idxOffset + 1) * sizeof(uint32_t));
298-
i2 = vk::RawBufferLoad < uint32_t > (indexBufferAddress + (idxOffset + 2) * sizeof(uint32_t));
299-
}
300-
break;
301-
default: // EIT_NONE
302-
{
303-
i0 = idxOffset;
304-
i1 = idxOffset + 1;
305-
i2 = idxOffset + 2;
306-
}
307-
}
308-
309-
const uint64_t normalVertexBufferAddress = geom.vertexBufferAddress + s_offsetsToNormalBytes[objType];
310-
float3 n0, n1, n2;
311-
switch (objType)
312-
{
313-
case OT_CUBE:
314-
{
315-
uint32_t v0 = vk::RawBufferLoad < uint32_t > (normalVertexBufferAddress + i0 * vertexStride, 2u);
316-
uint32_t v1 = vk::RawBufferLoad < uint32_t > (normalVertexBufferAddress + i1 * vertexStride, 2u);
317-
uint32_t v2 = vk::RawBufferLoad < uint32_t > (normalVertexBufferAddress + i2 * vertexStride, 2u);
318-
319-
n0 = normalize(nbl::hlsl::spirv::unpackSnorm4x8(v0).xyz);
320-
n1 = normalize(nbl::hlsl::spirv::unpackSnorm4x8(v1).xyz);
321-
n2 = normalize(nbl::hlsl::spirv::unpackSnorm4x8(v2).xyz);
322-
}
323-
break;
324-
case OT_SPHERE:
325-
case OT_CYLINDER:
326-
case OT_ARROW:
327-
case OT_CONE:
328-
{
329-
uint32_t v0 = vk::RawBufferLoad < uint32_t > (normalVertexBufferAddress + i0 * vertexStride);
330-
uint32_t v1 = vk::RawBufferLoad < uint32_t > (normalVertexBufferAddress + i1 * vertexStride);
331-
uint32_t v2 = vk::RawBufferLoad < uint32_t > (normalVertexBufferAddress + i2 * vertexStride);
332-
333-
n0 = normalize(unpackNormals3x10(v0));
334-
n1 = normalize(unpackNormals3x10(v1));
335-
n2 = normalize(unpackNormals3x10(v2));
336-
}
337-
break;
338-
case OT_RECTANGLE:
339-
case OT_DISK:
340-
case OT_ICOSPHERE:
341-
default:
342-
{
343-
n0 = vk::RawBufferLoad < float3 > (normalVertexBufferAddress + i0 * vertexStride);
344-
n1 = vk::RawBufferLoad < float3 > (normalVertexBufferAddress + i1 * vertexStride);
345-
n2 = vk::RawBufferLoad < float3 > (normalVertexBufferAddress + i2 * vertexStride);
346-
}
347-
}
348-
349-
float3 barycentrics = float3(0.0, bary);
350-
barycentrics.x = 1.0 - barycentrics.y - barycentrics.z;
351-
return normalize(barycentrics.x * n0 + barycentrics.y * n1 + barycentrics.z * n2);
352-
}
353273
#endif
354274

355275
namespace nbl

71_RayTracingPipeline/app_resources/raytrace.rchit.hlsl

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,103 @@
22

33
[[vk::push_constant]] SPushConstants pc;
44

5+
float32_t3 fetchVertexNormal(int instID, int primID, STriangleGeomInfo geom, float2 bary)
6+
{
7+
uint idxOffset = primID * 3;
8+
9+
const uint indexType = geom.indexType;
10+
const uint vertexStride = geom.vertexStride;
11+
12+
const uint32_t objType = geom.objType;
13+
const uint64_t indexBufferAddress = geom.indexBufferAddress;
14+
15+
uint i0, i1, i2;
16+
switch (indexType)
17+
{
18+
case 0: // EIT_16BIT
19+
{
20+
i0 = uint32_t(vk::RawBufferLoad < uint16_t > (indexBufferAddress + (idxOffset + 0) * sizeof(uint16_t), 2u));
21+
i1 = uint32_t(vk::RawBufferLoad < uint16_t > (indexBufferAddress + (idxOffset + 1) * sizeof(uint16_t), 2u));
22+
i2 = uint32_t(vk::RawBufferLoad < uint16_t > (indexBufferAddress + (idxOffset + 2) * sizeof(uint16_t), 2u));
23+
}
24+
break;
25+
case 1: // EIT_32BIT
26+
{
27+
i0 = vk::RawBufferLoad < uint32_t > (indexBufferAddress + (idxOffset + 0) * sizeof(uint32_t));
28+
i1 = vk::RawBufferLoad < uint32_t > (indexBufferAddress + (idxOffset + 1) * sizeof(uint32_t));
29+
i2 = vk::RawBufferLoad < uint32_t > (indexBufferAddress + (idxOffset + 2) * sizeof(uint32_t));
30+
}
31+
break;
32+
default: // EIT_NONE
33+
{
34+
i0 = idxOffset;
35+
i1 = idxOffset + 1;
36+
i2 = idxOffset + 2;
37+
}
38+
}
39+
40+
const uint64_t normalVertexBufferAddress = geom.normalBufferAddress;
41+
float3 n0, n1, n2;
42+
43+
// TODO(kevin): Currently this will work correctly both for cubes and rectangle, which are the only triangles geometry that is used in this example. Need to implement other geometry
44+
uint32_t v0 = vk::RawBufferLoad < uint32_t > (normalVertexBufferAddress + i0 * 4);
45+
uint32_t v1 = vk::RawBufferLoad < uint32_t > (normalVertexBufferAddress + i1 * 4);
46+
uint32_t v2 = vk::RawBufferLoad < uint32_t > (normalVertexBufferAddress + i2 * 4);
47+
48+
49+
n0 = normalize(nbl::hlsl::spirv::unpackSnorm4x8(v0).xyz);
50+
n1 = normalize(nbl::hlsl::spirv::unpackSnorm4x8(v1).xyz);
51+
n2 = normalize(nbl::hlsl::spirv::unpackSnorm4x8(v2).xyz);
52+
53+
// switch (objType)
54+
// {
55+
// case OT_CUBE:
56+
// {
57+
// // TODO(kevin): Don't hardcode the normal stride in hlsl
58+
// uint32_t v0 = vk::RawBufferLoad < uint32_t > (normalVertexBufferAddress + i0 * 4);
59+
// uint32_t v1 = vk::RawBufferLoad < uint32_t > (normalVertexBufferAddress + i1 * 4);
60+
// uint32_t v2 = vk::RawBufferLoad < uint32_t > (normalVertexBufferAddress + i2 * 4);
61+
//
62+
// n0 = normalize(nbl::hlsl::spirv::unpackSnorm4x8(v0).xyz);
63+
// n1 = normalize(nbl::hlsl::spirv::unpackSnorm4x8(v1).xyz);
64+
// n2 = normalize(nbl::hlsl::spirv::unpackSnorm4x8(v2).xyz);
65+
// }
66+
// break;
67+
// case OT_SPHERE:
68+
// case OT_CYLINDER:
69+
// case OT_ARROW:
70+
// case OT_CONE:
71+
// {
72+
// // TODO(kevin): Fix this logic. Don't use vertex stride since nomral is separated from position
73+
// uint32_t v0 = vk::RawBufferLoad < uint32_t > (normalVertexBufferAddress + i0 * vertexStride);
74+
// uint32_t v1 = vk::RawBufferLoad < uint32_t > (normalVertexBufferAddress + i1 * vertexStride);
75+
// uint32_t v2 = vk::RawBufferLoad < uint32_t > (normalVertexBufferAddress + i2 * vertexStride);
76+
//
77+
// n0 = normalize(unpackNormals3x10(v0));
78+
// n1 = normalize(unpackNormals3x10(v1));
79+
// n2 = normalize(unpackNormals3x10(v2));
80+
// }
81+
// break;
82+
// case OT_RECTANGLE:
83+
// case OT_DISK:
84+
// case OT_ICOSPHERE:
85+
// default:
86+
// {
87+
// // TODO(kevin): Don't hardcode the normal stride in hlsl
88+
// n0 = vk::RawBufferLoad < float3 > (normalVertexBufferAddress + i0 * 4);
89+
// n1 = vk::RawBufferLoad < float3 > (normalVertexBufferAddress + i1 * 4);
90+
// n2 = vk::RawBufferLoad < float3 > (normalVertexBufferAddress + i2 * 4);
91+
// }
92+
// }
93+
94+
// n0 = float3(0, 1, 0);
95+
// n1 = float3(0, 1, 0);
96+
// n2 = float3(0, 1, 0);
97+
98+
float3 barycentrics = float3(0.0, bary);
99+
barycentrics.x = 1.0 - barycentrics.y - barycentrics.z;
100+
return normalize(barycentrics.x * n0 + barycentrics.y * n1 + barycentrics.z * n2);
101+
}
5102

6103
[shader("closesthit")]
7104
void main(inout PrimaryPayload payload, in BuiltInTriangleIntersectionAttributes attribs)

71_RayTracingPipeline/include/common.hpp

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -45,40 +45,15 @@ struct ObjectMeta
4545
std::string_view name = "Unknown";
4646
};
4747

48-
struct ObjectDrawHookCpu
49-
{
50-
nbl::core::matrix3x4SIMD model;
51-
ObjectMeta meta;
52-
};
53-
5448
struct ReferenceObjectCpu
5549
{
5650
ObjectMeta meta;
5751
core::smart_refctd_ptr<ICPUPolygonGeometry> data;
5852
Material material;
5953
core::matrix3x4SIMD transform;
60-
};
6154

62-
struct ReferenceObjectGpu
63-
{
64-
struct Bindings
65-
{
66-
nbl::asset::SBufferBinding<IGPUBuffer> vertex, index;
67-
};
68-
69-
ObjectMeta meta;
70-
Bindings bindings;
71-
uint32_t vertexStride;
72-
nbl::asset::E_INDEX_TYPE indexType = nbl::asset::E_INDEX_TYPE::EIT_UNKNOWN;
73-
uint32_t indexCount = {};
74-
MaterialPacked material;
75-
core::matrix3x4SIMD transform;
76-
77-
const bool useIndex() const
78-
{
79-
return bindings.index.buffer && (indexType != E_INDEX_TYPE::EIT_UNKNOWN);
80-
}
8155
};
56+
8257
}
8358

8459
#endif // __NBL_THIS_EXAMPLE_COMMON_H_INCLUDED__

71_RayTracingPipeline/main.cpp

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@
66
#include "nbl/ext/FullScreenTriangle/FullScreenTriangle.h"
77
#include "nbl/builtin/hlsl/indirect_commands.hlsl"
88

9+
#include "nbl/examples/common/BuiltinResourcesApplication.hpp"
910

10-
class RaytracingPipelineApp final : public SimpleWindowedApplication, public application_templates::MonoAssetManagerAndBuiltinResourceApplication
11+
12+
class RaytracingPipelineApp final : public SimpleWindowedApplication, public BuiltinResourcesApplication
1113
{
1214
using device_base_t = SimpleWindowedApplication;
13-
using asset_base_t = application_templates::MonoAssetManagerAndBuiltinResourceApplication;
15+
using asset_base_t = BuiltinResourcesApplication;
1416
using clock_t = std::chrono::steady_clock;
1517

1618
constexpr static inline uint32_t WIN_W = 1280, WIN_H = 720;
@@ -1220,14 +1222,15 @@ class RaytracingPipelineApp final : public SimpleWindowedApplication, public app
12201222
}
12211223
else
12221224
{
1223-
auto triangles = make_refctd_dynamic_array<smart_refctd_dynamic_array<ICPUBottomLevelAccelerationStructure::Triangles<ICPUBuffer>>>(cpuObjects[i].data->exportForBLAS());
1225+
auto triangles = make_refctd_dynamic_array<smart_refctd_dynamic_array<ICPUBottomLevelAccelerationStructure::Triangles<ICPUBuffer>>>(1u);
12241226
auto primitiveCounts = make_refctd_dynamic_array<smart_refctd_dynamic_array<uint32_t>>(1u);
12251227

12261228
auto& tri = triangles->front();
12271229

12281230
auto& primCount = primitiveCounts->front();
12291231
primCount = cpuObjects[i].data->getPrimitiveCount();
12301232

1233+
tri = cpuObjects[i].data->exportForBLAS();
12311234
tri.geometryFlags = cpuObjects[i].material.isTransparent() ?
12321235
IGPUBottomLevelAccelerationStructure::GEOMETRY_FLAGS::NO_DUPLICATE_ANY_HIT_INVOCATION_BIT :
12331236
IGPUBottomLevelAccelerationStructure::GEOMETRY_FLAGS::OPAQUE_BIT;
@@ -1257,7 +1260,7 @@ class RaytracingPipelineApp final : public SimpleWindowedApplication, public app
12571260
inst.base.blas = cpuBlasList[i];
12581261
inst.base.flags = static_cast<uint32_t>(IGPUTopLevelAccelerationStructure::INSTANCE_FLAGS::TRIANGLE_FACING_CULL_DISABLE_BIT);
12591262
inst.base.instanceCustomIndex = i;
1260-
inst.base.instanceShaderBindingTableRecordOffset = isProceduralInstance ? 2 : 0;;
1263+
inst.base.instanceShaderBindingTableRecordOffset = isProceduralInstance ? 2 : 0;
12611264
inst.base.mask = 0xFF;
12621265
inst.transform = isProceduralInstance ? matrix3x4SIMD() : cpuObjects[i].transform;
12631266

@@ -1305,19 +1308,22 @@ class RaytracingPipelineApp final : public SimpleWindowedApplication, public app
13051308
inputs.allocator = &myalloc;
13061309

13071310
std::array<ICPUTopLevelAccelerationStructure*, 1u> tmpTlas;
1308-
std::array<ICPUPolygonGeometry*, std::size(cpuObjects)> tmpGeometries;
13091311
std::array<ICPUBuffer*, 1> tmpBuffers;
1312+
std::array<ICPUPolygonGeometry*, std::size(cpuObjects)> tmpGeometries;
1313+
std::array<CAssetConverter::patch_t<asset::ICPUPolygonGeometry>, std::size(cpuObjects)> tmpGeometryPatches;
13101314
{
13111315
tmpTlas[0] = cpuTlas.get();
13121316
tmpBuffers[0] = cpuProcBuffer.get();
13131317
for (uint32_t i = 0; i < cpuObjects.size(); i++)
13141318
{
13151319
tmpGeometries[i] = cpuObjects[i].data.get();
1320+
tmpGeometryPatches[i].indexBufferUsages= IGPUBuffer::E_USAGE_FLAGS::EUF_SHADER_DEVICE_ADDRESS_BIT;
13161321
}
13171322

13181323
std::get<CAssetConverter::SInputs::asset_span_t<ICPUTopLevelAccelerationStructure>>(inputs.assets) = tmpTlas;
13191324
std::get<CAssetConverter::SInputs::asset_span_t<ICPUBuffer>>(inputs.assets) = tmpBuffers;
13201325
std::get<CAssetConverter::SInputs::asset_span_t<ICPUPolygonGeometry>>(inputs.assets) = tmpGeometries;
1326+
std::get<CAssetConverter::SInputs::patch_span_t<ICPUPolygonGeometry>>(inputs.patches) = tmpGeometryPatches;
13211327
}
13221328

13231329
auto reservation = converter->reserve(inputs);
@@ -1346,6 +1352,7 @@ class RaytracingPipelineApp final : public SimpleWindowedApplication, public app
13461352

13471353
prepass.template operator() < ICPUTopLevelAccelerationStructure > (tmpTlas);
13481354
prepass.template operator() < ICPUBuffer > (tmpBuffers);
1355+
prepass.template operator() < ICPUPolygonGeometry > (tmpGeometries);
13491356
}
13501357

13511358
constexpr auto CompBufferCount = 2;
@@ -1425,25 +1432,37 @@ class RaytracingPipelineApp final : public SimpleWindowedApplication, public app
14251432
auto&& tlases = reservation.getGPUObjects<ICPUTopLevelAccelerationStructure>();
14261433
m_gpuTlas = tlases[0].value;
14271434
auto&& buffers = reservation.getGPUObjects<ICPUBuffer>();
1435+
m_proceduralAabbBuffer = buffers[0].value;
14281436

1429-
m_proceduralAabbBuffer = buffers[2 * proceduralBlasIdx].value;
1437+
auto&& gpuPolygonGeometries = reservation.getGPUObjects<ICPUPolygonGeometry>();
1438+
m_gpuPolygons.resize(gpuPolygonGeometries.size());
14301439

1431-
for (uint32_t i = 0; i < cpuObjects.size(); i++)
1440+
for (uint32_t i = 0; i < gpuPolygonGeometries.size(); i++)
14321441
{
14331442
const auto& cpuObject = cpuObjects[i];
1434-
const auto& cpuBlas = cpuBlasList[i];
1435-
const auto& geometry = cpuBlas->getTriangleGeometries()[0];
1436-
const uint64_t vertexBufferAddress = buffers[2 * i].value->getDeviceAddress();
1437-
const uint64_t indexBufferAddress = buffers[(2 * i) + 1].value->getDeviceAddress();
1438-
geomInfos[i] = {
1443+
const auto& gpuPolygon = gpuPolygonGeometries[i].value;
1444+
const auto gpuTriangles = gpuPolygon->exportForBLAS();
1445+
1446+
const auto& vertexBufferBinding = gpuTriangles.vertexData[0];
1447+
const uint64_t vertexBufferAddress = vertexBufferBinding.buffer->getDeviceAddress() + vertexBufferBinding.offset;
1448+
1449+
const auto& normalView = gpuPolygon->getNormalView();
1450+
const uint64_t normalBufferAddress = normalView ? normalView.src.buffer->getDeviceAddress() + normalView.src.offset : 0;
1451+
1452+
const auto& indexBufferBinding = gpuTriangles.indexData;
1453+
auto& geomInfo = geomInfos[i];
1454+
geomInfo = {
14391455
.material = hlsl::_static_cast<MaterialPacked>(cpuObject.material),
14401456
.vertexBufferAddress = vertexBufferAddress,
1441-
.indexBufferAddress = geometry.indexData.buffer ? indexBufferAddress : vertexBufferAddress,
1442-
.vertexStride = geometry.vertexStride,
1457+
.indexBufferAddress = indexBufferBinding.buffer ? indexBufferBinding.buffer->getDeviceAddress() + indexBufferBinding.offset : vertexBufferAddress,
1458+
.normalBufferAddress = normalBufferAddress,
1459+
.vertexStride = gpuTriangles.vertexStride,
14431460
.objType = cpuObject.meta.type,
1444-
.indexType = geometry.indexType,
1461+
.indexType = gpuTriangles.indexType,
14451462
.smoothNormals = scene::s_smoothNormals[cpuObject.meta.type],
14461463
};
1464+
1465+
m_gpuPolygons[i] = gpuPolygon;
14471466
}
14481467
}
14491468

@@ -1508,6 +1527,7 @@ class RaytracingPipelineApp final : public SimpleWindowedApplication, public app
15081527
core::vector<SProceduralGeomInfo> m_gpuIntersectionSpheres;
15091528
uint32_t m_intersectionHitGroupIdx;
15101529

1530+
core::vector<smart_refctd_ptr<IGPUPolygonGeometry>> m_gpuPolygons;
15111531
smart_refctd_ptr<IGPUTopLevelAccelerationStructure> m_gpuTlas;
15121532
smart_refctd_ptr<IGPUBuffer> m_instanceBuffer;
15131533

0 commit comments

Comments
 (0)