rtx: add dynamic lights

no shadows and such stuff yet
This commit is contained in:
Ivan 'provod' Avdeev 2021-03-10 09:38:06 -08:00
parent 77288a205b
commit 6d1dac453e
4 changed files with 106 additions and 42 deletions

View File

@ -2,18 +2,16 @@
#extension GL_EXT_ray_query : require
#extension GL_EXT_shader_16bit_storage : require
// FIXME shader specialization
layout(local_size_x = 16, local_size_y = 8, local_size_z = 1) in;
// struct Light {
// vec4 pos_r;
// vec4 color;
// };
layout(binding = 0, set = 0, rgba8) uniform image2D image;
layout(binding = 1, set = 0) uniform accelerationStructureEXT tlas;
layout(binding = 2, set = 0) uniform UBO {
mat4 inv_proj, inv_view;
// TODO combine
//int num_lights;
//Light lights[];
} ubo;
@ -34,6 +32,20 @@ layout(std430, binding = 3, set = 0) readonly buffer Kusochki { Kusok kusochki[]
layout(std430, binding = 4, set = 0) readonly buffer Indices { uint16_t indices[]; };
layout(std430, binding = 5, set = 0) readonly buffer Vertices { Vertex vertices[]; };
// TODO #include, use from here and regular shader
struct Light {
vec4 pos_r;
vec4 color;
};
// FIXME what should this be?
const float dlight_attenuation_const = 5000.;
// TODO specialize in vk_rtx.c
layout (constant_id = 1) const uint max_dlights = 32;
layout(set=0,binding=6) uniform UBODLights {
uint num_lights;
Light lights[max_dlights];
};
void main() {
vec2 res = imageSize(image);
vec2 uv = (gl_GlobalInvocationID.xy + .5) / res * 2. - 1.;
@ -53,7 +65,7 @@ void main() {
if (rayQueryGetIntersectionTypeEXT(rayQuery, true) != gl_RayQueryCommittedIntersectionTriangleEXT) {
C = vec3(1., 0., 1.);
} else {
//vec3 pos = O+D*l;
vec3 pos = O+D*l;
//C = fract(pos/100.);
//const int instance_index = rayQueryGetIntersectionInstanceIdEXT(rayQuery, true);
@ -68,18 +80,29 @@ void main() {
/* C.r = float(prim_index & 7) / 7.f; */
/* C.g = float((prim_index >> 3) & 7) / 7.f; */
/* C.b = float((prim_index >> 6) & 7) / 7.f; */
const uint first_index_offset = kusochki[instance_index].index_offset + prim_index * 3;
const uint first_vertex_index = uint(indices[first_index_offset]) + kusochki[instance_index].vertex_offset;
const vec3 normal = vertices[first_vertex_index].normal;
//const vec3 normal = vertices[kusochki[instance_index].vertex_offset].normal;
//const vec3 normal = vertices[prim_index * 3].normal;
C = normal * .5 + .5;
//C = normal * .5 + .5;
/* C.r = float(first_vertex_index & 31) / 31.f; */
/* C.g = float((first_vertex_index >> 5) & 31) / 31.f; */
/* C.b = float((first_vertex_index >> 10) & 31) / 31.f; */
const vec3 baseColor = vec3(1.);
for (uint i = 0; i < num_lights; ++i) {
const vec4 light_pos_r = lights[i].pos_r;
const vec3 light_color = lights[i].color.rgb;
const vec3 light_dir = light_pos_r.xyz - pos;
const float d2 = dot(light_dir, light_dir);
const float r2 = light_pos_r.w * light_pos_r.w;
const float attenuation = dlight_attenuation_const / (d2 + r2 * .5);
C += baseColor.rgb * light_color * max(0., dot(normalize(light_dir), normal)) * attenuation;
}
}
imageStore(image, ivec2(gl_GlobalInvocationID.xy), vec4(C, 1.));

View File

@ -575,6 +575,41 @@ void VK_RenderScheduleDraw( const render_draw_t *draw )
draw_command->ubo_offset = g_render_state.current_ubo_offset;
}
// Return offset of dlights data into UBO buffer
static uint32_t writeDlightsToUBO()
{
vk_ubo_lights_t* ubo_lights;
const uint32_t ubo_lights_offset = allocUniform(sizeof(*ubo_lights), 4);
if (ubo_lights_offset == UINT32_MAX) {
gEngine.Con_Printf(S_ERROR "Cannot allocate UBO for DLights\n");
return UINT32_MAX;
}
ubo_lights = (vk_ubo_lights_t*)((byte*)(g_render.uniform_buffer.mapped) + ubo_lights_offset);
// TODO this should not be here (where? vk_scene?)
ubo_lights->num_lights = 0;
for (int i = 0; i < MAX_DLIGHTS; ++i) {
const dlight_t *l = gEngine.GetDynamicLight(i);
if( !l || l->die < gpGlobals->time || !l->radius )
continue;
Vector4Set(
ubo_lights->light[ubo_lights->num_lights].color,
l->color.r / 255.f,
l->color.g / 255.f,
l->color.b / 255.f,
1.f);
Vector4Set(
ubo_lights->light[ubo_lights->num_lights].pos_r,
l->origin[0],
l->origin[1],
l->origin[2],
l->radius);
ubo_lights->num_lights++;
}
return ubo_lights_offset;
}
void VK_RenderEnd( VkCommandBuffer cmdbuf )
{
// TODO we can sort collected draw commands for more efficient and correct rendering
@ -585,6 +620,10 @@ void VK_RenderEnd( VkCommandBuffer cmdbuf )
int lightmap = -1;
uint32_t ubo_offset = -1;
const uint32_t dlights_ubo_offset = writeDlightsToUBO();
if (dlights_ubo_offset == UINT32_MAX)
return;
ASSERT(!vk_core.rtx);
{
@ -593,38 +632,7 @@ void VK_RenderEnd( VkCommandBuffer cmdbuf )
vkCmdBindIndexBuffer(cmdbuf, g_render.buffer.buffer, 0, VK_INDEX_TYPE_UINT16);
}
{
vk_ubo_lights_t* ubo_lights;
const uint32_t ubo_lights_offset = allocUniform(sizeof(*ubo_lights), 4);
if (ubo_lights_offset == UINT32_MAX) {
gEngine.Con_Printf(S_ERROR "Cannot allocate UBO for DLights\n");
return;
}
ubo_lights = (vk_ubo_lights_t*)((byte*)(g_render.uniform_buffer.mapped) + ubo_lights_offset);
// TODO this should not be here (where? vk_scene?)
ubo_lights->num_lights = 0;
for (int i = 0; i < MAX_DLIGHTS; ++i) {
const dlight_t *l = gEngine.GetDynamicLight(i);
if( !l || l->die < gpGlobals->time || !l->radius )
continue;
Vector4Set(
ubo_lights->light[ubo_lights->num_lights].color,
l->color.r / 255.f,
l->color.g / 255.f,
l->color.b / 255.f,
1.f);
Vector4Set(
ubo_lights->light[ubo_lights->num_lights].pos_r,
l->origin[0],
l->origin[1],
l->origin[2],
l->radius);
ubo_lights->num_lights++;
}
vkCmdBindDescriptorSets(vk_core.cb, VK_PIPELINE_BIND_POINT_GRAPHICS, g_render.pipeline_layout, 3, 1, vk_desc.ubo_sets + 1, 1, &ubo_lights_offset);
}
vkCmdBindDescriptorSets(vk_core.cb, VK_PIPELINE_BIND_POINT_GRAPHICS, g_render.pipeline_layout, 3, 1, vk_desc.ubo_sets + 1, 1, &dlights_ubo_offset);
for (int i = 0; i < g_render_state.num_draw_commands; ++i) {
const draw_command_t *const draw = g_render_state.draw_commands + i;
@ -684,6 +692,10 @@ void VK_RenderDebugLabelEnd( void )
void VK_RenderEndRTX( VkCommandBuffer cmdbuf, VkImageView img_dst_view, VkImage img_dst, uint32_t w, uint32_t h )
{
const uint32_t dlights_ubo_offset = writeDlightsToUBO();
if (dlights_ubo_offset == UINT32_MAX)
return;
ASSERT(vk_core.rtx);
VK_RaySceneBegin();
for (int i = 0; i < g_render_state.num_draw_commands; ++i) {
@ -725,6 +737,12 @@ void VK_RenderEndRTX( VkCommandBuffer cmdbuf, VkImageView img_dst_view, VkImage
.size = sizeof(float) * 16 * 2,
},
.dlights = {
.buffer = g_render.uniform_buffer.buffer,
.offset = dlights_ubo_offset,
.size = sizeof(vk_ubo_lights_t),
},
.geometry_data = {
.buffer = g_render.buffer.buffer,
.size = g_render.buffer_free_offset,

View File

@ -317,6 +317,11 @@ void VK_RaySceneEnd(const vk_ray_scene_render_args_t* args)
.accelerationStructureCount = 1,
.pAccelerationStructures = &g_rtx.tlas,
};
const VkDescriptorBufferInfo dbi_dlights = {
.buffer = args->dlights.buffer,
.offset = args->dlights.offset,
.range = args->dlights.size,
};
const VkWriteDescriptorSet wds[] = {
{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
@ -372,6 +377,15 @@ void VK_RaySceneEnd(const vk_ray_scene_render_args_t* args)
.dstArrayElement = 0,
.pBufferInfo = &dbi_vertices,
},
{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.dstSet = g_rtx.desc_set,
.dstBinding = 6,
.dstArrayElement = 0,
.pBufferInfo = &dbi_dlights,
},
};
vkUpdateDescriptorSets(vk_core.device, ARRAYSIZE(wds), wds, 0, NULL);
@ -444,6 +458,11 @@ static void createLayouts( void ) {
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
.descriptorCount = 1,
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
}, {
.binding = 6,
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.descriptorCount = 1,
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
},
};
@ -470,7 +489,7 @@ static void createLayouts( void ) {
VkDescriptorPoolSize pools[] = {
{.type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, .descriptorCount = 1},
{.type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, .descriptorCount = 3},
{.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, .descriptorCount = 1},
{.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, .descriptorCount = 2},
{.type = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, .descriptorCount = 1},
};

View File

@ -35,7 +35,11 @@ typedef struct {
uint32_t size;
} ubo;
// TODO dlights
struct {
VkBuffer buffer;
uint32_t offset;
uint32_t size;
} dlights;
// Buffer holding vertex and index data
struct {