Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 10 additions & 20 deletions 67_RayQueryGeometry/app_resources/common.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,22 @@

NBL_CONSTEXPR uint32_t WorkgroupSize = 16;

enum NormalType : uint32_t
{
NT_R8G8B8A8_SNORM,
NT_R32G32B32_SFLOAT,
NT_UNKNOWN
};

// we need bitfield support in NBL_HLSL_DECLARE_STRUCT it seems
struct SGeomInfo
{
uint64_t vertexBufferAddress;
uint64_t indexBufferAddress;
uint64_t normalBufferAddress;

uint32_t vertexStride : 29;
uint32_t indexType : 2; // 16 bit, 32 bit or none
uint32_t smoothNormals : 1; // flat for cube, rectangle, disk
uint32_t padding;
uint32_t normalType : 2;
uint32_t indexType : 1; // 16 bit, 32 bit
};

struct SPushConstants
Expand All @@ -28,20 +34,4 @@ struct SPushConstants
float32_t2 offsetNDC;
};

#ifdef __HLSL_VERSION
enum ObjectType : uint32_t // matches c++
{
OT_CUBE = 0,
OT_SPHERE,
OT_CYLINDER,
OT_RECTANGLE,
OT_DISK,
OT_ARROW,
OT_CONE,
OT_ICOSPHERE,

OT_COUNT
};
#endif

#endif // RQG_COMMON_HLSL
80 changes: 38 additions & 42 deletions 67_RayQueryGeometry/app_resources/render.comp.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -25,69 +25,64 @@ float3 unpackNormals3x10(uint32_t v)
return clamp(float3(pn) / 511.0, -1.0, 1.0);
}

float3 calculateSmoothNormals(int instID, int primID, SGeomInfo geom, float2 bary)
float3 calculateNormals(int primID, SGeomInfo geom, float2 bary)
{
const uint indexType = geom.indexType;
const uint vertexStride = geom.vertexStride;
const uint normalType = geom.normalType;

const uint64_t vertexBufferAddress = geom.vertexBufferAddress;
const uint64_t indexBufferAddress = geom.indexBufferAddress;
const uint64_t normalBufferAddress = geom.normalBufferAddress;

uint32_t3 indices;
switch (indexType)
if (indexBufferAddress == 0)
{
case 0: // EIT_16BIT
indices = uint32_t3((nbl::hlsl::bda::__ptr<uint16_t3>::create(indexBufferAddress)+primID).deref().load());
break;
case 1: // EIT_32BIT
indices = uint32_t3((nbl::hlsl::bda::__ptr<uint32_t3>::create(indexBufferAddress)+primID).deref().load());
break;
default: // EIT_NONE
indices[0] = primID * 3;
indices[1] = indices[0] + 1;
indices[2] = indices[0] + 2;
}
else {
switch (indexType)
{
indices[0] = primID * 3;
indices[1] = indices[0] + 1;
indices[2] = indices[0] + 2;
case 0: // EIT_16BIT
indices = uint32_t3((nbl::hlsl::bda::__ptr<uint16_t3>::create(indexBufferAddress)+primID).deref().load());
break;
case 1: // EIT_32BIT
indices = uint32_t3((nbl::hlsl::bda::__ptr<uint32_t3>::create(indexBufferAddress)+primID).deref().load());
break;
}
}

if (normalBufferAddress == 0 || normalType == NT_UNKNOWN)
{
float3 v0 = vk::RawBufferLoad<float3>(vertexBufferAddress + indices[0] * 12);
float3 v1 = vk::RawBufferLoad<float3>(vertexBufferAddress + indices[1] * 12);
float3 v2 = vk::RawBufferLoad<float3>(vertexBufferAddress + indices[2] * 12);

return normalize(cross(v2 - v0, v1 - v0));
}

float3 n0, n1, n2;
switch (instID)
switch (normalType)
{
case OT_CUBE:
case NT_R8G8B8A8_SNORM:
{
// TODO: document why the alignment is 2 here and nowhere else? isnt the `vertexStride` aligned to more than 2 anyway?
uint32_t v0 = vk::RawBufferLoad<uint32_t>(vertexBufferAddress + indices[0] * vertexStride, 2u);
uint32_t v1 = vk::RawBufferLoad<uint32_t>(vertexBufferAddress + indices[1] * vertexStride, 2u);
uint32_t v2 = vk::RawBufferLoad<uint32_t>(vertexBufferAddress + indices[2] * vertexStride, 2u);
uint32_t v0 = vk::RawBufferLoad<uint32_t>(normalBufferAddress + indices[0] * 4);
uint32_t v1 = vk::RawBufferLoad<uint32_t>(normalBufferAddress + indices[1] * 4);
uint32_t v2 = vk::RawBufferLoad<uint32_t>(normalBufferAddress + indices[2] * 4);

n0 = normalize(nbl::hlsl::spirv::unpackSnorm4x8(v0).xyz);
n1 = normalize(nbl::hlsl::spirv::unpackSnorm4x8(v1).xyz);
n2 = normalize(nbl::hlsl::spirv::unpackSnorm4x8(v2).xyz);
}
break;
case OT_SPHERE:
case OT_CYLINDER:
case OT_ARROW:
case OT_CONE:
case NT_R32G32B32_SFLOAT:
{
uint32_t v0 = vk::RawBufferLoad<uint32_t>(vertexBufferAddress + indices[0] * vertexStride);
uint32_t v1 = vk::RawBufferLoad<uint32_t>(vertexBufferAddress + indices[1] * vertexStride);
uint32_t v2 = vk::RawBufferLoad<uint32_t>(vertexBufferAddress + indices[2] * vertexStride);

n0 = normalize(unpackNormals3x10(v0));
n1 = normalize(unpackNormals3x10(v1));
n2 = normalize(unpackNormals3x10(v2));
n0 = normalize(vk::RawBufferLoad<float3>(normalBufferAddress + indices[0] * 12));
n1 = normalize(vk::RawBufferLoad<float3>(normalBufferAddress + indices[1] * 12));
n2 = normalize(vk::RawBufferLoad<float3>(normalBufferAddress + indices[2] * 12));
Comment on lines 74 to +83

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

normalization could have been hosted outside the switch to happen later, but oh well

}
break;
case OT_RECTANGLE:
case OT_DISK:
case OT_ICOSPHERE:
default:
{
n0 = normalize(vk::RawBufferLoad<float3>(vertexBufferAddress + indices[0] * vertexStride));
n1 = normalize(vk::RawBufferLoad<float3>(vertexBufferAddress + indices[1] * vertexStride));
n2 = normalize(vk::RawBufferLoad<float3>(vertexBufferAddress + indices[2] * vertexStride));
}
}

float3 barycentrics = float3(0.0, bary);
Expand Down Expand Up @@ -124,15 +119,16 @@ void main(uint32_t3 threadID : SV_DispatchThreadID)

if (spirv::rayQueryGetIntersectionTypeKHR(query, true) == spv::RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionTriangleKHR)
{
const int instID = spirv::rayQueryGetIntersectionInstanceIdKHR(query, true);
const int instanceCustomIndex = spirv::rayQueryGetIntersectionInstanceCustomIndexKHR(query, true);
const int geometryIndex = spirv::rayQueryGetIntersectionGeometryIndexKHR(query, true);
const int primID = spirv::rayQueryGetIntersectionPrimitiveIndexKHR(query, true);

// TODO: candidate for `bda::__ptr<SGeomInfo>`
const SGeomInfo geom = vk::RawBufferLoad<SGeomInfo>(pc.geometryInfoBuffer + instID * sizeof(SGeomInfo),8);
const SGeomInfo geom = vk::RawBufferLoad<SGeomInfo>(pc.geometryInfoBuffer + (instanceCustomIndex + geometryIndex) * sizeof(SGeomInfo), 8);

float3 normals;
float2 barycentrics = spirv::rayQueryGetIntersectionBarycentricsKHR(query, true);
normals = calculateSmoothNormals(instID, primID, geom, barycentrics);
normals = calculateNormals(primID, geom, barycentrics);

normals = normalize(normals) * 0.5 + 0.5;
color = float4(normals, 1.0);
Expand Down
16 changes: 16 additions & 0 deletions 67_RayQueryGeometry/include/common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,20 @@ using namespace nbl::examples;

#include "app_resources/common.hlsl"

namespace nbl::scene
{

using PolygonGeometryData = core::smart_refctd_ptr<ICPUPolygonGeometry>;
using GeometryCollectionData = core::smart_refctd_ptr<ICPUGeometryCollection>;
using GeometryData = std::variant<PolygonGeometryData, GeometryCollectionData>;
struct ReferenceObjectCpu
{
core::matrix3x4SIMD transform;
GeometryData data;
uint32_t instanceID;
};

}


#endif // _NBL_THIS_EXAMPLE_COMMON_H_INCLUDED_
Loading