Skip to content

Commit

Permalink
[:sparkles:] Shadow rays (#17)
Browse files Browse the repository at this point in the history
Y con esto, el tutorial está completado 🎉
  • Loading branch information
Asmilex committed Feb 17, 2022
1 parent 027283f commit ebca093
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 13 deletions.
33 changes: 22 additions & 11 deletions application/vulkan_ray_tracing/src/hello_vulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -706,7 +706,7 @@ void HelloVulkan::createTopLevelAS() {
void HelloVulkan::createRtDescriptorSet() {
m_rtDescSetLayoutBind.addBinding(
RtxBindings::eTlas, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1,
VK_SHADER_STAGE_RAYGEN_BIT_KHR
VK_SHADER_STAGE_RAYGEN_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR
); // TLAS

m_rtDescSetLayoutBind.addBinding(
Expand Down Expand Up @@ -767,7 +767,7 @@ void HelloVulkan::createRtPipeline() {
enum StageIndices {
eRaygen,
eMiss,
//eMiss2,
eMiss2,
eClosestHit,
eShaderGroupCount
};
Expand Down Expand Up @@ -796,11 +796,11 @@ void HelloVulkan::createRtPipeline() {
// // El segundo miss shader se invoca cuando un shadow ray no ha colisionado con la geometría.
// // Simplemente, indica que no ha habido oclusión.

// stage.module = nvvk::createShaderModule(m_device,
// nvh::loadFile("spv/raytraceShadow.rmiss.spv", true, defaultSearchPaths, true
// ));
// stage.stage = VK_SHADER_STAGE_MISS_BIT_KHR;
// stages[eMiss2] = stage;
stage.module = nvvk::createShaderModule(m_device,
nvh::loadFile("spv/raytraceShadow.rmiss.spv", true, defaultSearchPaths, true
));
stage.stage = VK_SHADER_STAGE_MISS_BIT_KHR;
stages[eMiss2] = stage;

// Hit group - closest hit
stage.module = nvvk::createShaderModule(m_device,
Expand Down Expand Up @@ -832,6 +832,11 @@ void HelloVulkan::createRtPipeline() {
group.generalShader = eMiss;
m_rtShaderGroups.push_back(group);

// Shadow miss
group.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR;
group.generalShader = eMiss2;
m_rtShaderGroups.push_back(group);

// closest hit shader

// Note that if the geometry were not triangles, we would have set the type
Expand Down Expand Up @@ -886,13 +891,18 @@ void HelloVulkan::createRtPipeline() {
To allow the underlying RTX layer to optimize the pipeline we indicate the maximum recursion depth used
by our shaders
For the simplistic shaders we currently have, we set this depth to 1,
For the simplistic shaders we currently have, we can set this depth to 1,
meaning that we must not trigger recursion at all (i.e. a hit shader calling TraceRayEXT()).
Note that it is preferable to keep the recursion level as low as possible,
replacing it by a loop formulation instead.
When shadow rays are added, we must increase the recursion depth to 2, since we
can shoot rays from the hit points of the camera rays.
Realisticly, it should be flatten to a loop.
*/
rayPipelineInfo.maxPipelineRayRecursionDepth = 1; // Ray depth
rayPipelineInfo.maxPipelineRayRecursionDepth = 2; // Ray depth
rayPipelineInfo.layout = m_rtPipelineLayout;

vkCreateRayTracingPipelinesKHR(m_device, {}, {}, 1, &rayPipelineInfo, nullptr, &m_rtPipeline);
Expand All @@ -908,8 +918,9 @@ void HelloVulkan::createRtPipeline() {
// - Besides exception, this could always be done like this

void HelloVulkan::createRtShaderBindingTable() {
// Siempre hay un único raygen, así que podemos ponerlo constantemente 1.
uint32_t missCount{1};
// Miss count: miss y shadows
// Hit count: solo hit.
uint32_t missCount{2};
uint32_t hitCount{1};
auto handleCount = 1 + missCount + hitCount;
uint32_t handleSize = m_rtProperties.shaderGroupHandleSize;
Expand Down
39 changes: 37 additions & 2 deletions application/vulkan_ray_tracing/src/shaders/raytrace.rchit
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
hitAttributeEXT vec3 attribs;

layout(location = 0) rayPayloadInEXT hitPayload prd;
layout(location = 1) rayPayloadEXT bool isShadowed;

layout(buffer_reference, scalar) buffer Vertices { Vertex v[]; }; // Posición del objeto
layout(buffer_reference, scalar) buffer Indices { ivec3 i[]; }; // Indices del triángulo
Expand All @@ -20,6 +21,7 @@ layout(buffer_reference, scalar) buffer MatIndices { int i[]; };
layout(set = 1, binding = eObjDescs, scalar) buffer ObjDesc_ { ObjDesc i[]; } objDesc;
layout(set = 1, binding = eTextures) uniform sampler2D textureSamplers[];

layout(set = 0, binding = eTlas) uniform accelerationStructureEXT topLevelAS; // Para los shadow rays

layout (push_constant) uniform _PushConstantRay { PushConstantRay pcRay; };

Expand Down Expand Up @@ -79,7 +81,40 @@ void main()
}

// Specular
vec3 specular = computeSpecular(mat, gl_WorldRayDirectionEXT, L, normal);
vec3 specular = vec3(0);
float attenuation = 1;

// Trazar shadow rays solo si la luz es visible desde la superficie
if (dot(normal, L) > 0) {
float tMin = 0.001;
float tMax = lightDistance;

vec3 origin = gl_WorldRayOriginEXT + gl_WorldRayDirectionEXT * gl_HitTEXT;
vec3 rayDir = L;

uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT | gl_RayFlagsSkipClosestHitShaderEXT;
isShadowed = true;

traceRayEXT(topLevelAS,
flags, // rayFlags
0xFF, // cullMask
0, // sbtRecordOffset
0, // sbtRecordStride
1, // missIndex
origin, // ray origin
tMin, // ray min range
rayDir, // ray direction
tMax, // ray max range
1 // payload (location = 1)
);

if (isShadowed) {
attenuation = 1.0 / (1.0 + lightDistance);
}
else {
specular = computeSpecular(mat, gl_WorldRayDirectionEXT, L, normal);
}
}

prd.hitValue = vec3(lightIntensity * (diffuse + specular));
prd.hitValue = vec3(lightIntensity * attenuation * (diffuse + specular));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#version 460
#extension GL_EXT_ray_tracing : require

layout(location = 1) rayPayloadInEXT bool isShadowed;

void main()
{
isShadowed = false;
}

0 comments on commit ebca093

Please sign in to comment.