问题描述
我正在尝试使用相同的 blas/tlas 加载多个网格,但看起来似乎不太正确。当它只有网格时它加载得很好,但我尝试了多个网格,它看起来像这样。我不确定使用 blas 和 tlas 中的设置的方式是否有问题,或者是否有多个网格改变了我在着色器中解压缩顶点的方式。
我也试过查看 nvidia 光线追踪教程和 sacha williams 光线追踪代码,看起来它们都只使用一个网格,每个 blas/tlas 在场景中加载为一个网格。对于样本来说,这看起来不错,但是当尝试通过变换、旋转或缩放来操纵每个网格个体时,这会不会导致问题?
这是blas和tlas代码:
void RayTraceRenderer::createBottomLevelaccelerationStructure(VulkanEngine& engine)
{
std::shared_ptr<TextureManager> manager = std::make_shared<TextureManager>(engine);
std::shared_ptr<Texture> texture = std::make_shared<Texture>();
model = Model(engine,manager,"C:/Users/dotha/source/repos/Vulkangraphics/Models/vulkanscene_shadow.obj",RayTraceDescriptorSetLayout,1,texture);
texture2D = Texture2D(engine,VK_FORMAT_R8G8B8A8_UnorM,"C:/Users/dotha/source/repos/Vulkangraphics/texture/Brick_diffuSEOriginal.bmp",1);
normalMap = Texture2D(engine,"C:/Users/dotha/source/repos/Vulkangraphics/texture/Brick_normal.bmp",1);
std::vector<VkaccelerationStructureGeometryKHR> GeometryaccelerationStructureList;
for (int x = 0; x < 11; x++)
{
auto mesh = model.SubMeshList[x];
glm::mat4 transformMatrix = glm::mat4(1.0f);
transformMatrix = glm::rotate(transformMatrix,glm::radians(180.0f),glm::vec3(0.0f,0.0f,1.0f));
vertexBuffer.CreateBuffer(engine,mesh.VertexList.size() * sizeof(Vertex),VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_acceleration_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR,VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,mesh.VertexList.data());
indexBuffer.CreateBuffer(engine,mesh.IndexList.size() * sizeof(uint32_t),mesh.IndexList.data());
transformBuffer.CreateBuffer(engine,sizeof(glm::mat4),VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_acceleration_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR,&transformMatrix);
VkDeviceOrHostAddressConstKHR vertexBufferDeviceAddress = engine.BufferToDeviceAddress(vertexBuffer.Buffer);
VkDeviceOrHostAddressConstKHR indexBufferDeviceAddress = engine.BufferToDeviceAddress(indexBuffer.Buffer);
VkDeviceOrHostAddressConstKHR transformBufferDeviceAddress = engine.BufferToDeviceAddress(transformBuffer.Buffer);
VkaccelerationStructureGeometryKHR GeometryaccelerationStructure = {};
GeometryaccelerationStructure.sType = VK_STRUCTURE_TYPE_acceleration_STRUCTURE_GEOMETRY_KHR;
GeometryaccelerationStructure.flags = VK_GEOMETRY_OPAQUE_BIT_KHR;
GeometryaccelerationStructure.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_KHR;
GeometryaccelerationStructure.geometry.triangles.sType = VK_STRUCTURE_TYPE_acceleration_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR;
GeometryaccelerationStructure.geometry.triangles.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT;
GeometryaccelerationStructure.geometry.triangles.vertexData = vertexBufferDeviceAddress;
GeometryaccelerationStructure.geometry.triangles.maxVertex = mesh.VertexList.size() * sizeof(Vertex);
GeometryaccelerationStructure.geometry.triangles.vertexStride = sizeof(Vertex);
GeometryaccelerationStructure.geometry.triangles.indexType = VK_INDEX_TYPE_UINT32;
GeometryaccelerationStructure.geometry.triangles.indexData = indexBufferDeviceAddress;
GeometryaccelerationStructure.geometry.triangles.transformData.deviceAddress = 0;
GeometryaccelerationStructure.geometry.triangles.transformData.hostAddress = nullptr;
GeometryaccelerationStructure.geometry.triangles.transformData = transformBufferDeviceAddress;
GeometryaccelerationStructureList.emplace_back(GeometryaccelerationStructure);
VkaccelerationStructurebuildrangeInfoKHR Acclerationbuildrange = {};
Acclerationbuildrange.primitiveCount = static_cast<uint32_t>(mesh.IndexList.size()) / 3;
Acclerationbuildrange.primitiveOffset = x;
Acclerationbuildrange.firstVertex = 0;
Acclerationbuildrange.transformOffset = 0;
AcclerationbuildrangeList.emplace_back(Acclerationbuildrange);
}
VkaccelerationStructureBuildGeometryInfoKHR accelerationBuildGeometry = {};
accelerationBuildGeometry.sType = VK_STRUCTURE_TYPE_acceleration_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
accelerationBuildGeometry.type = VK_acceleration_STRUCTURE_TYPE_BottOM_LEVEL_KHR;
accelerationBuildGeometry.flags = VK_BUILD_acceleration_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR;
accelerationBuildGeometry.geometryCount = static_cast<uint32_t>(GeometryaccelerationStructureList.size());
accelerationBuildGeometry.pGeometries = GeometryaccelerationStructureList.data();
maxPrimCount.resize(AcclerationbuildrangeList.size());
for (auto x = 0; x < AcclerationbuildrangeList.size(); x++)
{
maxPrimCount[x] = AcclerationbuildrangeList[x].primitiveCount;
}
VkaccelerationStructureBuildSizesInfoKHR accelerationBuildInfo = {};
accelerationBuildInfo.sType = VK_STRUCTURE_TYPE_acceleration_STRUCTURE_BUILD_SIZES_INFO_KHR;
vkGetaccelerationStructureBuildSizesKHR(engine.Device,VK_acceleration_STRUCTURE_BUILD_TYPE_DEVICE_KHR,&accelerationBuildGeometry,maxPrimCount.data(),&accelerationBuildInfo);
bottomLevelAS.CreateBuffer(engine,accelerationBuildInfo.accelerationStructureSize,VK_BUFFER_USAGE_acceleration_STRUCTURE_STORAGE_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
VkaccelerationStructureCreateInfoKHR accelerationStructureInfo = {};
accelerationStructureInfo.sType = VK_STRUCTURE_TYPE_acceleration_STRUCTURE_CREATE_INFO_KHR;
accelerationStructureInfo.buffer = bottomLevelAS.Buffer;
accelerationStructureInfo.size = accelerationBuildInfo.accelerationStructureSize;
accelerationStructureInfo.type = VK_acceleration_STRUCTURE_TYPE_BottOM_LEVEL_KHR;
VkResult result = vkCreateaccelerationStructureKHR(engine.Device,&accelerationStructureInfo,nullptr,&bottomLevelAS.BufferHandle);
VulkanBuffer ScratchBuffer = VulkanBuffer();
ScratchBuffer.CreateBuffer(engine,accelerationBuildInfo.buildScratchSize,VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
VkDeviceOrHostAddressConstKHR ScratchBufferDeviceAddress = engine.BufferToDeviceAddress(ScratchBuffer.GetBuffer());
VkaccelerationStructureBuildGeometryInfoKHR accelerationBuildGeometryInfo = {};
accelerationBuildGeometryInfo.sType = VK_STRUCTURE_TYPE_acceleration_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
accelerationBuildGeometryInfo.type = VK_acceleration_STRUCTURE_TYPE_BottOM_LEVEL_KHR;
accelerationBuildGeometryInfo.flags = VK_BUILD_acceleration_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR;
accelerationBuildGeometryInfo.mode = VK_BUILD_acceleration_STRUCTURE_MODE_BUILD_KHR;
accelerationBuildGeometryInfo.dstaccelerationStructure = bottomLevelAS.BufferHandle;
accelerationBuildGeometryInfo.geometryCount = static_cast<uint32_t>(GeometryaccelerationStructureList.size());
accelerationBuildGeometryInfo.pGeometries = GeometryaccelerationStructureList.data();
accelerationBuildGeometryInfo.scratchData.deviceAddress = ScratchBufferDeviceAddress.deviceAddress;
VkCommandBufferAllocateInfo commandBufferAllocateInfo{};
commandBufferAllocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
commandBufferAllocateInfo.commandPool = engine.GetRenderCommandPool();
commandBufferAllocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
commandBufferAllocateInfo.commandBufferCount = 1;
VkCommandBuffer cmdBuffer;
vkAllocateCommandBuffers(engine.Device,&commandBufferAllocateInfo,&cmdBuffer);
VkCommandBufferBeginInfo cmdBufferBeginInfo{};
cmdBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
auto asdf = AcclerationbuildrangeList.data();
vkBeginCommandBuffer(cmdBuffer,&cmdBufferBeginInfo);
vkCmdBuildaccelerationStructuresKHR(cmdBuffer,&accelerationBuildGeometryInfo,&asdf);
vkEndCommandBuffer(cmdBuffer);
VkSubmitInfo submitInfo{};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &cmdBuffer;
VkFenceCreateInfo fenceCreateInfo{};
fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
fenceCreateInfo.flags = 0;
VkFence fence;
vkCreateFence(engine.Device,&fenceCreateInfo,&fence);
vkQueueSubmit(engine.GraphicsQueue,&submitInfo,fence);
vkWaitForFences(engine.Device,&fence,VK_TRUE,100000000000);
vkDestroyFence(engine.Device,fence,nullptr);
vkFreeCommandBuffers(engine.Device,engine.GetRenderCommandPool(),&cmdBuffer);
VkaccelerationStructureDeviceAddressInfoKHR accelerationDeviceAddressInfo{};
accelerationDeviceAddressInfo.sType = VK_STRUCTURE_TYPE_acceleration_STRUCTURE_DEVICE_ADDRESS_INFO_KHR;
accelerationDeviceAddressInfo.accelerationStructure = bottomLevelAS.BufferHandle;
bottomLevelAS.BufferDeviceAddress = vkGetaccelerationStructureDeviceAddressKHR(engine.Device,&accelerationDeviceAddressInfo);
ScratchBuffer.DestoryBuffer(engine);
}
void RayTraceRenderer::createtopLevelaccelerationStructure(VulkanEngine& engine)
{
VkTransformMatrixKHR transformMatrix = {
1.0f,1.0f,0.0f
};
VkaccelerationStructureInstanceKHR accelerationInstance = {};
accelerationInstance.transform = transformMatrix;
accelerationInstance.instanceCustomIndex = 0;
accelerationInstance.mask = 0xFF;
accelerationInstance.instanceShaderBindingTableRecordOffset = 0;
accelerationInstance.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_disABLE_BIT_KHR;
accelerationInstance.accelerationStructureReference = bottomLevelAS.BufferDeviceAddress;
VulkanBuffer instancesBuffer;
instancesBuffer.CreateBuffer(engine,sizeof(VkaccelerationStructureInstanceKHR),&accelerationInstance);
VkDeviceOrHostAddressConstKHR TopLevelaccelerationInstanceBufferDeviceAddress{};
TopLevelaccelerationInstanceBufferDeviceAddress.deviceAddress = engine.BufferToDeviceAddress(instancesBuffer.Buffer).deviceAddress;
VkaccelerationStructureGeometryKHR accelerationGeometry = {};
accelerationGeometry.sType = VK_STRUCTURE_TYPE_acceleration_STRUCTURE_GEOMETRY_KHR;
accelerationGeometry.geometryType = VK_GEOMETRY_TYPE_INSTANCES_KHR;
accelerationGeometry.flags = VK_GEOMETRY_OPAQUE_BIT_KHR;
accelerationGeometry.geometry.instances.sType = VK_STRUCTURE_TYPE_acceleration_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR;
accelerationGeometry.geometry.instances.arrayOfPointers = VK_FALSE;
accelerationGeometry.geometry.instances.data = TopLevelaccelerationInstanceBufferDeviceAddress;
VkaccelerationStructureBuildGeometryInfoKHR accelerationStructureBuildGeometry = {};
accelerationStructureBuildGeometry.sType = VK_STRUCTURE_TYPE_acceleration_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
accelerationStructureBuildGeometry.type = VK_acceleration_STRUCTURE_TYPE_TOP_LEVEL_KHR;
accelerationStructureBuildGeometry.flags = VK_BUILD_acceleration_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR;
accelerationStructureBuildGeometry.geometryCount = 1;
accelerationStructureBuildGeometry.pGeometries = &accelerationGeometry;
VkaccelerationStructureBuildSizesInfoKHR accelerationBuildInfo = {};
accelerationBuildInfo.sType = VK_STRUCTURE_TYPE_acceleration_STRUCTURE_BUILD_SIZES_INFO_KHR;
vkGetaccelerationStructureBuildSizesKHR(engine.Device,&accelerationStructureBuildGeometry,&accelerationBuildInfo);
topLevelAS.CreateBuffer(engine,VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
VkaccelerationStructureCreateInfoKHR accelerationStructureInfo = {};
accelerationStructureInfo.sType = VK_STRUCTURE_TYPE_acceleration_STRUCTURE_CREATE_INFO_KHR;
accelerationStructureInfo.buffer = topLevelAS.Buffer;
accelerationStructureInfo.size = accelerationBuildInfo.accelerationStructureSize;
accelerationStructureInfo.type = VK_acceleration_STRUCTURE_TYPE_TOP_LEVEL_KHR;
VkResult result = vkCreateaccelerationStructureKHR(engine.Device,&topLevelAS.BufferHandle);
VulkanBuffer ScratchBuffer = VulkanBuffer();
ScratchBuffer.CreateBuffer(engine,VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
VkDeviceOrHostAddressConstKHR ScratchBufferDeviceAddress = engine.BufferToDeviceAddress(ScratchBuffer.GetBuffer());
VkaccelerationStructureBuildGeometryInfoKHR accelerationBuildGeometryInfo = {};
accelerationBuildGeometryInfo.sType = VK_STRUCTURE_TYPE_acceleration_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
accelerationBuildGeometryInfo.type = VK_acceleration_STRUCTURE_TYPE_TOP_LEVEL_KHR;
accelerationBuildGeometryInfo.flags = VK_BUILD_acceleration_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR;
accelerationBuildGeometryInfo.mode = VK_BUILD_acceleration_STRUCTURE_MODE_BUILD_KHR;
accelerationBuildGeometryInfo.dstaccelerationStructure = topLevelAS.BufferHandle;
accelerationBuildGeometryInfo.geometryCount = 1;
accelerationBuildGeometryInfo.pGeometries = &accelerationGeometry;
accelerationBuildGeometryInfo.scratchData.deviceAddress = ScratchBufferDeviceAddress.deviceAddress;
std::vector<VkaccelerationStructurebuildrangeInfoKHR*> AcclerationbuildrangeList;
VkaccelerationStructurebuildrangeInfoKHR Acclerationbuildrange = {};
Acclerationbuildrange.primitiveCount = static_cast<uint32_t>(maxPrimCount.size());
Acclerationbuildrange.primitiveOffset = 0;
Acclerationbuildrange.firstVertex = 0;
Acclerationbuildrange.transformOffset = 0;
AcclerationbuildrangeList.emplace_back(&Acclerationbuildrange);
VkCommandBufferAllocateInfo commandBufferAllocateInfo{};
commandBufferAllocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
commandBufferAllocateInfo.commandPool = engine.GetRenderCommandPool();
commandBufferAllocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
commandBufferAllocateInfo.commandBufferCount = 1;
VkCommandBuffer cmdBuffer;
vkAllocateCommandBuffers(engine.Device,&cmdBuffer);
VkCommandBufferBeginInfo cmdBufferBeginInfo{};
cmdBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
vkBeginCommandBuffer(cmdBuffer,AcclerationbuildrangeList.data());
vkEndCommandBuffer(cmdBuffer);
VkSubmitInfo submitInfo{};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &cmdBuffer;
VkFenceCreateInfo fenceCreateInfo{};
fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
fenceCreateInfo.flags = 0;
VkFence fence;
vkCreateFence(engine.Device,&cmdBuffer);
VkaccelerationStructureDeviceAddressInfoKHR accelerationDeviceAddressInfo{};
accelerationDeviceAddressInfo.sType = VK_STRUCTURE_TYPE_acceleration_STRUCTURE_DEVICE_ADDRESS_INFO_KHR;
accelerationDeviceAddressInfo.accelerationStructure = topLevelAS.BufferHandle;
topLevelAS.BufferDeviceAddress = vkGetaccelerationStructureDeviceAddressKHR(engine.Device,&accelerationDeviceAddressInfo);
ScratchBuffer.DestoryBuffer(engine);
}
和命中着色器代码:
#version 460
#extension GL_EXT_ray_tracing : require
#extension GL_EXT_nonuniform_qualifier : enable
layout(location = 0) rayPayloadInEXT vec3 hitValue;
layout(location = 2) rayPayloadEXT bool shadowed;
hitAttributeEXT vec3 attribs;
layout(binding = 0,set = 0) uniform accelerationStructureEXT topLevelAS;
layout(binding = 2,set = 0) uniform UBO
{
mat4 viewInverse;
mat4 projInverse;
mat4 modelInverse;
vec4 lightPos;
vec4 viewPos;
int vertexSize;
} ubo;
layout(binding = 3,set = 0) buffer Vertices { vec4 v[]; } vertices;
layout(binding = 4,set = 0) buffer Indices { uint i[]; } indices;
layout(binding = 5,set = 0) uniform sampler2D DiffuseMap;
layout(binding = 6,set = 0) uniform sampler2D normalMap;
struct Vertex
{
vec3 pos;
vec3 normal;
vec2 uv;
vec4 tangent;
vec4 BiTangant;
vec4 Color;
vec4 BoneID;
vec4 BoneWeights;
};
Vertex unpack(uint index)
{
// Unpack the vertices from the SSBO using the glTF vertex structure
// The multiplier is the size of the vertex divided by four float components (=16 bytes)
const int m = ubo.vertexSize / 16;
vec4 d0 = vertices.v[m * index + 0];
vec4 d1 = vertices.v[m * index + 1];
vec4 d2 = vertices.v[m * index + 2];
Vertex v;
v.pos = d0.xyz;
v.normal = vec3(d0.w,d1.x,d1.y);
v.Color = vec4(d2.x,d2.y,d2.z,1.0);
v.uv = vec2(d0.x,d0.y);
v.tangent = vec4(d0.w,d1.y,0.0f);
return v;
}
void main()
{
ivec3 index = ivec3(indices.i[3 * gl_PrimitiveID],indices.i[3 * gl_PrimitiveID + 1],indices.i[3 * gl_PrimitiveID + 2]);
Vertex v0 = unpack(index.x);
Vertex v1 = unpack(index.y);
Vertex v2 = unpack(index.z);
const vec3 barycentricCoords = vec3(1.0f - attribs.x - attribs.y,attribs.x,attribs.y);
vec3 worldPos = v0.pos * barycentricCoords.x + v1.pos * barycentricCoords.y + v2.pos * barycentricCoords.z;
vec3 normal2 = normalize(v0.normal * barycentricCoords.x + v1.normal * barycentricCoords.y + v2.normal * barycentricCoords.z);
vec2 texCoord = v0.uv * barycentricCoords.x + v1.uv * barycentricCoords.y + v2.uv * barycentricCoords.z;
vec3 tangent = v0.tangent.xyz * barycentricCoords.x + v1.tangent.xyz * barycentricCoords.y + v2.tangent.xyz * barycentricCoords.z;
mat3 normalMatrix = transpose(inverse(mat3(ubo.modelInverse)));
vec3 T = normalize(normalMatrix * tangent);
vec3 N = normalize(normalMatrix * normal2);
T = normalize(T - dot(T,N) * N);
vec3 B = cross(N,T);
mat3 TBN = transpose(mat3(T,B,N));
vec3 TangentLightPos = TBN * ubo.lightPos.xyz;
vec3 TangentViewPos = TBN * ubo.viewPos.xyz;
vec3 TangentFragPos = TBN * worldPos;
vec3 normal = texture(normalMap,texCoord).rgb;
normal = normalize(normal * 2.0 - 1.0);
vec3 color = texture(DiffuseMap,texCoord).rgb;
vec3 ambient = 0.1 * color;
vec3 lightDir = normalize(TangentLightPos - TangentFragPos);
float diff = max(dot(lightDir,normal),0.0);
vec3 diffuse = diff * color;
//vec3 lightVector = normalize(ubo.lightPos.xyz);
//float dot_product = max(dot(lightVector,0.2);
hitValue = ambient + diffuse;
// Shadow casting
float tmin = 0.001;
float tmax = 10000.0;
vec3 origin = gl_WorldRayOriginEXT + gl_WorldRayDirectionEXT * gl_HitTEXT;
shadowed = true;
// Trace shadow ray and offset indices to match shadow hit/miss shader group indices
traceRayEXT(topLevelAS,gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT | gl_RayFlagsSkipClosestHitShaderEXT,0xFF,origin,tmin,lightDir,tmax,2);
if (shadowed) {
hitValue *= 0.3;
}
else
{
vec3 viewDir = normalize(TangentLightPos - TangentFragPos);
vec3 reflectDir = reflect(-lightDir,normal);
vec3 halfwayDir = normalize(lightDir + viewDir);
float spec = pow(max(dot(normal,halfwayDir),0.0),32.0);
vec3 specular = vec3(0.2) * spec;
hitValue += specular;
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)