rtx: add emissive color, remove emissive flag

This commit is contained in:
Ivan Avdeev 2021-08-26 10:41:35 -07:00 committed by Ivan Avdeev
parent 8d06058aa4
commit d8ebf5ac33
10 changed files with 61 additions and 48 deletions

View File

@ -97,6 +97,7 @@ void main() {
payload.hit_pos_t = vec4(hit_pos, gl_HitTEXT);
payload.albedo = base_color;
payload.normal = normal;
payload.emissive = kusochki[kusok_index].emissive * base_color; // TODO emissive should have a special texture
payload.roughness = kusochki[kusok_index].roughness;
payload.kusok_index = kusok_index;
payload.material_flags = kusochki[kusok_index].material_flags;

View File

@ -48,7 +48,6 @@ layout(set = 0, binding = 7) uniform UBODLights {
// TODO #include, use from here and regular shader
struct EmissiveKusok {
uint kusok_index;
vec3 emissive_color;
vec4 tx_row_x, tx_row_y, tx_row_z;
};
@ -133,7 +132,7 @@ vec3 computeLighting() {
const EmissiveKusok ek = emissive_kusochki.kusochki[index_into_emissive_kusochki];
const uint emissive_kusok_index = emissive_kusochki.kusochki[index_into_emissive_kusochki].kusok_index;
const Kusok ekusok = kusochki[emissive_kusok_index];
const vec3 emissive = emissive_kusochki.kusochki[index_into_emissive_kusochki].emissive_color.rgb;
const vec3 emissive = ekusok.emissive;
// TODO streamline matrices layouts
const mat4x3 emissive_transform = mat4x3(
@ -282,19 +281,12 @@ void main() {
break;
}
if ((payload.material_flags & kXVkMaterialFlagEmissive) != 0) {
C += kc * payload.albedo; // TODO albedo is not correct, should have emissive field
}
C += kc * payload.emissive;
if ((payload.material_flags & kXVkMaterialFlagDiffuse) != 0) {
if ((payload.material_flags & kXVkMaterialFlagLighting) != 0) {
C += kc * computeLighting();
}
// HACK
if ((payload.material_flags & kXVkMaterialFlagReflective) != 0) {
payload.roughness = 0.;
}
float through_probablity = .0;
if ((payload.material_flags & kXVkMaterialFlagRefractive) != 0) {
through_probablity = .5; // .... FIXME
@ -305,9 +297,11 @@ void main() {
}
if (through_probablity > 0. && rand01() < through_probablity) {
// Refraction/additive
origin = payload.hit_pos_t.xyz - normal_offset_fudge * payload.normal;
kc *= payload.albedo; // ... FIXME
} else {
// Diffuse/specular bounce
origin = payload.hit_pos_t.xyz + normal_offset_fudge * payload.normal;
// TODO this is totally not correct
@ -320,7 +314,6 @@ void main() {
direction *= dot(direction, payload.normal);
kc *= mix(vec3(1.), dot(direction, payload.normal) * payload.albedo, payload.roughness);
}
} // for all bounces
{

View File

@ -4,6 +4,7 @@ struct RayPayload {
vec4 hit_pos_t;
vec3 albedo;
vec3 normal;
vec3 emissive;
float roughness;
int kusok_index;
uint material_flags;

View File

@ -0,0 +1,6 @@
// Common definitions for both shaders and native code
#define kXVkMaterialFlagLighting (1<<0)
#define kXVkMaterialFlagAdditive (1<<1)
#define kXVkMaterialFlagRefractive (1<<2)
#define kXVkMaterialFlagAlphaTest (1<<3)

View File

@ -1,18 +1,9 @@
#extension GL_EXT_shader_16bit_storage : require
//#extension GL_EXT_shader_8bit_storage : require
// Shared with native
#define kXVkMaterialFlagEmissive (1<<0)
#define kXVkMaterialFlagDiffuse (1<<1) // means: compute lighting
#define kXVkMaterialFlagAdditive (1<<2)
#define kXVkMaterialFlagReflective (1<<3)
#define kXVkMaterialFlagRefractive (1<<4)
#define kXVkMaterialFlagAlphaTest (1<<5)
// TODO?
// DoLighting
// PassThrough ??? reflective vs refractive + additive
#include "ray_interop.h"
// TODO move to ray_interop
struct Kusok {
uint index_offset;
uint vertex_offset;
@ -22,6 +13,7 @@ struct Kusok {
uint texture;
float roughness;
uint material_flags;
vec3 emissive;
};
struct Vertex {

View File

@ -418,13 +418,13 @@ static void addSurfaceLightToCell( const int light_cell[3], int emissive_surface
++cluster->num_emissive_surfaces;
}
qboolean VK_LightsAddEmissiveSurface( const struct vk_render_geometry_s *geom, const matrix3x4 *transform_row ) {
const vk_emissive_surface_t *VK_LightsAddEmissiveSurface( const struct vk_render_geometry_s *geom, const matrix3x4 *transform_row ) {
const int texture_num = geom->texture; // Animated texture
if (!geom->surf)
return false; // TODO break? no surface means that model is not brush
return NULL; // TODO break? no surface means that model is not brush
if (geom->material != kXVkMaterialSky && geom->material != kXVkMaterialEmissive && !g_lights.map.emissive_textures[texture_num].set)
return false;
return NULL;
if (g_lights.num_emissive_surfaces < 256) {
// Insert into emissive surfaces
@ -484,11 +484,13 @@ qboolean VK_LightsAddEmissiveSurface( const struct vk_render_geometry_s *geom, c
}
}
}
++g_lights.num_emissive_surfaces;
return esurf;
}
++g_lights.num_emissive_surfaces;
return true;
return NULL;
}
void VK_LightsFrameFinalize( void )

View File

@ -48,7 +48,11 @@ void VK_LightsNewMap( void );
void VK_LightsFrameInit( void );
// TODO there is an arguably better way to organize this.
// a. this only belongs to ray tracing mode
// b. kusochki now have emissive color, so it probably makes more sense to not store emissive
// separately in emissive surfaces.
struct vk_render_geometry_s;
qboolean VK_LightsAddEmissiveSurface( const struct vk_render_geometry_s *geom, const matrix3x4 *transform_row );
const vk_emissive_surface_t *VK_LightsAddEmissiveSurface( const struct vk_render_geometry_s *geom, const matrix3x4 *transform_row );
void VK_LightsFrameFinalize( void );

View File

@ -3,19 +3,13 @@
#include "vk_core.h"
#include "vk_buffer.h"
#include "shaders/ray_interop.h"
#define MAX_ACCELS 1024
#define MAX_KUSOCHKI 8192
#define MAX_EMISSIVE_KUSOCHKI 256
#define MODEL_CACHE_SIZE 1024
// Shared with shaders
#define kXVkMaterialFlagEmissive (1<<0)
#define kXVkMaterialFlagDiffuse (1<<1)
#define kXVkMaterialFlagAdditive (1<<2)
#define kXVkMaterialFlagReflective (1<<3)
#define kXVkMaterialFlagRefractive (1<<4)
#define kXVkMaterialFlagAlphaTest (1<<5)
typedef struct vk_ray_model_s {
VkAccelerationStructureKHR as;
VkAccelerationStructureGeometryKHR *geoms;
@ -40,6 +34,11 @@ typedef struct {
uint32_t texture;
float roughness;
uint32_t material_flags;
float _padding_0[2];
vec3_t emissive;
float _padding_1[1];
} vk_kusok_data_t;
typedef struct {
@ -48,8 +47,6 @@ typedef struct {
struct {
uint32_t kusok_index;
uint32_t padding__[3];
vec3_t emissive_color;
uint32_t padding___;
matrix3x4 transform;
} kusochki[MAX_EMISSIVE_KUSOCHKI];
} vk_emissive_kusochki_t;

View File

@ -6,6 +6,7 @@
#include "vk_light.h"
#include "eiface.h"
#include "xash3d_mathlib.h"
#include <string.h>
@ -217,6 +218,7 @@ vk_ray_model_t* VK_RayModelCreate( vk_ray_model_init_t args ) {
kusochki[i].texture = mg->texture;
kusochki[i].roughness = mg->material == kXVkMaterialWater ? 0. : 1.; // FIXME
VectorSet(kusochki[i].emissive, 0, 0, 0 );
// We don't know render_mode yet
// TODO: assume diffuse-only surface by default?
@ -283,6 +285,9 @@ void VK_RayModelDestroy( struct vk_ray_model_s *model ) {
void VK_RayFrameAddModel( vk_ray_model_t *model, const vk_render_model_t *render_model, const matrix3x4 *transform_row ) {
uint32_t material_flags = 0;
qboolean reflective = false;
qboolean force_emissive = false;
ASSERT(vk_core.rtx);
ASSERT(g_ray_model_state.frame.num_models <= ARRAYSIZE(g_ray_model_state.frame.models));
@ -305,24 +310,26 @@ void VK_RayFrameAddModel( vk_ray_model_t *model, const vk_render_model_t *render
switch (render_model->render_mode) {
case kRenderNormal:
material_flags = kXVkMaterialFlagDiffuse;
material_flags = kXVkMaterialFlagLighting;
break;
// C = (1 - alpha) * DST + alpha * SRC (TODO is this right?)
case kRenderTransColor:
case kRenderTransTexture:
material_flags = kXVkMaterialFlagDiffuse | kXVkMaterialFlagReflective | kXVkMaterialFlagRefractive;
material_flags = kXVkMaterialFlagLighting | kXVkMaterialFlagRefractive;
reflective = true;
break;
// Additive blending: C = SRC * alpha + DST
case kRenderGlow:
case kRenderTransAdd:
material_flags = kXVkMaterialFlagAdditive | kXVkMaterialFlagEmissive;
material_flags = kXVkMaterialFlagAdditive;
force_emissive = true;
break;
// Alpha test (TODO additive? mixing?)
case kRenderTransAlpha:
material_flags = kXVkMaterialFlagDiffuse | kXVkMaterialFlagAlphaTest;
material_flags = kXVkMaterialFlagLighting | kXVkMaterialFlagAlphaTest;
break;
default:
@ -331,10 +338,21 @@ void VK_RayFrameAddModel( vk_ray_model_t *model, const vk_render_model_t *render
for (int i = 0; i < render_model->num_geometries; ++i) {
const vk_render_geometry_t *geom = render_model->geometries + i;
const qboolean emissive = VK_LightsAddEmissiveSurface( geom, transform_row );
const vk_emissive_surface_t *esurf = VK_LightsAddEmissiveSurface( geom, transform_row );
vk_kusok_data_t *kusok = (vk_kusok_data_t*)(g_ray_model_state.kusochki_buffer.mapped) + geom->kusok_index;
kusok->texture = geom->texture;
kusok->material_flags = material_flags | (emissive ? kXVkMaterialFlagEmissive : 0);
kusok->material_flags = material_flags;
// HACK until there is proper specular
// FIXME also this erases previour roughness conditionally
if (reflective)
kusok->roughness = 0.f;
if (esurf) {
VectorCopy(esurf->emissive, kusok->emissive);
} else if (force_emissive) {
VectorSet(kusok->emissive, 1.f, 1.f, 1.f);
}
}
}

View File

@ -660,7 +660,6 @@ static void updateLights( void )
ek->num_kusochki = g_lights.num_emissive_surfaces;
for (int i = 0; i < g_lights.num_emissive_surfaces; ++i) {
ek->kusochki[i].kusok_index = g_lights.emissive_surfaces[i].kusok_index;
VectorCopy(g_lights.emissive_surfaces[i].emissive, ek->kusochki[i].emissive_color);
Matrix3x4_Copy(ek->kusochki[i].transform, g_lights.emissive_surfaces[i].transform);
}
}