Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Raytracing pipeline demo #173

Open
wants to merge 38 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
881e40b
Update Bloom example, removed memory barriers on FFT
Fletterio Jan 22, 2025
444c917
Implement Ray Tracing Demo
Jan 22, 2025
c991e20
Add ImGui Overlay
Jan 22, 2025
6ac8f88
Implement multiple light type
Jan 22, 2025
9091da1
Implement callable shader
Jan 22, 2025
d303356
Implement procedural geometry intersection shader demo
Jan 24, 2025
f261f7c
Add Readme
Jan 24, 2025
7b5059c
Fix alignment issue of scratch buffer
Jan 24, 2025
8cbb0dc
Fix alignment issue of scratch buffer
Jan 24, 2025
a9d5f8b
Fix alignment issue of scratch buffer
Jan 24, 2025
feedf65
Reduce Push Constant Size and skip compacting procedural geometries
Jan 24, 2025
e369368
Fix occlusion of procedural geometries
Jan 24, 2025
c2c82d4
71: cache shaders
alichraghi Jan 24, 2025
34a3fa9
Remove unnecesary log
Jan 24, 2025
ec88268
Change recursion depth to 1 so the demo can be run on more devices.
Jan 25, 2025
d21c22c
Temporarily remove procedural geometries to debug crash on amd cards.
Jan 25, 2025
bc093c7
Use Nabla AABB type instead creating another aabb type
Jan 25, 2025
1dc682a
Fix query compact blas size issue
Jan 26, 2025
ab58218
Reorder hlsl datastructure to reduce padding and make it more compact
Feb 5, 2025
6966942
Adjust changes to SPhysicalDeviceLimit regarding shaderGroupHandleSize
Feb 5, 2025
ef02db2
Adjust changes to ray tracing SShaderGroupParams
Feb 5, 2025
c810949
Adjust ray tracing pipeline demo to remove SStridedBufferRegion
Feb 6, 2025
13251ca
Pack material into more compact representation before send to gpu.
Feb 6, 2025
c48b5b9
Change ray tracing implementation from recursion to loop based
Feb 11, 2025
73b3f99
Assign Blas flag according the the primitives transparency
Feb 11, 2025
adb7bb6
Store material information in intersection shader
Feb 11, 2025
bc16d1b
Refactor shadow ray tracing implementation to use opacity instead of …
Feb 11, 2025
dc7db46
Remove unnecessary read of attenuation by miss shader
Feb 11, 2025
86f4f4b
Remove unnecsarry topLevelAs binding declaration
Feb 11, 2025
96f25ca
Rework gpu random value generation to use pcg hash and xoroshiro
Feb 11, 2025
583c0f9
Add trace ray indirect option
Feb 11, 2025
0797b33
Use matrix changes to reset frameAccumulationCounter
Feb 11, 2025
7409e4b
Remove comment in CCamera.hpp
Feb 11, 2025
f9c3fad
Remove unnecesarry calculation of vertex position
Feb 11, 2025
0da41df
Tidy up variable name and file name
Feb 12, 2025
890c992
Update demo to use SShaderGroupHandle type
Feb 25, 2025
ee10d47
Merge branch 'master' into raytracing_pipeline_demo
Feb 25, 2025
19ad8b0
Fix spot light
Feb 25, 2025
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
Prev Previous commit
Next Next commit
Implement procedural geometry intersection shader demo
Signed-off-by: kevyuu <kevin.kayu@gmail.com>
  • Loading branch information
kevyuu committed Jan 24, 2025
commit d303356516823fedea27e4a3da03d56d753b66a8
39 changes: 37 additions & 2 deletions 71_RayTracingPipeline/app_resources/common.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,20 @@ struct Material
uint32_t illum; // illumination model (see http://www.fileformat.info/format/material/)
};

struct SGeomInfo
struct SProceduralGeomInfo
{
float32_t3 center;
float32_t radius;
Material material;

Choose a reason for hiding this comment

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

get in the habit of placing large members first to avoid padding

};

struct Aabb
{
float32_t3 minimum;
float32_t3 maximum;
};

struct STriangleGeomInfo
{
uint64_t vertexBufferAddress;
uint64_t indexBufferAddress;
Expand All @@ -29,6 +42,13 @@ struct SGeomInfo
Material material;
};

enum E_GEOM_TYPE : int32_t
{
EGT_TRIANGLES,
EGT_PROCEDURAL,
EGT_COUNT
};

enum E_LIGHT_TYPE : int32_t
{
ELT_DIRECTIONAL,
Expand All @@ -37,6 +57,20 @@ enum E_LIGHT_TYPE : int32_t
ELT_COUNT
};

enum E_RAY_TYPE : int32_t
{
ERT_PRIMARY, // Ray shoot from camera
ERT_OCCLUSION,
ERT_COUNT
};

enum E_MISS_TYPE : int32_t
{
EMT_PRIMARY,
EMT_OCCLUSION,
EMT_COUNT
};

struct Light
{
float32_t3 direction;
Expand All @@ -59,7 +93,8 @@ struct SPushConstants
float32_t3 camPos;
float32_t4x4 invMVP;

uint64_t geometryInfoBuffer;
uint64_t proceduralGeomInfoBuffer;
uint64_t triangleGeomInfoBuffer;
uint32_t frameCounter;
};

Expand Down
2 changes: 1 addition & 1 deletion 71_RayTracingPipeline/app_resources/raytrace.rahit.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ using AnyHitPayload = ShadowPayload;
void main(inout AnyHitPayload p, in BuiltInTriangleIntersectionAttributes attribs)
{
const int instID = InstanceID();
const SGeomInfo geom = vk::RawBufferLoad < SGeomInfo > (pc.geometryInfoBuffer + instID * sizeof(SGeomInfo));
const STriangleGeomInfo geom = vk::RawBufferLoad < STriangleGeomInfo > (pc.triangleGeomInfoBuffer + instID * sizeof(STriangleGeomInfo));

if (geom.material.illum != 4)
return;
Expand Down
10 changes: 5 additions & 5 deletions 71_RayTracingPipeline/app_resources/raytrace.rchit.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ struct VertexData
float32_t3 normal;
};

VertexData fetchVertexData(int instID, int primID, SGeomInfo geom, float2 bary)
VertexData fetchVertexData(int instID, int primID, STriangleGeomInfo geom, float2 bary)
{
uint idxOffset = primID * 3;

Expand Down Expand Up @@ -116,7 +116,7 @@ void main(inout ColorPayload p, in BuiltInTriangleIntersectionAttributes attribs
{
const int instID = InstanceID();
const int primID = PrimitiveIndex();
const SGeomInfo geom = vk::RawBufferLoad < SGeomInfo > (pc.geometryInfoBuffer + instID * sizeof(SGeomInfo));
const STriangleGeomInfo geom = vk::RawBufferLoad < STriangleGeomInfo > (pc.triangleGeomInfoBuffer + instID * sizeof(STriangleGeomInfo));
const VertexData vertexData = fetchVertexData(instID, primID, geom, attribs.barycentrics);
const float32_t3 worldPosition = mul(ObjectToWorld3x4(), float32_t4(vertexData.position, 1));
const float32_t3 worldNormal = mul(vertexData.normal, WorldToObject3x4()).xyz;
Expand All @@ -132,16 +132,16 @@ void main(inout ColorPayload p, in BuiltInTriangleIntersectionAttributes attribs
if (dot(worldNormal, cLight.outLightDir) > 0)
{
RayDesc rayDesc;
rayDesc.Origin = WorldRayOrigin() + WorldRayDirection() * RayTCurrent() + worldNormal * 0.02f;
rayDesc.Origin = WorldRayOrigin() + WorldRayDirection() * RayTCurrent();
rayDesc.Direction = cLight.outLightDir;
rayDesc.TMin = 0.001;
rayDesc.TMin = 0.01;
rayDesc.TMax = cLight.outLightDistance;

uint flags = RAY_FLAG_SKIP_CLOSEST_HIT_SHADER;

Choose a reason for hiding this comment

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

what's the reason for not having RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH here?

ShadowPayload shadowPayload;
shadowPayload.isShadowed = true;
shadowPayload.seed = p.seed;
TraceRay(topLevelAS, flags, 0xFF, 1, 0, 1, rayDesc, shadowPayload);
TraceRay(topLevelAS, flags, 0xFF, ERT_OCCLUSION, 0, EMT_OCCLUSION, rayDesc, shadowPayload);

bool isShadowed = shadowPayload.isShadowed;
if (isShadowed)
Expand Down
6 changes: 3 additions & 3 deletions 71_RayTracingPipeline/app_resources/raytrace.rgen.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ void main()
RayDesc rayDesc;
rayDesc.Origin = pc.camPos;
rayDesc.Direction = direction;
rayDesc.TMin = 0.01;
rayDesc.TMax = 1000.0;
rayDesc.TMin = 0.001;
rayDesc.TMax = 10000.0;

ColorPayload payload;
payload.seed = seed;
TraceRay(topLevelAS, RAY_FLAG_NONE, 0xff, 0, 0, 0, rayDesc, payload);
TraceRay(topLevelAS, RAY_FLAG_NONE, 0xff, ERT_PRIMARY, 0, EMT_PRIMARY, rayDesc, payload);

hitValues += payload.hitValue;
}
Expand Down
54 changes: 54 additions & 0 deletions 71_RayTracingPipeline/app_resources/raytrace.rint.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#include "common.hlsl"

[[vk::push_constant]] SPushConstants pc;

struct Ray
{
float32_t3 origin;
float32_t3 direction;
};

struct Attrib
{
float3 HitAttribute;
};

Choose a reason for hiding this comment

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

you never fill this out?


// Ray-Sphere intersection
// http://viclw17.github.io/2018/07/16/raytracing-ray-sphere-intersection/
float32_t hitSphere(SProceduralGeomInfo s, Ray r)
{
float32_t3 oc = r.origin - s.center;
float32_t a = dot(r.direction, r.direction);
float32_t b = 2.0 * dot(oc, r.direction);
float32_t c = dot(oc, oc) - s.radius * s.radius;
float32_t discriminant = b * b - 4 * a * c;

if (discriminant < 0)
{
return -1.0;
}
else
{
return (-b - sqrt(discriminant)) / (2.0 * a);
}
}

[shader("intersection")]
void main()
{
Ray ray;
ray.origin = WorldRayOrigin();
ray.direction = WorldRayDirection();

const int primID = PrimitiveIndex();

// Sphere data
SProceduralGeomInfo sphere = vk::RawBufferLoad < SProceduralGeomInfo > (pc.proceduralGeomInfoBuffer + primID * sizeof(SProceduralGeomInfo));

float32_t tHit = hitSphere(sphere, ray);

Attrib attrib;
// Report hit point
if (tHit > 0)
ReportHit(tHit, 0, attrib);
}
61 changes: 61 additions & 0 deletions 71_RayTracingPipeline/app_resources/raytrace_procedural.rchit.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#include "common.hlsl"

[[vk::push_constant]] SPushConstants pc;

[[vk::binding(0, 0)]] RaytracingAccelerationStructure topLevelAS;

[shader("closesthit")]
void main(inout ColorPayload p, in BuiltInTriangleIntersectionAttributes attribs)

Choose a reason for hiding this comment

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

BuiltInTriangleIntersectionAttributes? but its not a triangle?

{
const int instID = InstanceID();
const int primID = PrimitiveIndex();
float32_t3 worldPosition = WorldRayOrigin() + WorldRayDirection() * RayTCurrent();

SProceduralGeomInfo sphere = vk::RawBufferLoad < SProceduralGeomInfo > (pc.proceduralGeomInfoBuffer + primID * sizeof(SProceduralGeomInfo));

// Computing the normal at hit position
float32_t3 worldNormal = normalize(worldPosition - sphere.center);

Choose a reason for hiding this comment

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

you already had to load and compute some of this in the intersection shader, is it not possible to pass it in the payload/custom attribs to the closest hit shader?


RayLight cLight;
cLight.inHitPosition = worldPosition;
CallShader(pc.light.type, cLight);

// Material of the object
Material mat = sphere.material;

// Diffuse
float3 diffuse = computeDiffuse(sphere.material, cLight.outLightDir, worldNormal);
float3 specular = float3(0, 0, 0);
float attenuation = 1;

// Tracing shadow ray only if the light is visible from the surface
if (dot(worldNormal, cLight.outLightDir) > 0)
{
RayDesc rayDesc;
rayDesc.Origin = WorldRayOrigin() + WorldRayDirection() * RayTCurrent();
rayDesc.Direction = cLight.outLightDir;
rayDesc.TMin = 0.01;
rayDesc.TMax = cLight.outLightDistance;

uint flags =
RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH | RAY_FLAG_FORCE_OPAQUE |
RAY_FLAG_SKIP_CLOSEST_HIT_SHADER;

ShadowPayload shadowPayload;
shadowPayload.isShadowed = true;
shadowPayload.seed = p.seed;
TraceRay(topLevelAS, flags, 0xFF, ERT_OCCLUSION, 0, EMT_PRIMARY, rayDesc, shadowPayload);

bool isShadowed = shadowPayload.isShadowed;
if (isShadowed)
{
attenuation = 0.3;
}
else
{
specular = computeSpecular(sphere.material, WorldRayDirection(), cLight.outLightDir, worldNormal);
}
}

p.hitValue = (cLight.outIntensity * attenuation * (diffuse + specular));
}
Loading