mirror of
https://github.com/ZDoom/ZDRay.git
synced 2025-02-03 13:11:04 +00:00
Trace sunlight on the GPU
This commit is contained in:
parent
b12f31f182
commit
ca5c48836f
5 changed files with 261 additions and 50 deletions
|
@ -6,13 +6,36 @@ static const char* glsl_closesthit = R"glsl(
|
|||
struct hitPayload
|
||||
{
|
||||
float hitAttenuation;
|
||||
bool isSkyRay;
|
||||
};
|
||||
|
||||
struct SurfaceInfo
|
||||
{
|
||||
vec3 Normal;
|
||||
float EmissiveDistance;
|
||||
vec3 EmissiveColor;
|
||||
float EmissiveIntensity;
|
||||
float Sky;
|
||||
float Padding0, Padding1, Padding2;
|
||||
};
|
||||
|
||||
layout(location = 0) rayPayloadInEXT hitPayload payload;
|
||||
|
||||
layout(set = 0, binding = 5) buffer SurfaceIndexBuffer { int surfaceIndices[]; };
|
||||
layout(set = 0, binding = 6) buffer SurfaceBuffer { SurfaceInfo surfaces[]; };
|
||||
|
||||
void main()
|
||||
{
|
||||
payload.hitAttenuation = 0.0;
|
||||
SurfaceInfo surface = surfaces[surfaceIndices[gl_PrimitiveID]];
|
||||
|
||||
if (!payload.isSkyRay)
|
||||
{
|
||||
payload.hitAttenuation = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
payload.hitAttenuation = surface.Sky;
|
||||
}
|
||||
}
|
||||
|
||||
)glsl";
|
||||
|
|
|
@ -6,13 +6,21 @@ static const char* glsl_miss = R"glsl(
|
|||
struct hitPayload
|
||||
{
|
||||
float hitAttenuation;
|
||||
bool isSkyRay;
|
||||
};
|
||||
|
||||
layout(location = 0) rayPayloadInEXT hitPayload payload;
|
||||
|
||||
void main()
|
||||
{
|
||||
payload.hitAttenuation = 1.0;
|
||||
if (!payload.isSkyRay)
|
||||
{
|
||||
payload.hitAttenuation = 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
payload.hitAttenuation = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
)glsl";
|
||||
|
|
|
@ -6,6 +6,7 @@ static const char* glsl_raygen = R"glsl(
|
|||
struct hitPayload
|
||||
{
|
||||
float hitAttenuation;
|
||||
bool isSkyRay;
|
||||
};
|
||||
|
||||
layout(location = 0) rayPayloadEXT hitPayload payload;
|
||||
|
@ -60,47 +61,76 @@ void main()
|
|||
emittance = imageLoad(outputs, texelPos);
|
||||
|
||||
const float minDistance = 0.01;
|
||||
float dist = distance(LightOrigin, origin);
|
||||
if (dist > minDistance && dist < LightRadius)
|
||||
const uint sample_count = 1024;
|
||||
|
||||
payload.isSkyRay = (PassType == 0.0);
|
||||
if (!payload.isSkyRay)
|
||||
{
|
||||
vec3 dir = normalize(LightOrigin - origin);
|
||||
|
||||
float distAttenuation = max(1.0 - (dist / LightRadius), 0.0);
|
||||
float angleAttenuation = max(dot(normal, dir), 0.0);
|
||||
float spotAttenuation = 1.0;
|
||||
if (LightOuterAngleCos > -1.0)
|
||||
float dist = distance(LightOrigin, origin);
|
||||
if (dist > minDistance && dist < LightRadius)
|
||||
{
|
||||
float cosDir = dot(dir, LightSpotDir);
|
||||
spotAttenuation = smoothstep(LightOuterAngleCos, LightInnerAngleCos, cosDir);
|
||||
spotAttenuation = max(spotAttenuation, 0.0);
|
||||
}
|
||||
vec3 dir = normalize(LightOrigin - origin);
|
||||
|
||||
float attenuation = distAttenuation * angleAttenuation * spotAttenuation;
|
||||
if (attenuation > 0.0)
|
||||
{
|
||||
const uint sample_count = 1024;
|
||||
float shadowAttenuation = 0.0;
|
||||
vec3 e0 = cross(normal, abs(normal.x) < abs(normal.y) ? vec3(1.0, 0.0, 0.0) : vec3(0.0, 1.0, 0.0));
|
||||
vec3 e1 = cross(normal, e0);
|
||||
e0 = cross(normal, e1);
|
||||
for (uint i = 0; i < sample_count; i++)
|
||||
float distAttenuation = max(1.0 - (dist / LightRadius), 0.0);
|
||||
float angleAttenuation = max(dot(normal, dir), 0.0);
|
||||
float spotAttenuation = 1.0;
|
||||
if (LightOuterAngleCos > -1.0)
|
||||
{
|
||||
vec2 offset = (Hammersley(i, sample_count) - 0.5) * SampleDistance;
|
||||
vec3 origin2 = origin + offset.x * e0 + offset.y * e1;
|
||||
|
||||
float dist2 = distance(LightOrigin, origin2);
|
||||
vec3 dir2 = normalize(LightOrigin - origin2);
|
||||
|
||||
traceRayEXT(acc, gl_RayFlagsOpaqueEXT, 0xff, 0, 0, 0, origin2, minDistance, dir2, dist2, 0);
|
||||
shadowAttenuation += payload.hitAttenuation;
|
||||
float cosDir = dot(dir, LightSpotDir);
|
||||
spotAttenuation = smoothstep(LightOuterAngleCos, LightInnerAngleCos, cosDir);
|
||||
spotAttenuation = max(spotAttenuation, 0.0);
|
||||
}
|
||||
shadowAttenuation *= 1.0 / float(sample_count);
|
||||
|
||||
attenuation *= shadowAttenuation;
|
||||
float attenuation = distAttenuation * angleAttenuation * spotAttenuation;
|
||||
if (attenuation > 0.0)
|
||||
{
|
||||
float shadowAttenuation = 0.0;
|
||||
vec3 e0 = cross(normal, abs(normal.x) < abs(normal.y) ? vec3(1.0, 0.0, 0.0) : vec3(0.0, 1.0, 0.0));
|
||||
vec3 e1 = cross(normal, e0);
|
||||
e0 = cross(normal, e1);
|
||||
for (uint i = 0; i < sample_count; i++)
|
||||
{
|
||||
vec2 offset = (Hammersley(i, sample_count) - 0.5) * SampleDistance;
|
||||
vec3 origin2 = origin + offset.x * e0 + offset.y * e1;
|
||||
|
||||
emittance.rgb += LightColor * (attenuation * LightIntensity);
|
||||
float dist2 = distance(LightOrigin, origin2);
|
||||
vec3 dir2 = normalize(LightOrigin - origin2);
|
||||
|
||||
traceRayEXT(acc, gl_RayFlagsOpaqueEXT, 0xff, 0, 0, 0, origin2, minDistance, dir2, dist2, 0);
|
||||
shadowAttenuation += payload.hitAttenuation;
|
||||
}
|
||||
shadowAttenuation *= 1.0 / float(sample_count);
|
||||
|
||||
attenuation *= shadowAttenuation;
|
||||
|
||||
emittance.rgb += LightColor * (attenuation * LightIntensity);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vec3 e0 = cross(normal, abs(normal.x) < abs(normal.y) ? vec3(1.0, 0.0, 0.0) : vec3(0.0, 1.0, 0.0));
|
||||
vec3 e1 = cross(normal, e0);
|
||||
e0 = cross(normal, e1);
|
||||
|
||||
origin += normal * 0.1;
|
||||
|
||||
float attenuation = 0.0;
|
||||
for (uint i = 0; i < sample_count; i++)
|
||||
{
|
||||
vec2 offset = (Hammersley(i, sample_count) - 0.5) * SampleDistance;
|
||||
vec3 origin2 = origin + offset.x * e0 + offset.y * e1;
|
||||
|
||||
float dist2 = 32768.0;
|
||||
vec3 dir2 = LightSpotDir;
|
||||
|
||||
traceRayEXT(acc, gl_RayFlagsOpaqueEXT, 0xff, 0, 0, 0, origin2, minDistance, dir2, dist2, 0);
|
||||
attenuation += payload.hitAttenuation;
|
||||
}
|
||||
attenuation *= 1.0 / float(sample_count);
|
||||
|
||||
emittance.rgb += LightColor * (attenuation * LightIntensity);
|
||||
}
|
||||
|
||||
emittance.w += 1.0;
|
||||
imageStore(outputs, texelPos, emittance);
|
||||
|
|
|
@ -191,7 +191,51 @@ void GPURaytracer::Raytrace(LevelMesh* level)
|
|||
barrier2.addImage(outputImage.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, 0, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT);
|
||||
barrier2.execute(cmdbuffer.get(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR);
|
||||
|
||||
bool firstPass = true;
|
||||
// Sunlight
|
||||
{
|
||||
Uniforms uniforms = {};
|
||||
uniforms.LightOrigin = Vec3(0.0f, 0.0f, 0.0f);
|
||||
uniforms.LightRadius = -1.0f;
|
||||
uniforms.LightIntensity = 1.0f;
|
||||
uniforms.LightInnerAngleCos = -1.0f;
|
||||
uniforms.LightOuterAngleCos = -1.0f;
|
||||
uniforms.LightSpotDir = mesh->map->GetSunDirection();
|
||||
uniforms.LightColor = mesh->map->GetSunColor();
|
||||
uniforms.PassType = 0.0f;
|
||||
uniforms.SampleDistance = (float)mesh->samples;
|
||||
|
||||
auto data = uniformTransferBuffer->Map(0, sizeof(Uniforms));
|
||||
memcpy(data, &uniforms, sizeof(Uniforms));
|
||||
uniformTransferBuffer->Unmap();
|
||||
|
||||
cmdbuffer->copyBuffer(uniformTransferBuffer.get(), uniformBuffer.get());
|
||||
|
||||
PipelineBarrier barrier3;
|
||||
barrier3.addBuffer(uniformBuffer.get(), VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT);
|
||||
barrier3.execute(cmdbuffer.get(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR);
|
||||
|
||||
cmdbuffer->bindPipeline(VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, pipeline.get());
|
||||
cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, pipelineLayout.get(), 0, descriptorSet.get());
|
||||
cmdbuffer->traceRays(&rgenRegion, &missRegion, &hitRegion, &callRegion, rayTraceImageSize, rayTraceImageSize, 1);
|
||||
|
||||
cmdbuffer->end();
|
||||
|
||||
auto submitFence = std::make_unique<VulkanFence>(device.get());
|
||||
|
||||
QueueSubmit submit;
|
||||
submit.addCommandBuffer(cmdbuffer.get());
|
||||
submit.execute(device.get(), device->graphicsQueue, submitFence.get());
|
||||
|
||||
vkWaitForFences(device->device, 1, &submitFence->fence, VK_TRUE, std::numeric_limits<uint64_t>::max());
|
||||
vkResetFences(device->device, 1, &submitFence->fence);
|
||||
|
||||
printf(".");
|
||||
|
||||
cmdbuffer.reset();
|
||||
cmdbuffer = cmdpool->createBuffer();
|
||||
cmdbuffer->begin();
|
||||
}
|
||||
|
||||
for (ThingLight& light : mesh->map->ThingLights)
|
||||
{
|
||||
Uniforms uniforms = {};
|
||||
|
@ -202,9 +246,8 @@ void GPURaytracer::Raytrace(LevelMesh* level)
|
|||
uniforms.LightOuterAngleCos = light.outerAngleCos;
|
||||
uniforms.LightSpotDir = light.SpotDir();
|
||||
uniforms.LightColor = light.rgb;
|
||||
uniforms.PassType = firstPass ? 0.0f : 1.0f;
|
||||
uniforms.PassType = 1.0f;
|
||||
uniforms.SampleDistance = (float)mesh->samples;
|
||||
firstPass = false;
|
||||
|
||||
auto data = uniformTransferBuffer->Map(0, sizeof(Uniforms));
|
||||
memcpy(data, &uniforms, sizeof(Uniforms));
|
||||
|
@ -518,11 +561,64 @@ Vec3 GPURaytracer::GetSurfaceEmittance(Surface* surface, float distance)
|
|||
|
||||
void GPURaytracer::CreateVertexAndIndexBuffers()
|
||||
{
|
||||
std::vector<SurfaceInfo> surfaces;
|
||||
surfaces.reserve(mesh->surfaces.size());
|
||||
for (const auto& surface : mesh->surfaces)
|
||||
{
|
||||
SurfaceLightDef* def = nullptr;
|
||||
if (surface->type >= ST_MIDDLESIDE && surface->type <= ST_LOWERSIDE)
|
||||
{
|
||||
int lightdefidx = mesh->map->Sides[surface->typeIndex].lightdef;
|
||||
if (lightdefidx != -1)
|
||||
{
|
||||
def = &mesh->map->SurfaceLights[lightdefidx];
|
||||
}
|
||||
}
|
||||
else if (surface->type == ST_FLOOR || surface->type == ST_CEILING)
|
||||
{
|
||||
MapSubsectorEx* sub = &mesh->map->GLSubsectors[surface->typeIndex];
|
||||
IntSector* sector = mesh->map->GetSectorFromSubSector(sub);
|
||||
|
||||
if (sector && surface->numVerts > 0)
|
||||
{
|
||||
if (sector->floorlightdef != -1 && surface->type == ST_FLOOR)
|
||||
{
|
||||
def = &mesh->map->SurfaceLights[sector->floorlightdef];
|
||||
}
|
||||
else if (sector->ceilinglightdef != -1 && surface->type == ST_CEILING)
|
||||
{
|
||||
def = &mesh->map->SurfaceLights[sector->ceilinglightdef];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SurfaceInfo info;
|
||||
info.Sky = surface->bSky ? 1.0f : 0.0f;
|
||||
info.Normal = surface->plane.Normal();
|
||||
if (def)
|
||||
{
|
||||
info.EmissiveDistance = def->distance;
|
||||
info.EmissiveIntensity = def->intensity;
|
||||
info.EmissiveColor = def->rgb;
|
||||
}
|
||||
else
|
||||
{
|
||||
info.EmissiveDistance = 0.0f;
|
||||
info.EmissiveIntensity = 0.0f;
|
||||
info.EmissiveColor = Vec3(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
surfaces.push_back(info);
|
||||
}
|
||||
|
||||
size_t vertexbuffersize = (size_t)mesh->MeshVertices.Size() * sizeof(Vec3);
|
||||
size_t indexbuffersize = (size_t)mesh->MeshElements.Size() * sizeof(uint32_t);
|
||||
size_t transferbuffersize = vertexbuffersize + indexbuffersize;
|
||||
size_t surfaceindexbuffersize = (size_t)mesh->MeshSurfaces.Size() * sizeof(uint32_t);
|
||||
size_t surfacebuffersize = (size_t)surfaces.size() * sizeof(SurfaceInfo);
|
||||
size_t transferbuffersize = vertexbuffersize + indexbuffersize + surfaceindexbuffersize + surfacebuffersize;
|
||||
size_t vertexoffset = 0;
|
||||
size_t indexoffset = vertexoffset + vertexbuffersize;
|
||||
size_t surfaceindexoffset = indexoffset + indexbuffersize;
|
||||
size_t surfaceoffset = surfaceindexoffset + surfaceindexbuffersize;
|
||||
|
||||
BufferBuilder vbuilder;
|
||||
vbuilder.setUsage(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
|
||||
|
@ -536,6 +632,18 @@ void GPURaytracer::CreateVertexAndIndexBuffers()
|
|||
indexBuffer = ibuilder.create(device.get());
|
||||
indexBuffer->SetDebugName("indexBuffer");
|
||||
|
||||
BufferBuilder sibuilder;
|
||||
sibuilder.setUsage(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
|
||||
sibuilder.setSize(surfaceindexbuffersize);
|
||||
surfaceIndexBuffer = sibuilder.create(device.get());
|
||||
surfaceIndexBuffer->SetDebugName("surfaceIndexBuffer");
|
||||
|
||||
BufferBuilder sbuilder;
|
||||
sbuilder.setUsage(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
|
||||
sbuilder.setSize(surfacebuffersize);
|
||||
surfaceBuffer = sbuilder.create(device.get());
|
||||
surfaceBuffer->SetDebugName("surfaceBuffer");
|
||||
|
||||
BufferBuilder tbuilder;
|
||||
tbuilder.setUsage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY);
|
||||
tbuilder.setSize(transferbuffersize);
|
||||
|
@ -544,10 +652,14 @@ void GPURaytracer::CreateVertexAndIndexBuffers()
|
|||
uint8_t* data = (uint8_t*)transferBuffer->Map(0, transferbuffersize);
|
||||
memcpy(data + vertexoffset, mesh->MeshVertices.Data(), vertexbuffersize);
|
||||
memcpy(data + indexoffset, mesh->MeshElements.Data(), indexbuffersize);
|
||||
memcpy(data + surfaceindexoffset, mesh->MeshSurfaces.Data(), surfaceindexbuffersize);
|
||||
memcpy(data + surfaceoffset, surfaces.data(), surfacebuffersize);
|
||||
transferBuffer->Unmap();
|
||||
|
||||
cmdbuffer->copyBuffer(transferBuffer.get(), vertexBuffer.get(), vertexoffset);
|
||||
cmdbuffer->copyBuffer(transferBuffer.get(), indexBuffer.get(), indexoffset);
|
||||
cmdbuffer->copyBuffer(transferBuffer.get(), surfaceIndexBuffer.get(), surfaceindexoffset);
|
||||
cmdbuffer->copyBuffer(transferBuffer.get(), surfaceBuffer.get(), surfaceoffset);
|
||||
|
||||
VkMemoryBarrier barrier = { VK_STRUCTURE_TYPE_MEMORY_BARRIER };
|
||||
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
|
@ -725,20 +837,41 @@ void GPURaytracer::CreateTopLevelAccelerationStructure()
|
|||
|
||||
void GPURaytracer::CreateShaders()
|
||||
{
|
||||
ShaderBuilder builder1;
|
||||
builder1.setRayGenShader(glsl_raygen);
|
||||
shaderRayGen = builder1.create(device.get());
|
||||
shaderRayGen->SetDebugName("shaderRayGen");
|
||||
try
|
||||
{
|
||||
ShaderBuilder builder;
|
||||
builder.setRayGenShader(glsl_raygen);
|
||||
shaderRayGen = builder.create(device.get());
|
||||
shaderRayGen->SetDebugName("shaderRayGen");
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
throw std::runtime_error(std::string("Could not compile raygen shader: ") + e.what());
|
||||
}
|
||||
|
||||
ShaderBuilder builder2;
|
||||
builder2.setMissShader(glsl_miss);
|
||||
shaderMiss = builder2.create(device.get());
|
||||
shaderMiss->SetDebugName("shaderMiss");
|
||||
try
|
||||
{
|
||||
ShaderBuilder builder;
|
||||
builder.setMissShader(glsl_miss);
|
||||
shaderMiss = builder.create(device.get());
|
||||
shaderMiss->SetDebugName("shaderMiss");
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
throw std::runtime_error(std::string("Could not compile miss shader: ") + e.what());
|
||||
}
|
||||
|
||||
ShaderBuilder builder;
|
||||
builder.setClosestHitShader(glsl_closesthit);
|
||||
shaderClosestHit = builder.create(device.get());
|
||||
shaderClosestHit->SetDebugName("shaderClosestHit");
|
||||
try
|
||||
{
|
||||
ShaderBuilder builder;
|
||||
builder.setClosestHitShader(glsl_closesthit);
|
||||
shaderClosestHit = builder.create(device.get());
|
||||
shaderClosestHit->SetDebugName("shaderClosestHit");
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
throw std::runtime_error(std::string("Could not compile closest hit shader: ") + e.what());
|
||||
}
|
||||
}
|
||||
|
||||
void GPURaytracer::CreatePipeline()
|
||||
|
@ -749,6 +882,8 @@ void GPURaytracer::CreatePipeline()
|
|||
setbuilder.addBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_RAYGEN_BIT_KHR);
|
||||
setbuilder.addBinding(3, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_RAYGEN_BIT_KHR);
|
||||
setbuilder.addBinding(4, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_RAYGEN_BIT_KHR);
|
||||
setbuilder.addBinding(5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
||||
setbuilder.addBinding(6, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
|
||||
descriptorSetLayout = setbuilder.create(device.get());
|
||||
descriptorSetLayout->SetDebugName("descriptorSetLayout");
|
||||
|
||||
|
@ -895,6 +1030,7 @@ void GPURaytracer::CreateDescriptorSet()
|
|||
poolbuilder.addPoolSize(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1);
|
||||
poolbuilder.addPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 3);
|
||||
poolbuilder.addPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1);
|
||||
poolbuilder.addPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2);
|
||||
poolbuilder.setMaxSets(1);
|
||||
descriptorPool = poolbuilder.create(device.get());
|
||||
descriptorPool->SetDebugName("descriptorPool");
|
||||
|
@ -908,5 +1044,7 @@ void GPURaytracer::CreateDescriptorSet()
|
|||
write.addStorageImage(descriptorSet.get(), 2, normalsImageView.get(), VK_IMAGE_LAYOUT_GENERAL);
|
||||
write.addStorageImage(descriptorSet.get(), 3, outputImageView.get(), VK_IMAGE_LAYOUT_GENERAL);
|
||||
write.addBuffer(descriptorSet.get(), 4, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, uniformBuffer.get());
|
||||
write.addBuffer(descriptorSet.get(), 5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, surfaceIndexBuffer.get());
|
||||
write.addBuffer(descriptorSet.get(), 6, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, surfaceBuffer.get());
|
||||
write.updateSets(device.get());
|
||||
}
|
||||
|
|
|
@ -20,6 +20,16 @@ struct Uniforms
|
|||
float Padding;
|
||||
};
|
||||
|
||||
struct SurfaceInfo
|
||||
{
|
||||
Vec3 Normal;
|
||||
float EmissiveDistance;
|
||||
Vec3 EmissiveColor;
|
||||
float EmissiveIntensity;
|
||||
float Sky;
|
||||
float Padding0, Padding1, Padding2;
|
||||
};
|
||||
|
||||
class GPURaytracer
|
||||
{
|
||||
public:
|
||||
|
@ -56,6 +66,8 @@ private:
|
|||
std::unique_ptr<VulkanBuffer> vertexBuffer;
|
||||
std::unique_ptr<VulkanBuffer> indexBuffer;
|
||||
std::unique_ptr<VulkanBuffer> transferBuffer;
|
||||
std::unique_ptr<VulkanBuffer> surfaceIndexBuffer;
|
||||
std::unique_ptr<VulkanBuffer> surfaceBuffer;
|
||||
|
||||
std::unique_ptr<VulkanBuffer> blScratchBuffer;
|
||||
std::unique_ptr<VulkanBuffer> blAccelStructBuffer;
|
||||
|
|
Loading…
Reference in a new issue