rtx: add static light entities
This was an attempt to add map lighting w/o lightmaps. Unfortunately there are just not enought of them to explain all light in maps. We're missing something else. A lot of it.
This commit is contained in:
parent
a04b367a32
commit
379f6ee409
|
@ -3,9 +3,9 @@
|
|||
- [x] rtx: (debug/dev) shader reload
|
||||
- [x] rtx: make projection matrix independent render global/current/static state
|
||||
- [x] rtx: model matrices
|
||||
- [x] rtx: light entities -- still not enough to enlight maps :(
|
||||
|
||||
# Next
|
||||
- [ ] rtx: light entities
|
||||
- [ ] rtx: path tracing
|
||||
- [ ] rtx: textures
|
||||
- [ ] rtx: add fps
|
||||
|
@ -15,6 +15,8 @@
|
|||
- [ ] rtx: some studio models have glitchy geometry
|
||||
|
||||
# Planned
|
||||
- [ ] rtx: lower resolution framebuffer + upscale
|
||||
- [ ] dlight for flashlight seems to be broken
|
||||
- [ ] restore render debug labels
|
||||
- [ ] make 2nd commad buffer for resource upload
|
||||
- [ ] fix sprite blending; there are commented out functions that we really need (see tunnel before the helicopter in the very beginning)
|
||||
|
|
|
@ -102,7 +102,8 @@ void main() {
|
|||
const vec4 light_pos_r = lights[i].pos_r;
|
||||
const vec3 light_color = lights[i].color.rgb;
|
||||
|
||||
rand01_state += fract((light_pos_r.x + light_pos_r.y + light_pos_r.z)/100.);
|
||||
rand01_state = fract((pos.x + pos.y + pos.z)/100.) + uv.x + uv.y + fract(pc.t) + i;
|
||||
//rand01_state += fract(fract(pc.t) + i + (light_pos_r.x + light_pos_r.y + light_pos_r.z)/1000.);
|
||||
|
||||
// Find random point on a sphere
|
||||
// TODO proper BRDF importance sampling and correct random point distribution
|
||||
|
|
|
@ -55,6 +55,11 @@ static struct {
|
|||
vk_buffer_alloc_t allocs[MAX_ALLOCS];
|
||||
int allocs_free[MAX_ALLOCS];
|
||||
int num_free_allocs;
|
||||
|
||||
struct {
|
||||
vec3_t origin, color;
|
||||
} static_lights[32];
|
||||
int num_static_lights;
|
||||
} g_render;
|
||||
|
||||
static qboolean createPipelines( void )
|
||||
|
@ -405,7 +410,8 @@ void VK_RenderBufferClearFrame( void )
|
|||
|
||||
if (alloc->lifetime != LifetimeSingleFrame)
|
||||
continue;
|
||||
alloc->unit_size = 0;
|
||||
|
||||
alloc->unit_size = 0;
|
||||
g_render.allocs_free[g_render.num_free_allocs++] = i;
|
||||
ASSERT(g_render.num_free_allocs <= MAX_ALLOCS);
|
||||
}
|
||||
|
@ -416,6 +422,7 @@ void VK_RenderBufferClearMap( void )
|
|||
{
|
||||
g_render.buffer_free_offset = g_render.buffer_frame_begin_offset = 0;
|
||||
g_render.stat.align_holes_size = 0;
|
||||
g_render.num_static_lights = 0;
|
||||
resetAllocFreeList();
|
||||
}
|
||||
|
||||
|
@ -588,10 +595,21 @@ void VK_RenderScheduleDraw( const render_draw_t *draw )
|
|||
Matrix3x4_Copy(draw_command->transform, g_render_state.model);
|
||||
}
|
||||
|
||||
void VK_RenderAddStaticLight(vec3_t origin, vec3_t color)
|
||||
{
|
||||
if (g_render.num_static_lights == ARRAYSIZE(g_render.static_lights))
|
||||
return;
|
||||
|
||||
VectorCopy(origin, g_render.static_lights[g_render.num_static_lights].origin);
|
||||
VectorCopy(color, g_render.static_lights[g_render.num_static_lights].color);
|
||||
g_render.num_static_lights++;
|
||||
}
|
||||
|
||||
// Return offset of dlights data into UBO buffer
|
||||
static uint32_t writeDlightsToUBO()
|
||||
{
|
||||
vk_ubo_lights_t* ubo_lights;
|
||||
int num_lights = 0;
|
||||
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");
|
||||
|
@ -599,27 +617,45 @@ static uint32_t writeDlightsToUBO()
|
|||
}
|
||||
ubo_lights = (vk_ubo_lights_t*)((byte*)(g_render.uniform_buffer.mapped) + ubo_lights_offset);
|
||||
|
||||
for (int i = 0; i < g_render.num_static_lights && num_lights < ARRAYSIZE(ubo_lights->light); ++i) {
|
||||
Vector4Set(
|
||||
ubo_lights->light[num_lights].color,
|
||||
g_render.static_lights[i].color[0],
|
||||
g_render.static_lights[i].color[1],
|
||||
g_render.static_lights[i].color[2],
|
||||
1.f);
|
||||
Vector4Set(
|
||||
ubo_lights->light[num_lights].pos_r,
|
||||
g_render.static_lights[i].origin[0],
|
||||
g_render.static_lights[i].origin[1],
|
||||
g_render.static_lights[i].origin[2],
|
||||
50.f /* FIXME WHAT */);
|
||||
|
||||
num_lights++;
|
||||
}
|
||||
|
||||
// TODO this should not be here (where? vk_scene?)
|
||||
ubo_lights->num_lights = 0;
|
||||
for (int i = 0; i < MAX_DLIGHTS; ++i) {
|
||||
for (int i = 0; i < MAX_DLIGHTS && num_lights < ARRAYSIZE(ubo_lights->light); ++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,
|
||||
ubo_lights->light[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,
|
||||
ubo_lights->light[num_lights].pos_r,
|
||||
l->origin[0],
|
||||
l->origin[1],
|
||||
l->origin[2],
|
||||
l->radius);
|
||||
ubo_lights->num_lights++;
|
||||
|
||||
num_lights++;
|
||||
}
|
||||
|
||||
ubo_lights->num_lights = num_lights;
|
||||
return ubo_lights_offset;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,9 @@ void VK_RenderStateSetMatrixProjection(const matrix4x4 proj);
|
|||
void VK_RenderStateSetMatrixView(const matrix4x4 view);
|
||||
void VK_RenderStateSetMatrixModel(const matrix4x4 model);
|
||||
|
||||
// TODO: radius, intensity, style, PVS bits, etc..
|
||||
void VK_RenderAddStaticLight(vec3_t origin, vec3_t color);
|
||||
|
||||
// TODO is this a good place?
|
||||
typedef struct vk_vertex_s {
|
||||
// TODO padding needed for storage buffer reading, figure out how to fix in GLSL/SPV side
|
||||
|
|
|
@ -79,6 +79,96 @@ int R_FIXME_GetEntityRenderMode( cl_entity_t *ent )
|
|||
return ent->curstate.rendermode;
|
||||
}
|
||||
|
||||
static void parseLights( void ) {
|
||||
const model_t* const world = gEngine.pfnGetModelByIndex( 1 );
|
||||
char *pos;
|
||||
enum {
|
||||
Unknown,
|
||||
Light, LightSpot,
|
||||
} classname = Unknown;
|
||||
struct {
|
||||
vec3_t origin;
|
||||
vec3_t color;
|
||||
//float radius;
|
||||
int style;
|
||||
} light = {0};
|
||||
enum {
|
||||
HaveOrigin = 1,
|
||||
HaveColor = 2,
|
||||
//HaveStyle = 4,
|
||||
HaveClass = 8,
|
||||
HaveAll = HaveOrigin | HaveColor | HaveClass,
|
||||
};
|
||||
unsigned int have = 0;
|
||||
|
||||
ASSERT(world);
|
||||
|
||||
pos = world->entities;
|
||||
for (;;) {
|
||||
string key, value;
|
||||
|
||||
pos = gEngine.COM_ParseFile(pos, key);
|
||||
if (!pos)
|
||||
break;
|
||||
if (key[0] == '{') {
|
||||
classname = Unknown;
|
||||
have = 0;
|
||||
continue;
|
||||
}
|
||||
if (key[0] == '}') {
|
||||
// TODO handle entity
|
||||
if (have != HaveAll)
|
||||
continue;
|
||||
if (classname != Light && classname != LightSpot)
|
||||
continue;
|
||||
VK_RenderAddStaticLight(light.origin, light.color);
|
||||
continue;
|
||||
}
|
||||
|
||||
pos = gEngine.COM_ParseFile(pos, value);
|
||||
if (!pos)
|
||||
break;
|
||||
|
||||
if (Q_strcmp(key, "origin") == 0) {
|
||||
const int components = sscanf(value, "%f %f %f",
|
||||
&light.origin[0],
|
||||
&light.origin[1],
|
||||
&light.origin[2]);
|
||||
if (components == 3)
|
||||
have |= HaveOrigin;
|
||||
} else
|
||||
if (Q_strcmp(key, "_light") == 0) {
|
||||
float scale = 1.f / 255.f;
|
||||
const int components = sscanf(value, "%f %f %f %f",
|
||||
&light.color[0],
|
||||
&light.color[1],
|
||||
&light.color[2],
|
||||
&scale);
|
||||
if (components == 1) {
|
||||
light.color[2] = light.color[1] = light.color[0] = light.color[0] / 255.f;
|
||||
have |= HaveColor;
|
||||
} else if (components == 4) {
|
||||
scale /= 255.f * 255.f;
|
||||
light.color[0] *= scale;
|
||||
light.color[1] *= scale;
|
||||
light.color[2] *= scale;
|
||||
have |= HaveColor;
|
||||
} else if (components == 3) {
|
||||
light.color[0] *= scale;
|
||||
light.color[1] *= scale;
|
||||
light.color[2] *= scale;
|
||||
have |= HaveColor;
|
||||
}
|
||||
} else if (Q_strcmp(key, "classname") == 0) {
|
||||
if (Q_strcmp(value, "light") == 0)
|
||||
classname = Light;
|
||||
else if (Q_strcmp(value, "light_spot") == 0)
|
||||
classname = LightSpot;
|
||||
have |= HaveClass;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// tell the renderer what new map is started
|
||||
void R_NewMap( void )
|
||||
{
|
||||
|
@ -100,6 +190,8 @@ void R_NewMap( void )
|
|||
// This leads to ASSERTS firing when trying to draw erased buffers.
|
||||
VK_RenderBufferClearMap();
|
||||
|
||||
parseLights();
|
||||
|
||||
// Load all models at once
|
||||
gEngine.Con_Reportf( "Num models: %d:\n", num_models );
|
||||
for( int i = 0; i < num_models; i++ )
|
||||
|
|
Loading…
Reference in New Issue