mirror of
https://github.com/w23/xash3d-fwgs
synced 2025-01-18 23:00:01 +01:00
rt: stub better emissive surfaces representation path
Light polygons that are: - self-sufficient (no kusochki indirection needed). - pre-transformed - contain enough metadata (area, center, normal) for quick sampling - are polygons with up to 7 vertices and not triangles (easier sampling) Also move rad file reading to before brush model loading, as it now requires lighting data.
This commit is contained in:
parent
e4ade833e8
commit
b31462fe18
@ -438,6 +438,63 @@ static model_sizes_t computeSizes( const model_t *mod ) {
|
||||
return sizes;
|
||||
}
|
||||
|
||||
static void loadEmissiveSurface(const model_t *mod, const int surface_index, const msurface_t *surf, const vec3_t emissive) {
|
||||
rt_light_polygon_t lpoly;
|
||||
lpoly.num_vertices = Q_min(7, surf->numedges);
|
||||
|
||||
if (surf->numedges > 7)
|
||||
gEngine.Con_Printf(S_WARN "emissive surface %d has %d vertices; clipping to 7\n", surface_index, surf->numedges);
|
||||
|
||||
VectorCopy(emissive, lpoly.emissive);
|
||||
|
||||
VectorSet(lpoly.center, 0, 0, 0);
|
||||
VectorSet(lpoly.normal, 0, 0, 0);
|
||||
|
||||
for (int i = 0; i < lpoly.num_vertices; ++i) {
|
||||
const int iedge = mod->surfedges[surf->firstedge + i];
|
||||
const medge_t *edge = mod->edges + (iedge >= 0 ? iedge : -iedge);
|
||||
const mvertex_t *vertex = mod->vertexes + (iedge >= 0 ? edge->v[0] : edge->v[1]);
|
||||
VectorCopy(vertex->position, lpoly.vertices[i]);
|
||||
VectorAdd(vertex->position, lpoly.center, lpoly.center);
|
||||
|
||||
if (i > 1) {
|
||||
vec3_t e[2], normal;
|
||||
VectorSubtract(lpoly.vertices[i-1], lpoly.vertices[i-2], e[0]);
|
||||
VectorSubtract(lpoly.vertices[i-0], lpoly.vertices[i-2], e[1]);
|
||||
CrossProduct(e[0], e[1], normal);
|
||||
VectorAdd(normal, lpoly.normal, lpoly.normal);
|
||||
}
|
||||
}
|
||||
|
||||
VectorM(1.f / lpoly.num_vertices, lpoly.center, lpoly.center);
|
||||
|
||||
lpoly.area = VectorLength(lpoly.normal);
|
||||
|
||||
VectorNormalize(lpoly.normal);
|
||||
{
|
||||
const float dot = DotProduct(lpoly.normal, surf->plane->normal);
|
||||
if (fabs(dot) < (1.f - 1e-5f)) {
|
||||
gEngine.Con_Reportf(S_WARN "surf=%d normal=(%f, %f, %f) computed=(%f, %f, %f) dot=%f dir=%d\n",
|
||||
surf->plane->normal[0],
|
||||
surf->plane->normal[1],
|
||||
surf->plane->normal[2],
|
||||
lpoly.normal[0],
|
||||
lpoly.normal[1],
|
||||
lpoly.normal[2],
|
||||
dot,
|
||||
!!FBitSet( surf->flags, SURF_PLANEBACK )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if( FBitSet( surf->flags, SURF_PLANEBACK ))
|
||||
VectorNegate( surf->plane->normal, lpoly.normal );
|
||||
else
|
||||
VectorCopy( surf->plane->normal, lpoly.normal );
|
||||
|
||||
RT_LightAddPolygon(&lpoly);
|
||||
}
|
||||
|
||||
static qboolean loadBrushSurfaces( model_sizes_t sizes, const model_t *mod ) {
|
||||
vk_brush_model_t *bmodel = mod->cache.data;
|
||||
uint32_t vertex_offset = 0;
|
||||
@ -460,6 +517,7 @@ static qboolean loadBrushSurfaces( model_sizes_t sizes, const model_t *mod ) {
|
||||
index_offset = index_buffer.buffer.unit.offset;
|
||||
|
||||
// Load sorted by gl_texturenum
|
||||
// TODO this does not make that much sense in vulkan (can sort later)
|
||||
for (int t = 0; t <= sizes.max_texture_id; ++t)
|
||||
{
|
||||
for( int i = 0; i < mod->nummodelsurfaces; ++i)
|
||||
@ -480,6 +538,15 @@ static qboolean loadBrushSurfaces( model_sizes_t sizes, const model_t *mod ) {
|
||||
if (t != tex_id)
|
||||
continue;
|
||||
|
||||
{
|
||||
vec3_t emissive;
|
||||
if (psurf && (psurf->flags & Patch_Surface_Emissive)) {
|
||||
loadEmissiveSurface(mod, surface_index, surf, psurf->emissive);
|
||||
} else if (RT_GetEmissiveForTexture(emissive, tex_id)) {
|
||||
loadEmissiveSurface(mod, surface_index, surf, emissive);
|
||||
}
|
||||
}
|
||||
|
||||
++num_geometries;
|
||||
|
||||
//gEngine.Con_Reportf( "surface %d: numverts=%d numedges=%d\n", i, surf->polys ? surf->polys->numverts : -1, surf->numedges );
|
||||
|
@ -489,6 +489,20 @@ void VK_LightsNewMap( void ) {
|
||||
clusterBitMapInit();
|
||||
|
||||
prepareSurfacesLeafVisibilityCache();
|
||||
|
||||
// Load RAD data based on map name
|
||||
memset(g_lights.map.emissive_textures, 0, sizeof(g_lights.map.emissive_textures));
|
||||
loadRadData( map, "maps/lights.rad" );
|
||||
|
||||
{
|
||||
int name_len = Q_strlen(map->name);
|
||||
|
||||
// Strip ".bsp" suffix
|
||||
if (name_len > 4 && 0 == Q_stricmp(map->name + name_len - 4, ".bsp"))
|
||||
name_len -= 4;
|
||||
|
||||
loadRadData( map, "%.*s.rad", name_len, map->name );
|
||||
}
|
||||
}
|
||||
|
||||
void VK_LightsFrameInit( void ) {
|
||||
@ -1019,20 +1033,6 @@ void VK_LightsLoadMapStaticLights( void ) {
|
||||
|
||||
processStaticPointLights();
|
||||
|
||||
// Load RAD data based on map name
|
||||
memset(g_lights.map.emissive_textures, 0, sizeof(g_lights.map.emissive_textures));
|
||||
loadRadData( map, "maps/lights.rad" );
|
||||
|
||||
{
|
||||
int name_len = Q_strlen(map->name);
|
||||
|
||||
// Strip ".bsp" suffix
|
||||
if (name_len > 4 && 0 == Q_stricmp(map->name + name_len - 4, ".bsp"))
|
||||
name_len -= 4;
|
||||
|
||||
loadRadData( map, "%.*s.rad", name_len, map->name );
|
||||
}
|
||||
|
||||
// Load static map model
|
||||
{
|
||||
matrix3x4 xform;
|
||||
@ -1060,7 +1060,7 @@ void VK_LightsLoadMapStaticLights( void ) {
|
||||
}
|
||||
}
|
||||
|
||||
void XVK_GetEmissiveForTexture( vec3_t out, int texture_id ) {
|
||||
qboolean RT_GetEmissiveForTexture( vec3_t out, int texture_id ) {
|
||||
ASSERT(texture_id >= 0);
|
||||
ASSERT(texture_id < MAX_TEXTURES);
|
||||
|
||||
@ -1068,8 +1068,9 @@ void XVK_GetEmissiveForTexture( vec3_t out, int texture_id ) {
|
||||
vk_emissive_texture_t *const etex = g_lights.map.emissive_textures + texture_id;
|
||||
if (etex->set) {
|
||||
VectorCopy(etex->emissive, out);
|
||||
return true;
|
||||
} else {
|
||||
VectorSet(out, 0, 0, 0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1158,3 +1159,18 @@ void VK_LightsFrameFinalize( void ) {
|
||||
debug_dump_lights.enabled = false;
|
||||
APROF_SCOPE_END(finalize);
|
||||
}
|
||||
|
||||
int RT_LightAddPolygon(const rt_light_polygon_t *lpoly) {
|
||||
gEngine.Con_Reportf("RT_LightAddPolygon center=(%f, %f, %f) normal=(%f, %f, %f) area=%f num_vertices=%d\n",
|
||||
lpoly->center[0],
|
||||
lpoly->center[1],
|
||||
lpoly->center[2],
|
||||
lpoly->normal[0],
|
||||
lpoly->normal[1],
|
||||
lpoly->normal[2],
|
||||
lpoly->area,
|
||||
lpoly->num_vertices
|
||||
);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
@ -30,6 +30,16 @@ typedef struct {
|
||||
matrix3x4 transform;
|
||||
} vk_emissive_surface_t;
|
||||
|
||||
typedef struct {
|
||||
vec3_t emissive;
|
||||
vec3_t normal;
|
||||
vec3_t center;
|
||||
float area;
|
||||
int num_vertices;
|
||||
vec3_t vertices[7];
|
||||
// uint32_t kusok_index;
|
||||
} rt_light_polygon_t;
|
||||
|
||||
enum {
|
||||
LightFlag_Environment = 0x1,
|
||||
};
|
||||
@ -57,9 +67,14 @@ typedef struct {
|
||||
vk_emissive_texture_t emissive_textures[MAX_TEXTURES];
|
||||
} map;
|
||||
|
||||
// FIXME deprecate
|
||||
int num_emissive_surfaces;
|
||||
vk_emissive_surface_t emissive_surfaces[MAX_SURFACE_LIGHTS];
|
||||
|
||||
int num_light_polygons;
|
||||
rt_light_polygon_t light_polygons[MAX_SURFACE_LIGHTS];
|
||||
|
||||
|
||||
int num_point_lights;
|
||||
vk_point_light_t point_lights[MAX_POINT_LIGHTS];
|
||||
|
||||
@ -87,7 +102,9 @@ void VK_LightsFrameInit( void );
|
||||
// separately in emissive surfaces.
|
||||
struct vk_render_geometry_s;
|
||||
void VK_LightsAddEmissiveSurface( const struct vk_render_geometry_s *geom, const matrix3x4 *transform_row, qboolean static_map );
|
||||
void XVK_GetEmissiveForTexture( vec3_t out, int texture_id );
|
||||
qboolean RT_GetEmissiveForTexture( vec3_t out, int texture_id );
|
||||
|
||||
int RT_LightAddPolygon(const rt_light_polygon_t *light);
|
||||
|
||||
void VK_LightsFrameFinalize( void );
|
||||
|
||||
|
@ -400,7 +400,7 @@ void VK_RayFrameAddModel( vk_ray_model_t *model, const vk_render_model_t *render
|
||||
if (geom->material == kXVkMaterialEmissive) {
|
||||
VectorCopy( geom->emissive, kusok->emissive );
|
||||
} else {
|
||||
XVK_GetEmissiveForTexture( kusok->emissive, geom->texture );
|
||||
RT_GetEmissiveForTexture( kusok->emissive, geom->texture );
|
||||
}
|
||||
|
||||
if (geom->material == kXVkMaterialConveyor) {
|
||||
|
@ -142,8 +142,6 @@ void R_NewMap( void )
|
||||
// This is to ensure that we have computed lightstyles properly
|
||||
VK_RunLightStyles();
|
||||
|
||||
VK_LightsNewMap();
|
||||
|
||||
XVK_SetupSky( gEngine.pfnGetMoveVars()->skyName );
|
||||
|
||||
if (vk_core.rtx)
|
||||
@ -167,9 +165,12 @@ void R_NewMap( void )
|
||||
XVK_ReloadMaterials();
|
||||
|
||||
// Parse patch data
|
||||
// Depens on loaded materials. Must preceed loading brush models.
|
||||
// Depends on loaded materials. Must preceed loading brush models.
|
||||
XVK_ParseMapPatches();
|
||||
|
||||
// Need parsed map entities, and also should happen before brush model loading
|
||||
VK_LightsNewMap();
|
||||
|
||||
// Load all models at once
|
||||
gEngine.Con_Reportf( "Num models: %d:\n", num_models );
|
||||
for( int i = 0; i < num_models; i++ )
|
||||
|
Loading…
x
Reference in New Issue
Block a user