Professional Documents
Culture Documents
h"
#include <string.h>
#include <iostream>
#include <fstream>
: m_instance(instance)
, m_device(device)
, m_gpu(gpu)
, m_queue(queue)
, m_commandPool(commandPool)
, m_raytracingPipelineProperties(raytracingProperties)
void CRayTracing::init() {
vkGetPhysicalDeviceMemoryProperties(m_gpu, &m_gpuMemProps);
void CRayTracing::initScene() {
// Setup materials.
uint32_t primitiveIndex,
glm::vec4 const& albedo,
attributes.albedo = albedo;
attributes.reflectanceCoef = reflectanceCoef;
attributes.diffuseCoef = diffuseCoef;
attributes.specularCoef = specularCoef;
attributes.specularPower = specularPower;
attributes.stepScale = stepScale;
};
m_planeMaterialCB = { glm::vec4(0.9f, 0.9f, 0.9f, 1.0f), 0.25f, 1.0f, 0.4f, 50.0f, 1.0f, /*padding*/
glm::vec3(0.0f) };
uint32_t offset = 0;
offset += AnalyticPrimitive::Count;
}
offset += VolumetricPrimitive::Count;
// Setup camera.
updateCameraMatrices();
// Setup lights.
glm::vec4 lightPosition;
glm::vec4 lightAmbientColor;
glm::vec4 lightDiffuseColor;
m_sceneCB.lightPosition = lightPosition;
m_sceneCB.lightAmbientColor = lightAmbientColor;
float d = 0.6f;
m_sceneCB.lightDiffuseColor = lightDiffuseColor;
uint32_t instanceIndex = 0;
m_aabbInstanceCB[instanceIndex].instanceIndex = instanceIndex;
m_aabbInstanceCB[instanceIndex].primitiveType = primitiveIndex;
++instanceIndex;
}
m_aabbInstanceCB[instanceIndex].instanceIndex = instanceIndex;
m_aabbInstanceCB[instanceIndex].primitiveType = primitiveIndex;
++instanceIndex;
m_aabbInstanceCB[instanceIndex].instanceIndex = instanceIndex;
m_aabbInstanceCB[instanceIndex].primitiveType = primitiveIndex;
++instanceIndex;
void CRayTracing::createSceneBuffer() {
m_sceneBuffer = m_helper.createBuffer(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT |
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, sizeof(SceneConstantBuffer),
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
void CRayTracing::updateSceneBuffer() {
void CRayTracing::createAABBPrimitiveBuffer() {
m_aabbPrimitiveBuffer = m_helper.createBuffer(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT |
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, sizeof(PrimitiveInstancePerFrameBuffer) *
IntersectionShaderType::kTotalPrimitiveCount, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
void CRayTracing::updateAABBPrimitiveBuffer() {
m_helper.copyToBuffer(m_aabbPrimitiveBuffer, m_aabbPrimitiveAttributeBuffer,
sizeof(PrimitiveInstancePerFrameBuffer) * IntersectionShaderType::kTotalPrimitiveCount);
std::streampos size = 0;
if (file.is_open()) {
size = file.tellg();
file.seekg(0, std::ios::beg);
file.read(reinterpret_cast<char*>(memory), size);
file.close();
shaderInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
shaderInfo.codeSize = static_cast<size_t>(size);
shaderInfo.pCode = reinterpret_cast<uint32_t*>(memory);
VkShaderModule shaderModule;
if (res != VK_SUCCESS) {
delete[] memory;
shaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
shaderStageInfo.stage = type;
shaderStageInfo.module = shaderModule;
shaderStageInfo.pName = "main";
m_shaderStages.push_back(shaderStageInfo);
m_shaderGroups.clear();
createRayGenShaderGroups();
m_shaderGroups.push_back(m_rayGenShaderGroups[index]);
createMissShaderGroups();
for (size_t index = 0; index < m_missShaderGroups.size(); ++index) {
m_shaderGroups.push_back(m_missShaderGroups[index]);
createHitShaderGroups();
m_shaderGroups.push_back(m_hitShaderGroups[index]);
raytracingPipelineInfo.sType = VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_KHR;
raytracingPipelineInfo.maxPipelineRayRecursionDepth = 3;
raytracingPipelineInfo.stageCount = static_cast<uint32_t>(m_shaderStages.size());
raytracingPipelineInfo.pStages = m_shaderStages.data();
raytracingPipelineInfo.groupCount = static_cast<uint32_t>(m_shaderGroups.size());
raytracingPipelineInfo.pGroups = m_shaderGroups.data();
raytracingPipelineInfo.layout = pipelineLayout;
raytracingPipelineInfo.basePipelineIndex = 0;
raytracingPipelineInfo.basePipelineHandle = VK_NULL_HANDLE;
createRayGenShaderTable();
//createMissShaderTable();
//createHitShaderTable();
return m_raytracingPipeline;
}
VulkanBuffer CRayTracing::getRayGenShaderGroups() {
return m_raygenShaderGroupBuffer;
VulkanBuffer CRayTracing::getMissShaderGroups() {
return m_missShaderGroupBuffer;
VulkanBuffer CRayTracing::getHitShaderGroups() {
return m_hitShaderGroupBuffer;
void CRayTracing::createRayGenShaderTable() {
uint32_t raygenAlignment =
CVulkanHelper::alignTo(m_raytracingPipelineProperties.shaderGroupHandleSize *
m_rayGenShaderGroups.size(), m_raytracingPipelineProperties.shaderGroupBaseAlignment);
uint32_t missAlignment =
CVulkanHelper::alignTo(m_raytracingPipelineProperties.shaderGroupHandleSize *
m_missShaderGroups.size(), m_raytracingPipelineProperties.shaderGroupBaseAlignment);
VkDeviceSize bufferSize =
raygenAlignment
+ missAlignment
// we don't need to align the last part as only the base addresses must be aligned and not the
buffer itself
+ (m_raytracingPipelineProperties.shaderGroupHandleSize + sizeof(PrimitiveConstantBuffer) +
sizeof(PrimitiveInstanceConstantBuffer)) * m_aabbs.size();
m_raygenShaderGroupBuffer =
m_helper.createBuffer(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, bufferSize,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
void* data = nullptr;
VK_CHECK(vkGetRayTracingShaderGroupHandlesKHR(m_device, m_raytracingPipeline, 0,
static_cast<uint32_t>(m_rayGenShaderGroups.size()),
m_raytracingPipelineProperties.shaderGroupHandleSize * m_rayGenShaderGroups.size(),
mappedMemory));
mappedMemory += raygenAlignment;
VK_CHECK(vkGetRayTracingShaderGroupHandlesKHR(m_device, m_raytracingPipeline,
static_cast<uint32_t>(m_rayGenShaderGroups.size()),
static_cast<uint32_t>(m_missShaderGroups.size()),
m_raytracingPipelineProperties.shaderGroupHandleSize * m_missShaderGroups.size(),
mappedMemory));
mappedMemory += missAlignment;
VK_CHECK(vkGetRayTracingShaderGroupHandlesKHR(m_device, m_raytracingPipeline,
static_cast<uint32_t>(m_rayGenShaderGroups.size() + m_missShaderGroups.size()), 1,
m_raytracingPipelineProperties.shaderGroupHandleSize, mappedMemory));
mappedMemory += m_raytracingPipelineProperties.shaderGroupHandleSize;
uint32_t offset = 0;
VK_CHECK(vkGetRayTracingShaderGroupHandlesKHR(m_device, m_raytracingPipeline,
static_cast<uint32_t>(m_rayGenShaderGroups.size() + m_missShaderGroups.size() + 1), 1,
m_raytracingPipelineProperties.shaderGroupHandleSize, mappedMemory));
mappedMemory += m_raytracingPipelineProperties.shaderGroupHandleSize;
mappedMemory += sizeof(m_aabbMaterialCB[0]);
offset += AnalyticPrimitive::Count;
VK_CHECK(vkGetRayTracingShaderGroupHandlesKHR(m_device, m_raytracingPipeline,
static_cast<uint32_t>(m_rayGenShaderGroups.size() + m_missShaderGroups.size() + 2), 1,
m_raytracingPipelineProperties.shaderGroupHandleSize, mappedMemory));
mappedMemory += m_raytracingPipelineProperties.shaderGroupHandleSize;
mappedMemory += sizeof(m_aabbMaterialCB[0]);
mappedMemory += sizeof(m_aabbInstanceCB[0]);
offset += VolumetricPrimitive::Count;
VK_CHECK(vkGetRayTracingShaderGroupHandlesKHR(m_device, m_raytracingPipeline,
static_cast<uint32_t>(m_rayGenShaderGroups.size() + m_missShaderGroups.size() + 3), 1,
m_raytracingPipelineProperties.shaderGroupHandleSize, mappedMemory));
mappedMemory += m_raytracingPipelineProperties.shaderGroupHandleSize;
mappedMemory += sizeof(m_aabbMaterialCB[0]);
mappedMemory += sizeof(m_aabbInstanceCB[0]);
}
vkUnmapMemory(m_device, m_raygenShaderGroupBuffer.memory);
void CRayTracing::createMissShaderTable() {
m_missShaderGroupBuffer = m_helper.createBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
bufferSize, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
vkGetRayTracingShaderGroupHandlesKHR(m_device, m_raytracingPipeline,
static_cast<uint32_t>(m_rayGenShaderGroups.size()),
static_cast<uint32_t>(m_missShaderGroups.size()), bufferSize, mappedMemory);
vkUnmapMemory(m_device, m_missShaderGroupBuffer.memory);
void CRayTracing::createHitShaderTable() {
m_hitShaderGroupBuffer = m_helper.createBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
bufferSize, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
vkGetRayTracingShaderGroupHandlesKHR(m_device, m_raytracingPipeline,
static_cast<uint32_t>(m_rayGenShaderGroups.size() + m_missShaderGroups.size()),
m_raytracingPipelineProperties.shaderGroupHandleSize, bufferSize, mappedMemory);
mappedMemory += m_raytracingPipelineProperties.shaderGroupHandleSize;
memcpy(mappedMemory, &m_planeMaterialCB, sizeof(PrimitiveConstantBuffer));
vkGetRayTracingShaderGroupHandlesKHR(m_device, m_raytracingPipeline,
static_cast<uint32_t>(m_rayGenShaderGroups.size() + m_missShaderGroups.size() /*+ index*/ + 1),
m_raytracingPipelineProperties.shaderGroupHandleSize, bufferSize, mappedMemory);
mappedMemory += m_raytracingPipelineProperties.shaderGroupHandleSize;
mappedMemory += sizeof(PrimitiveConstantBuffer);
mappedMemory += sizeof(PrimitiveInstanceConstantBuffer);
// vkGetRayTracingShaderGroupHandles(m_device, m_raytracingPipeline,
m_rayGenShaderGroups.size() + m_missShaderGroups.size() /*+ index*/ + 2,
m_raytracingProperties.shaderGroupHandleSize, bufferSize, mappedMemory);
// mappedMemory += m_raytracingProperties.shaderGroupHandleSize;
// mappedMemory += sizeof(PrimitiveConstantBuffer);
// mappedMemory += sizeof(PrimitiveInstanceConstantBuffer);
//}
vkUnmapMemory(m_device, m_hitShaderGroupBuffer.memory);
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
imageInfo.imageType = VK_IMAGE_TYPE_2D;
imageInfo.format = format;
imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
imageInfo.mipLevels = 1;
imageInfo.arrayLayers = 1;
imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
imageInfo.queueFamilyIndexCount = 0;
imageInfo.pQueueFamilyIndices = nullptr;
imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
VkImage offscreenImage;
VkMemoryRequirements memoryRequirements;
memoryAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
memoryAllocInfo.allocationSize = memoryRequirements.size;
memoryAllocInfo.memoryTypeIndex = memoryType;
VkDeviceMemory offsreenImageMemory;
VulkanImage image;
image.handle = offscreenImage;
image.memory = offsreenImageMemory;
image.size = memoryRequirements.size;
image.format = format;
image.width = width;
image.height = height;
m_offscreenImage = image;
return image;
offscreenImageViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
offscreenImageViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
offscreenImageViewInfo.format = m_offscreenImage.format;
offscreenImageViewInfo.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
offscreenImageViewInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
offscreenImageViewInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
offscreenImageViewInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
offscreenImageViewInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
offscreenImageViewInfo.image = m_offscreenImage.handle;
VkImageView offscreenImageView;
descriptorAccelerationStructureInfo.sType =
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR;
descriptorAccelerationStructureInfo.accelerationStructureCount = 1;
descriptorAccelerationStructureInfo.pAccelerationStructures = &m_topLevelAs;
accelerationStructureWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
accelerationStructureWrite.pNext = &descriptorAccelerationStructureInfo;
accelerationStructureWrite.dstSet = descriptorSet;
accelerationStructureWrite.descriptorCount = 1;
accelerationStructureWrite.dstBinding = 0;
accelerationStructureWrite.descriptorType =
VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR;
descriptorOutputImageInfo.sampler = VK_NULL_HANDLE;
descriptorOutputImageInfo.imageView = offscreenImageView;
descriptorOutputImageInfo.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
outputImageWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
outputImageWrite.dstSet = descriptorSet;
outputImageWrite.dstBinding = 1;
outputImageWrite.dstArrayElement = 0;
outputImageWrite.descriptorCount = 1;
outputImageWrite.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
outputImageWrite.pImageInfo = &descriptorOutputImageInfo;
descriptorSceneBufferInfo.buffer = m_sceneBuffer.handle;
descriptorSceneBufferInfo.range = m_sceneBuffer.size;
sceneBufferWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
sceneBufferWrite.dstSet = descriptorSet;
sceneBufferWrite.dstBinding = 2;
sceneBufferWrite.dstArrayElement = 0;
sceneBufferWrite.descriptorCount = 1;
sceneBufferWrite.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
sceneBufferWrite.pBufferInfo = &descriptorSceneBufferInfo;
descriptorFacesBufferInfo.buffer = m_facesBuffer.handle;
descriptorFacesBufferInfo.range = m_facesBuffer.size;
facesBufferWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
facesBufferWrite.dstSet = descriptorSet;
facesBufferWrite.dstBinding = 3;
facesBufferWrite.dstArrayElement = 0;
facesBufferWrite.descriptorCount = 1;
facesBufferWrite.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
facesBufferWrite.pBufferInfo = &descriptorFacesBufferInfo;
VkDescriptorBufferInfo descriptorNormalBufferInfo = {};
descriptorNormalBufferInfo.buffer = m_normalBuffer.handle;
descriptorNormalBufferInfo.range = m_normalBuffer.size;
normalBufferWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
normalBufferWrite.dstSet = descriptorSet;
normalBufferWrite.dstBinding = 4;
normalBufferWrite.dstArrayElement = 0;
normalBufferWrite.descriptorCount = 1;
normalBufferWrite.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
normalBufferWrite.pBufferInfo = &descriptorNormalBufferInfo;
descriptorAABBPrimitiveBufferInfo.buffer = m_aabbPrimitiveBuffer.handle;
descriptorAABBPrimitiveBufferInfo.range = m_aabbPrimitiveBuffer.size;
sceneAABBPrimitiveBufferWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
sceneAABBPrimitiveBufferWrite.dstSet = descriptorSet;
sceneAABBPrimitiveBufferWrite.dstBinding = 5;
sceneAABBPrimitiveBufferWrite.dstArrayElement = 0;
sceneAABBPrimitiveBufferWrite.descriptorCount = 1;
sceneAABBPrimitiveBufferWrite.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
sceneAABBPrimitiveBufferWrite.pBufferInfo = &descriptorAABBPrimitiveBufferInfo;
void CRayTracing::createPrimitives() {
void CRayTracing::createShaderStages() {
//createShader(VK_SHADER_STAGE_RAYGEN_BIT_NV, "shader/raygen_nv.spv");
//createShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV, "shader/closest_hit_triangle_nv.spv");
//createShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV, "shader/closest_hit_aabb_nv.spv");
//createShader(VK_SHADER_STAGE_MISS_BIT_NV, "shader/miss_nv.spv");
//createShader(VK_SHADER_STAGE_MISS_BIT_NV, "shader/miss_shadow_ray_nv.spv");
//createShader(VK_SHADER_STAGE_INTERSECTION_BIT_NV, "shader/intersection_analytic_nv.spv");
//createShader(VK_SHADER_STAGE_INTERSECTION_BIT_NV,
"shader/intersection_volumetric_nv.spv");
//createShader(VK_SHADER_STAGE_INTERSECTION_BIT_NV,
"shader/intersection_signed_distance_nv.spv");
createShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR, "shader/raygen_ext.spv");
createShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, "shader/closest_hit_triangle_ext.spv");
createShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, "shader/closest_hit_aabb_ext.spv");
createShader(VK_SHADER_STAGE_MISS_BIT_KHR, "shader/miss_ext.spv");
createShader(VK_SHADER_STAGE_MISS_BIT_KHR, "shader/miss_shadow_ray_ext.spv");
createShader(VK_SHADER_STAGE_INTERSECTION_BIT_KHR, "shader/intersection_analytic_ext.spv");
createShader(VK_SHADER_STAGE_INTERSECTION_BIT_KHR,
"shader/intersection_volumetric_ext.spv");
createShader(VK_SHADER_STAGE_INTERSECTION_BIT_KHR,
"shader/intersection_signed_distance_ext.spv");
}
void CRayTracing::createRayGenShaderGroups() {
raygenShaderGroupInfo.sType =
VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR;
raygenShaderGroupInfo.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR;
raygenShaderGroupInfo.generalShader = 0;
raygenShaderGroupInfo.closestHitShader = VK_SHADER_UNUSED_KHR;
raygenShaderGroupInfo.anyHitShader = VK_SHADER_UNUSED_KHR;
raygenShaderGroupInfo.intersectionShader = VK_SHADER_UNUSED_KHR;
m_rayGenShaderGroups.push_back(raygenShaderGroupInfo);
void CRayTracing::createMissShaderGroups() {
missShaderGroupInfo.sType =
VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR;
missShaderGroupInfo.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR;
missShaderGroupInfo.generalShader = 3;
missShaderGroupInfo.closestHitShader = VK_SHADER_UNUSED_KHR;
missShaderGroupInfo.anyHitShader = VK_SHADER_UNUSED_KHR;
missShaderGroupInfo.intersectionShader = VK_SHADER_UNUSED_KHR;
m_missShaderGroups.push_back(missShaderGroupInfo);
missShaderGroupInfo.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR;
missShaderGroupInfo.generalShader = 4;
missShaderGroupInfo.closestHitShader = VK_SHADER_UNUSED_KHR;
missShaderGroupInfo.anyHitShader = VK_SHADER_UNUSED_KHR;
missShaderGroupInfo.intersectionShader = VK_SHADER_UNUSED_KHR;
m_missShaderGroups.push_back(missShaderGroupInfo);
void CRayTracing::createHitShaderGroups() {
closestHitShaderGroupInfo.sType =
VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR;
closestHitShaderGroupInfo.type =
VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR;
closestHitShaderGroupInfo.generalShader = VK_SHADER_UNUSED_KHR;
closestHitShaderGroupInfo.closestHitShader = 1;
closestHitShaderGroupInfo.anyHitShader = VK_SHADER_UNUSED_KHR;
closestHitShaderGroupInfo.intersectionShader = VK_SHADER_UNUSED_KHR;
m_hitShaderGroups.push_back(closestHitShaderGroupInfo);
closestHitShaderGroupInfo.type =
VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_KHR;
closestHitShaderGroupInfo.generalShader = VK_SHADER_UNUSED_KHR;
closestHitShaderGroupInfo.closestHitShader = 2;
closestHitShaderGroupInfo.anyHitShader = VK_SHADER_UNUSED_KHR;
closestHitShaderGroupInfo.intersectionShader = 5;
m_hitShaderGroups.push_back(closestHitShaderGroupInfo);
closestHitShaderGroupInfo.type =
VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_KHR;
closestHitShaderGroupInfo.generalShader = VK_SHADER_UNUSED_KHR;
closestHitShaderGroupInfo.closestHitShader = 2;
closestHitShaderGroupInfo.anyHitShader = VK_SHADER_UNUSED_KHR;
closestHitShaderGroupInfo.intersectionShader = 6;
m_hitShaderGroups.push_back(closestHitShaderGroupInfo);
closestHitShaderGroupInfo.type =
VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_KHR;
closestHitShaderGroupInfo.generalShader = VK_SHADER_UNUSED_KHR;
closestHitShaderGroupInfo.closestHitShader = 2;
closestHitShaderGroupInfo.anyHitShader = VK_SHADER_UNUSED_KHR;
closestHitShaderGroupInfo.intersectionShader = 7;
m_hitShaderGroups.push_back(closestHitShaderGroupInfo);
void CRayTracing::createCommandBuffers() {
void CRayTracing::buildAccelerationStructurePlane() {
}
BottomLevelAccelerationStructure
CRayTracing::createBottomLevelAccelerationStructure(VkAccelerationStructureBuildSizesInfoKHR
const& asBuildSizes) {
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
bufferInfo.usage = VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR;
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
bufferInfo.size = asBuildSizes.accelerationStructureSize;
VulkanBuffer accelerationBuffer =
m_helper.createBuffer(VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR |
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, asBuildSizes.accelerationStructureSize,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
accelerationStructureInfo.sType =
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR;
accelerationStructureInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
accelerationStructureInfo.buffer = accelerationBuffer.handle;
accelerationStructureInfo.offset = 0;
accelerationStructureInfo.size = asBuildSizes.accelerationStructureSize;
VkAccelerationStructureKHR accelerationStructure;
accDeviceAddressInfo.sType =
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR;
accDeviceAddressInfo.accelerationStructure = accelerationStructure;
VkDeviceAddress accelerationStructureHandle =
vkGetAccelerationStructureDeviceAddressKHR(m_device, &accDeviceAddressInfo);
accStruct.buffer = accelerationBuffer;
accStruct.handle = accelerationStructure;
accStruct.gpuAddress = accelerationStructureHandle;
return accStruct;
void CRayTracing::buildTriangleAccelerationStructure() {
buildPlaneGeometry();
triangleGeometry.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR;
triangleGeometry.pNext = nullptr;
triangleGeometry.flags = 0;
triangleGeometry.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_KHR;
triangleGeometry.geometry = {};
triangleGeometry.geometry.triangles.sType =
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR;
triangleGeometry.geometry.triangles.pNext = nullptr;
triangleGeometry.geometry.triangles.vertexData.deviceAddress = m_vertexBuffer.address;
triangleGeometry.geometry.triangles.vertexStride = sizeof(Vertex);
triangleGeometry.geometry.triangles.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT;
triangleGeometry.geometry.triangles.indexData.deviceAddress = m_indexBuffer.address;
triangleGeometry.geometry.triangles.indexType = VK_INDEX_TYPE_UINT16;
triangleGeometry.geometry.triangles.maxVertex = 4;
triangleGeometryInfo.sType =
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
triangleGeometryInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
triangleGeometryInfo.geometryCount = 1;
triangleGeometryInfo.mode = VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR;
triangleGeometryInfo.pGeometries = &triangleGeometry;
VkAccelerationStructureBuildSizesInfoKHR triangleAccelerationStructureSizes;
triangleAccelerationStructureSizes.sType =
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR;
vkGetAccelerationStructureBuildSizesKHR(m_device,
VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, &triangleGeometryInfo,
&triangleGeometryInfo.geometryCount, &triangleAccelerationStructureSizes);
BottomLevelAccelerationStructure triangleAccStruct =
createBottomLevelAccelerationStructure(triangleAccelerationStructureSizes);
std::vector<VkAccelerationStructureGeometryKHR> aabbGeometries(m_aabbBuffers.size());
std::vector<VkAccelerationStructureBuildSizesInfoKHR> aabbAsBuildSizes(m_aabbBuffers.size());
std::vector<BottomLevelAccelerationStructure> accStructs(m_aabbBuffers.size());
aabbGeometries[index] = {};
aabbGeometries[index].sType =
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR;
aabbGeometries[index].pNext = nullptr;
aabbGeometries[index].geometryType = VK_GEOMETRY_TYPE_AABBS_KHR;
aabbGeometries[index].geometry = {};
aabbGeometries[index].geometry.aabbs.sType =
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_AABBS_DATA_KHR;
aabbGeometries[index].geometry.aabbs.stride = sizeof(VkAabbPositionsKHR);
aabbGeometries[index].geometry.aabbs.data.deviceAddress = m_aabbBuffers[index].address;
aabbGeometries[index].flags = 0;
aabbGeometryInfo.sType =
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
aabbGeometryInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
aabbGeometryInfo.geometryCount = 1;
aabbGeometryInfo.mode = VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR;
aabbGeometryInfo.pGeometries = &aabbGeometries[index];
aabbAsBuildSizes[index] = {};
aabbAsBuildSizes[index].sType =
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR;
vkGetAccelerationStructureBuildSizesKHR(m_device,
VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, &aabbGeometryInfo,
&aabbGeometryInfo.geometryCount, &aabbAsBuildSizes[index]);
accStructs[index] = createBottomLevelAccelerationStructure(aabbAsBuildSizes[index]);
float triangleTransform[3][4] = {
};
triangleGeomInstance.mask = 1;
triangleGeomInstance.instanceShaderBindingTableRecordOffset = 0;
triangleGeomInstance.accelerationStructureReference = triangleAccStruct.gpuAddress;
std::vector<VkAccelerationStructureInstanceKHR> instances;
instances.push_back(triangleGeomInstance);
float aabbTransform[3][4] =
};
aabbGeomInstance.mask = 1;
aabbGeomInstance.instanceShaderBindingTableRecordOffset = 1 + index;
aabbGeomInstance.accelerationStructureReference = accStructs[index].gpuAddress;
instances.push_back(aabbGeomInstance);
VulkanBuffer instanceBuffer =
m_helper.createBuffer(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, instanceBufferSize,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
topLevelGeometry.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR;
topLevelGeometry.pNext = nullptr;
topLevelGeometry.flags = 0;
topLevelGeometry.geometryType = VK_GEOMETRY_TYPE_INSTANCES_KHR;
topLevelGeometry.geometry = {};
topLevelGeometry.geometry.instances.sType =
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR;
topLevelGeometry.geometry.instances.arrayOfPointers = VK_FALSE;
topLevelGeometry.geometry.instances.data.deviceAddress = instanceBuffer.address;
topAccelerationStructureGeometryInfo.sType =
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
topAccelerationStructureGeometryInfo.type =
VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR;
topAccelerationStructureGeometryInfo.geometryCount = 1;
topAccelerationStructureGeometryInfo.pGeometries = &topLevelGeometry;
VkAccelerationStructureBuildSizesInfoKHR topAccelerationStructureSizes;
topAccelerationStructureSizes.sType =
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR;
vkGetAccelerationStructureBuildSizesKHR(m_device,
VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, &topAccelerationStructureGeometryInfo,
&count, &topAccelerationStructureSizes);
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
bufferInfo.usage = VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR;
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
bufferInfo.size = topAccelerationStructureSizes.accelerationStructureSize;
VulkanBuffer topAccelerationBuffer =
m_helper.createBuffer(VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR |
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
topAccelerationStructureSizes.accelerationStructureSize, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
topAccInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR;
topAccInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR;
topAccInfo.buffer = topAccelerationBuffer.handle;
topAccInfo.offset = 0;
topAccInfo.size = topAccelerationStructureSizes.accelerationStructureSize;
VkAccelerationStructureKHR topAccelerationStructure;
VK_CHECK(vkCreateAccelerationStructureKHR(m_device, &topAccInfo, nullptr,
&topAccelerationStructure));
VkDeviceSize bottomTriangleAccelerationStructureBufferSize =
triangleAccelerationStructureSizes.buildScratchSize;
VkDeviceSize bottomAabbAccelerationStructureBufferSize = 0;
bottomAabbAccelerationStructureBufferSize = std::max(aabbAsBuildSizes[index].buildScratchSize,
bottomAabbAccelerationStructureBufferSize);
commandBufferAllocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
commandBufferAllocInfo.commandPool = m_commandPool;
commandBufferAllocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
commandBufferAllocInfo.commandBufferCount = 1;
VkCommandBuffer cmdBuffer;
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
VK_CHECK(vkBeginCommandBuffer(cmdBuffer, &beginInfo));
memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
memoryBarrier.srcAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR;
memoryBarrier.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
triangleBuildRangeInfo.primitiveCount = 2;
triangleBuildRangeInfo.primitiveOffset = 0;
triangleBuildRangeInfo.firstVertex = 0;
triangleBuildRangeInfo.transformOffset = 0;
asBuildInfo.sType =
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
asBuildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
asBuildInfo.geometryCount = 1;
asBuildInfo.pGeometries = &triangleGeometry;
asBuildInfo.flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR;
asBuildInfo.srcAccelerationStructure = VK_NULL_HANDLE;
asBuildInfo.dstAccelerationStructure = triangleAccStruct.handle;
asBuildInfo.scratchData.deviceAddress = scratchBuffer.address;
vkCmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR,
VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, 0, 1, &memoryBarrier, 0, nullptr, 0,
nullptr);
aabbBuildRangeInfo.primitiveCount = 1;
aabbBuildRangeInfo.primitiveOffset = 0;
aabbBuildRangeInfo.firstVertex = 0;
aabbBuildRangeInfo.transformOffset = 0;
asBuildInfo.sType =
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
asBuildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
asBuildInfo.geometryCount = 1;//aabbGeometries.size();
asBuildInfo.pGeometries = &aabbGeometries[index];
asBuildInfo.flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR;
asBuildInfo.srcAccelerationStructure = VK_NULL_HANDLE;
asBuildInfo.dstAccelerationStructure = accStructs[index].handle;
asBuildInfo.scratchData.deviceAddress = scratchBuffer.address;
vkCmdPipelineBarrier(cmdBuffer,
VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR,
VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, 0, 1, &memoryBarrier, 0, nullptr, 0,
nullptr);
topLevelBuildRangeInfo.primitiveCount = static_cast<uint32_t>(instances.size());
topLevelBuildRangeInfo.primitiveOffset = 0;
topLevelBuildRangeInfo.firstVertex = 0;
topLevelBuildRangeInfo.transformOffset = 0;
asBuildInfo.sType =
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
asBuildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR;
asBuildInfo.geometryCount = 1;
asBuildInfo.pGeometries = &topLevelGeometry;
asBuildInfo.flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR;
asBuildInfo.srcAccelerationStructure = VK_NULL_HANDLE;
asBuildInfo.dstAccelerationStructure = topAccelerationStructure;
asBuildInfo.scratchData.deviceAddress = scratchBuffer.address;
std::vector<VkAccelerationStructureBuildRangeInfoKHR*> asOffsetInfos =
{ &topLevelBuildRangeInfo };
VK_CHECK(vkEndCommandBuffer(cmdBuffer));
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &cmdBuffer;
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
m_topLevelAs = topAccelerationStructure;
void CRayTracing::updateCameraMatrices() {
m_sceneCB.cameraPosition = m_eye;
m_sceneCB.projectionToWorld = glm::inverse(viewProj);
glm::vec3 vTranslation =
+ glm::vec3(m_aabbs[primitiveIndex].maxX, m_aabbs[primitiveIndex].maxY,
m_aabbs[primitiveIndex].maxZ));
m_aabbPrimitiveAttributeBuffer[primitiveIndex].localSpaceToBottomLevelAS = transform;
m_aabbPrimitiveAttributeBuffer[primitiveIndex].bottomLevelASToLocalSpace =
glm::inverse(transform);
};
uint32_t offset = 0;
{
offset += AnalyticPrimitive::Count;
offset += VolumetricPrimitive::Count;
void CRayTracing::buildProceduralGeometryAABBs() {
);
return VkAabbPositionsKHR {
};
};
m_aabbs.resize(IntersectionShaderType::kTotalPrimitiveCount);
uint32_t offset = 0;
offset += AnalyticPrimitive::Count;
}
{
offset += VolumetricPrimitive::Count;
VulkanBuffer aabbBuffer =
m_helper.createBuffer(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
sizeof(VkAabbPositionsKHR), VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
m_aabbBuffers.push_back(aabbBuffer);
}
void CRayTracing::buildPlaneGeometry() {
Index indices[] = {
3, 1, 0,
2, 1, 3
};
Vertex vertices[] = {
};
m_indexBuffer = m_helper.createBuffer(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT |
VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR, sizeof(indices),
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
m_vertexBuffer = m_helper.createBuffer(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT |
VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR, sizeof(vertices),
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
std::vector<uint32_t> faces;
faces.push_back(indices[index + 0]);
faces.push_back(indices[index + 1]);
faces.push_back(indices[index + 2]);
faces.push_back(0);
}
m_facesBuffer = m_helper.createBuffer(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, faces.size() * sizeof(uint32_t),
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
glm::vec4 normals[] = {
};
m_normalBuffer = m_helper.createBuffer(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, sizeof(normals),
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
void CRayTracing::update() {
if (m_animateCamera)
{
float secondsToRotateAround = 48.0f;
updateCameraMatrices();
if (m_animateLight)
animateGeometryTime += elapsedTime;
updateAABBPrimitivesAttributes(animateGeometryTime);
m_sceneCB.elapsedTime = animateGeometryTime;
updateSceneBuffer();
updateAABBPrimitiveBuffer();