more perf improvements

main
Dominik Madarász 2024-08-30 23:23:07 +02:00
parent 7fd64941f3
commit 9e2e216fd0
12 changed files with 1938 additions and 1929 deletions

View File

@ -1162,7 +1162,7 @@ typedef struct light_t {
unsigned shadow_technique;
float shadow_distance;
float shadow_bias;
mat44 shadow_matrix[6];
mat44 shadow_matrix[4];
bool cached;
} light_t;
light_t light();
@ -1186,7 +1186,7 @@ typedef struct shadowmap_t {
int light_step;
int cascade_index;
unsigned shadow_technique;
float cascade_splits[6];
float cascade_splits[4];
bool blur_csm;
bool blur_vsm;
float csm_blur_scale;
@ -1194,16 +1194,22 @@ typedef struct shadowmap_t {
bool skip_render;
int lights_pushed;
handle fbo;
uint64_t vram_usage;
uint64_t vram_usage_total;
uint64_t vram_usage_vsm;
uint64_t vram_usage_csm;
struct {
int gen;
unsigned shadow_technique;
handle texture, depth_texture;
handle texture_2d[6], depth_texture_2d[6];
handle texture_2d[4], depth_texture_2d[4];
handle blur_texture, blur_texture_2d;
float cascade_distances[6];
float cascade_distances[4];
} maps[MAX_LIGHTS];
handle saved_fb;
handle saved_pass;
int saved_vp[4];
int gen;
} shadowmap_t;
shadowmap_t shadowmap(int vsm_texture_width, int csm_texture_width);
void shadowmap_destroy(shadowmap_t *s);

View File

@ -1,5 +1,6 @@
#include "v4k.h"
int SKY_DIR = 0;
const char *SKY_DIRS[] = {
"cubemaps/bridge3/",
@ -29,6 +30,7 @@ int main(int argc, char** argv) {
skybox_t sky = {0};
model_t mdl = {0};
shadowmap_t sm = {0};
light_t lit = light(); {
lit.type = LIGHT_POINT;
lit.cast_shadows = true;
@ -208,6 +210,14 @@ int main(int argc, char** argv) {
ui_slider("CSM Blur Scale", &sm.csm_blur_scale);
ui_bool("VSM Blur", &sm.blur_vsm);
ui_slider("VSM Blur Scale", &sm.vsm_blur_scale);
int sm_vram = sm.vram_usage / 1024 / 1024;
int sm_vram_total = sm.vram_usage_total / 1024 / 1024;
int sm_vram_vsm = sm.vram_usage_vsm / 1024 / 1024;
int sm_vram_csm = sm.vram_usage_csm / 1024 / 1024;
ui_int("Vram Usage", &sm_vram);
ui_int("Vram Usage Total", &sm_vram_total);
ui_int("Vram Usage VSM", &sm_vram_vsm);
ui_int("Vram Usage CSM", &sm_vram_csm);
ui_panel_end();
}
}

View File

@ -1,26 +1,6 @@
# Blender 4.2.1 LTS MTL File: 'None'
# www.blender.org
newmtl backWall
Ns 10.000005
Ka 1.000000 1.000000 1.000000
Kd 0.725000 0.710000 0.680000
Ks 0.000000 0.000000 0.000000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 1
newmtl ceiling
Ns 10.000005
Ka 1.000000 1.000000 1.000000
Kd 0.725000 0.710000 0.680000
Ks 0.000000 0.000000 0.000000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 1
newmtl floor
Ns 10.000005
Ka 1.000000 1.000000 1.000000
@ -31,36 +11,6 @@ Ni 1.000000
d 1.000000
illum 1
newmtl leftWall
Ns 10.000005
Ka 1.000000 1.000000 1.000000
Kd 0.630000 0.065000 0.050000
Ks 0.000000 0.000000 0.000000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 1
newmtl light
Ns 10.000005
Ka 1.000000 1.000000 1.000000
Kd 0.780000 0.780000 0.780000
Ks 0.000000 0.000000 0.000000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 1
newmtl rightWall
Ns 10.000005
Ka 1.000000 1.000000 1.000000
Kd 0.140000 0.450000 0.091000
Ks 0.000000 0.000000 0.000000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 1
newmtl shortBox
Ns 10.000005
Ka 1.000000 1.000000 1.000000

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
#define LIGHT_GLSL
#define MAX_LIGHTS 16
#define NUM_SHADOW_CASCADES 6
#define NUM_SHADOW_CASCADES 4
#include "brdf.glsl"
@ -126,7 +126,9 @@ vec3 lighting(material_t m) {
vec3 lit_contrib = shading_light(u_lights[i], m);
#ifdef FS_PASS
lit += lit_contrib * shadowing(i).xyz;
if (lit_contrib.xyz != vec3(0,0,0)) {
lit += lit_contrib * shadowing(i).xyz;
}
#endif
}
#endif

View File

@ -8,25 +8,30 @@ uniform float u_cascade_distances[MAX_LIGHTS * NUM_SHADOW_CASCADES];
uniform samplerCube shadowMap[MAX_LIGHTS];
uniform sampler2D shadowMap2D[MAX_LIGHTS * NUM_SHADOW_CASCADES];
const float bias_modifier[NUM_SHADOW_CASCADES] = float[NUM_SHADOW_CASCADES](0.95, 0.35, 0.20, 0.15, 0.15, 0.15);
// const float bias_modifier[NUM_SHADOW_CASCADES] = float[NUM_SHADOW_CASCADES](0.95, 0.35, 0.20, 0.15);
// const float bias_modifier[NUM_SHADOW_CASCADES] = float[NUM_SHADOW_CASCADES](0.95, 0.35, 0.20, 0.1, 0.1, 0.1);
const float bias_modifier[NUM_SHADOW_CASCADES] = float[NUM_SHADOW_CASCADES](0.95, 0.35, 0.20, 0.15);
//// From http://fabiensanglard.net/shadowmappingVSM/index.php
float shadow_vsm(float distance, vec3 dir, int light_index) {
distance = distance/200;
// Define offsets for 2x2 PCF
vec3 offsets[4] = vec3[4](
// Define offsets for 3x3 PCF
vec3 offsets[9] = vec3[9](
vec3(-1, -1, 0) * 0.01,
vec3( 0, -1, 0) * 0.01,
vec3( 1, -1, 0) * 0.01,
vec3(-1, 0, 0) * 0.01,
vec3( 0, 0, 0) * 0.01,
vec3( 1, 0, 0) * 0.01,
vec3(-1, 1, 0) * 0.01,
vec3( 0, 1, 0) * 0.01,
vec3( 1, 1, 0) * 0.01
);
float shadow = 0.0;
// Perform 2x2 PCF
for (int i = 0; i < 4; i++) {
// Perform 3x3 PCF
for (int i = 0; i < 9; i++) {
vec3 sampleDir = dir + offsets[i] * (rand(vec2(v_position_ws.x + offsets[i].x, v_position_ws.y + offsets[i].y))*1.75f + 1.25f);
vec2 moments = texture(shadowMap[light_index], sampleDir).rg;
@ -43,15 +48,16 @@ float shadow_vsm(float distance, vec3 dir, int light_index) {
}
// Calculate VSM for this sample
float variance = max(moments.y - (moments.x * moments.x), 0.0002);
float p = step(distance, moments.x);
float variance = max(moments.y - (moments.x * moments.x), 0.00002);
float d = distance - moments.x;
float p_max = variance / (variance + d*d);
float p_max = linstep(0.2, 1.0, variance / (variance + d*d));
shadow += p_max;
shadow += min(max(p, p_max), 1.0);
}
// Average the results
return shadow / 4.0;
return shadow / 9.0;
}
float shadow_csm(float distance, vec3 lightDir, int light_index) {

View File

@ -30,6 +30,10 @@ float rand(vec2 co) {
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}
float linstep(float edge0, float edge1, float x) {
return clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
}
// Classic Perlin 3D Noise
// by Stefan Gustavson
//

View File

@ -17267,7 +17267,7 @@ enum SHADOW_TECHNIQUE {
SHADOW_CSM,
};
#define NUM_SHADOW_CASCADES 6
#define NUM_SHADOW_CASCADES 4
typedef struct light_t {
char type;
@ -17330,7 +17330,14 @@ typedef struct shadowmap_t {
int lights_pushed;
handle fbo;
// VRAM usage
uint64_t vram_usage;
uint64_t vram_usage_total;
uint64_t vram_usage_vsm;
uint64_t vram_usage_csm;
struct {
int gen;
unsigned shadow_technique;
handle texture, depth_texture;
handle texture_2d[NUM_SHADOW_CASCADES], depth_texture_2d[NUM_SHADOW_CASCADES];
@ -17342,6 +17349,7 @@ typedef struct shadowmap_t {
handle saved_fb;
handle saved_pass;
int saved_vp[4];
int gen;
} shadowmap_t;
API shadowmap_t shadowmap(int vsm_texture_width, int csm_texture_width); // = 512, 4096
@ -383321,7 +383329,7 @@ shadowmap_init_caster_vsm(shadowmap_t *s, int light_index, int texture_width) {
glGenTextures(1, &s->maps[light_index].texture);
glBindTexture(GL_TEXTURE_CUBE_MAP, s->maps[light_index].texture);
for (int i = 0; i < 6; i++) {
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB32F, texture_width, texture_width, 0, GL_RGB, GL_FLOAT, 0);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RG32F, texture_width, texture_width, 0, GL_RG, GL_FLOAT, 0);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 0);
@ -383360,7 +383368,7 @@ shadowmap_init_caster_csm(shadowmap_t *s, int light_index, int texture_width) {
for (int i = 0; i < NUM_SHADOW_CASCADES; i++) {
glGenTextures(1, &s->maps[light_index].texture_2d[i]);
glBindTexture(GL_TEXTURE_2D, s->maps[light_index].texture_2d[i]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, texture_width, texture_width, 0, GL_RGB, GL_FLOAT, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, texture_width, texture_width, 0, GL_RED, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
@ -383395,12 +383403,19 @@ shadowmap_t shadowmap(int vsm_texture_width, int csm_texture_width) { // = 512,
s.blur_vsm = false;
s.csm_blur_scale = 0.5f;
s.vsm_blur_scale = 0.75f;
#if 0
s.cascade_splits[0] = 0.1f;
s.cascade_splits[1] = 0.3f;
s.cascade_splits[2] = 0.7f;
s.cascade_splits[3] = 1.0f;
s.cascade_splits[4] = 1.0f;
s.cascade_splits[5] = 1.0f; /* sticks to camera far plane */
#else
s.cascade_splits[0] = 0.1f;
s.cascade_splits[1] = 0.5f;
s.cascade_splits[2] = 1.0f;
s.cascade_splits[3] = 1.0f; /* sticks to camera far plane */
#endif
glGenFramebuffers(1, &s.fbo);
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &s.saved_fb);
@ -383424,10 +383439,9 @@ shadowmap_t shadowmap(int vsm_texture_width, int csm_texture_width) { // = 512,
static inline
void shadowmap_destroy_light(shadowmap_t *s, int light_index) {
if (s->fbo) {
glDeleteFramebuffers(1, &s->fbo);
s->fbo = 0;
}
s->maps[light_index].gen = 0;
s->maps[light_index].shadow_technique = 0xFFFF;
if (s->maps[light_index].texture) {
glDeleteTextures(1, &s->maps[light_index].texture);
s->maps[light_index].texture = 0;
@ -383436,7 +383450,7 @@ void shadowmap_destroy_light(shadowmap_t *s, int light_index) {
glDeleteTextures(1, &s->maps[light_index].depth_texture);
s->maps[light_index].depth_texture = 0;
}
for (int i = 0; i < NUM_SHADOW_CASCADES; i++) {
if (s->maps[light_index].texture_2d[i]) {
glDeleteTextures(1, &s->maps[light_index].texture_2d[i]);
@ -383452,6 +383466,11 @@ void shadowmap_destroy_light(shadowmap_t *s, int light_index) {
glDeleteTextures(1, &s->maps[light_index].blur_texture_2d);
s->maps[light_index].blur_texture_2d = 0;
}
if (s->maps[light_index].blur_texture) {
glDeleteTextures(1, &s->maps[light_index].blur_texture);
s->maps[light_index].blur_texture = 0;
}
}
void shadowmap_destroy(shadowmap_t *s) {
@ -383468,9 +383487,16 @@ void shadowmap_begin(shadowmap_t *s) {
glGetIntegerv(GL_VIEWPORT, s->saved_vp);
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &s->saved_fb);
for (int i = 0; i < MAX_LIGHTS; i++) {
if (s->maps[i].gen != s->gen) {
shadowmap_destroy_light(s, i);
}
}
s->step = 0;
s->light_step = 0;
s->cascade_index = 0;
s->gen++;
active_shadowmap = s;
s->saved_pass = model_getpass();
}
@ -383617,7 +383643,7 @@ void shadowmap_blur_csm(shadowmap_t *s, int light_index) {
float borderColor[] = {1.0, 1.0, 1.0, 1.0};
glGenTextures(1, &s->maps[light_index].blur_texture_2d);
glBindTexture(GL_TEXTURE_2D, s->maps[light_index].blur_texture_2d);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, s->csm_texture_width, s->csm_texture_width, 0, GL_RGB, GL_FLOAT, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, s->csm_texture_width, s->csm_texture_width, 0, GL_RED, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@ -383694,7 +383720,7 @@ void shadowmap_blur_vsm(shadowmap_t *s, int light_index) {
glGenTextures(1, &s->maps[light_index].blur_texture);
glBindTexture(GL_TEXTURE_CUBE_MAP, s->maps[light_index].blur_texture);
for (int i = 0; i < 6; i++) {
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB32F, s->vsm_texture_width, s->vsm_texture_width, 0, GL_RGB, GL_FLOAT, 0);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_R32F, s->vsm_texture_width, s->vsm_texture_width, 0, GL_RED, GL_FLOAT, 0);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@ -383829,7 +383855,7 @@ void shadowmap_light(shadowmap_t *s, light_t *l, mat44 cam_proj, mat44 cam_view)
}
if (s->maps[s->light_step].shadow_technique != l->shadow_technique) {
// shadowmap_destroy_light(s, s->light_step); // @todo: we might wanna free the other set
shadowmap_destroy_light(s, s->light_step); // @todo: we might wanna free the other set
if (l->shadow_technique == SHADOW_VSM) {
shadowmap_init_caster_vsm(s, s->light_step, s->vsm_texture_width);
} else if (l->shadow_technique == SHADOW_CSM) {
@ -383837,6 +383863,7 @@ void shadowmap_light(shadowmap_t *s, light_t *l, mat44 cam_proj, mat44 cam_view)
}
}
s->maps[s->light_step].gen = s->gen;
s->maps[s->light_step].shadow_technique = l->shadow_technique;
ASSERT(s->lights_pushed == 0);
@ -383863,6 +383890,73 @@ void shadowmap_end(shadowmap_t *s) {
glViewport(s->saved_vp[0], s->saved_vp[1], s->saved_vp[2], s->saved_vp[3]);
glBindFramebuffer(GL_FRAMEBUFFER, s->saved_fb);
active_shadowmap = NULL;
// calculate vram usage
s->vram_usage = 0;
s->vram_usage_total = 0;
s->vram_usage_vsm = 0;
s->vram_usage_csm = 0;
{
const int faces = 6;
const int cascades = NUM_SHADOW_CASCADES;
for (int i = 0; i < MAX_LIGHTS; i++) {
// VSM textures
if (s->maps[i].texture != 0) {
// Color texture (GL_RG32F)
s->vram_usage += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // 8 bytes per pixel (2 * 32-bit float)
// Depth texture (GL_DEPTH_COMPONENT, assuming 8-bit depth)
s->vram_usage += s->vsm_texture_width * s->vsm_texture_width * faces * 1;
}
// Color texture (GL_RG32F)
s->vram_usage_total += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // 8 bytes per pixel (2 * 32-bit float)
// Depth texture (GL_DEPTH_COMPONENT, assuming 8-bit depth)
s->vram_usage_total += s->vsm_texture_width * s->vsm_texture_width * faces * 1;
// Color texture (GL_RG32F)
s->vram_usage_vsm += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // 8 bytes per pixel (2 * 32-bit float)
// Depth texture (GL_DEPTH_COMPONENT, assuming 8-bit depth)
s->vram_usage_vsm += s->vsm_texture_width * s->vsm_texture_width * faces * 1;
// CSM textures
if (s->maps[i].texture_2d[0] != 0) {
for (int j = 0; j < cascades; j++) {
// Color texture (GL_R32F)
s->vram_usage += s->csm_texture_width * s->csm_texture_width * 4; // 4 bytes per pixel (1 * 32-bit float)
// Depth texture (GL_DEPTH_COMPONENT, assuming 8-bit depth)
s->vram_usage += s->csm_texture_width * s->csm_texture_width * 1;
}
}
for (int j = 0; j < cascades; j++) {
// Color texture (GL_R32F)
s->vram_usage_total += s->csm_texture_width * s->csm_texture_width * 4; // 4 bytes per pixel (1 * 32-bit float)
// Depth texture (GL_DEPTH_COMPONENT, assuming 8-bit depth)
s->vram_usage_total += s->csm_texture_width * s->csm_texture_width * 1;
s->vram_usage_csm += s->csm_texture_width * s->csm_texture_width * 4; // 4 bytes per pixel (1 * 32-bit float)
// Depth texture (GL_DEPTH_COMPONENT, assuming 8-bit depth)
s->vram_usage_csm += s->csm_texture_width * s->csm_texture_width * 1;
}
// VSM blur texture (if used)
if (s->maps[i].blur_texture != 0) {
s->vram_usage += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // Assuming same format as VSM color texture
}
s->vram_usage_total += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // Assuming same format as VSM color texture
s->vram_usage_vsm += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // Assuming same format as VSM color texture
// CSM blur texture (if used)
if (s->maps[i].blur_texture_2d != 0) {
s->vram_usage += s->csm_texture_width * s->csm_texture_width * 4; // Assuming same format as CSM color texture
}
s->vram_usage_total += s->csm_texture_width * s->csm_texture_width * 4; // Assuming same format as CSM color texture
s->vram_usage_csm += s->csm_texture_width * s->csm_texture_width * 4; // Assuming same format as CSM color texture
}
}
}
// -----------------------------------------------------------------------------

View File

@ -1587,7 +1587,7 @@ shadowmap_init_caster_vsm(shadowmap_t *s, int light_index, int texture_width) {
glGenTextures(1, &s->maps[light_index].texture);
glBindTexture(GL_TEXTURE_CUBE_MAP, s->maps[light_index].texture);
for (int i = 0; i < 6; i++) {
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB32F, texture_width, texture_width, 0, GL_RGB, GL_FLOAT, 0);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RG32F, texture_width, texture_width, 0, GL_RG, GL_FLOAT, 0);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 0);
@ -1626,7 +1626,7 @@ shadowmap_init_caster_csm(shadowmap_t *s, int light_index, int texture_width) {
for (int i = 0; i < NUM_SHADOW_CASCADES; i++) {
glGenTextures(1, &s->maps[light_index].texture_2d[i]);
glBindTexture(GL_TEXTURE_2D, s->maps[light_index].texture_2d[i]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, texture_width, texture_width, 0, GL_RGB, GL_FLOAT, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, texture_width, texture_width, 0, GL_RED, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
@ -1661,12 +1661,19 @@ shadowmap_t shadowmap(int vsm_texture_width, int csm_texture_width) { // = 512,
s.blur_vsm = false;
s.csm_blur_scale = 0.5f;
s.vsm_blur_scale = 0.75f;
#if 0
s.cascade_splits[0] = 0.1f;
s.cascade_splits[1] = 0.3f;
s.cascade_splits[2] = 0.7f;
s.cascade_splits[3] = 1.0f;
s.cascade_splits[4] = 1.0f;
s.cascade_splits[5] = 1.0f; /* sticks to camera far plane */
#else
s.cascade_splits[0] = 0.1f;
s.cascade_splits[1] = 0.5f;
s.cascade_splits[2] = 1.0f;
s.cascade_splits[3] = 1.0f; /* sticks to camera far plane */
#endif
glGenFramebuffers(1, &s.fbo);
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &s.saved_fb);
@ -1690,10 +1697,9 @@ shadowmap_t shadowmap(int vsm_texture_width, int csm_texture_width) { // = 512,
static inline
void shadowmap_destroy_light(shadowmap_t *s, int light_index) {
if (s->fbo) {
glDeleteFramebuffers(1, &s->fbo);
s->fbo = 0;
}
s->maps[light_index].gen = 0;
s->maps[light_index].shadow_technique = 0xFFFF;
if (s->maps[light_index].texture) {
glDeleteTextures(1, &s->maps[light_index].texture);
s->maps[light_index].texture = 0;
@ -1702,7 +1708,7 @@ void shadowmap_destroy_light(shadowmap_t *s, int light_index) {
glDeleteTextures(1, &s->maps[light_index].depth_texture);
s->maps[light_index].depth_texture = 0;
}
for (int i = 0; i < NUM_SHADOW_CASCADES; i++) {
if (s->maps[light_index].texture_2d[i]) {
glDeleteTextures(1, &s->maps[light_index].texture_2d[i]);
@ -1718,6 +1724,11 @@ void shadowmap_destroy_light(shadowmap_t *s, int light_index) {
glDeleteTextures(1, &s->maps[light_index].blur_texture_2d);
s->maps[light_index].blur_texture_2d = 0;
}
if (s->maps[light_index].blur_texture) {
glDeleteTextures(1, &s->maps[light_index].blur_texture);
s->maps[light_index].blur_texture = 0;
}
}
void shadowmap_destroy(shadowmap_t *s) {
@ -1734,9 +1745,16 @@ void shadowmap_begin(shadowmap_t *s) {
glGetIntegerv(GL_VIEWPORT, s->saved_vp);
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &s->saved_fb);
for (int i = 0; i < MAX_LIGHTS; i++) {
if (s->maps[i].gen != s->gen) {
shadowmap_destroy_light(s, i);
}
}
s->step = 0;
s->light_step = 0;
s->cascade_index = 0;
s->gen++;
active_shadowmap = s;
s->saved_pass = model_getpass();
}
@ -1883,7 +1901,7 @@ void shadowmap_blur_csm(shadowmap_t *s, int light_index) {
float borderColor[] = {1.0, 1.0, 1.0, 1.0};
glGenTextures(1, &s->maps[light_index].blur_texture_2d);
glBindTexture(GL_TEXTURE_2D, s->maps[light_index].blur_texture_2d);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, s->csm_texture_width, s->csm_texture_width, 0, GL_RGB, GL_FLOAT, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, s->csm_texture_width, s->csm_texture_width, 0, GL_RED, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@ -1960,7 +1978,7 @@ void shadowmap_blur_vsm(shadowmap_t *s, int light_index) {
glGenTextures(1, &s->maps[light_index].blur_texture);
glBindTexture(GL_TEXTURE_CUBE_MAP, s->maps[light_index].blur_texture);
for (int i = 0; i < 6; i++) {
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB32F, s->vsm_texture_width, s->vsm_texture_width, 0, GL_RGB, GL_FLOAT, 0);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_R32F, s->vsm_texture_width, s->vsm_texture_width, 0, GL_RED, GL_FLOAT, 0);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@ -2095,7 +2113,7 @@ void shadowmap_light(shadowmap_t *s, light_t *l, mat44 cam_proj, mat44 cam_view)
}
if (s->maps[s->light_step].shadow_technique != l->shadow_technique) {
// shadowmap_destroy_light(s, s->light_step); // @todo: we might wanna free the other set
shadowmap_destroy_light(s, s->light_step); // @todo: we might wanna free the other set
if (l->shadow_technique == SHADOW_VSM) {
shadowmap_init_caster_vsm(s, s->light_step, s->vsm_texture_width);
} else if (l->shadow_technique == SHADOW_CSM) {
@ -2103,6 +2121,7 @@ void shadowmap_light(shadowmap_t *s, light_t *l, mat44 cam_proj, mat44 cam_view)
}
}
s->maps[s->light_step].gen = s->gen;
s->maps[s->light_step].shadow_technique = l->shadow_technique;
ASSERT(s->lights_pushed == 0);
@ -2129,6 +2148,73 @@ void shadowmap_end(shadowmap_t *s) {
glViewport(s->saved_vp[0], s->saved_vp[1], s->saved_vp[2], s->saved_vp[3]);
glBindFramebuffer(GL_FRAMEBUFFER, s->saved_fb);
active_shadowmap = NULL;
// calculate vram usage
s->vram_usage = 0;
s->vram_usage_total = 0;
s->vram_usage_vsm = 0;
s->vram_usage_csm = 0;
{
const int faces = 6;
const int cascades = NUM_SHADOW_CASCADES;
for (int i = 0; i < MAX_LIGHTS; i++) {
// VSM textures
if (s->maps[i].texture != 0) {
// Color texture (GL_RG32F)
s->vram_usage += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // 8 bytes per pixel (2 * 32-bit float)
// Depth texture (GL_DEPTH_COMPONENT, assuming 8-bit depth)
s->vram_usage += s->vsm_texture_width * s->vsm_texture_width * faces * 1;
}
// Color texture (GL_RG32F)
s->vram_usage_total += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // 8 bytes per pixel (2 * 32-bit float)
// Depth texture (GL_DEPTH_COMPONENT, assuming 8-bit depth)
s->vram_usage_total += s->vsm_texture_width * s->vsm_texture_width * faces * 1;
// Color texture (GL_RG32F)
s->vram_usage_vsm += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // 8 bytes per pixel (2 * 32-bit float)
// Depth texture (GL_DEPTH_COMPONENT, assuming 8-bit depth)
s->vram_usage_vsm += s->vsm_texture_width * s->vsm_texture_width * faces * 1;
// CSM textures
if (s->maps[i].texture_2d[0] != 0) {
for (int j = 0; j < cascades; j++) {
// Color texture (GL_R32F)
s->vram_usage += s->csm_texture_width * s->csm_texture_width * 4; // 4 bytes per pixel (1 * 32-bit float)
// Depth texture (GL_DEPTH_COMPONENT, assuming 8-bit depth)
s->vram_usage += s->csm_texture_width * s->csm_texture_width * 1;
}
}
for (int j = 0; j < cascades; j++) {
// Color texture (GL_R32F)
s->vram_usage_total += s->csm_texture_width * s->csm_texture_width * 4; // 4 bytes per pixel (1 * 32-bit float)
// Depth texture (GL_DEPTH_COMPONENT, assuming 8-bit depth)
s->vram_usage_total += s->csm_texture_width * s->csm_texture_width * 1;
s->vram_usage_csm += s->csm_texture_width * s->csm_texture_width * 4; // 4 bytes per pixel (1 * 32-bit float)
// Depth texture (GL_DEPTH_COMPONENT, assuming 8-bit depth)
s->vram_usage_csm += s->csm_texture_width * s->csm_texture_width * 1;
}
// VSM blur texture (if used)
if (s->maps[i].blur_texture != 0) {
s->vram_usage += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // Assuming same format as VSM color texture
}
s->vram_usage_total += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // Assuming same format as VSM color texture
s->vram_usage_vsm += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // Assuming same format as VSM color texture
// CSM blur texture (if used)
if (s->maps[i].blur_texture_2d != 0) {
s->vram_usage += s->csm_texture_width * s->csm_texture_width * 4; // Assuming same format as CSM color texture
}
s->vram_usage_total += s->csm_texture_width * s->csm_texture_width * 4; // Assuming same format as CSM color texture
s->vram_usage_csm += s->csm_texture_width * s->csm_texture_width * 4; // Assuming same format as CSM color texture
}
}
}
// -----------------------------------------------------------------------------

View File

@ -299,7 +299,7 @@ enum SHADOW_TECHNIQUE {
SHADOW_CSM,
};
#define NUM_SHADOW_CASCADES 6
#define NUM_SHADOW_CASCADES 4
typedef struct light_t {
char type;
@ -362,7 +362,14 @@ typedef struct shadowmap_t {
int lights_pushed;
handle fbo;
// VRAM usage
uint64_t vram_usage;
uint64_t vram_usage_total;
uint64_t vram_usage_vsm;
uint64_t vram_usage_csm;
struct {
int gen;
unsigned shadow_technique;
handle texture, depth_texture;
handle texture_2d[NUM_SHADOW_CASCADES], depth_texture_2d[NUM_SHADOW_CASCADES];
@ -374,6 +381,7 @@ typedef struct shadowmap_t {
handle saved_fb;
handle saved_pass;
int saved_vp[4];
int gen;
} shadowmap_t;
API shadowmap_t shadowmap(int vsm_texture_width, int csm_texture_width); // = 512, 4096

View File

@ -18386,7 +18386,7 @@ shadowmap_init_caster_vsm(shadowmap_t *s, int light_index, int texture_width) {
glGenTextures(1, &s->maps[light_index].texture);
glBindTexture(GL_TEXTURE_CUBE_MAP, s->maps[light_index].texture);
for (int i = 0; i < 6; i++) {
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB32F, texture_width, texture_width, 0, GL_RGB, GL_FLOAT, 0);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RG32F, texture_width, texture_width, 0, GL_RG, GL_FLOAT, 0);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 0);
@ -18425,7 +18425,7 @@ shadowmap_init_caster_csm(shadowmap_t *s, int light_index, int texture_width) {
for (int i = 0; i < NUM_SHADOW_CASCADES; i++) {
glGenTextures(1, &s->maps[light_index].texture_2d[i]);
glBindTexture(GL_TEXTURE_2D, s->maps[light_index].texture_2d[i]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, texture_width, texture_width, 0, GL_RGB, GL_FLOAT, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, texture_width, texture_width, 0, GL_RED, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
@ -18460,12 +18460,19 @@ shadowmap_t shadowmap(int vsm_texture_width, int csm_texture_width) { // = 512,
s.blur_vsm = false;
s.csm_blur_scale = 0.5f;
s.vsm_blur_scale = 0.75f;
#if 0
s.cascade_splits[0] = 0.1f;
s.cascade_splits[1] = 0.3f;
s.cascade_splits[2] = 0.7f;
s.cascade_splits[3] = 1.0f;
s.cascade_splits[4] = 1.0f;
s.cascade_splits[5] = 1.0f; /* sticks to camera far plane */
#else
s.cascade_splits[0] = 0.1f;
s.cascade_splits[1] = 0.5f;
s.cascade_splits[2] = 1.0f;
s.cascade_splits[3] = 1.0f; /* sticks to camera far plane */
#endif
glGenFramebuffers(1, &s.fbo);
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &s.saved_fb);
@ -18489,10 +18496,9 @@ shadowmap_t shadowmap(int vsm_texture_width, int csm_texture_width) { // = 512,
static inline
void shadowmap_destroy_light(shadowmap_t *s, int light_index) {
if (s->fbo) {
glDeleteFramebuffers(1, &s->fbo);
s->fbo = 0;
}
s->maps[light_index].gen = 0;
s->maps[light_index].shadow_technique = 0xFFFF;
if (s->maps[light_index].texture) {
glDeleteTextures(1, &s->maps[light_index].texture);
s->maps[light_index].texture = 0;
@ -18501,7 +18507,7 @@ void shadowmap_destroy_light(shadowmap_t *s, int light_index) {
glDeleteTextures(1, &s->maps[light_index].depth_texture);
s->maps[light_index].depth_texture = 0;
}
for (int i = 0; i < NUM_SHADOW_CASCADES; i++) {
if (s->maps[light_index].texture_2d[i]) {
glDeleteTextures(1, &s->maps[light_index].texture_2d[i]);
@ -18517,6 +18523,11 @@ void shadowmap_destroy_light(shadowmap_t *s, int light_index) {
glDeleteTextures(1, &s->maps[light_index].blur_texture_2d);
s->maps[light_index].blur_texture_2d = 0;
}
if (s->maps[light_index].blur_texture) {
glDeleteTextures(1, &s->maps[light_index].blur_texture);
s->maps[light_index].blur_texture = 0;
}
}
void shadowmap_destroy(shadowmap_t *s) {
@ -18533,9 +18544,16 @@ void shadowmap_begin(shadowmap_t *s) {
glGetIntegerv(GL_VIEWPORT, s->saved_vp);
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &s->saved_fb);
for (int i = 0; i < MAX_LIGHTS; i++) {
if (s->maps[i].gen != s->gen) {
shadowmap_destroy_light(s, i);
}
}
s->step = 0;
s->light_step = 0;
s->cascade_index = 0;
s->gen++;
active_shadowmap = s;
s->saved_pass = model_getpass();
}
@ -18682,7 +18700,7 @@ void shadowmap_blur_csm(shadowmap_t *s, int light_index) {
float borderColor[] = {1.0, 1.0, 1.0, 1.0};
glGenTextures(1, &s->maps[light_index].blur_texture_2d);
glBindTexture(GL_TEXTURE_2D, s->maps[light_index].blur_texture_2d);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, s->csm_texture_width, s->csm_texture_width, 0, GL_RGB, GL_FLOAT, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, s->csm_texture_width, s->csm_texture_width, 0, GL_RED, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@ -18759,7 +18777,7 @@ void shadowmap_blur_vsm(shadowmap_t *s, int light_index) {
glGenTextures(1, &s->maps[light_index].blur_texture);
glBindTexture(GL_TEXTURE_CUBE_MAP, s->maps[light_index].blur_texture);
for (int i = 0; i < 6; i++) {
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB32F, s->vsm_texture_width, s->vsm_texture_width, 0, GL_RGB, GL_FLOAT, 0);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_R32F, s->vsm_texture_width, s->vsm_texture_width, 0, GL_RED, GL_FLOAT, 0);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@ -18894,7 +18912,7 @@ void shadowmap_light(shadowmap_t *s, light_t *l, mat44 cam_proj, mat44 cam_view)
}
if (s->maps[s->light_step].shadow_technique != l->shadow_technique) {
// shadowmap_destroy_light(s, s->light_step); // @todo: we might wanna free the other set
shadowmap_destroy_light(s, s->light_step); // @todo: we might wanna free the other set
if (l->shadow_technique == SHADOW_VSM) {
shadowmap_init_caster_vsm(s, s->light_step, s->vsm_texture_width);
} else if (l->shadow_technique == SHADOW_CSM) {
@ -18902,6 +18920,7 @@ void shadowmap_light(shadowmap_t *s, light_t *l, mat44 cam_proj, mat44 cam_view)
}
}
s->maps[s->light_step].gen = s->gen;
s->maps[s->light_step].shadow_technique = l->shadow_technique;
ASSERT(s->lights_pushed == 0);
@ -18928,6 +18947,73 @@ void shadowmap_end(shadowmap_t *s) {
glViewport(s->saved_vp[0], s->saved_vp[1], s->saved_vp[2], s->saved_vp[3]);
glBindFramebuffer(GL_FRAMEBUFFER, s->saved_fb);
active_shadowmap = NULL;
// calculate vram usage
s->vram_usage = 0;
s->vram_usage_total = 0;
s->vram_usage_vsm = 0;
s->vram_usage_csm = 0;
{
const int faces = 6;
const int cascades = NUM_SHADOW_CASCADES;
for (int i = 0; i < MAX_LIGHTS; i++) {
// VSM textures
if (s->maps[i].texture != 0) {
// Color texture (GL_RG32F)
s->vram_usage += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // 8 bytes per pixel (2 * 32-bit float)
// Depth texture (GL_DEPTH_COMPONENT, assuming 8-bit depth)
s->vram_usage += s->vsm_texture_width * s->vsm_texture_width * faces * 1;
}
// Color texture (GL_RG32F)
s->vram_usage_total += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // 8 bytes per pixel (2 * 32-bit float)
// Depth texture (GL_DEPTH_COMPONENT, assuming 8-bit depth)
s->vram_usage_total += s->vsm_texture_width * s->vsm_texture_width * faces * 1;
// Color texture (GL_RG32F)
s->vram_usage_vsm += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // 8 bytes per pixel (2 * 32-bit float)
// Depth texture (GL_DEPTH_COMPONENT, assuming 8-bit depth)
s->vram_usage_vsm += s->vsm_texture_width * s->vsm_texture_width * faces * 1;
// CSM textures
if (s->maps[i].texture_2d[0] != 0) {
for (int j = 0; j < cascades; j++) {
// Color texture (GL_R32F)
s->vram_usage += s->csm_texture_width * s->csm_texture_width * 4; // 4 bytes per pixel (1 * 32-bit float)
// Depth texture (GL_DEPTH_COMPONENT, assuming 8-bit depth)
s->vram_usage += s->csm_texture_width * s->csm_texture_width * 1;
}
}
for (int j = 0; j < cascades; j++) {
// Color texture (GL_R32F)
s->vram_usage_total += s->csm_texture_width * s->csm_texture_width * 4; // 4 bytes per pixel (1 * 32-bit float)
// Depth texture (GL_DEPTH_COMPONENT, assuming 8-bit depth)
s->vram_usage_total += s->csm_texture_width * s->csm_texture_width * 1;
s->vram_usage_csm += s->csm_texture_width * s->csm_texture_width * 4; // 4 bytes per pixel (1 * 32-bit float)
// Depth texture (GL_DEPTH_COMPONENT, assuming 8-bit depth)
s->vram_usage_csm += s->csm_texture_width * s->csm_texture_width * 1;
}
// VSM blur texture (if used)
if (s->maps[i].blur_texture != 0) {
s->vram_usage += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // Assuming same format as VSM color texture
}
s->vram_usage_total += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // Assuming same format as VSM color texture
s->vram_usage_vsm += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // Assuming same format as VSM color texture
// CSM blur texture (if used)
if (s->maps[i].blur_texture_2d != 0) {
s->vram_usage += s->csm_texture_width * s->csm_texture_width * 4; // Assuming same format as CSM color texture
}
s->vram_usage_total += s->csm_texture_width * s->csm_texture_width * 4; // Assuming same format as CSM color texture
s->vram_usage_csm += s->csm_texture_width * s->csm_texture_width * 4; // Assuming same format as CSM color texture
}
}
}
// -----------------------------------------------------------------------------

View File

@ -3334,7 +3334,7 @@ enum SHADOW_TECHNIQUE {
SHADOW_CSM,
};
#define NUM_SHADOW_CASCADES 6
#define NUM_SHADOW_CASCADES 4
typedef struct light_t {
char type;
@ -3397,7 +3397,14 @@ typedef struct shadowmap_t {
int lights_pushed;
handle fbo;
// VRAM usage
uint64_t vram_usage;
uint64_t vram_usage_total;
uint64_t vram_usage_vsm;
uint64_t vram_usage_csm;
struct {
int gen;
unsigned shadow_technique;
handle texture, depth_texture;
handle texture_2d[NUM_SHADOW_CASCADES], depth_texture_2d[NUM_SHADOW_CASCADES];
@ -3409,6 +3416,7 @@ typedef struct shadowmap_t {
handle saved_fb;
handle saved_pass;
int saved_vp[4];
int gen;
} shadowmap_t;
API shadowmap_t shadowmap(int vsm_texture_width, int csm_texture_width); // = 512, 4096