graphics - 我在使用 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;
}
}
解决方案
推荐阅读
- python - Rasa - 获取用于自定义操作的槽值
- javascript - if语句无法执行
- postgresql - 如何在 yocto 中构建支持 openSSL 的 PostgreSQL?
- arrays - 尝试在 reactjs 中组合 event.target.value 捕获的输入输入值
- javascript - findIndex() 返回 -1 且索引号不正确
- php - PHP - 在数组中设置一个数组,然后在 json (IPN 文件) 中获取它的值
- objective-c - 在objectiveC中定义半公共变量
- python - 有没有一种很好的pythonic方法来进行左值排列?
- python - 只有用户名和密码(没有我们的证书和私钥)
- laravel - Laravel 5.8 的 auth.reminder.repository