首页 > 解决方案 > 我在使用 Vulkan Ray-Tracing 使多个网格在同一个 blas/tlas 上看起来正确时遇到了一些问题

问题描述

我正在尝试使用相同的 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, VK_FORMAT_R8G8B8A8_UNORM, "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), 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.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, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &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, 1, &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, nullptr, &fence);
vkQueueSubmit(engine.GraphicsQueue, 1, &submitInfo, fence);
vkWaitForFences(engine.Device, 1, &fence, VK_TRUE, 100000000000);
vkDestroyFence(engine.Device, fence, nullptr);
vkFreeCommandBuffers(engine.Device, engine.GetRenderCommandPool(), 1, &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, 0.0f, 0.0f, 0.0f,
        0.0f, 1.0f, 0.0f, 0.0f,
        0.0f, 0.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), VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &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, VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, &AccelerationStructureBuildGeometry, maxPrimCount.data(), &AccelerationBuildInfo);

topLevelAS.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 = topLevelAS.Buffer;
AccelerationStructureInfo.size = AccelerationBuildInfo.accelerationStructureSize;
AccelerationStructureInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR;
VkResult result = vkCreateAccelerationStructureKHR(engine.Device, &AccelerationStructureInfo, nullptr, &topLevelAS.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_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, &commandBufferAllocateInfo, &cmdBuffer);

VkCommandBufferBeginInfo cmdBufferBeginInfo{};
cmdBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;

vkBeginCommandBuffer(cmdBuffer, &cmdBufferBeginInfo);
vkCmdBuildAccelerationStructuresKHR(cmdBuffer, 1, &AccelerationBuildGeometryInfo, 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, &fenceCreateInfo, nullptr, &fence);
vkQueueSubmit(engine.GraphicsQueue, 1, &submitInfo, fence);
vkWaitForFences(engine.Device, 1, &fence, VK_TRUE, 100000000000);
vkDestroyFence(engine.Device, fence, nullptr);
vkFreeCommandBuffers(engine.Device, engine.GetRenderCommandPool(), 1, &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, 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, normal), 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, 1, 0, 1, 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;
}

}

标签: graphics3dgame-enginevulkanraytracing

解决方案


推荐阅读