PCSS impl
parent
82ec9fc3be
commit
80aad50ed3
|
@ -1166,6 +1166,7 @@ typedef struct light_t {
|
||||||
float variance_transition;
|
float variance_transition;
|
||||||
float shadow_bias;
|
float shadow_bias;
|
||||||
float normal_bias;
|
float normal_bias;
|
||||||
|
float shadow_softness;
|
||||||
bool cached;
|
bool cached;
|
||||||
bool processed_shadows;
|
bool processed_shadows;
|
||||||
} light_t;
|
} light_t;
|
||||||
|
@ -1207,7 +1208,6 @@ typedef struct shadowmap_t {
|
||||||
handle depth_texture;
|
handle depth_texture;
|
||||||
handle depth_texture_2d;
|
handle depth_texture_2d;
|
||||||
int filter_size, window_size;
|
int filter_size, window_size;
|
||||||
float offset_radius;
|
|
||||||
handle offsets_texture;
|
handle offsets_texture;
|
||||||
struct {
|
struct {
|
||||||
int gen;
|
int gen;
|
||||||
|
|
|
@ -90,7 +90,7 @@ int main(int argc, char** argv) {
|
||||||
if( !initialized ) {
|
if( !initialized ) {
|
||||||
initialized = 1;
|
initialized = 1;
|
||||||
sky = skybox(flag("--mie") ? 0 : SKY_DIRS[SKY_DIR], 0);
|
sky = skybox(flag("--mie") ? 0 : SKY_DIRS[SKY_DIR], 0);
|
||||||
sm = shadowmap(512, 2048);
|
sm = shadowmap(512, 4096);
|
||||||
// sm.blur_pcf = 1;
|
// sm.blur_pcf = 1;
|
||||||
// sm.blur_scale
|
// sm.blur_scale
|
||||||
mdl = model(OBJ_MDLS[OBJ_MDL], 0);
|
mdl = model(OBJ_MDLS[OBJ_MDL], 0);
|
||||||
|
@ -113,7 +113,7 @@ int main(int argc, char** argv) {
|
||||||
};
|
};
|
||||||
static unsigned mode = DIR;
|
static unsigned mode = DIR;
|
||||||
|
|
||||||
if (active) {
|
if (!ui_active()) {
|
||||||
if (input_down(KEY_1)) mode = POINT;
|
if (input_down(KEY_1)) mode = POINT;
|
||||||
if (input_down(KEY_2)) mode = SPOT;
|
if (input_down(KEY_2)) mode = SPOT;
|
||||||
if (input_down(KEY_3)) mode = DIR;
|
if (input_down(KEY_3)) mode = DIR;
|
||||||
|
|
|
@ -30,6 +30,7 @@ struct light_t {
|
||||||
float normal_bias;
|
float normal_bias;
|
||||||
float min_variance;
|
float min_variance;
|
||||||
float variance_transition;
|
float variance_transition;
|
||||||
|
float shadow_softness;
|
||||||
};
|
};
|
||||||
|
|
||||||
const int LIGHT_DIRECTIONAL = 0;
|
const int LIGHT_DIRECTIONAL = 0;
|
||||||
|
|
|
@ -10,62 +10,85 @@ uniform sampler2D shadowMap2D[MAX_LIGHTS * NUM_SHADOW_CASCADES];
|
||||||
uniform sampler3D shadow_offsets;
|
uniform sampler3D shadow_offsets;
|
||||||
uniform int shadow_filter_size;
|
uniform int shadow_filter_size;
|
||||||
uniform int shadow_window_size;
|
uniform int shadow_window_size;
|
||||||
uniform float shadow_offset_radius;
|
|
||||||
|
|
||||||
// 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.1, 0.1, 0.1);
|
||||||
const float bias_modifier[NUM_SHADOW_CASCADES] = float[NUM_SHADOW_CASCADES](1.0, 6.0, 9.0, 16.0);
|
const float bias_modifier[NUM_SHADOW_CASCADES] = float[NUM_SHADOW_CASCADES](1.0, 6.0, 9.0, 16.0);
|
||||||
// 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.15);
|
||||||
|
|
||||||
//// From http://fabiensanglard.net/shadowmappingVSM/index.php
|
vec2 shadow_vsm_variance(vec3 dir, int light_index, float distance, float min_variance, float variance_transition) {
|
||||||
float shadow_vsm(float distance, vec3 dir, int light_index, float min_variance, float variance_transition) {
|
// Calculate the variance
|
||||||
distance = distance/200;
|
vec2 moments = texture(shadowMap[light_index], dir).rg;
|
||||||
|
|
||||||
// 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 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;
|
|
||||||
|
|
||||||
// If the shadow map is sampled outside of its bounds, add 1.0
|
|
||||||
if (moments.x == 1.0 && moments.y == 1.0) {
|
|
||||||
shadow += 1.0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Surface is fully lit if the current fragment is before the light occluder
|
|
||||||
if (distance <= moments.x) {
|
|
||||||
shadow += 1.0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate VSM for this sample
|
|
||||||
float p = step(distance, moments.x);
|
|
||||||
float variance = max(moments.y - (moments.x * moments.x), min_variance);
|
float variance = max(moments.y - (moments.x * moments.x), min_variance);
|
||||||
float d = distance - moments.x;
|
float d = distance - moments.x;
|
||||||
float p_max = linstep(variance_transition, 1.0, variance / (variance + d*d));
|
return vec2(linstep(variance_transition, 1.0, variance / (variance + d * d)), moments.x);
|
||||||
|
|
||||||
shadow += min(max(p, p_max), 1.0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Average the results
|
//// From http://fabiensanglard.net/shadowmappingVSM/index.php
|
||||||
return shadow / 9.0;
|
float shadow_vsm(float distance, vec3 dir, int light_index, float min_variance, float variance_transition, float shadow_softness_raw) {
|
||||||
|
distance = distance / 200;
|
||||||
|
float shadow_softness = shadow_softness_raw * 10.0;
|
||||||
|
|
||||||
|
// Get the offset coordinates
|
||||||
|
ivec3 ofs_coord = ivec3(0);
|
||||||
|
vec2 ofs = mod(gl_FragCoord.xy, vec2(shadow_window_size));
|
||||||
|
ofs_coord.yz = ivec2(ofs);
|
||||||
|
float ofs_sum = 0.0;
|
||||||
|
int samples_div2 = int(shadow_filter_size * shadow_filter_size / 2.0);
|
||||||
|
vec4 sc = vec4(dir, 1.0);
|
||||||
|
sc.z = dir.z;
|
||||||
|
|
||||||
|
vec2 texelSize = 1.0 / textureSize(shadowMap[light_index], 0);
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
ofs_coord.x = i;
|
||||||
|
vec4 offsets = texelFetch(shadow_offsets, ofs_coord, 0) * shadow_softness;
|
||||||
|
sc.xy = dir.xy + offsets.rg * texelSize;
|
||||||
|
vec2 variance = shadow_vsm_variance(sc.xyz, light_index, distance, min_variance, variance_transition);
|
||||||
|
ofs_sum += min(max(step(distance, variance.y), variance.x), 1.0);
|
||||||
|
|
||||||
|
sc.xy = dir.xy + offsets.ba * texelSize;
|
||||||
|
variance = shadow_vsm_variance(sc.xyz, light_index, distance, min_variance, variance_transition);
|
||||||
|
ofs_sum += min(max(step(distance, variance.y), variance.x), 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
float shadow_csm(float distance, vec3 lightDir, int light_index, float shadow_bias, float normal_bias) {
|
float shadow_sum = ofs_sum / 8.0;
|
||||||
|
|
||||||
|
if (shadow_sum != 0.0 && shadow_sum != 1.0) {
|
||||||
|
for (int i = 4; i < samples_div2; i++) {
|
||||||
|
ofs_coord.x = i;
|
||||||
|
vec4 offsets = texelFetch(shadow_offsets, ofs_coord, 0) * shadow_softness;
|
||||||
|
sc.xy = dir.xy + offsets.rg * texelSize;
|
||||||
|
vec2 variance = shadow_vsm_variance(sc.xyz, light_index, distance, min_variance, variance_transition);
|
||||||
|
ofs_sum += min(max(step(distance, variance.y), variance.x), 1.0);
|
||||||
|
|
||||||
|
sc.xy = dir.xy + offsets.ba * texelSize;
|
||||||
|
variance = shadow_vsm_variance(sc.xyz, light_index, distance, min_variance, variance_transition);
|
||||||
|
ofs_sum += min(max(step(distance, variance.y), variance.x), 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
shadow_sum = ofs_sum / (samples_div2 * 2.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// vec3 sampleDir = dir + (rand(vec2(v_position_ws.x, v_position_ws.y))*0.25f);
|
||||||
|
// float shadow = 0.0;
|
||||||
|
// vec2 moments = ;
|
||||||
|
|
||||||
|
// // Calculate the variance
|
||||||
|
// float variance = max(moments.y - (moments.x * moments.x), min_variance);
|
||||||
|
// float d = distance - moments.x;
|
||||||
|
// float p_max = linstep(variance_transition, 1.0, variance / (variance + d * d));
|
||||||
|
|
||||||
|
return shadow_sum;//min(max(step(distance, moments.x), shadow_sum), 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
float shadowmap_cascade_sample(vec2 sc, int cascade_index, float blend_factor) {
|
||||||
|
float s1 = texture(shadowMap2D[cascade_index], sc).r;
|
||||||
|
// float s2 = texture(shadowMap2D[cascade_index + 1], sc).r;
|
||||||
|
// return mix(s1, s2, blend_factor);
|
||||||
|
return s1;
|
||||||
|
}
|
||||||
|
|
||||||
|
float shadow_csm(float distance, vec3 lightDir, int light_index, float shadow_bias, float normal_bias, float shadow_softness) {
|
||||||
// Determine which cascade to use
|
// Determine which cascade to use
|
||||||
int cascade_index = -1;
|
int cascade_index = -1;
|
||||||
int min_cascades_range = light_index * NUM_SHADOW_CASCADES;
|
int min_cascades_range = light_index * NUM_SHADOW_CASCADES;
|
||||||
|
@ -80,9 +103,25 @@ float shadow_csm(float distance, vec3 lightDir, int light_index, float shadow_bi
|
||||||
cascade_index = max_cascades_range - 1;
|
cascade_index = max_cascades_range - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
light_t light = u_lights[light_index];
|
|
||||||
int matrix_index = cascade_index - min_cascades_range;
|
int matrix_index = cascade_index - min_cascades_range;
|
||||||
|
|
||||||
|
// Blend cascades using a blend region value
|
||||||
|
float blend_region = 200.0;
|
||||||
|
float blend_factor = 0.0;
|
||||||
|
if (matrix_index < NUM_SHADOW_CASCADES - 1) {
|
||||||
|
blend_factor = 0.5;
|
||||||
|
}
|
||||||
|
// float cascade_start = u_cascade_distances[cascade_index];
|
||||||
|
// float cascade_end = u_cascade_distances[cascade_index + 1];
|
||||||
|
// float blend_start = cascade_end - blend_region;
|
||||||
|
|
||||||
|
// if (distance > blend_start) {
|
||||||
|
// blend_factor = smoothstep(blend_start, cascade_end, distance);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
light_t light = u_lights[light_index];
|
||||||
|
|
||||||
vec4 fragPosLightSpace = light.shadow_matrix[matrix_index] * vec4(v_position_ws, 1.0);
|
vec4 fragPosLightSpace = light.shadow_matrix[matrix_index] * vec4(v_position_ws, 1.0);
|
||||||
|
|
||||||
// Perform perspective divide
|
// Perform perspective divide
|
||||||
|
@ -116,13 +155,13 @@ float shadow_csm(float distance, vec3 lightDir, int light_index, float shadow_bi
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
ofs_coord.x = i;
|
ofs_coord.x = i;
|
||||||
vec4 offsets = texelFetch(shadow_offsets, ofs_coord, 0) * shadow_offset_radius;
|
vec4 offsets = texelFetch(shadow_offsets, ofs_coord, 0) * shadow_softness;
|
||||||
sc.xy = projCoords.xy + offsets.rg * texelSize;
|
sc.xy = projCoords.xy + offsets.rg * texelSize;
|
||||||
float csmDepth = texture(shadowMap2D[cascade_index], sc.xy).r;
|
float csmDepth = shadowmap_cascade_sample(sc.xy, cascade_index, blend_factor);
|
||||||
ofs_sum += currentDepth - bias > csmDepth ? 1.0 : 0.0;
|
ofs_sum += currentDepth - bias > csmDepth ? 1.0 : 0.0;
|
||||||
|
|
||||||
sc.xy = projCoords.xy + offsets.ba * texelSize;
|
sc.xy = projCoords.xy + offsets.ba * texelSize;
|
||||||
csmDepth = texture(shadowMap2D[cascade_index], sc.xy).r;
|
csmDepth = shadowmap_cascade_sample(sc.xy, cascade_index, blend_factor);
|
||||||
ofs_sum += currentDepth - bias > csmDepth ? 1.0 : 0.0;
|
ofs_sum += currentDepth - bias > csmDepth ? 1.0 : 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,13 +170,13 @@ float shadow_csm(float distance, vec3 lightDir, int light_index, float shadow_bi
|
||||||
if (shadow_sum != 0.0 && shadow_sum != 1.0) {
|
if (shadow_sum != 0.0 && shadow_sum != 1.0) {
|
||||||
for (int i = 4; i < samples_div2; i++) {
|
for (int i = 4; i < samples_div2; i++) {
|
||||||
ofs_coord.x = i;
|
ofs_coord.x = i;
|
||||||
vec4 offsets = texelFetch(shadow_offsets, ofs_coord, 0) * shadow_offset_radius;
|
vec4 offsets = texelFetch(shadow_offsets, ofs_coord, 0) * shadow_softness;
|
||||||
sc.xy = projCoords.xy + offsets.rg * texelSize;
|
sc.xy = projCoords.xy + offsets.rg * texelSize;
|
||||||
float csmDepth = texture(shadowMap2D[cascade_index], sc.xy).r;
|
float csmDepth = shadowmap_cascade_sample(sc.xy, cascade_index, blend_factor);
|
||||||
ofs_sum += currentDepth - bias > csmDepth ? 1.0 : 0.0;
|
ofs_sum += currentDepth - bias > csmDepth ? 1.0 : 0.0;
|
||||||
|
|
||||||
sc.xy = projCoords.xy + offsets.ba * texelSize;
|
sc.xy = projCoords.xy + offsets.ba * texelSize;
|
||||||
csmDepth = texture(shadowMap2D[cascade_index], sc.xy).r;
|
csmDepth = shadowmap_cascade_sample(sc.xy, cascade_index, blend_factor);
|
||||||
ofs_sum += currentDepth - bias > csmDepth ? 1.0 : 0.0;
|
ofs_sum += currentDepth - bias > csmDepth ? 1.0 : 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,12 +192,12 @@ vec4 shadowmap(int idx, in vec4 peye, in vec4 neye) {
|
||||||
|
|
||||||
if (light.processed_shadows) {
|
if (light.processed_shadows) {
|
||||||
if (light.type == LIGHT_DIRECTIONAL) {
|
if (light.type == LIGHT_DIRECTIONAL) {
|
||||||
shadowFactor = shadow_csm(-peye.z, light.dir, idx, light.shadow_bias, light.normal_bias);
|
shadowFactor = shadow_csm(-peye.z, light.dir, idx, light.shadow_bias, light.normal_bias, light.shadow_softness);
|
||||||
} else if (light.type == LIGHT_POINT || light.type == LIGHT_SPOT) {
|
} else if (light.type == LIGHT_POINT || light.type == LIGHT_SPOT) {
|
||||||
vec3 light_pos = (view * vec4(light.pos, 1.0)).xyz;
|
vec3 light_pos = (view * vec4(light.pos, 1.0)).xyz;
|
||||||
vec3 dir = light_pos - fragment;
|
vec3 dir = light_pos - fragment;
|
||||||
vec4 sc = inv_view * vec4(dir, 0.0);
|
vec4 sc = inv_view * vec4(dir, 0.0);
|
||||||
shadowFactor = shadow_vsm(length(dir), -sc.xyz, idx, light.min_variance, light.variance_transition);
|
shadowFactor = shadow_vsm(length(dir), -sc.xyz, idx, light.min_variance, light.variance_transition, light.shadow_softness);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17291,6 +17291,7 @@ typedef struct light_t {
|
||||||
float variance_transition; //< VSM
|
float variance_transition; //< VSM
|
||||||
float shadow_bias; //< CSM
|
float shadow_bias; //< CSM
|
||||||
float normal_bias; //< CSM
|
float normal_bias; //< CSM
|
||||||
|
float shadow_softness;
|
||||||
|
|
||||||
// internals
|
// internals
|
||||||
bool cached; //< used by scene to invalidate cached light data
|
bool cached; //< used by scene to invalidate cached light data
|
||||||
|
@ -17350,7 +17351,6 @@ typedef struct shadowmap_t {
|
||||||
|
|
||||||
// shadowmap offsets texture;
|
// shadowmap offsets texture;
|
||||||
int filter_size, window_size;
|
int filter_size, window_size;
|
||||||
float offset_radius;
|
|
||||||
handle offsets_texture;
|
handle offsets_texture;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
@ -383307,10 +383307,11 @@ light_t light() {
|
||||||
l.outerCone = 0.9f; // 25 deg
|
l.outerCone = 0.9f; // 25 deg
|
||||||
l.cast_shadows = true;
|
l.cast_shadows = true;
|
||||||
l.processed_shadows = false;
|
l.processed_shadows = false;
|
||||||
l.shadow_distance = 200.0f;
|
l.shadow_distance = 400.0f;
|
||||||
l.shadow_near_clip = 0.01f;
|
l.shadow_near_clip = 0.01f;
|
||||||
l.shadow_bias = 0.15f;
|
l.shadow_bias = 0.15f;
|
||||||
l.normal_bias = 0.05f;
|
l.normal_bias = 0.05f;
|
||||||
|
l.shadow_softness = 7.0f;
|
||||||
l.min_variance = 0.00002f;
|
l.min_variance = 0.00002f;
|
||||||
l.variance_transition = 0.2f;
|
l.variance_transition = 0.2f;
|
||||||
return l;
|
return l;
|
||||||
|
@ -383393,6 +383394,7 @@ void light_update(unsigned num_lights, light_t *lv) {
|
||||||
shader_float(va("u_lights[%d].outerCone", i), lv[i].outerCone);
|
shader_float(va("u_lights[%d].outerCone", i), lv[i].outerCone);
|
||||||
shader_float(va("u_lights[%d].shadow_bias", i), lv[i].shadow_bias);
|
shader_float(va("u_lights[%d].shadow_bias", i), lv[i].shadow_bias);
|
||||||
shader_float(va("u_lights[%d].normal_bias", i), lv[i].normal_bias);
|
shader_float(va("u_lights[%d].normal_bias", i), lv[i].normal_bias);
|
||||||
|
shader_float(va("u_lights[%d].shadow_softness", i), lv[i].shadow_softness);
|
||||||
shader_float(va("u_lights[%d].min_variance", i), lv[i].min_variance);
|
shader_float(va("u_lights[%d].min_variance", i), lv[i].min_variance);
|
||||||
shader_float(va("u_lights[%d].variance_transition", i), lv[i].variance_transition);
|
shader_float(va("u_lights[%d].variance_transition", i), lv[i].variance_transition);
|
||||||
shader_bool(va("u_lights[%d].processed_shadows", i), lv[i].processed_shadows);
|
shader_bool(va("u_lights[%d].processed_shadows", i), lv[i].processed_shadows);
|
||||||
|
@ -383420,6 +383422,7 @@ void ui_light(light_t *l) {
|
||||||
ui_float("Outer Cone", &l->outerCone);
|
ui_float("Outer Cone", &l->outerCone);
|
||||||
ui_float_("Shadow Bias", &l->shadow_bias, 0.00005);
|
ui_float_("Shadow Bias", &l->shadow_bias, 0.00005);
|
||||||
ui_float_("Normal Bias", &l->normal_bias, 0.00005);
|
ui_float_("Normal Bias", &l->normal_bias, 0.00005);
|
||||||
|
ui_float_("Shadow Softness", &l->shadow_softness, 0.5);
|
||||||
ui_float_("Min Variance", &l->min_variance, 0.00005);
|
ui_float_("Min Variance", &l->min_variance, 0.00005);
|
||||||
ui_float_("Variance Transition", &l->variance_transition, 0.0005);
|
ui_float_("Variance Transition", &l->variance_transition, 0.0005);
|
||||||
}
|
}
|
||||||
|
@ -383468,7 +383471,7 @@ shadowmap_init_caster_vsm(shadowmap_t *s, int light_index, int texture_width) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a cubemap color texture
|
// Create a cubemap moments texture
|
||||||
glGenTextures(1, &s->maps[light_index].texture);
|
glGenTextures(1, &s->maps[light_index].texture);
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, s->maps[light_index].texture);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, s->maps[light_index].texture);
|
||||||
for (int i = 0; i < 6; i++) {
|
for (int i = 0; i < 6; i++) {
|
||||||
|
@ -383526,7 +383529,6 @@ shadowmap_t shadowmap(int vsm_texture_width, int csm_texture_width) { // = 512,
|
||||||
s.vsm_blur_scale = 0.75f;
|
s.vsm_blur_scale = 0.75f;
|
||||||
s.filter_size = 8;
|
s.filter_size = 8;
|
||||||
s.window_size = 10;
|
s.window_size = 10;
|
||||||
s.offset_radius = 7.0f;
|
|
||||||
#if 0
|
#if 0
|
||||||
s.cascade_splits[0] = 0.1f;
|
s.cascade_splits[0] = 0.1f;
|
||||||
s.cascade_splits[1] = 0.3f;
|
s.cascade_splits[1] = 0.3f;
|
||||||
|
@ -384121,7 +384123,6 @@ void ui_shadowmap(shadowmap_t *s) {
|
||||||
if (ui_collapse("Shadowmap Offsets", "shadowmap_offsets")) {
|
if (ui_collapse("Shadowmap Offsets", "shadowmap_offsets")) {
|
||||||
ui_int("Filter Size", &s->filter_size);
|
ui_int("Filter Size", &s->filter_size);
|
||||||
ui_int("Window Size", &s->window_size);
|
ui_int("Window Size", &s->window_size);
|
||||||
ui_float("Random Radius", &s->offset_radius);
|
|
||||||
ui_collapse_end();
|
ui_collapse_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -386326,7 +386327,6 @@ void model_set_uniforms(model_t m, int shader, mat44 mv, mat44 proj, mat44 view,
|
||||||
glBindTexture(GL_TEXTURE_3D, m.shadow_map->offsets_texture);
|
glBindTexture(GL_TEXTURE_3D, m.shadow_map->offsets_texture);
|
||||||
shader_int("shadow_filter_size", m.shadow_map->filter_size);
|
shader_int("shadow_filter_size", m.shadow_map->filter_size);
|
||||||
shader_int("shadow_window_size", m.shadow_map->window_size);
|
shader_int("shadow_window_size", m.shadow_map->window_size);
|
||||||
shader_float("shadow_offset_radius", m.shadow_map->offset_radius);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (m.shadow_map == NULL || !m.shadow_receiver) {
|
else if (m.shadow_map == NULL || !m.shadow_receiver) {
|
||||||
|
|
|
@ -1482,10 +1482,11 @@ light_t light() {
|
||||||
l.outerCone = 0.9f; // 25 deg
|
l.outerCone = 0.9f; // 25 deg
|
||||||
l.cast_shadows = true;
|
l.cast_shadows = true;
|
||||||
l.processed_shadows = false;
|
l.processed_shadows = false;
|
||||||
l.shadow_distance = 200.0f;
|
l.shadow_distance = 400.0f;
|
||||||
l.shadow_near_clip = 0.01f;
|
l.shadow_near_clip = 0.01f;
|
||||||
l.shadow_bias = 0.15f;
|
l.shadow_bias = 0.15f;
|
||||||
l.normal_bias = 0.05f;
|
l.normal_bias = 0.05f;
|
||||||
|
l.shadow_softness = 7.0f;
|
||||||
l.min_variance = 0.00002f;
|
l.min_variance = 0.00002f;
|
||||||
l.variance_transition = 0.2f;
|
l.variance_transition = 0.2f;
|
||||||
return l;
|
return l;
|
||||||
|
@ -1568,6 +1569,7 @@ void light_update(unsigned num_lights, light_t *lv) {
|
||||||
shader_float(va("u_lights[%d].outerCone", i), lv[i].outerCone);
|
shader_float(va("u_lights[%d].outerCone", i), lv[i].outerCone);
|
||||||
shader_float(va("u_lights[%d].shadow_bias", i), lv[i].shadow_bias);
|
shader_float(va("u_lights[%d].shadow_bias", i), lv[i].shadow_bias);
|
||||||
shader_float(va("u_lights[%d].normal_bias", i), lv[i].normal_bias);
|
shader_float(va("u_lights[%d].normal_bias", i), lv[i].normal_bias);
|
||||||
|
shader_float(va("u_lights[%d].shadow_softness", i), lv[i].shadow_softness);
|
||||||
shader_float(va("u_lights[%d].min_variance", i), lv[i].min_variance);
|
shader_float(va("u_lights[%d].min_variance", i), lv[i].min_variance);
|
||||||
shader_float(va("u_lights[%d].variance_transition", i), lv[i].variance_transition);
|
shader_float(va("u_lights[%d].variance_transition", i), lv[i].variance_transition);
|
||||||
shader_bool(va("u_lights[%d].processed_shadows", i), lv[i].processed_shadows);
|
shader_bool(va("u_lights[%d].processed_shadows", i), lv[i].processed_shadows);
|
||||||
|
@ -1595,6 +1597,7 @@ void ui_light(light_t *l) {
|
||||||
ui_float("Outer Cone", &l->outerCone);
|
ui_float("Outer Cone", &l->outerCone);
|
||||||
ui_float_("Shadow Bias", &l->shadow_bias, 0.00005);
|
ui_float_("Shadow Bias", &l->shadow_bias, 0.00005);
|
||||||
ui_float_("Normal Bias", &l->normal_bias, 0.00005);
|
ui_float_("Normal Bias", &l->normal_bias, 0.00005);
|
||||||
|
ui_float_("Shadow Softness", &l->shadow_softness, 0.5);
|
||||||
ui_float_("Min Variance", &l->min_variance, 0.00005);
|
ui_float_("Min Variance", &l->min_variance, 0.00005);
|
||||||
ui_float_("Variance Transition", &l->variance_transition, 0.0005);
|
ui_float_("Variance Transition", &l->variance_transition, 0.0005);
|
||||||
}
|
}
|
||||||
|
@ -1643,7 +1646,7 @@ shadowmap_init_caster_vsm(shadowmap_t *s, int light_index, int texture_width) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a cubemap color texture
|
// Create a cubemap moments texture
|
||||||
glGenTextures(1, &s->maps[light_index].texture);
|
glGenTextures(1, &s->maps[light_index].texture);
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, s->maps[light_index].texture);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, s->maps[light_index].texture);
|
||||||
for (int i = 0; i < 6; i++) {
|
for (int i = 0; i < 6; i++) {
|
||||||
|
@ -1701,7 +1704,6 @@ shadowmap_t shadowmap(int vsm_texture_width, int csm_texture_width) { // = 512,
|
||||||
s.vsm_blur_scale = 0.75f;
|
s.vsm_blur_scale = 0.75f;
|
||||||
s.filter_size = 8;
|
s.filter_size = 8;
|
||||||
s.window_size = 10;
|
s.window_size = 10;
|
||||||
s.offset_radius = 7.0f;
|
|
||||||
#if 0
|
#if 0
|
||||||
s.cascade_splits[0] = 0.1f;
|
s.cascade_splits[0] = 0.1f;
|
||||||
s.cascade_splits[1] = 0.3f;
|
s.cascade_splits[1] = 0.3f;
|
||||||
|
@ -2296,7 +2298,6 @@ void ui_shadowmap(shadowmap_t *s) {
|
||||||
if (ui_collapse("Shadowmap Offsets", "shadowmap_offsets")) {
|
if (ui_collapse("Shadowmap Offsets", "shadowmap_offsets")) {
|
||||||
ui_int("Filter Size", &s->filter_size);
|
ui_int("Filter Size", &s->filter_size);
|
||||||
ui_int("Window Size", &s->window_size);
|
ui_int("Window Size", &s->window_size);
|
||||||
ui_float("Random Radius", &s->offset_radius);
|
|
||||||
ui_collapse_end();
|
ui_collapse_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4501,7 +4502,6 @@ void model_set_uniforms(model_t m, int shader, mat44 mv, mat44 proj, mat44 view,
|
||||||
glBindTexture(GL_TEXTURE_3D, m.shadow_map->offsets_texture);
|
glBindTexture(GL_TEXTURE_3D, m.shadow_map->offsets_texture);
|
||||||
shader_int("shadow_filter_size", m.shadow_map->filter_size);
|
shader_int("shadow_filter_size", m.shadow_map->filter_size);
|
||||||
shader_int("shadow_window_size", m.shadow_map->window_size);
|
shader_int("shadow_window_size", m.shadow_map->window_size);
|
||||||
shader_float("shadow_offset_radius", m.shadow_map->offset_radius);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (m.shadow_map == NULL || !m.shadow_receiver) {
|
else if (m.shadow_map == NULL || !m.shadow_receiver) {
|
||||||
|
|
|
@ -323,6 +323,7 @@ typedef struct light_t {
|
||||||
float variance_transition; //< VSM
|
float variance_transition; //< VSM
|
||||||
float shadow_bias; //< CSM
|
float shadow_bias; //< CSM
|
||||||
float normal_bias; //< CSM
|
float normal_bias; //< CSM
|
||||||
|
float shadow_softness;
|
||||||
|
|
||||||
// internals
|
// internals
|
||||||
bool cached; //< used by scene to invalidate cached light data
|
bool cached; //< used by scene to invalidate cached light data
|
||||||
|
@ -382,7 +383,6 @@ typedef struct shadowmap_t {
|
||||||
|
|
||||||
// shadowmap offsets texture;
|
// shadowmap offsets texture;
|
||||||
int filter_size, window_size;
|
int filter_size, window_size;
|
||||||
float offset_radius;
|
|
||||||
handle offsets_texture;
|
handle offsets_texture;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|
10
engine/v4k.c
10
engine/v4k.c
|
@ -18336,10 +18336,11 @@ light_t light() {
|
||||||
l.outerCone = 0.9f; // 25 deg
|
l.outerCone = 0.9f; // 25 deg
|
||||||
l.cast_shadows = true;
|
l.cast_shadows = true;
|
||||||
l.processed_shadows = false;
|
l.processed_shadows = false;
|
||||||
l.shadow_distance = 200.0f;
|
l.shadow_distance = 400.0f;
|
||||||
l.shadow_near_clip = 0.01f;
|
l.shadow_near_clip = 0.01f;
|
||||||
l.shadow_bias = 0.15f;
|
l.shadow_bias = 0.15f;
|
||||||
l.normal_bias = 0.05f;
|
l.normal_bias = 0.05f;
|
||||||
|
l.shadow_softness = 7.0f;
|
||||||
l.min_variance = 0.00002f;
|
l.min_variance = 0.00002f;
|
||||||
l.variance_transition = 0.2f;
|
l.variance_transition = 0.2f;
|
||||||
return l;
|
return l;
|
||||||
|
@ -18422,6 +18423,7 @@ void light_update(unsigned num_lights, light_t *lv) {
|
||||||
shader_float(va("u_lights[%d].outerCone", i), lv[i].outerCone);
|
shader_float(va("u_lights[%d].outerCone", i), lv[i].outerCone);
|
||||||
shader_float(va("u_lights[%d].shadow_bias", i), lv[i].shadow_bias);
|
shader_float(va("u_lights[%d].shadow_bias", i), lv[i].shadow_bias);
|
||||||
shader_float(va("u_lights[%d].normal_bias", i), lv[i].normal_bias);
|
shader_float(va("u_lights[%d].normal_bias", i), lv[i].normal_bias);
|
||||||
|
shader_float(va("u_lights[%d].shadow_softness", i), lv[i].shadow_softness);
|
||||||
shader_float(va("u_lights[%d].min_variance", i), lv[i].min_variance);
|
shader_float(va("u_lights[%d].min_variance", i), lv[i].min_variance);
|
||||||
shader_float(va("u_lights[%d].variance_transition", i), lv[i].variance_transition);
|
shader_float(va("u_lights[%d].variance_transition", i), lv[i].variance_transition);
|
||||||
shader_bool(va("u_lights[%d].processed_shadows", i), lv[i].processed_shadows);
|
shader_bool(va("u_lights[%d].processed_shadows", i), lv[i].processed_shadows);
|
||||||
|
@ -18449,6 +18451,7 @@ void ui_light(light_t *l) {
|
||||||
ui_float("Outer Cone", &l->outerCone);
|
ui_float("Outer Cone", &l->outerCone);
|
||||||
ui_float_("Shadow Bias", &l->shadow_bias, 0.00005);
|
ui_float_("Shadow Bias", &l->shadow_bias, 0.00005);
|
||||||
ui_float_("Normal Bias", &l->normal_bias, 0.00005);
|
ui_float_("Normal Bias", &l->normal_bias, 0.00005);
|
||||||
|
ui_float_("Shadow Softness", &l->shadow_softness, 0.5);
|
||||||
ui_float_("Min Variance", &l->min_variance, 0.00005);
|
ui_float_("Min Variance", &l->min_variance, 0.00005);
|
||||||
ui_float_("Variance Transition", &l->variance_transition, 0.0005);
|
ui_float_("Variance Transition", &l->variance_transition, 0.0005);
|
||||||
}
|
}
|
||||||
|
@ -18497,7 +18500,7 @@ shadowmap_init_caster_vsm(shadowmap_t *s, int light_index, int texture_width) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a cubemap color texture
|
// Create a cubemap moments texture
|
||||||
glGenTextures(1, &s->maps[light_index].texture);
|
glGenTextures(1, &s->maps[light_index].texture);
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, s->maps[light_index].texture);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, s->maps[light_index].texture);
|
||||||
for (int i = 0; i < 6; i++) {
|
for (int i = 0; i < 6; i++) {
|
||||||
|
@ -18555,7 +18558,6 @@ shadowmap_t shadowmap(int vsm_texture_width, int csm_texture_width) { // = 512,
|
||||||
s.vsm_blur_scale = 0.75f;
|
s.vsm_blur_scale = 0.75f;
|
||||||
s.filter_size = 8;
|
s.filter_size = 8;
|
||||||
s.window_size = 10;
|
s.window_size = 10;
|
||||||
s.offset_radius = 7.0f;
|
|
||||||
#if 0
|
#if 0
|
||||||
s.cascade_splits[0] = 0.1f;
|
s.cascade_splits[0] = 0.1f;
|
||||||
s.cascade_splits[1] = 0.3f;
|
s.cascade_splits[1] = 0.3f;
|
||||||
|
@ -19150,7 +19152,6 @@ void ui_shadowmap(shadowmap_t *s) {
|
||||||
if (ui_collapse("Shadowmap Offsets", "shadowmap_offsets")) {
|
if (ui_collapse("Shadowmap Offsets", "shadowmap_offsets")) {
|
||||||
ui_int("Filter Size", &s->filter_size);
|
ui_int("Filter Size", &s->filter_size);
|
||||||
ui_int("Window Size", &s->window_size);
|
ui_int("Window Size", &s->window_size);
|
||||||
ui_float("Random Radius", &s->offset_radius);
|
|
||||||
ui_collapse_end();
|
ui_collapse_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21355,7 +21356,6 @@ void model_set_uniforms(model_t m, int shader, mat44 mv, mat44 proj, mat44 view,
|
||||||
glBindTexture(GL_TEXTURE_3D, m.shadow_map->offsets_texture);
|
glBindTexture(GL_TEXTURE_3D, m.shadow_map->offsets_texture);
|
||||||
shader_int("shadow_filter_size", m.shadow_map->filter_size);
|
shader_int("shadow_filter_size", m.shadow_map->filter_size);
|
||||||
shader_int("shadow_window_size", m.shadow_map->window_size);
|
shader_int("shadow_window_size", m.shadow_map->window_size);
|
||||||
shader_float("shadow_offset_radius", m.shadow_map->offset_radius);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (m.shadow_map == NULL || !m.shadow_receiver) {
|
else if (m.shadow_map == NULL || !m.shadow_receiver) {
|
||||||
|
|
|
@ -3358,6 +3358,7 @@ typedef struct light_t {
|
||||||
float variance_transition; //< VSM
|
float variance_transition; //< VSM
|
||||||
float shadow_bias; //< CSM
|
float shadow_bias; //< CSM
|
||||||
float normal_bias; //< CSM
|
float normal_bias; //< CSM
|
||||||
|
float shadow_softness;
|
||||||
|
|
||||||
// internals
|
// internals
|
||||||
bool cached; //< used by scene to invalidate cached light data
|
bool cached; //< used by scene to invalidate cached light data
|
||||||
|
@ -3417,7 +3418,6 @@ typedef struct shadowmap_t {
|
||||||
|
|
||||||
// shadowmap offsets texture;
|
// shadowmap offsets texture;
|
||||||
int filter_size, window_size;
|
int filter_size, window_size;
|
||||||
float offset_radius;
|
|
||||||
handle offsets_texture;
|
handle offsets_texture;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|
Loading…
Reference in New Issue