Eevee: Put all constant uniforms in a global UBO.

This is an optimization / cleanup commit.

The use of a global ubo remove lots of uniform lookups and only transfert data when needed.

Lots of renaming for more consistent codestyle.
This commit is contained in:
Clément Foucault 2018-01-21 17:25:10 +01:00
parent 790025c01e
commit a507c251b2
25 changed files with 530 additions and 520 deletions

View File

@ -135,6 +135,7 @@ data_to_c_simple(engines/eevee/shaders/default_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/default_world_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/background_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/concentric_samples_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/common_uniforms_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lamps_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lightprobe_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl SRC)

View File

@ -55,6 +55,7 @@ static void eevee_view_layer_data_free(void *storage)
DRW_UBO_FREE_SAFE(sldata->probe_ubo);
DRW_UBO_FREE_SAFE(sldata->grid_ubo);
DRW_UBO_FREE_SAFE(sldata->planar_ubo);
DRW_UBO_FREE_SAFE(sldata->common_ubo);
DRW_FRAMEBUFFER_FREE_SAFE(sldata->probe_fb);
DRW_FRAMEBUFFER_FREE_SAFE(sldata->probe_filter_fb);
DRW_TEXTURE_FREE_SAFE(sldata->probe_rt);
@ -62,9 +63,6 @@ static void eevee_view_layer_data_free(void *storage)
DRW_TEXTURE_FREE_SAFE(sldata->probe_pool);
DRW_TEXTURE_FREE_SAFE(sldata->irradiance_pool);
DRW_TEXTURE_FREE_SAFE(sldata->irradiance_rt);
/* Volumetrics */
MEM_SAFE_FREE(sldata->volumetrics);
}
static void eevee_lightprobe_data_free(void *storage)

View File

@ -102,6 +102,7 @@ static void eevee_create_shader_downsample(void)
void EEVEE_effects_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
EEVEE_StorageList *stl = vedata->stl;
EEVEE_FramebufferList *fbl = vedata->fbl;
EEVEE_TextureList *txl = vedata->txl;
@ -169,8 +170,8 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
mip_size[0] = floorf(fmaxf(1.0f, mip_size[0] / 2.0f));
mip_size[1] = floorf(fmaxf(1.0f, mip_size[1] / 2.0f));
}
stl->g_data->mip_ratio[i][0] = viewport_size[0] / (mip_size[0] * powf(2.0f, floorf(log2f(floorf(viewport_size[0] / mip_size[0])))));
stl->g_data->mip_ratio[i][1] = viewport_size[1] / (mip_size[1] * powf(2.0f, floorf(log2f(floorf(viewport_size[1] / mip_size[1])))));
common_data->mip_ratio[i][0] = viewport_size[0] / (mip_size[0] * powf(2.0f, floorf(log2f(floorf(viewport_size[0] / mip_size[0])))));
common_data->mip_ratio[i][1] = viewport_size[1] / (mip_size[1] * powf(2.0f, floorf(log2f(floorf(viewport_size[1] / mip_size[1])))));
}
@ -209,12 +210,10 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
}
}
void EEVEE_effects_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
void EEVEE_effects_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_PassList *psl = vedata->psl;
EEVEE_StorageList *stl = vedata->stl;
EEVEE_TextureList *txl = vedata->txl;
EEVEE_EffectsInfo *effects = stl->effects;
int downsample_write = DRW_STATE_WRITE_DEPTH;
/* Intel gpu seems to have problem rendering to only depth format.
@ -229,7 +228,7 @@ void EEVEE_effects_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *v
psl->color_downsample_ps = DRW_pass_create("Downsample", DRW_STATE_WRITE_COLOR);
DRWShadingGroup *grp = DRW_shgroup_create(e_data.downsample_sh, psl->color_downsample_ps);
DRW_shgroup_uniform_buffer(grp, "source", &e_data.color_src);
DRW_shgroup_uniform_float(grp, "fireflyFactor", &effects->ssr_firefly_fac, 1);
DRW_shgroup_uniform_float(grp, "fireflyFactor", &sldata->common_data.ssr_firefly_fac, 1);
DRW_shgroup_call_add(grp, quad, NULL);
}
@ -401,7 +400,7 @@ void EEVEE_downsample_cube_buffer(EEVEE_Data *vedata, struct GPUFrameBuffer *fb_
DRW_stats_group_end();
}
void EEVEE_draw_effects(EEVEE_Data *vedata)
void EEVEE_draw_effects(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_TextureList *txl = vedata->txl;
EEVEE_FramebufferList *fbl = vedata->fbl;
@ -478,7 +477,7 @@ void EEVEE_draw_effects(EEVEE_Data *vedata)
}
/* Record pers matrix for the next frame. */
DRW_viewport_matrix_get(stl->g_data->prev_persmat, DRW_MAT_PERS);
DRW_viewport_matrix_get(sldata->common_data.prev_persmat, DRW_MAT_PERS);
/* Update double buffer status if render mode. */
if (DRW_state_is_image_render()) {

View File

@ -66,10 +66,14 @@ static void eevee_engine_init(void *ved)
(int)viewport_size[0], (int)viewport_size[1],
&tex, 1);
if (sldata->common_ubo == NULL) {
sldata->common_ubo = DRW_uniformbuffer_create(sizeof(sldata->common_data), &sldata->common_data);
}
/* EEVEE_effects_init needs to go first for TAA */
EEVEE_effects_init(sldata, vedata);
EEVEE_materials_init(stl, fbl);
EEVEE_materials_init(sldata, stl, fbl);
EEVEE_lights_init(sldata);
EEVEE_lightprobes_init(sldata, vedata);
@ -188,6 +192,9 @@ static void eevee_draw_background(void *vedata)
EEVEE_lightprobes_refresh(sldata, vedata);
DRW_stats_group_end();
/* Update common buffer after probe rendering. */
DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
/* Refresh shadows */
DRW_stats_group_start("Shadows");
EEVEE_draw_shadows(sldata, psl);
@ -263,7 +270,7 @@ static void eevee_draw_background(void *vedata)
/* Post Process */
DRW_stats_group_start("Post FX");
EEVEE_draw_effects(vedata);
EEVEE_draw_effects(sldata, vedata);
DRW_stats_group_end();
if ((stl->effects->taa_current_sample > 1) && !DRW_state_is_image_render()) {

View File

@ -107,6 +107,7 @@ extern char datatoc_irradiance_lib_glsl[];
extern char datatoc_lightprobe_lib_glsl[];
extern char datatoc_octahedron_lib_glsl[];
extern char datatoc_bsdf_common_lib_glsl[];
extern char datatoc_common_uniforms_lib_glsl[];
extern char datatoc_bsdf_sampling_lib_glsl[];
extern GlobalsUboStorage ts;
@ -205,6 +206,7 @@ static void lightprobe_shaders_init(void)
char *shader_str = NULL;
shader_str = BLI_string_joinN(
datatoc_common_uniforms_lib_glsl,
datatoc_bsdf_common_lib_glsl,
datatoc_bsdf_sampling_lib_glsl,
datatoc_lightprobe_filter_glossy_frag_glsl);
@ -218,6 +220,7 @@ static void lightprobe_shaders_init(void)
MEM_freeN(shader_str);
shader_str = BLI_string_joinN(
datatoc_common_uniforms_lib_glsl,
datatoc_bsdf_common_lib_glsl,
datatoc_bsdf_sampling_lib_glsl,
datatoc_lightprobe_filter_diffuse_frag_glsl);
@ -227,6 +230,7 @@ static void lightprobe_shaders_init(void)
MEM_freeN(shader_str);
shader_str = BLI_string_joinN(
datatoc_common_uniforms_lib_glsl,
datatoc_bsdf_common_lib_glsl,
datatoc_bsdf_sampling_lib_glsl,
datatoc_lightprobe_filter_visibility_frag_glsl);
@ -237,6 +241,7 @@ static void lightprobe_shaders_init(void)
shader_str = BLI_string_joinN(
datatoc_octahedron_lib_glsl,
datatoc_common_uniforms_lib_glsl,
datatoc_bsdf_common_lib_glsl,
datatoc_irradiance_lib_glsl,
datatoc_lightprobe_lib_glsl,
@ -252,6 +257,7 @@ static void lightprobe_shaders_init(void)
shader_str = BLI_string_joinN(
datatoc_octahedron_lib_glsl,
datatoc_common_uniforms_lib_glsl,
datatoc_bsdf_common_lib_glsl,
datatoc_lightprobe_lib_glsl,
datatoc_lightprobe_cube_display_frag_glsl);
@ -276,6 +282,7 @@ static void lightprobe_shaders_init(void)
void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *UNUSED(vedata))
{
EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
bool update_all = false;
const DRWContextState *draw_ctx = DRW_context_state_get();
ViewLayer *view_layer = draw_ctx->view_layer;
@ -288,15 +295,16 @@ void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *UNUSED(veda
if (!sldata->probes) {
sldata->probes = MEM_callocN(sizeof(EEVEE_LightProbesInfo), "EEVEE_LightProbesInfo");
sldata->probes->specular_toggle = true;
sldata->probes->ssr_toggle = true;
sldata->probes->sss_toggle = true;
sldata->probes->grid_initialized = false;
sldata->probe_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_LightProbe) * MAX_PROBE, NULL);
sldata->grid_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_LightGrid) * MAX_GRID, NULL);
sldata->planar_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_PlanarReflection) * MAX_PLANAR, NULL);
}
common_data->spec_toggle = true;
common_data->ssr_toggle = true;
common_data->sss_toggle = true;
int prop_bounce_num = BKE_collection_engine_property_value_get_int(props, "gi_diffuse_bounces");
if (sldata->probes->num_bounce != prop_bounce_num) {
sldata->probes->num_bounce = prop_bounce_num;
@ -315,8 +323,8 @@ void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *UNUSED(veda
}
int visibility_res = BKE_collection_engine_property_value_get_int(props, "gi_visibility_resolution");
if (sldata->probes->irradiance_vis_size != visibility_res) {
sldata->probes->irradiance_vis_size = visibility_res;
if (common_data->prb_irradiance_vis_size != visibility_res) {
common_data->prb_irradiance_vis_size = visibility_res;
update_all = true;
}
@ -360,6 +368,7 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
EEVEE_StorageList *stl = vedata->stl;
EEVEE_LightProbesInfo *pinfo = sldata->probes;
pinfo->do_cube_update = false;
pinfo->num_cube = 1; /* at least one for the world */
pinfo->num_grid = 1;
pinfo->num_planar = 0;
@ -500,8 +509,8 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
DRW_shgroup_attrib_float(grp, "probe_id", 1); /* XXX this works because we are still uploading 4bytes and using the right stride */
DRW_shgroup_attrib_float(grp, "probe_location", 3);
DRW_shgroup_attrib_float(grp, "sphere_size", 1);
DRW_shgroup_uniform_float(grp, "lodCubeMax", &sldata->probes->lod_cube_max, 1);
DRW_shgroup_uniform_buffer(grp, "probeCubes", &sldata->probe_pool);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
geom = DRW_cache_quad_get();
grp = stl->g_data->planar_display_shgrp = DRW_shgroup_instance_create(e_data.probe_planar_display_sh, psl->probe_display, geom);
@ -516,7 +525,7 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get();
DRWShadingGroup *grp = stl->g_data->planar_downsample = DRW_shgroup_instance_create(e_data.probe_planar_downsample_sh, psl->probe_planar_downsample_ps, geom);
DRW_shgroup_uniform_buffer(grp, "source", &txl->planar_pool);
DRW_shgroup_uniform_float(grp, "fireflyFactor", &stl->effects->ssr_firefly_fac, 1);
DRW_shgroup_uniform_float(grp, "fireflyFactor", &sldata->common_data.ssr_firefly_fac, 1);
}
}
@ -549,7 +558,6 @@ void EEVEE_lightprobes_cache_add(EEVEE_ViewLayerData *sldata, Object *ob)
ped->need_update = true;
ped->probe_id = 0;
if (probe->type == LIGHTPROBE_TYPE_GRID) {
ped->updated_cells = 0;
ped->updated_lvl = 0;
@ -565,6 +573,8 @@ void EEVEE_lightprobes_cache_add(EEVEE_ViewLayerData *sldata, Object *ob)
ped->probe_id = 0;
}
pinfo->do_cube_update |= ped->need_update;
if (probe->type == LIGHTPROBE_TYPE_CUBE) {
pinfo->probes_cube_ref[pinfo->num_cube] = ob;
pinfo->num_cube++;
@ -832,6 +842,7 @@ static void EEVEE_lightprobes_updates(EEVEE_ViewLayerData *sldata, EEVEE_PassLis
void EEVEE_lightprobes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
EEVEE_StorageList *stl = vedata->stl;
EEVEE_LightProbesInfo *pinfo = sldata->probes;
Object *ob;
@ -849,7 +860,7 @@ void EEVEE_lightprobes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *ved
}
int irr_size[3];
irradiance_pool_size_get(pinfo->irradiance_vis_size, pinfo->total_irradiance_samples, irr_size);
irradiance_pool_size_get(common_data->prb_irradiance_vis_size, pinfo->total_irradiance_samples, irr_size);
if ((irr_size[0] != pinfo->cache_irradiance_size[0]) ||
(irr_size[1] != pinfo->cache_irradiance_size[1]) ||
@ -876,7 +887,7 @@ void EEVEE_lightprobes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *ved
/* Tag probes to refresh */
e_data.update_world |= PROBE_UPDATE_CUBE;
e_data.world_ready_to_shade = false;
pinfo->num_render_cube = 0;
common_data->prb_num_render_cube = 0;
pinfo->cache_num_cube = pinfo->num_cube;
for (int i = 1; (ob = pinfo->probes_cube_ref[i]) && (i < MAX_PROBE); i++) {
@ -908,7 +919,7 @@ void EEVEE_lightprobes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *ved
sldata->irradiance_rt = DRW_texture_create_2D_array(irr_size[0], irr_size[1], irr_size[2],
irradiance_format, DRW_TEX_FILTER, NULL);
}
pinfo->num_render_grid = 0;
common_data->prb_num_render_grid = 0;
pinfo->updated_bounce = 0;
pinfo->grid_initialized = false;
e_data.update_world |= PROBE_UPDATE_GRID;
@ -920,9 +931,9 @@ void EEVEE_lightprobes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *ved
}
}
if (pinfo->num_render_grid > pinfo->num_grid) {
if (common_data->prb_num_render_grid > pinfo->num_grid) {
/* This can happen when deleting a probe. */
pinfo->num_render_grid = pinfo->num_grid;
common_data->prb_num_render_grid = pinfo->num_grid;
}
EEVEE_lightprobes_updates(sldata, vedata->psl, vedata->stl);
@ -939,14 +950,14 @@ static void downsample_planar(void *vedata, int level)
EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
const float *size = DRW_viewport_size_get();
copy_v2_v2(stl->g_data->texel_size, size);
copy_v2_v2(stl->g_data->planar_texel_size, size);
for (int i = 0; i < level - 1; ++i) {
stl->g_data->texel_size[0] /= 2.0f;
stl->g_data->texel_size[1] /= 2.0f;
min_ff(floorf(stl->g_data->texel_size[0]), 1.0f);
min_ff(floorf(stl->g_data->texel_size[1]), 1.0f);
stl->g_data->planar_texel_size[0] /= 2.0f;
stl->g_data->planar_texel_size[1] /= 2.0f;
min_ff(floorf(stl->g_data->planar_texel_size[0]), 1.0f);
min_ff(floorf(stl->g_data->planar_texel_size[1]), 1.0f);
}
invert_v2(stl->g_data->texel_size);
invert_v2(stl->g_data->planar_texel_size);
DRW_draw_pass(psl->probe_planar_downsample_ps);
}
@ -1018,7 +1029,7 @@ static void glossy_filter_probe(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata,
CLAMP_MIN(mipsize, 1);
}
/* For shading, save max level of the octahedron map */
pinfo->lod_cube_max = (float)(maxlevel - min_lod_level) - 1.0f;
sldata->common_data.prb_lod_cube_max = (float)(maxlevel - min_lod_level) - 1.0f;
/* reattach to have a valid framebuffer. */
DRW_framebuffer_texture_attach(sldata->probe_filter_fb, sldata->probe_pool, 0, 0);
@ -1029,10 +1040,11 @@ static void diffuse_filter_probe(
EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, EEVEE_PassList *psl, int offset,
float clipsta, float clipend, float vis_range, float vis_blur)
{
EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
EEVEE_LightProbesInfo *pinfo = sldata->probes;
int pool_size[3];
irradiance_pool_size_get(pinfo->irradiance_vis_size, pinfo->total_irradiance_samples, pool_size);
irradiance_pool_size_get(common_data->prb_irradiance_vis_size, pinfo->total_irradiance_samples, pool_size);
/* find cell position on the virtual 3D texture */
/* NOTE : Keep in sync with load_irradiance_cell() */
@ -1076,23 +1088,24 @@ static void diffuse_filter_probe(
/* Compute visibility */
pinfo->samples_ct = 512.0f; /* TODO refine */
pinfo->invsamples_ct = 1.0f / pinfo->samples_ct;
pinfo->shres = pinfo->irradiance_vis_size;
pinfo->shres = common_data->prb_irradiance_vis_size;
pinfo->visibility_range = vis_range;
pinfo->visibility_blur = vis_blur;
pinfo->near_clip = -clipsta;
pinfo->far_clip = -clipend;
pinfo->texel_size = 1.0f / (float)pinfo->irradiance_vis_size;
pinfo->texel_size = 1.0f / (float)common_data->prb_irradiance_vis_size;
int cell_per_col = pool_size[1] / pinfo->irradiance_vis_size;
cell_per_row = pool_size[0] / pinfo->irradiance_vis_size;
x = pinfo->irradiance_vis_size * (offset % cell_per_row);
y = pinfo->irradiance_vis_size * ((offset / cell_per_row) % cell_per_col);
int cell_per_col = pool_size[1] / common_data->prb_irradiance_vis_size;
cell_per_row = pool_size[0] / common_data->prb_irradiance_vis_size;
x = common_data->prb_irradiance_vis_size * (offset % cell_per_row);
y = common_data->prb_irradiance_vis_size * ((offset / cell_per_row) % cell_per_col);
int layer = 1 + ((offset / cell_per_row) / cell_per_col);
DRW_framebuffer_texture_detach(sldata->irradiance_rt);
DRW_framebuffer_texture_layer_attach(sldata->probe_filter_fb, sldata->irradiance_rt, 0, layer, 0);
DRW_framebuffer_viewport_size(sldata->probe_filter_fb, x, y, pinfo->irradiance_vis_size, sldata->probes->irradiance_vis_size);
DRW_framebuffer_viewport_size(sldata->probe_filter_fb, x, y, common_data->prb_irradiance_vis_size,
common_data->prb_irradiance_vis_size);
DRW_draw_pass(psl->probe_visibility_compute);
}
@ -1111,23 +1124,13 @@ static void render_scene_to_probe(
EEVEE_StorageList *stl = vedata->stl;
EEVEE_LightProbesInfo *pinfo = sldata->probes;
float winmat[4][4], wininv[4][4], posmat[4][4], tmp_ao_dist, tmp_ao_settings;
float winmat[4][4], wininv[4][4], posmat[4][4];
unit_m4(posmat);
/* Move to capture position */
negate_v3_v3(posmat[3], pos);
/* Disable specular lighting when rendering probes to avoid feedback loops (looks bad). */
sldata->probes->specular_toggle = false;
sldata->probes->ssr_toggle = false;
sldata->probes->sss_toggle = false;
/* Disable AO until we find a way to hide really bad discontinuities between cubefaces. */
tmp_ao_dist = stl->effects->ao_dist;
tmp_ao_settings = stl->effects->ao_settings;
stl->effects->ao_settings = 0.0f; /* Disable AO */
/* 1 - Render to each cubeface individually.
* We do this instead of using geometry shader because a) it's faster,
* b) it's easier than fixing the nodetree shaders (for view dependant effects). */
@ -1143,6 +1146,9 @@ static void render_scene_to_probe(
stl->g_data->minzbuffer = e_data.depth_placeholder;
txl->maxzbuffer = e_data.depth_placeholder;
/* Update common uniforms */
DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
/* Detach to rebind the right cubeface. */
DRW_framebuffer_bind(sldata->probe_fb);
DRW_framebuffer_texture_detach(sldata->probe_rt);
@ -1204,14 +1210,9 @@ static void render_scene_to_probe(
DRW_viewport_matrix_override_unset(DRW_MAT_WININV);
/* Restore */
pinfo->specular_toggle = true;
pinfo->ssr_toggle = true;
pinfo->sss_toggle = true;
txl->planar_pool = tmp_planar_pool;
stl->g_data->minzbuffer = tmp_minz;
txl->maxzbuffer = tmp_maxz;
stl->effects->ao_dist = tmp_ao_dist;
stl->effects->ao_settings = tmp_ao_settings;
}
static void render_scene_to_planar(
@ -1250,11 +1251,6 @@ static void render_scene_to_planar(
DRW_framebuffer_clear(false, true, false, NULL, 1.0);
/* Turn off ssr to avoid black specular */
/* TODO : Enable SSR in planar reflections? (Would be very heavy) */
sldata->probes->ssr_toggle = false;
sldata->probes->sss_toggle = false;
/* Avoid using the texture attached to framebuffer when rendering. */
/* XXX */
GPUTexture *tmp_planar_pool = txl->planar_pool;
@ -1286,8 +1282,6 @@ static void render_scene_to_planar(
DRW_state_clip_planes_reset();
/* Restore */
sldata->probes->ssr_toggle = true;
sldata->probes->sss_toggle = true;
txl->planar_pool = tmp_planar_pool;
txl->planar_depth = tmp_planar_depth;
DRW_viewport_matrix_override_unset(DRW_MAT_PERS);
@ -1373,8 +1367,9 @@ static void lightprobe_cell_world_location_get(EEVEE_LightGrid *egrid, float loc
static void lightprobes_refresh_world(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
EEVEE_PassList *psl = vedata->psl;
EEVEE_LightProbesInfo *pinfo = sldata->probes;
render_world_to_probe(sldata, psl);
if (e_data.update_world & PROBE_UPDATE_CUBE) {
glossy_filter_probe(sldata, vedata, psl, 0);
@ -1391,8 +1386,8 @@ static void lightprobes_refresh_world(EEVEE_ViewLayerData *sldata, EEVEE_Data *v
e_data.update_world = 0;
if (!e_data.world_ready_to_shade) {
e_data.world_ready_to_shade = true;
pinfo->num_render_cube = 1;
pinfo->num_render_grid = 1;
common_data->prb_num_render_cube = 1;
common_data->prb_num_render_grid = 1;
}
DRW_viewport_request_redraw();
}
@ -1425,36 +1420,53 @@ static void lightprobes_refresh_initialize_grid(EEVEE_ViewLayerData *sldata, EEV
static void lightprobes_refresh_planar(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
EEVEE_TextureList *txl = vedata->txl;
Object *ob;
EEVEE_LightProbesInfo *pinfo = sldata->probes;
if (pinfo->num_planar == 0) {
return;
}
/* Temporary Remove all planar reflections (avoid lag effect). */
common_data->prb_num_planar = 0;
/* Turn off ssr to avoid black specular */
/* TODO : Enable SSR in planar reflections? (Would be very heavy) */
common_data->ssr_toggle = false;
common_data->sss_toggle = false;
DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
for (int i = 0; (ob = pinfo->probes_planar_ref[i]) && (i < MAX_PLANAR); i++) {
EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_ensure(ob);
if (!ped->need_update) {
continue;
}
/* Temporary Remove all planar reflections (avoid lag effect). */
int tmp_num_planar = pinfo->num_planar;
pinfo->num_planar = 0;
render_scene_to_planar(sldata, vedata, i, ped->viewmat, ped->persmat, ped->planer_eq_offset);
/* Restore */
pinfo->num_planar = tmp_num_planar;
ped->need_update = false;
ped->probe_id = i;
}
/* Restore */
common_data->prb_num_planar = pinfo->num_planar;
common_data->ssr_toggle = true;
common_data->sss_toggle = true;
/* If there is at least one planar probe */
if (pinfo->num_planar > 0 && (vedata->stl->effects->enabled_effects & EFFECT_SSR) != 0) {
const int max_lod = 9;
DRW_stats_group_start("Planar Probe Downsample");
DRW_framebuffer_recursive_downsample(vedata->fbl->downsample_fb, txl->planar_pool, max_lod, &downsample_planar, vedata);
/* For shading, save max level of the planar map */
pinfo->lod_planar_max = (float)(max_lod);
common_data->prb_lod_planar_max = (float)(max_lod);
DRW_stats_group_end();
}
}
static void lightprobes_refresh_cube(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
EEVEE_PassList *psl = vedata->psl;
EEVEE_StorageList *stl = vedata->stl;
EEVEE_LightProbesInfo *pinfo = sldata->probes;
@ -1470,7 +1482,7 @@ static void lightprobes_refresh_cube(EEVEE_ViewLayerData *sldata, EEVEE_Data *ve
ped->need_update = false;
ped->probe_id = i;
if (!ped->ready_to_shade) {
pinfo->num_render_cube++;
common_data->prb_num_render_cube++;
ped->ready_to_shade = true;
}
#if 0
@ -1487,6 +1499,7 @@ static void lightprobes_refresh_cube(EEVEE_ViewLayerData *sldata, EEVEE_Data *ve
static void lightprobes_refresh_all_no_world(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
EEVEE_PassList *psl = vedata->psl;
EEVEE_StorageList *stl = vedata->stl;
EEVEE_LightProbesInfo *pinfo = sldata->probes;
@ -1506,7 +1519,7 @@ static void lightprobes_refresh_all_no_world(EEVEE_ViewLayerData *sldata, EEVEE_
/* Reflection probes depend on diffuse lighting thus on irradiance grid,
* so update them first. */
while (pinfo->updated_bounce < pinfo->num_bounce) {
pinfo->num_render_grid = pinfo->num_grid;
common_data->prb_num_render_grid = pinfo->num_grid;
/* TODO(sergey): This logic can be split into smaller functions. */
for (int i = 1; (ob = pinfo->probes_grid_ref[i]) && (i < MAX_GRID); i++) {
EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_ensure(ob);
@ -1550,16 +1563,16 @@ static void lightprobes_refresh_all_no_world(EEVEE_ViewLayerData *sldata, EEVEE_
lightprobe_cell_world_location_get(egrid, grid_loc, pos);
SWAP(GPUTexture *, sldata->irradiance_pool, sldata->irradiance_rt);
/* Temporary Remove all probes. */
int tmp_num_render_grid = pinfo->num_render_grid;
int tmp_num_render_cube = pinfo->num_render_cube;
int tmp_num_planar = pinfo->num_planar;
int tmp_num_render_grid = common_data->prb_num_render_grid;
int tmp_num_render_cube = common_data->prb_num_render_cube;
int tmp_num_planar = common_data->prb_num_planar;
float tmp_level_bias = egrid->level_bias;
pinfo->num_render_cube = 0;
pinfo->num_planar = 0;
common_data->prb_num_render_cube = 0;
common_data->prb_num_planar = 0;
/* Use light from previous bounce when capturing radiance. */
if (pinfo->updated_bounce == 0) {
/* But not on first bounce. */
pinfo->num_render_grid = 0;
common_data->prb_num_render_grid = 0;
}
else {
/* Remove bias */
@ -1572,10 +1585,10 @@ static void lightprobes_refresh_all_no_world(EEVEE_ViewLayerData *sldata, EEVEE_
/* To see what is going on. */
SWAP(GPUTexture *, sldata->irradiance_pool, sldata->irradiance_rt);
/* Restore */
pinfo->num_render_cube = tmp_num_render_cube;
common_data->prb_num_render_cube = tmp_num_render_cube;
pinfo->num_planar = tmp_num_planar;
if (pinfo->updated_bounce == 0) {
pinfo->num_render_grid = tmp_num_render_grid;
common_data->prb_num_render_grid = tmp_num_render_grid;
}
else {
egrid->level_bias = tmp_level_bias;
@ -1603,7 +1616,7 @@ static void lightprobes_refresh_all_no_world(EEVEE_ViewLayerData *sldata, EEVEE_
}
pinfo->updated_bounce++;
pinfo->num_render_grid = pinfo->num_grid;
common_data->prb_num_render_grid = pinfo->num_grid;
if (pinfo->updated_bounce < pinfo->num_bounce) {
/* Retag all grids to update for next bounce */
@ -1631,18 +1644,39 @@ static void lightprobes_refresh_all_no_world(EEVEE_ViewLayerData *sldata, EEVEE_
void EEVEE_lightprobes_refresh(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_LightProbesInfo *pinfo = sldata->probes;
EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
/* Disable specular lighting when rendering probes to avoid feedback loops (looks bad). */
common_data->spec_toggle = false;
common_data->ssr_toggle = false;
common_data->sss_toggle = false;
/* Disable AO until we find a way to hide really bad discontinuities between cubefaces. */
float tmp_ao_dist = common_data->ao_dist;
float tmp_ao_settings = common_data->ao_settings;
common_data->ao_settings = 0.0f;
common_data->ao_dist = 0.0f;
/* Render world in priority */
if (e_data.update_world) {
lightprobes_refresh_world(sldata, vedata);
}
else if (true) { /* TODO if at least one probe needs refresh */
else if (pinfo->do_cube_update || (pinfo->updated_bounce < pinfo->num_bounce)) {
lightprobes_refresh_all_no_world(sldata, vedata);
}
/* Restore */
common_data->spec_toggle = true;
common_data->ssr_toggle = true;
common_data->sss_toggle = true;
common_data->ao_dist = tmp_ao_dist;
common_data->ao_settings = tmp_ao_settings;
lightprobes_refresh_planar(sldata, vedata);
/* Disable SSR if we cannot read previous frame */
sldata->probes->ssr_toggle = vedata->stl->g_data->valid_double_buffer;
common_data->ssr_toggle = vedata->stl->g_data->valid_double_buffer;
}
void EEVEE_lightprobes_free(void)

View File

@ -484,6 +484,8 @@ void EEVEE_lights_cache_finish(EEVEE_ViewLayerData *sldata)
EEVEE_LampsInfo *linfo = sldata->lamps;
DRWTextureFormat shadow_pool_format = DRW_TEX_R_32;
sldata->common_data.la_num_light = linfo->num_light;
/* Setup enough layers. */
/* Free textures if number mismatch. */
if (linfo->num_layer != linfo->cache_num_layer) {

View File

@ -63,7 +63,7 @@ static struct {
unsigned int sss_count;
float viewvecs[2][4];
float view_vecs[2][4];
float alpha_hash_offset;
float noise_offsets[3];
} e_data = {NULL}; /* Engine data */
@ -81,6 +81,7 @@ extern char datatoc_btdf_lut_frag_glsl[];
extern char datatoc_bsdf_common_lib_glsl[];
extern char datatoc_bsdf_direct_lib_glsl[];
extern char datatoc_bsdf_sampling_lib_glsl[];
extern char datatoc_common_uniforms_lib_glsl[];
extern char datatoc_irradiance_lib_glsl[];
extern char datatoc_octahedron_lib_glsl[];
extern char datatoc_lit_surface_frag_glsl[];
@ -350,65 +351,59 @@ static char *eevee_get_volume_defines(int options)
**/
static void add_standard_uniforms(
DRWShadingGroup *shgrp, EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata,
int *ssr_id, float *refract_depth, bool use_ssrefraction, bool use_alpha_blend, bool use_sss)
int *ssr_id, float *refract_depth, bool use_ssrefraction, bool use_alpha_blend)
{
if (ssr_id == NULL) {
static int no_ssr = -1.0f;
ssr_id = &no_ssr;
}
DRW_shgroup_uniform_block(shgrp, "probe_block", sldata->probe_ubo);
DRW_shgroup_uniform_block(shgrp, "grid_block", sldata->grid_ubo);
DRW_shgroup_uniform_block(shgrp, "planar_block", sldata->planar_ubo);
DRW_shgroup_uniform_block(shgrp, "light_block", sldata->light_ubo);
DRW_shgroup_uniform_block(shgrp, "shadow_block", sldata->shadow_ubo);
DRW_shgroup_uniform_int(shgrp, "light_count", &sldata->lamps->num_light, 1);
DRW_shgroup_uniform_int(shgrp, "probe_count", &sldata->probes->num_render_cube, 1);
DRW_shgroup_uniform_int(shgrp, "grid_count", &sldata->probes->num_render_grid, 1);
DRW_shgroup_uniform_int(shgrp, "planar_count", &sldata->probes->num_planar, 1);
DRW_shgroup_uniform_bool(shgrp, "specToggle", &sldata->probes->specular_toggle, 1);
DRW_shgroup_uniform_bool(shgrp, "ssrToggle", &sldata->probes->ssr_toggle, 1);
DRW_shgroup_uniform_float(shgrp, "lodCubeMax", &sldata->probes->lod_cube_max, 1);
DRW_shgroup_uniform_texture(shgrp, "utilTex", e_data.util_tex);
DRW_shgroup_uniform_buffer(shgrp, "probeCubes", &sldata->probe_pool);
DRW_shgroup_uniform_buffer(shgrp, "probePlanars", &vedata->txl->planar_pool);
DRW_shgroup_uniform_buffer(shgrp, "irradianceGrid", &sldata->irradiance_pool);
DRW_shgroup_uniform_int(shgrp, "irradianceVisibilitySize", &sldata->probes->irradiance_vis_size, 1);
DRW_shgroup_uniform_buffer(shgrp, "shadowTexture", &sldata->shadow_pool);
DRW_shgroup_uniform_int(shgrp, "outputSsrId", ssr_id, 1);
DRW_shgroup_uniform_vec4(shgrp, "aoParameters[0]", &vedata->stl->effects->ao_dist, 2);
DRW_shgroup_uniform_vec4(shgrp, "viewvecs[0]", (float *)vedata->stl->g_data->viewvecs, 2);
DRW_shgroup_uniform_buffer(shgrp, "maxzBuffer", &vedata->txl->maxzbuffer);
DRW_shgroup_uniform_vec2(shgrp, "mipRatio[0]", (float *)vedata->stl->g_data->mip_ratio, 10);
DRW_shgroup_uniform_vec4(shgrp, "ssrParameters", &vedata->stl->effects->ssr_quality, 1);
DRW_shgroup_uniform_block(shgrp, "common_block", sldata->common_ubo);
if (refract_depth != NULL) {
DRW_shgroup_uniform_float(shgrp, "refractionDepth", refract_depth, 1);
/* TODO if glossy or diffuse bsdf */
if (true) {
DRW_shgroup_uniform_texture(shgrp, "utilTex", e_data.util_tex);
DRW_shgroup_uniform_buffer(shgrp, "shadowTexture", &sldata->shadow_pool);
DRW_shgroup_uniform_buffer(shgrp, "maxzBuffer", &vedata->txl->maxzbuffer);
if ((vedata->stl->effects->enabled_effects & EFFECT_GTAO) != 0) {
DRW_shgroup_uniform_buffer(shgrp, "horizonBuffer", &vedata->txl->gtao_horizons);
}
else {
/* Use maxzbuffer as fallback to avoid sampling problem on certain platform, see: T52593 */
DRW_shgroup_uniform_buffer(shgrp, "horizonBuffer", &vedata->txl->maxzbuffer);
}
}
/* TODO if diffuse bsdf */
if (true) {
DRW_shgroup_uniform_buffer(shgrp, "irradianceGrid", &sldata->irradiance_pool);
}
/* TODO if glossy bsdf */
if (true) {
DRW_shgroup_uniform_buffer(shgrp, "probeCubes", &sldata->probe_pool);
DRW_shgroup_uniform_buffer(shgrp, "probePlanars", &vedata->txl->planar_pool);
DRW_shgroup_uniform_int(shgrp, "outputSsrId", ssr_id, 1);
}
if (use_ssrefraction) {
BLI_assert(refract_depth != NULL);
DRW_shgroup_uniform_float(shgrp, "refractionDepth", refract_depth, 1);
DRW_shgroup_uniform_buffer(shgrp, "colorBuffer", &vedata->txl->refract_color);
DRW_shgroup_uniform_float(shgrp, "borderFadeFactor", &vedata->stl->effects->ssr_border_fac, 1);
DRW_shgroup_uniform_float(shgrp, "maxRoughness", &vedata->stl->effects->ssr_max_roughness, 1);
}
if (vedata->stl->effects->use_ao) {
DRW_shgroup_uniform_buffer(shgrp, "horizonBuffer", &vedata->txl->gtao_horizons);
}
else {
/* Use maxzbuffer as fallback to avoid sampling problem on certain platform, see: T52593 */
DRW_shgroup_uniform_buffer(shgrp, "horizonBuffer", &vedata->txl->maxzbuffer);
}
if (vedata->stl->effects->use_volumetrics && use_alpha_blend) {
if ((vedata->stl->effects->enabled_effects & EFFECT_VOLUMETRIC) != 0 &&
use_alpha_blend)
{
/* Do not use history buffers as they already have been swapped */
DRW_shgroup_uniform_buffer(shgrp, "inScattering", &vedata->txl->volume_scatter);
DRW_shgroup_uniform_buffer(shgrp, "inTransmittance", &vedata->txl->volume_transmittance);
DRW_shgroup_uniform_vec2(shgrp, "volume_uv_ratio", (float *)sldata->volumetrics->volume_coord_scale, 1);
DRW_shgroup_uniform_vec3(shgrp, "volume_param", (float *)sldata->volumetrics->depth_param, 1);
}
if (use_sss) {
DRW_shgroup_uniform_bool(shgrp, "sssToggle", &sldata->probes->sss_toggle, 1);
}
}
@ -491,13 +486,14 @@ void EEVEE_update_noise(EEVEE_PassList *psl, EEVEE_FramebufferList *fbl, double
DRW_framebuffer_texture_detach(e_data.util_tex);
}
void EEVEE_materials_init(EEVEE_StorageList *stl, EEVEE_FramebufferList *fbl)
void EEVEE_materials_init(EEVEE_ViewLayerData *sldata, EEVEE_StorageList *stl, EEVEE_FramebufferList *fbl)
{
if (!e_data.frag_shader_lib) {
char *frag_str = NULL;
/* Shaders */
e_data.frag_shader_lib = BLI_string_joinN(
datatoc_common_uniforms_lib_glsl,
datatoc_bsdf_common_lib_glsl,
datatoc_bsdf_sampling_lib_glsl,
datatoc_ambient_occlusion_lib_glsl,
@ -521,6 +517,7 @@ void EEVEE_materials_init(EEVEE_StorageList *stl, EEVEE_FramebufferList *fbl)
datatoc_volumetric_lib_glsl);
e_data.volume_shader_lib = BLI_string_joinN(
datatoc_common_uniforms_lib_glsl,
datatoc_bsdf_common_lib_glsl,
datatoc_ambient_occlusion_lib_glsl,
datatoc_octahedron_lib_glsl,
@ -571,12 +568,12 @@ void EEVEE_materials_init(EEVEE_StorageList *stl, EEVEE_FramebufferList *fbl)
}
{
/* Update viewvecs */
/* Update view_vecs */
const bool is_persp = DRW_viewport_is_persp_get();
float invproj[4][4], winmat[4][4];
/* view vectors for the corners of the view frustum.
* Can be used to recreate the world space position easily */
float viewvecs[3][4] = {
float view_vecs[3][4] = {
{-1.0f, -1.0f, -1.0f, 1.0f},
{1.0f, -1.0f, -1.0f, 1.0f},
{-1.0f, 1.0f, -1.0f, 1.0f}
@ -588,28 +585,28 @@ void EEVEE_materials_init(EEVEE_StorageList *stl, EEVEE_FramebufferList *fbl)
/* convert the view vectors to view space */
for (int i = 0; i < 3; i++) {
mul_m4_v4(invproj, viewvecs[i]);
mul_m4_v4(invproj, view_vecs[i]);
/* normalized trick see:
* http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */
mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][3]);
mul_v3_fl(view_vecs[i], 1.0f / view_vecs[i][3]);
if (is_persp)
mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][2]);
viewvecs[i][3] = 1.0;
mul_v3_fl(view_vecs[i], 1.0f / view_vecs[i][2]);
view_vecs[i][3] = 1.0;
}
copy_v4_v4(stl->g_data->viewvecs[0], viewvecs[0]);
copy_v4_v4(stl->g_data->viewvecs[1], viewvecs[1]);
copy_v4_v4(sldata->common_data.view_vecs[0], view_vecs[0]);
copy_v4_v4(sldata->common_data.view_vecs[1], view_vecs[1]);
/* we need to store the differences */
stl->g_data->viewvecs[1][0] -= viewvecs[0][0];
stl->g_data->viewvecs[1][1] = viewvecs[2][1] - viewvecs[0][1];
sldata->common_data.view_vecs[1][0] -= view_vecs[0][0];
sldata->common_data.view_vecs[1][1] = view_vecs[2][1] - view_vecs[0][1];
/* calculate a depth offset as well */
if (!is_persp) {
float vec_far[] = {-1.0f, -1.0f, 1.0f, 1.0f};
mul_m4_v4(invproj, vec_far);
mul_v3_fl(vec_far, 1.0f / vec_far[3]);
stl->g_data->viewvecs[1][2] = vec_far[2] - viewvecs[0][2];
sldata->common_data.view_vecs[1][2] = vec_far[2] - view_vecs[0][2];
}
}
@ -677,6 +674,7 @@ struct GPUMaterial *EEVEE_material_mesh_get(
struct Scene *scene, Material *ma, EEVEE_Data *vedata,
bool use_blend, bool use_multiply, bool use_refract, bool use_sss, bool use_translucency, int shadow_method)
{
EEVEE_EffectsInfo *effects = vedata->stl->effects;
const void *engine = &DRW_engine_viewport_eevee_type;
int options = VAR_MAT_MESH;
@ -684,9 +682,9 @@ struct GPUMaterial *EEVEE_material_mesh_get(
if (use_multiply) options |= VAR_MAT_MULT;
if (use_refract) options |= VAR_MAT_REFRACT;
if (use_sss) options |= VAR_MAT_SSS;
if (use_sss && vedata->stl->effects->sss_separate_albedo) options |= VAR_MAT_SSSALBED;
if (use_sss && effects->sss_separate_albedo) options |= VAR_MAT_SSSALBED;
if (use_translucency) options |= VAR_MAT_TRANSLUC;
if (vedata->stl->effects->use_volumetrics && use_blend) options |= VAR_MAT_VOLUME;
if (((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) && use_blend) options |= VAR_MAT_VOLUME;
options |= eevee_material_shadow_option(shadow_method);
@ -802,6 +800,7 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_create(
EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, DRWPass *pass,
bool is_hair, bool is_flat_normal, bool use_blend, bool use_ssr, int shadow_method)
{
EEVEE_EffectsInfo *effects = vedata->stl->effects;
static int ssr_id;
ssr_id = (use_ssr) ? 1 : -1;
int options = VAR_MAT_MESH;
@ -809,7 +808,7 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_create(
if (is_hair) options |= VAR_MAT_HAIR;
if (is_flat_normal) options |= VAR_MAT_FLAT;
if (use_blend) options |= VAR_MAT_BLEND;
if (vedata->stl->effects->use_volumetrics && use_blend) options |= VAR_MAT_VOLUME;
if (((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) && use_blend) options |= VAR_MAT_VOLUME;
options |= eevee_material_shadow_option(shadow_method);
@ -818,7 +817,7 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_create(
}
DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.default_lit[options], pass);
add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, false, use_blend, false);
add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, false, use_blend);
return shgrp;
}
@ -848,7 +847,7 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_get(
vedata->psl->default_pass[options] = DRW_pass_create("Default Lit Pass", state);
DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.default_lit[options], vedata->psl->default_pass[options]);
add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, false, false, false);
add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, false, false);
}
return DRW_shgroup_create(e_data.default_lit[options], vedata->psl->default_pass[options]);
@ -859,19 +858,6 @@ void EEVEE_materials_cache_init(EEVEE_Data *vedata)
EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
{
const DRWContextState *draw_ctx = DRW_context_state_get();
ViewLayer *view_layer = draw_ctx->view_layer;
IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE);
/* Global AO Switch*/
stl->effects->use_ao = BKE_collection_engine_property_value_get_bool(props, "gtao_enable");
stl->effects->use_bent_normals = BKE_collection_engine_property_value_get_bool(props, "gtao_use_bent_normals");
/* SSR switch */
stl->effects->use_ssr = BKE_collection_engine_property_value_get_bool(props, "ssr_enable");
/* Volumetrics */
stl->effects->use_volumetrics = BKE_collection_engine_property_value_get_bool(props, "volumetric_enable");
}
/* Create Material Ghash */
{
stl->g_data->material_hash = BLI_ghash_ptr_new("Eevee_material ghash");
@ -1011,6 +997,7 @@ static void material_opaque(
bool do_cull, bool use_flat_nor, struct GPUMaterial **gpumat, struct GPUMaterial **gpumat_depth,
struct DRWShadingGroup **shgrp, struct DRWShadingGroup **shgrp_depth, struct DRWShadingGroup **shgrp_depth_clip)
{
EEVEE_EffectsInfo *effects = vedata->stl->effects;
const DRWContextState *draw_ctx = DRW_context_state_get();
Scene *scene = draw_ctx->scene;
EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
@ -1024,9 +1011,9 @@ static void material_opaque(
const bool use_gpumat = (ma->use_nodes && ma->nodetree);
const bool use_refract = ((ma->blend_flag & MA_BL_SS_REFRACTION) != 0) &&
((stl->effects->enabled_effects & EFFECT_REFRACT) != 0);
((effects->enabled_effects & EFFECT_REFRACT) != 0);
const bool use_sss = ((ma->blend_flag & MA_BL_SS_SUBSURFACE) != 0) &&
((stl->effects->enabled_effects & EFFECT_SSS) != 0);
((effects->enabled_effects & EFFECT_SSS) != 0);
const bool use_translucency = use_sss && ((ma->blend_flag & MA_BL_TRANSLUCENCY) != 0);
EeveeMaterialShadingGroups *emsg = BLI_ghash_lookup(material_hash, (const void *)ma);
@ -1055,8 +1042,8 @@ static void material_opaque(
if (*shgrp) {
static int no_ssr = -1;
static int first_ssr = 1;
int *ssr_id = (stl->effects->use_ssr && !use_refract) ? &first_ssr : &no_ssr;
add_standard_uniforms(*shgrp, sldata, vedata, ssr_id, &ma->refract_depth, use_refract, false, use_sss);
int *ssr_id = (((effects->enabled_effects & EFFECT_SSR) != 0) && !use_refract) ? &first_ssr : &no_ssr;
add_standard_uniforms(*shgrp, sldata, vedata, ssr_id, &ma->refract_depth, use_refract, false);
if (use_sss) {
struct GPUTexture *sss_tex_profile = NULL;
@ -1071,7 +1058,7 @@ static void material_opaque(
}
DRW_shgroup_stencil_mask(*shgrp, e_data.sss_count + 1);
EEVEE_subsurface_add_pass(vedata, e_data.sss_count + 1, sss_profile);
EEVEE_subsurface_add_pass(sldata, vedata, e_data.sss_count + 1, sss_profile);
e_data.sss_count++;
}
}
@ -1101,7 +1088,7 @@ static void material_opaque(
}
if (*shgrp_depth != NULL) {
add_standard_uniforms(*shgrp_depth, sldata, vedata, NULL, NULL, false, false, false);
add_standard_uniforms(*shgrp_depth, sldata, vedata, NULL, NULL, false, false);
if (ma->blend_method == MA_BM_CLIP) {
DRW_shgroup_uniform_float(*shgrp_depth, "alphaThreshold", &ma->alpha_threshold, 1);
@ -1117,7 +1104,8 @@ static void material_opaque(
/* Fallback to default shader */
if (*shgrp == NULL) {
*shgrp = EEVEE_default_shading_group_get(sldata, vedata, false, use_flat_nor, stl->effects->use_ssr, linfo->shadow_method);
bool use_ssr = ((effects->enabled_effects & EFFECT_SSR) != 0);
*shgrp = EEVEE_default_shading_group_get(sldata, vedata, false, use_flat_nor, use_ssr, linfo->shadow_method);
DRW_shgroup_uniform_vec3(*shgrp, "basecol", color_p, 1);
DRW_shgroup_uniform_float(*shgrp, "metallic", metal_p, 1);
DRW_shgroup_uniform_float(*shgrp, "specular", spec_p, 1);
@ -1169,7 +1157,7 @@ static void material_transparent(
if (*shgrp) {
static int ssr_id = -1; /* TODO transparent SSR */
bool use_blend = (ma->blend_method & MA_BM_BLEND) != 0;
add_standard_uniforms(*shgrp, sldata, vedata, &ssr_id, &ma->refract_depth, use_refract, use_blend, false);
add_standard_uniforms(*shgrp, sldata, vedata, &ssr_id, &ma->refract_depth, use_refract, use_blend);
}
else {
/* Shader failed : pink color */
@ -1373,7 +1361,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sld
}
/* Volumetrics */
if (vedata->stl->effects->use_volumetrics && use_volume_material) {
if (((stl->effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) && use_volume_material) {
EEVEE_volumes_cache_object_add(sldata, vedata, scene, ob);
}
}
@ -1421,7 +1409,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sld
shgrp = DRW_shgroup_material_create(gpumat, psl->material_pass);
if (shgrp) {
add_standard_uniforms(shgrp, sldata, vedata, NULL, NULL, false, false, false);
add_standard_uniforms(shgrp, sldata, vedata, NULL, NULL, false, false);
BLI_ghash_insert(material_hash, ma, shgrp);
@ -1439,7 +1427,9 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sld
/* Fallback to default shader */
if (shgrp == NULL) {
shgrp = EEVEE_default_shading_group_get(sldata, vedata, true, false, stl->effects->use_ssr, sldata->lamps->shadow_method);
bool use_ssr = ((stl->effects->enabled_effects & EFFECT_SSR) != 0);
shgrp = EEVEE_default_shading_group_get(sldata, vedata, true, false, use_ssr,
sldata->lamps->shadow_method);
DRW_shgroup_uniform_vec3(shgrp, "basecol", color_p, 1);
DRW_shgroup_uniform_float(shgrp, "metallic", metal_p, 1);
DRW_shgroup_uniform_float(shgrp, "specular", spec_p, 1);

View File

@ -44,12 +44,14 @@ static struct {
} e_data = {NULL}; /* Engine data */
extern char datatoc_ambient_occlusion_lib_glsl[];
extern char datatoc_common_uniforms_lib_glsl[];
extern char datatoc_bsdf_common_lib_glsl[];
extern char datatoc_effect_gtao_frag_glsl[];
static void eevee_create_shader_occlusion(void)
{
char *frag_str = BLI_string_joinN(
datatoc_common_uniforms_lib_glsl,
datatoc_bsdf_common_lib_glsl,
datatoc_ambient_occlusion_lib_glsl,
datatoc_effect_gtao_frag_glsl);
@ -61,12 +63,12 @@ static void eevee_create_shader_occlusion(void)
MEM_freeN(frag_str);
}
int EEVEE_occlusion_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
int EEVEE_occlusion_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
EEVEE_StorageList *stl = vedata->stl;
EEVEE_FramebufferList *fbl = vedata->fbl;
EEVEE_TextureList *txl = vedata->txl;
EEVEE_EffectsInfo *effects = stl->effects;
const DRWContextState *draw_ctx = DRW_context_state_get();
ViewLayer *view_layer = draw_ctx->view_layer;
@ -82,22 +84,19 @@ int EEVEE_occlusion_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata
eevee_create_shader_occlusion();
}
effects->ao_dist = BKE_collection_engine_property_value_get_float(props, "gtao_distance");
effects->ao_factor = BKE_collection_engine_property_value_get_float(props, "gtao_factor");
effects->ao_quality = 1.0f - BKE_collection_engine_property_value_get_float(props, "gtao_quality");
common_data->ao_dist = BKE_collection_engine_property_value_get_float(props, "gtao_distance");
common_data->ao_factor = BKE_collection_engine_property_value_get_float(props, "gtao_factor");
common_data->ao_quality = 1.0f - BKE_collection_engine_property_value_get_float(props, "gtao_quality");
effects->ao_settings = 1.0; /* USE_AO */
common_data->ao_settings = 1.0; /* USE_AO */
if (BKE_collection_engine_property_value_get_bool(props, "gtao_use_bent_normals")) {
effects->ao_settings += 2.0; /* USE_BENT_NORMAL */
common_data->ao_settings += 2.0; /* USE_BENT_NORMAL */
}
if (BKE_collection_engine_property_value_get_bool(props, "gtao_denoise")) {
effects->ao_settings += 4.0; /* USE_DENOISE */
common_data->ao_settings += 4.0; /* USE_DENOISE */
}
effects->ao_bounce_fac = (float)BKE_collection_engine_property_value_get_bool(props, "gtao_bounce");
effects->ao_texsize[0] = ((int)viewport_size[0]);
effects->ao_texsize[1] = ((int)viewport_size[1]);
common_data->ao_bounce_fac = (float)BKE_collection_engine_property_value_get_bool(props, "gtao_bounce");
DRWFboTexture tex = {&txl->gtao_horizons, DRW_TEX_RGBA_8, 0};
@ -119,12 +118,12 @@ int EEVEE_occlusion_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata
/* Cleanup */
DRW_TEXTURE_FREE_SAFE(txl->gtao_horizons);
DRW_FRAMEBUFFER_FREE_SAFE(fbl->gtao_fb);
effects->ao_settings = 0.0f;
common_data->ao_settings = 0.0f;
return 0;
}
void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_PassList *psl = vedata->psl;
EEVEE_StorageList *stl = vedata->stl;
@ -148,36 +147,30 @@ void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data
**/
psl->ao_horizon_search = DRW_pass_create("GTAO Horizon Search", DRW_STATE_WRITE_COLOR);
DRWShadingGroup *grp = DRW_shgroup_create(e_data.gtao_sh, psl->ao_horizon_search);
DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
DRW_shgroup_uniform_buffer(grp, "maxzBuffer", &txl->maxzbuffer);
DRW_shgroup_uniform_buffer(grp, "depthBuffer", &effects->ao_src_depth);
DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)stl->g_data->viewvecs, 2);
DRW_shgroup_uniform_vec2(grp, "mipRatio[0]", (float *)stl->g_data->mip_ratio, 10);
DRW_shgroup_uniform_vec4(grp, "aoParameters[0]", &stl->effects->ao_dist, 2);
DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_call_add(grp, quad, NULL);
psl->ao_horizon_search_layer = DRW_pass_create("GTAO Horizon Search Layer", DRW_STATE_WRITE_COLOR);
grp = DRW_shgroup_create(e_data.gtao_layer_sh, psl->ao_horizon_search_layer);
DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
DRW_shgroup_uniform_buffer(grp, "maxzBuffer", &txl->maxzbuffer);
DRW_shgroup_uniform_buffer(grp, "depthBufferLayered", &effects->ao_src_depth);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_int(grp, "layer", &stl->effects->ao_depth_layer, 1);
DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)stl->g_data->viewvecs, 2);
DRW_shgroup_uniform_vec2(grp, "mipRatio[0]", (float *)stl->g_data->mip_ratio, 10);
DRW_shgroup_uniform_vec4(grp, "aoParameters[0]", &stl->effects->ao_dist, 2);
DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
DRW_shgroup_call_add(grp, quad, NULL);
if (G.debug_value == 6) {
psl->ao_horizon_debug = DRW_pass_create("GTAO Horizon Debug", DRW_STATE_WRITE_COLOR);
grp = DRW_shgroup_create(e_data.gtao_debug_sh, psl->ao_horizon_debug);
DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
DRW_shgroup_uniform_buffer(grp, "maxzBuffer", &txl->maxzbuffer);
DRW_shgroup_uniform_buffer(grp, "depthBuffer", &dtxl->depth);
DRW_shgroup_uniform_buffer(grp, "normalBuffer", &txl->ssr_normal_input);
DRW_shgroup_uniform_buffer(grp, "horizonBuffer", &txl->gtao_horizons);
DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)stl->g_data->viewvecs, 2);
DRW_shgroup_uniform_vec2(grp, "mipRatio[0]", (float *)stl->g_data->mip_ratio, 10);
DRW_shgroup_uniform_vec4(grp, "aoParameters[0]", &stl->effects->ao_dist, 2);
DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_call_add(grp, quad, NULL);
}
}

View File

@ -343,18 +343,6 @@ typedef struct EEVEE_ShadowCasterBuffer {
unsigned int count;
} EEVEE_ShadowCasterBuffer;
/* ************ VOLUME DATA ************ */
typedef struct EEVEE_VolumetricsInfo {
float integration_step_count, shadow_step_count, sample_distribution, light_clamp;
float integration_start, integration_end;
float depth_param[3], history_alpha;
bool use_lights, use_volume_shadows;
int froxel_tex_size[3];
float inv_tex_size[3];
float volume_coord_scale[2];
float jitter[3];
} EEVEE_VolumetricsInfo;
/* ************ LIGHT DATA ************* */
typedef struct EEVEE_LampsInfo {
int num_light, cache_num_light;
@ -440,12 +428,9 @@ typedef struct EEVEE_LightProbesInfo {
int num_bounce;
int cubemap_res;
int target_size;
int irradiance_vis_size;
int grid_initialized;
struct World *prev_world;
/* Actual number of probes that have datas. */
int num_render_cube;
int num_render_grid;
bool do_cube_update;
/* For rendering probes */
float probemat[6][4][4];
int layer;
@ -461,10 +446,6 @@ typedef struct EEVEE_LightProbesInfo {
float visibility_range;
float visibility_blur;
int shres;
int shnbr;
int specular_toggle;
int ssr_toggle;
int sss_toggle;
/* List of probes in the scene. */
/* XXX This is fragile, can get out of sync quickly. */
struct Object *probes_cube_ref[MAX_PROBE];
@ -487,30 +468,15 @@ enum {
typedef struct EEVEE_EffectsInfo {
int enabled_effects;
bool swap_double_buffer;
/* SSSS */
int sss_sample_count;
float sss_jitter_threshold;
bool sss_separate_albedo;
/* Volumetrics */
bool use_volumetrics;
int volume_current_sample;
/* SSR */
bool use_ssr;
bool reflection_trace_full;
bool ssr_use_normalization;
int ssr_neighbor_ofs;
int ssr_halfres_ofs[2];
float ssr_brdf_bias;
float ssr_firefly_fac;
float ssr_border_fac;
float ssr_max_roughness;
float ssr_quality;
float ssr_thickness;
float ssr_pixelsize[2];
/* Temporal Anti Aliasing */
int taa_current_sample;
int taa_render_sample;
@ -522,29 +488,19 @@ typedef struct EEVEE_EffectsInfo {
float overide_persinv[4][4];
float overide_winmat[4][4];
float overide_wininv[4][4];
/* Ambient Occlusion */
bool use_ao, use_bent_normals;
float ao_dist, pad1, ao_factor, pad2;
float ao_offset, ao_bounce_fac, ao_quality, ao_settings;
float ao_sample_nbr;
int ao_texsize[2], hori_tex_layers;
int ao_depth_layer;
struct GPUTexture *ao_src_depth; /* pointer copy */
/* Motion Blur */
float current_ndc_to_world[4][4];
float past_world_to_ndc[4][4];
float tmp_mat[4][4];
int motion_blur_samples;
/* Depth Of Field */
float dof_near_far[2];
float dof_params[3];
float dof_bokeh[4];
float dof_layer_select[2];
int dof_target_size[2];
/* Bloom */
int bloom_iteration_ct;
float source_texel_size[2];
@ -557,7 +513,6 @@ typedef struct EEVEE_EffectsInfo {
float unf_source_texel_size[2];
struct GPUTexture *unf_source_buffer; /* pointer copy */
struct GPUTexture *unf_base_buffer; /* pointer copy */
/* Not alloced, just a copy of a *GPUtexture in EEVEE_TextureList. */
struct GPUTexture *source_buffer; /* latest updated texture */
struct GPUFrameBuffer *target_buffer; /* next target to render to */
@ -578,6 +533,58 @@ enum {
EFFECT_SSS = (1 << 11),
};
/* ***************** COMMON DATA **************** */
/* Common uniform buffer containing all "constant" data over the whole drawing pipeline. */
/* !! CAUTION !!
* - [i]vec3 need to be paded to [i]vec4 (even in ubo declaration).
* - Make sure that [i]vec4 start at a multiple of 16 bytes.
* - Arrays of vec2/vec3 are padded as arrays of vec4.
* - sizeof(bool) == sizeof(int) in GLSL so use int in C */
typedef struct EEVEE_CommonUniformBuffer {
float prev_persmat[4][4]; /* mat4 */
float view_vecs[2][4]; /* vec4[2] */
float mip_ratio[10][4]; /* vec2[10] */
/* Ambient Occlusion */
/* -- 16 byte aligned -- */
float ao_dist, pad1, ao_factor, pad2; /* vec4 */
float ao_offset, ao_bounce_fac, ao_quality, ao_settings; /* vec4 */
/* Volumetric */
/* -- 16 byte aligned -- */
int vol_tex_size[3], pad3; /* ivec3 */
float vol_depth_param[3], pad4; /* vec3 */
float vol_inv_tex_size[3], pad5; /* vec3 */
float vol_jitter[3], pad6; /* vec3 */
float vol_coord_scale[2], pad7[2]; /* vec2 */
/* -- 16 byte aligned -- */
float vol_history_alpha; /* float */
float vol_light_clamp; /* float */
float vol_shadow_steps; /* float */
int vol_use_lights; /* bool */
/* Screen Space Reflections */
/* -- 16 byte aligned -- */
float ssr_quality, ssr_thickness, ssr_pixelsize[2]; /* vec4 */
float ssr_border_fac; /* float */
float ssr_max_roughness; /* float */
float ssr_firefly_fac; /* float */
float ssr_brdf_bias; /* float */
int ssr_toggle; /* bool */
/* SubSurface Scattering */
float sss_jitter_threshold; /* float */
int sss_toggle; /* bool */
/* Specular */
int spec_toggle; /* bool */
/* Lamps */
int la_num_light; /* int */
/* Probes */
int prb_num_planar; /* int */
int prb_num_render_cube; /* int */
int prb_num_render_grid; /* int */
int prb_irradiance_vis_size; /* int */
float prb_lod_cube_max; /* float */
float prb_lod_planar_max; /* float */
} EEVEE_CommonUniformBuffer;
/* ************** SCENE LAYER DATA ************** */
typedef struct EEVEE_ViewLayerData {
/* Lamps */
@ -615,10 +622,9 @@ typedef struct EEVEE_ViewLayerData {
struct GPUTexture *irradiance_pool;
struct GPUTexture *irradiance_rt;
struct ListBase probe_queue; /* List of probes to update */
/* Volumetrics */
struct EEVEE_VolumetricsInfo *volumetrics;
/* Common Uniform Buffer */
struct EEVEE_CommonUniformBuffer common_data;
struct GPUUniformBuffer *common_ubo;
} EEVEE_ViewLayerData;
/* ************ OBJECT DATA ************ */
@ -712,15 +718,11 @@ typedef struct EEVEE_PrivateData {
struct GPUTexture *ssr_pdf_output;
struct GPUTexture *gtao_horizons_debug;
float background_alpha; /* TODO find a better place for this. */
float viewvecs[2][4];
/* For planar probes */
float texel_size[2];
/* To correct mip level texel mis-alignement */
float mip_ratio[10][2]; /* TODO put in a UBO */
float planar_texel_size[2];
/* For double buffering */
bool view_updated;
bool valid_double_buffer;
float prev_persmat[4][4];
} EEVEE_PrivateData; /* Transient data */
/* eevee_data.c */
@ -735,7 +737,7 @@ EEVEE_LampEngineData *EEVEE_lamp_data_ensure(Object *ob);
/* eevee_materials.c */
struct GPUTexture *EEVEE_materials_get_util_tex(void); /* XXX */
void EEVEE_materials_init(EEVEE_StorageList *stl, EEVEE_FramebufferList *fbl);
void EEVEE_materials_init(EEVEE_ViewLayerData *sldata, EEVEE_StorageList *stl, EEVEE_FramebufferList *fbl);
void EEVEE_materials_cache_init(EEVEE_Data *vedata);
void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata, Object *ob);
void EEVEE_materials_cache_finish(EEVEE_Data *vedata);
@ -805,7 +807,8 @@ void EEVEE_screen_raytrace_free(void);
/* eevee_subsurface.c */
int EEVEE_subsurface_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_subsurface_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_subsurface_add_pass(EEVEE_Data *vedata, unsigned int sss_id, struct GPUUniformBuffer *sss_profile);
void EEVEE_subsurface_add_pass(
EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, unsigned int sss_id, struct GPUUniformBuffer *sss_profile);
void EEVEE_subsurface_data_render(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_subsurface_compute(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_subsurface_free(void);
@ -838,7 +841,7 @@ void EEVEE_create_minmax_buffer(EEVEE_Data *vedata, struct GPUTexture *depth_src
void EEVEE_downsample_buffer(EEVEE_Data *vedata, struct GPUFrameBuffer *fb_src, struct GPUTexture *texture_src, int level);
void EEVEE_downsample_cube_buffer(EEVEE_Data *vedata, struct GPUFrameBuffer *fb_src, struct GPUTexture *texture_src, int level);
void EEVEE_effects_do_gtao(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_draw_effects(EEVEE_Data *vedata);
void EEVEE_draw_effects(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_effects_free(void);
/* Shadow Matrix */

View File

@ -50,6 +50,7 @@ static struct {
} e_data = {NULL}; /* Engine data */
extern char datatoc_ambient_occlusion_lib_glsl[];
extern char datatoc_common_uniforms_lib_glsl[];
extern char datatoc_bsdf_common_lib_glsl[];
extern char datatoc_bsdf_sampling_lib_glsl[];
extern char datatoc_octahedron_lib_glsl[];
@ -61,6 +62,7 @@ static struct GPUShader *eevee_effects_screen_raytrace_shader_get(int options)
{
if (e_data.ssr_sh[options] == NULL) {
char *ssr_shader_str = BLI_string_joinN(
datatoc_common_uniforms_lib_glsl,
datatoc_bsdf_common_lib_glsl,
datatoc_bsdf_sampling_lib_glsl,
datatoc_octahedron_lib_glsl,
@ -93,8 +95,9 @@ static struct GPUShader *eevee_effects_screen_raytrace_shader_get(int options)
return e_data.ssr_sh[options];
}
int EEVEE_screen_raytrace_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
int EEVEE_screen_raytrace_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
EEVEE_StorageList *stl = vedata->stl;
EEVEE_FramebufferList *fbl = vedata->fbl;
EEVEE_TextureList *txl = vedata->txl;
@ -108,8 +111,8 @@ int EEVEE_screen_raytrace_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *
RE_engine_id_BLENDER_EEVEE);
/* Compute pixel size, (shared with contact shadows) */
copy_v2_v2(effects->ssr_pixelsize, viewport_size);
invert_v2(effects->ssr_pixelsize);
copy_v2_v2(common_data->ssr_pixelsize, viewport_size);
invert_v2(common_data->ssr_pixelsize);
if (BKE_collection_engine_property_value_get_bool(props, "ssr_enable")) {
const bool use_refraction = BKE_collection_engine_property_value_get_bool(props, "ssr_refraction");
@ -124,16 +127,15 @@ int EEVEE_screen_raytrace_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *
bool prev_trace_full = effects->reflection_trace_full;
effects->reflection_trace_full = !BKE_collection_engine_property_value_get_bool(props, "ssr_halfres");
effects->ssr_use_normalization = BKE_collection_engine_property_value_get_bool(props, "ssr_normalize_weight");
effects->ssr_quality = 1.0f - 0.95f * BKE_collection_engine_property_value_get_float(props, "ssr_quality");
effects->ssr_thickness = BKE_collection_engine_property_value_get_float(props, "ssr_thickness");
effects->ssr_border_fac = BKE_collection_engine_property_value_get_float(props, "ssr_border_fade");
effects->ssr_firefly_fac = BKE_collection_engine_property_value_get_float(props, "ssr_firefly_fac");
effects->ssr_max_roughness = BKE_collection_engine_property_value_get_float(props, "ssr_max_roughness");
effects->ssr_brdf_bias = 0.1f + effects->ssr_quality * 0.6f; /* Range [0.1, 0.7]. */
common_data->ssr_thickness = BKE_collection_engine_property_value_get_float(props, "ssr_thickness");
common_data->ssr_border_fac = BKE_collection_engine_property_value_get_float(props, "ssr_border_fade");
common_data->ssr_firefly_fac = BKE_collection_engine_property_value_get_float(props, "ssr_firefly_fac");
common_data->ssr_max_roughness = BKE_collection_engine_property_value_get_float(props, "ssr_max_roughness");
common_data->ssr_quality = 1.0f - 0.95f * BKE_collection_engine_property_value_get_float(props, "ssr_quality");
common_data->ssr_brdf_bias = 0.1f + common_data->ssr_quality * 0.6f; /* Range [0.1, 0.7]. */
if (effects->ssr_firefly_fac < 1e-8f) {
effects->ssr_firefly_fac = FLT_MAX;
if (common_data->ssr_firefly_fac < 1e-8f) {
common_data->ssr_firefly_fac = FLT_MAX;
}
if (prev_trace_full != effects->reflection_trace_full) {
@ -214,16 +216,11 @@ void EEVEE_screen_raytrace_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *v
DRW_shgroup_uniform_buffer(grp, "depthBuffer", &e_data.depth_src);
DRW_shgroup_uniform_buffer(grp, "normalBuffer", &txl->ssr_normal_input);
DRW_shgroup_uniform_buffer(grp, "specroughBuffer", &txl->ssr_specrough_input);
DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
DRW_shgroup_uniform_buffer(grp, "maxzBuffer", &txl->maxzbuffer);
DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)stl->g_data->viewvecs, 2);
DRW_shgroup_uniform_vec2(grp, "mipRatio[0]", (float *)stl->g_data->mip_ratio, 10);
DRW_shgroup_uniform_vec4(grp, "ssrParameters", &effects->ssr_quality, 1);
DRW_shgroup_uniform_int(grp, "planar_count", &sldata->probes->num_planar, 1);
DRW_shgroup_uniform_float(grp, "maxRoughness", &effects->ssr_max_roughness, 1);
DRW_shgroup_uniform_float(grp, "brdfBias", &effects->ssr_brdf_bias, 1);
DRW_shgroup_uniform_buffer(grp, "planarDepth", &vedata->txl->planar_depth);
DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
if (!effects->reflection_trace_full) {
DRW_shgroup_uniform_ivec2(grp, "halfresOffset", effects->ssr_halfres_ofs, 1);
}
@ -234,30 +231,18 @@ void EEVEE_screen_raytrace_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *v
DRW_shgroup_uniform_buffer(grp, "depthBuffer", &e_data.depth_src);
DRW_shgroup_uniform_buffer(grp, "normalBuffer", &txl->ssr_normal_input);
DRW_shgroup_uniform_buffer(grp, "specroughBuffer", &txl->ssr_specrough_input);
DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
DRW_shgroup_uniform_buffer(grp, "prevColorBuffer", &txl->color_double_buffer);
DRW_shgroup_uniform_mat4(grp, "PastViewProjectionMatrix", (float *)stl->g_data->prev_persmat);
DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)stl->g_data->viewvecs, 2);
DRW_shgroup_uniform_int(grp, "planar_count", &sldata->probes->num_planar, 1);
DRW_shgroup_uniform_int(grp, "probe_count", &sldata->probes->num_render_cube, 1);
DRW_shgroup_uniform_vec2(grp, "mipRatio[0]", (float *)stl->g_data->mip_ratio, 10);
DRW_shgroup_uniform_float(grp, "borderFadeFactor", &effects->ssr_border_fac, 1);
DRW_shgroup_uniform_float(grp, "maxRoughness", &effects->ssr_max_roughness, 1);
DRW_shgroup_uniform_float(grp, "lodCubeMax", &sldata->probes->lod_cube_max, 1);
DRW_shgroup_uniform_float(grp, "lodPlanarMax", &sldata->probes->lod_planar_max, 1);
DRW_shgroup_uniform_float(grp, "fireflyFactor", &effects->ssr_firefly_fac, 1);
DRW_shgroup_uniform_float(grp, "brdfBias", &effects->ssr_brdf_bias, 1);
DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
DRW_shgroup_uniform_buffer(grp, "probeCubes", &sldata->probe_pool);
DRW_shgroup_uniform_buffer(grp, "probePlanars", &vedata->txl->planar_pool);
DRW_shgroup_uniform_buffer(grp, "planarDepth", &vedata->txl->planar_depth);
DRW_shgroup_uniform_buffer(grp, "hitBuffer", &vedata->txl->ssr_hit_output);
DRW_shgroup_uniform_buffer(grp, "pdfBuffer", &stl->g_data->ssr_pdf_output);
DRW_shgroup_uniform_buffer(grp, "prevColorBuffer", &txl->color_double_buffer);
DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_int(grp, "neighborOffset", &effects->ssr_neighbor_ofs, 1);
DRW_shgroup_uniform_vec4(grp, "aoParameters[0]", &effects->ao_dist, 2);
if (effects->use_ao) {
if ((effects->enabled_effects & EFFECT_GTAO) != 0) {
DRW_shgroup_uniform_buffer(grp, "horizonBuffer", &vedata->txl->gtao_horizons);
}
else {

View File

@ -27,7 +27,7 @@
#include "DRW_render.h"
#include "BLI_dynstr.h"
#include "BLI_string_utils.h"
#include "eevee_private.h"
#include "GPU_texture.h"
@ -36,18 +36,26 @@ static struct {
struct GPUShader *sss_sh[3];
} e_data = {NULL}; /* Engine data */
extern char datatoc_common_uniforms_lib_glsl[];
extern char datatoc_effect_subsurface_frag_glsl[];
static void eevee_create_shader_subsurface(void)
{
e_data.sss_sh[0] = DRW_shader_create_fullscreen(datatoc_effect_subsurface_frag_glsl, "#define FIRST_PASS\n");
e_data.sss_sh[1] = DRW_shader_create_fullscreen(datatoc_effect_subsurface_frag_glsl, "#define SECOND_PASS\n");
e_data.sss_sh[2] = DRW_shader_create_fullscreen(datatoc_effect_subsurface_frag_glsl, "#define SECOND_PASS\n"
"#define USE_SEP_ALBEDO\n");
char *frag_str = BLI_string_joinN(
datatoc_common_uniforms_lib_glsl,
datatoc_effect_subsurface_frag_glsl);
e_data.sss_sh[0] = DRW_shader_create_fullscreen(frag_str, "#define FIRST_PASS\n");
e_data.sss_sh[1] = DRW_shader_create_fullscreen(frag_str, "#define SECOND_PASS\n");
e_data.sss_sh[2] = DRW_shader_create_fullscreen(frag_str, "#define SECOND_PASS\n"
"#define USE_SEP_ALBEDO\n");
MEM_freeN(frag_str);
}
int EEVEE_subsurface_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
int EEVEE_subsurface_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
EEVEE_StorageList *stl = vedata->stl;
EEVEE_EffectsInfo *effects = stl->effects;
EEVEE_FramebufferList *fbl = vedata->fbl;
@ -60,8 +68,8 @@ int EEVEE_subsurface_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedat
if (BKE_collection_engine_property_value_get_bool(props, "sss_enable")) {
effects->sss_sample_count = 1 + BKE_collection_engine_property_value_get_int(props, "sss_samples") * 2;
effects->sss_jitter_threshold = BKE_collection_engine_property_value_get_float(props, "sss_jitter_threshold");
effects->sss_separate_albedo = BKE_collection_engine_property_value_get_bool(props, "sss_separate_albedo");
common_data->sss_jitter_threshold = BKE_collection_engine_property_value_get_float(props, "sss_jitter_threshold");
/* Shaders */
if (!e_data.sss_sh[0]) {
@ -117,7 +125,8 @@ void EEVEE_subsurface_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data
}
}
void EEVEE_subsurface_add_pass(EEVEE_Data *vedata, unsigned int sss_id, struct GPUUniformBuffer *sss_profile)
void EEVEE_subsurface_add_pass(
EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, unsigned int sss_id, struct GPUUniformBuffer *sss_profile)
{
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
EEVEE_TextureList *txl = vedata->txl;
@ -127,23 +136,21 @@ void EEVEE_subsurface_add_pass(EEVEE_Data *vedata, unsigned int sss_id, struct G
struct Gwn_Batch *quad = DRW_cache_fullscreen_quad_get();
DRWShadingGroup *grp = DRW_shgroup_create(e_data.sss_sh[0], psl->sss_blur_ps);
DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)vedata->stl->g_data->viewvecs, 2);
DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
DRW_shgroup_uniform_buffer(grp, "depthBuffer", &dtxl->depth);
DRW_shgroup_uniform_buffer(grp, "sssData", &txl->sss_data);
DRW_shgroup_uniform_block(grp, "sssProfile", sss_profile);
DRW_shgroup_uniform_float(grp, "jitterThreshold", &effects->sss_jitter_threshold, 1);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_stencil_mask(grp, sss_id);
DRW_shgroup_call_add(grp, quad, NULL);
struct GPUShader *sh = (effects->sss_separate_albedo) ? e_data.sss_sh[2] : e_data.sss_sh[1];
grp = DRW_shgroup_create(sh, psl->sss_resolve_ps);
DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)vedata->stl->g_data->viewvecs, 2);
DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
DRW_shgroup_uniform_buffer(grp, "depthBuffer", &dtxl->depth);
DRW_shgroup_uniform_buffer(grp, "sssData", &txl->sss_blur);
DRW_shgroup_uniform_block(grp, "sssProfile", sss_profile);
DRW_shgroup_uniform_float(grp, "jitterThreshold", &effects->sss_jitter_threshold, 1);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_stencil_mask(grp, sss_id);
DRW_shgroup_call_add(grp, quad, NULL);

View File

@ -51,6 +51,7 @@ static struct {
struct GPUShader *volumetric_clear_sh;
struct GPUShader *volumetric_scatter_sh;
struct GPUShader *volumetric_scatter_with_lamps_sh;
struct GPUShader *volumetric_integration_sh;
struct GPUShader *volumetric_resolve_sh;
@ -63,6 +64,7 @@ static struct {
extern char datatoc_bsdf_common_lib_glsl[];
extern char datatoc_bsdf_direct_lib_glsl[];
extern char datatoc_common_uniforms_lib_glsl[];
extern char datatoc_octahedron_lib_glsl[];
extern char datatoc_irradiance_lib_glsl[];
extern char datatoc_lamps_lib_glsl[];
@ -78,10 +80,12 @@ extern char datatoc_gpu_shader_fullscreen_vert_glsl[];
static void eevee_create_shader_volumes(void)
{
e_data.volumetric_common_lib = BLI_string_joinN(
datatoc_common_uniforms_lib_glsl,
datatoc_bsdf_common_lib_glsl,
datatoc_volumetric_lib_glsl);
e_data.volumetric_common_lamps_lib = BLI_string_joinN(
datatoc_common_uniforms_lib_glsl,
datatoc_bsdf_common_lib_glsl,
datatoc_bsdf_direct_lib_glsl,
datatoc_octahedron_lib_glsl,
@ -104,6 +108,15 @@ static void eevee_create_shader_volumes(void)
SHADER_DEFINES
"#define VOLUMETRICS\n"
"#define VOLUME_SHADOW\n");
e_data.volumetric_scatter_with_lamps_sh = DRW_shader_create_with_lib(
datatoc_volumetric_vert_glsl,
datatoc_volumetric_geom_glsl,
datatoc_volumetric_scatter_frag_glsl,
e_data.volumetric_common_lamps_lib,
SHADER_DEFINES
"#define VOLUMETRICS\n"
"#define VOLUME_LIGHTING\n"
"#define VOLUME_SHADOW\n");
e_data.volumetric_integration_sh = DRW_shader_create_with_lib(
datatoc_volumetric_vert_glsl,
datatoc_volumetric_geom_glsl,
@ -121,6 +134,7 @@ int EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
EEVEE_FramebufferList *fbl = vedata->fbl;
EEVEE_TextureList *txl = vedata->txl;
EEVEE_EffectsInfo *effects = stl->effects;
EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
const DRWContextState *draw_ctx = DRW_context_state_get();
ViewLayer *view_layer = draw_ctx->view_layer;
@ -137,29 +151,23 @@ int EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
eevee_create_shader_volumes();
}
if (sldata->volumetrics == NULL) {
sldata->volumetrics = MEM_callocN(sizeof(EEVEE_VolumetricsInfo), "EEVEE_VolumetricsInfo");
}
EEVEE_VolumetricsInfo *volumetrics = sldata->volumetrics;
int tile_size = BKE_collection_engine_property_value_get_int(props, "volumetric_tile_size");
/* Find Froxel Texture resolution. */
int froxel_tex_size[3];
int tex_size[3];
froxel_tex_size[0] = (int)ceilf(fmaxf(1.0f, viewport_size[0] / (float)tile_size));
froxel_tex_size[1] = (int)ceilf(fmaxf(1.0f, viewport_size[1] / (float)tile_size));
froxel_tex_size[2] = max_ii(BKE_collection_engine_property_value_get_int(props, "volumetric_samples"), 1);
tex_size[0] = (int)ceilf(fmaxf(1.0f, viewport_size[0] / (float)tile_size));
tex_size[1] = (int)ceilf(fmaxf(1.0f, viewport_size[1] / (float)tile_size));
tex_size[2] = max_ii(BKE_collection_engine_property_value_get_int(props, "volumetric_samples"), 1);
volumetrics->volume_coord_scale[0] = viewport_size[0] / (float)(tile_size * froxel_tex_size[0]);
volumetrics->volume_coord_scale[1] = viewport_size[1] / (float)(tile_size * froxel_tex_size[1]);
common_data->vol_coord_scale[0] = viewport_size[0] / (float)(tile_size * tex_size[0]);
common_data->vol_coord_scale[1] = viewport_size[1] / (float)(tile_size * tex_size[1]);
/* TODO compute snap to maxZBuffer for clustered rendering */
if ((volumetrics->froxel_tex_size[0] != froxel_tex_size[0]) ||
(volumetrics->froxel_tex_size[1] != froxel_tex_size[1]) ||
(volumetrics->froxel_tex_size[2] != froxel_tex_size[2]))
if ((common_data->vol_tex_size[0] != tex_size[0]) ||
(common_data->vol_tex_size[1] != tex_size[1]) ||
(common_data->vol_tex_size[2] != tex_size[2]))
{
DRW_TEXTURE_FREE_SAFE(txl->volume_prop_scattering);
DRW_TEXTURE_FREE_SAFE(txl->volume_prop_extinction);
@ -172,38 +180,46 @@ int EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_FRAMEBUFFER_FREE_SAFE(fbl->volumetric_fb);
DRW_FRAMEBUFFER_FREE_SAFE(fbl->volumetric_scat_fb);
DRW_FRAMEBUFFER_FREE_SAFE(fbl->volumetric_integ_fb);
volumetrics->froxel_tex_size[0] = froxel_tex_size[0];
volumetrics->froxel_tex_size[1] = froxel_tex_size[1];
volumetrics->froxel_tex_size[2] = froxel_tex_size[2];
common_data->vol_tex_size[0] = tex_size[0];
common_data->vol_tex_size[1] = tex_size[1];
common_data->vol_tex_size[2] = tex_size[2];
volumetrics->inv_tex_size[0] = 1.0f / (float)(volumetrics->froxel_tex_size[0]);
volumetrics->inv_tex_size[1] = 1.0f / (float)(volumetrics->froxel_tex_size[1]);
volumetrics->inv_tex_size[2] = 1.0f / (float)(volumetrics->froxel_tex_size[2]);
common_data->vol_inv_tex_size[0] = 1.0f / (float)(tex_size[0]);
common_data->vol_inv_tex_size[1] = 1.0f / (float)(tex_size[1]);
common_data->vol_inv_tex_size[2] = 1.0f / (float)(tex_size[2]);
}
/* Like frostbite's paper, 5% blend of the new frame. */
volumetrics->history_alpha = (txl->volume_prop_scattering == NULL) ? 0.0f : 0.95f;
common_data->vol_history_alpha = (txl->volume_prop_scattering == NULL) ? 0.0f : 0.95f;
if (txl->volume_prop_scattering == NULL) {
/* Volume properties: We evaluate all volumetric objects
* and store their final properties into each froxel */
txl->volume_prop_scattering = DRW_texture_create_3D(froxel_tex_size[0], froxel_tex_size[1], froxel_tex_size[2], DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER, NULL);
txl->volume_prop_extinction = DRW_texture_create_3D(froxel_tex_size[0], froxel_tex_size[1], froxel_tex_size[2], DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER, NULL);
txl->volume_prop_emission = DRW_texture_create_3D(froxel_tex_size[0], froxel_tex_size[1], froxel_tex_size[2], DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER, NULL);
txl->volume_prop_phase = DRW_texture_create_3D(froxel_tex_size[0], froxel_tex_size[1], froxel_tex_size[2], DRW_TEX_RG_16, DRW_TEX_FILTER, NULL);
txl->volume_prop_scattering = DRW_texture_create_3D(tex_size[0], tex_size[1], tex_size[2],
DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER, NULL);
txl->volume_prop_extinction = DRW_texture_create_3D(tex_size[0], tex_size[1], tex_size[2],
DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER, NULL);
txl->volume_prop_emission = DRW_texture_create_3D(tex_size[0], tex_size[1], tex_size[2],
DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER, NULL);
txl->volume_prop_phase = DRW_texture_create_3D(tex_size[0], tex_size[1], tex_size[2],
DRW_TEX_RG_16, DRW_TEX_FILTER, NULL);
/* Volume scattering: We compute for each froxel the
* Scattered light towards the view. We also resolve temporal
* super sampling during this stage. */
txl->volume_scatter = DRW_texture_create_3D(froxel_tex_size[0], froxel_tex_size[1], froxel_tex_size[2], DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER, NULL);
txl->volume_transmittance = DRW_texture_create_3D(froxel_tex_size[0], froxel_tex_size[1], froxel_tex_size[2], DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER, NULL);
txl->volume_scatter = DRW_texture_create_3D(tex_size[0], tex_size[1], tex_size[2],
DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER, NULL);
txl->volume_transmittance = DRW_texture_create_3D(tex_size[0], tex_size[1], tex_size[2],
DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER, NULL);
/* Final integration: We compute for each froxel the
* amount of scattered light and extinction coef at this
* given depth. We use theses textures as double buffer
* for the volumetric history. */
txl->volume_scatter_history = DRW_texture_create_3D(froxel_tex_size[0], froxel_tex_size[1], froxel_tex_size[2], DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER, NULL);
txl->volume_transmittance_history = DRW_texture_create_3D(froxel_tex_size[0], froxel_tex_size[1], froxel_tex_size[2], DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER, NULL);
txl->volume_scatter_history = DRW_texture_create_3D(tex_size[0], tex_size[1], tex_size[2],
DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER, NULL);
txl->volume_transmittance_history = DRW_texture_create_3D(tex_size[0], tex_size[1], tex_size[2],
DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER, NULL);
}
/* Temporal Super sampling jitter */
@ -221,7 +237,7 @@ int EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
}
if (do_taa) {
volumetrics->history_alpha = 0.0f;
common_data->vol_history_alpha = 0.0f;
current_sample = effects->taa_current_sample - 1;
effects->volume_current_sample = -1;
}
@ -234,9 +250,9 @@ int EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
}
BLI_halton_3D(ht_primes, ht_offset, current_sample, ht_point);
volumetrics->jitter[0] = (float)ht_point[0];
volumetrics->jitter[1] = (float)ht_point[1];
volumetrics->jitter[2] = (float)ht_point[2];
common_data->vol_jitter[0] = (float)ht_point[0];
common_data->vol_jitter[1] = (float)ht_point[1];
common_data->vol_jitter[2] = (float)ht_point[2];
/* Framebuffer setup */
DRWFboTexture tex_vol[4] = {{&txl->volume_prop_scattering, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER},
@ -245,63 +261,64 @@ int EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{&txl->volume_prop_phase, DRW_TEX_RG_16, DRW_TEX_FILTER}};
DRW_framebuffer_init(&fbl->volumetric_fb, &draw_engine_eevee_type,
(int)froxel_tex_size[0], (int)froxel_tex_size[1],
(int)tex_size[0], (int)tex_size[1],
tex_vol, 4);
DRWFboTexture tex_vol_scat[2] = {{&txl->volume_scatter, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER},
{&txl->volume_transmittance, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER}};
DRW_framebuffer_init(&fbl->volumetric_scat_fb, &draw_engine_eevee_type,
(int)froxel_tex_size[0], (int)froxel_tex_size[1],
(int)tex_size[0], (int)tex_size[1],
tex_vol_scat, 2);
DRWFboTexture tex_vol_integ[2] = {{&txl->volume_scatter_history, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER},
{&txl->volume_transmittance_history, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER}};
DRW_framebuffer_init(&fbl->volumetric_integ_fb, &draw_engine_eevee_type,
(int)froxel_tex_size[0], (int)froxel_tex_size[1],
(int)tex_size[0], (int)tex_size[1],
tex_vol_integ, 2);
volumetrics->integration_start = BKE_collection_engine_property_value_get_float(props, "volumetric_start");
volumetrics->integration_end = BKE_collection_engine_property_value_get_float(props, "volumetric_end");
volumetrics->sample_distribution = 4.0f * (1.00001f - BKE_collection_engine_property_value_get_float(props, "volumetric_sample_distribution"));
volumetrics->use_volume_shadows = BKE_collection_engine_property_value_get_bool(props, "volumetric_shadows");
volumetrics->light_clamp = BKE_collection_engine_property_value_get_float(props, "volumetric_light_clamp");
float integration_start = BKE_collection_engine_property_value_get_float(props, "volumetric_start");
float integration_end = BKE_collection_engine_property_value_get_float(props, "volumetric_end");
common_data->vol_light_clamp = BKE_collection_engine_property_value_get_float(props, "volumetric_light_clamp");
if (volumetrics->use_volume_shadows) {
volumetrics->shadow_step_count = (float)BKE_collection_engine_property_value_get_int(props, "volumetric_shadow_samples");
common_data->vol_shadow_steps = (float)BKE_collection_engine_property_value_get_int(props, "volumetric_shadow_samples");
if (BKE_collection_engine_property_value_get_bool(props, "volumetric_shadows")) {
}
else {
volumetrics->shadow_step_count = 0;
common_data->vol_shadow_steps = 0;
}
if (DRW_viewport_is_persp_get()) {
const float clip_start = stl->g_data->viewvecs[0][2];
/* Negate */
float near = volumetrics->integration_start = min_ff(-volumetrics->integration_start, clip_start - 1e-4f);
float far = volumetrics->integration_end = min_ff(-volumetrics->integration_end, near - 1e-4f);
float sample_distribution = BKE_collection_engine_property_value_get_float(props, "volumetric_sample_distribution");
sample_distribution = 4.0f * (1.00001f - sample_distribution);
volumetrics->depth_param[0] = (far - near * exp2(1.0f / volumetrics->sample_distribution)) / (far - near);
volumetrics->depth_param[1] = (1.0f - volumetrics->depth_param[0]) / near;
volumetrics->depth_param[2] = volumetrics->sample_distribution;
const float clip_start = common_data->view_vecs[0][2];
/* Negate */
float near = integration_start = min_ff(-integration_start, clip_start - 1e-4f);
float far = integration_end = min_ff(-integration_end, near - 1e-4f);
common_data->vol_depth_param[0] = (far - near * exp2(1.0f / sample_distribution)) / (far - near);
common_data->vol_depth_param[1] = (1.0f - common_data->vol_depth_param[0]) / near;
common_data->vol_depth_param[2] = sample_distribution;
}
else {
const float clip_start = stl->g_data->viewvecs[0][2];
const float clip_end = stl->g_data->viewvecs[1][2];
volumetrics->integration_start = min_ff(volumetrics->integration_end, clip_start);
volumetrics->integration_end = max_ff(-volumetrics->integration_end, clip_end);
const float clip_start = common_data->view_vecs[0][2];
const float clip_end = common_data->view_vecs[1][2];
integration_start = min_ff(integration_end, clip_start);
integration_end = max_ff(-integration_end, clip_end);
volumetrics->depth_param[0] = volumetrics->integration_start;
volumetrics->depth_param[1] = volumetrics->integration_end;
volumetrics->depth_param[2] = 1.0f / (volumetrics->integration_end - volumetrics->integration_start);
common_data->vol_depth_param[0] = integration_start;
common_data->vol_depth_param[1] = integration_end;
common_data->vol_depth_param[2] = 1.0f / (integration_end - integration_start);
}
/* Disable clamp if equal to 0. */
if (volumetrics->light_clamp == 0.0) {
volumetrics->light_clamp = FLT_MAX;
if (common_data->vol_light_clamp == 0.0) {
common_data->vol_light_clamp = FLT_MAX;
}
volumetrics->use_lights = BKE_collection_engine_property_value_get_bool(props, "volumetric_lights");
common_data->vol_use_lights = BKE_collection_engine_property_value_get_bool(props, "volumetric_lights");
return EFFECT_VOLUMETRIC | EFFECT_POST_BUFFER;
}
@ -328,12 +345,11 @@ void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
EEVEE_StorageList *stl = vedata->stl;
EEVEE_TextureList *txl = vedata->txl;
EEVEE_EffectsInfo *effects = stl->effects;
EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
if ((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) {
const DRWContextState *draw_ctx = DRW_context_state_get();
Scene *scene = draw_ctx->scene;
EEVEE_VolumetricsInfo *volumetrics = sldata->volumetrics;
static int zero = 0;
DRWShadingGroup *grp;
/* Quick breakdown of the Volumetric rendering:
@ -370,65 +386,59 @@ void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
if (wo != NULL && wo->use_nodes && wo->nodetree) {
struct GPUMaterial *mat = EEVEE_material_world_volume_get(scene, wo);
grp = DRW_shgroup_material_empty_tri_batch_create(mat, psl->volumetric_world_ps, volumetrics->froxel_tex_size[2]);
grp = DRW_shgroup_material_empty_tri_batch_create(mat,
psl->volumetric_world_ps,
common_data->vol_tex_size[2]);
if (grp) {
DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)stl->g_data->viewvecs, 2);
DRW_shgroup_uniform_ivec3(grp, "volumeTextureSize", (int *)volumetrics->froxel_tex_size, 1);
DRW_shgroup_uniform_vec2(grp, "volume_uv_ratio", (float *)volumetrics->volume_coord_scale, 1);
DRW_shgroup_uniform_vec3(grp, "volume_param", (float *)volumetrics->depth_param, 1);
DRW_shgroup_uniform_vec3(grp, "volume_jitter", (float *)volumetrics->jitter, 1);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
}
}
else {
/* If no world or volume material is present just clear the buffer with this drawcall */
grp = DRW_shgroup_empty_tri_batch_create(e_data.volumetric_clear_sh, psl->volumetric_world_ps, volumetrics->froxel_tex_size[2]);
grp = DRW_shgroup_empty_tri_batch_create(e_data.volumetric_clear_sh,
psl->volumetric_world_ps,
common_data->vol_tex_size[2]);
DRW_shgroup_uniform_ivec3(grp, "volumeTextureSize", (int *)volumetrics->froxel_tex_size, 1);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
}
/* Volumetric Objects */
psl->volumetric_objects_ps = DRW_pass_create("Volumetric Properties", DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE);
psl->volumetric_objects_ps = DRW_pass_create("Volumetric Properties", DRW_STATE_WRITE_COLOR |
DRW_STATE_ADDITIVE);
struct GPUShader *scatter_sh = (common_data->vol_use_lights) ? e_data.volumetric_scatter_with_lamps_sh
: e_data.volumetric_scatter_sh;
psl->volumetric_scatter_ps = DRW_pass_create("Volumetric Scattering", DRW_STATE_WRITE_COLOR);
grp = DRW_shgroup_empty_tri_batch_create(e_data.volumetric_scatter_sh, psl->volumetric_scatter_ps, volumetrics->froxel_tex_size[2]);
DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)stl->g_data->viewvecs, 2);
DRW_shgroup_uniform_vec2(grp, "volume_uv_ratio", (float *)volumetrics->volume_coord_scale, 1);
DRW_shgroup_uniform_vec3(grp, "volume_param", (float *)volumetrics->depth_param, 1);
DRW_shgroup_uniform_vec3(grp, "volume_jitter", (float *)volumetrics->jitter, 1);
DRW_shgroup_uniform_mat4(grp, "PastViewProjectionMatrix", (float *)stl->g_data->prev_persmat);
DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
DRW_shgroup_uniform_int(grp, "light_count", (volumetrics->use_lights) ? &sldata->lamps->num_light : &zero, 1);
grp = DRW_shgroup_empty_tri_batch_create(scatter_sh, psl->volumetric_scatter_ps,
common_data->vol_tex_size[2]);
DRW_shgroup_uniform_buffer(grp, "irradianceGrid", &sldata->irradiance_pool);
DRW_shgroup_uniform_buffer(grp, "shadowTexture", &sldata->shadow_pool);
DRW_shgroup_uniform_float(grp, "volume_light_clamp", &volumetrics->light_clamp, 1);
DRW_shgroup_uniform_float(grp, "volume_shadows_steps", &volumetrics->shadow_step_count, 1);
DRW_shgroup_uniform_float(grp, "volume_history_alpha", &volumetrics->history_alpha, 1);
DRW_shgroup_uniform_buffer(grp, "volumeScattering", &txl->volume_prop_scattering);
DRW_shgroup_uniform_buffer(grp, "volumeExtinction", &txl->volume_prop_extinction);
DRW_shgroup_uniform_buffer(grp, "volumeEmission", &txl->volume_prop_emission);
DRW_shgroup_uniform_buffer(grp, "volumePhase", &txl->volume_prop_phase);
DRW_shgroup_uniform_buffer(grp, "historyScattering", &txl->volume_scatter_history);
DRW_shgroup_uniform_buffer(grp, "historyTransmittance", &txl->volume_transmittance_history);
DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
psl->volumetric_integration_ps = DRW_pass_create("Volumetric Integration", DRW_STATE_WRITE_COLOR);
grp = DRW_shgroup_empty_tri_batch_create(e_data.volumetric_integration_sh, psl->volumetric_integration_ps, volumetrics->froxel_tex_size[2]);
DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)stl->g_data->viewvecs, 2);
DRW_shgroup_uniform_vec2(grp, "volume_uv_ratio", (float *)volumetrics->volume_coord_scale, 1);
DRW_shgroup_uniform_vec3(grp, "volume_param", (float *)volumetrics->depth_param, 1);
grp = DRW_shgroup_empty_tri_batch_create(e_data.volumetric_integration_sh,
psl->volumetric_integration_ps,
common_data->vol_tex_size[2]);
DRW_shgroup_uniform_buffer(grp, "volumeScattering", &txl->volume_scatter);
DRW_shgroup_uniform_buffer(grp, "volumeExtinction", &txl->volume_transmittance);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
psl->volumetric_resolve_ps = DRW_pass_create("Volumetric Resolve", DRW_STATE_WRITE_COLOR);
grp = DRW_shgroup_create(e_data.volumetric_resolve_sh, psl->volumetric_resolve_ps);
DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)stl->g_data->viewvecs, 2);
DRW_shgroup_uniform_vec2(grp, "volume_uv_ratio", (float *)volumetrics->volume_coord_scale, 1);
DRW_shgroup_uniform_vec3(grp, "volume_param", (float *)volumetrics->depth_param, 1);
DRW_shgroup_uniform_buffer(grp, "inScattering", &txl->volume_scatter);
DRW_shgroup_uniform_buffer(grp, "inTransmittance", &txl->volume_transmittance);
DRW_shgroup_uniform_buffer(grp, "inSceneColor", &e_data.color_src);
DRW_shgroup_uniform_buffer(grp, "inSceneDepth", &e_data.depth_src);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
}
@ -438,7 +448,6 @@ void EEVEE_volumes_cache_object_add(EEVEE_ViewLayerData *sldata, EEVEE_Data *ved
float *texcoloc = NULL;
float *texcosize = NULL;
struct ModifierData *md = NULL;
EEVEE_VolumetricsInfo *volumetrics = sldata->volumetrics;
Material *ma = give_current_material(ob, 1);
if (ma == NULL) {
@ -447,7 +456,7 @@ void EEVEE_volumes_cache_object_add(EEVEE_ViewLayerData *sldata, EEVEE_Data *ved
struct GPUMaterial *mat = EEVEE_material_mesh_volume_get(scene, ma);
DRWShadingGroup *grp = DRW_shgroup_material_empty_tri_batch_create(mat, vedata->psl->volumetric_objects_ps, volumetrics->froxel_tex_size[2]);
DRWShadingGroup *grp = DRW_shgroup_material_empty_tri_batch_create(mat, vedata->psl->volumetric_objects_ps, sldata->common_data.vol_tex_size[2]);
/* Making sure it's updated. */
invert_m4_m4(ob->imat, ob->obmat);
@ -455,14 +464,10 @@ void EEVEE_volumes_cache_object_add(EEVEE_ViewLayerData *sldata, EEVEE_Data *ved
BKE_mesh_texspace_get_reference((struct Mesh *)ob->data, NULL, &texcoloc, NULL, &texcosize);
if (grp) {
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_mat4(grp, "volumeObjectMatrix", (float *)ob->imat);
DRW_shgroup_uniform_vec3(grp, "volumeOrcoLoc", texcoloc, 1);
DRW_shgroup_uniform_vec3(grp, "volumeOrcoSize", texcosize, 1);
DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)vedata->stl->g_data->viewvecs, 2);
DRW_shgroup_uniform_ivec3(grp, "volumeTextureSize", (int *)volumetrics->froxel_tex_size, 1);
DRW_shgroup_uniform_vec2(grp, "volume_uv_ratio", (float *)volumetrics->volume_coord_scale, 1);
DRW_shgroup_uniform_vec3(grp, "volume_param", (float *)volumetrics->depth_param, 1);
DRW_shgroup_uniform_vec3(grp, "volume_jitter", (float *)volumetrics->jitter, 1);
}
/* Smoke Simulation */
@ -572,6 +577,7 @@ void EEVEE_volumes_free(void)
DRW_SHADER_FREE_SAFE(e_data.volumetric_clear_sh);
DRW_SHADER_FREE_SAFE(e_data.volumetric_scatter_sh);
DRW_SHADER_FREE_SAFE(e_data.volumetric_scatter_with_lamps_sh);
DRW_SHADER_FREE_SAFE(e_data.volumetric_integration_sh);
DRW_SHADER_FREE_SAFE(e_data.volumetric_resolve_sh);
}

View File

@ -33,19 +33,8 @@ uniform sampler2DArray utilTex;
#define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
#endif /* UTIL_TEX */
uniform vec4 aoParameters[2];
uniform sampler2D horizonBuffer;
#define aoDistance aoParameters[0].x
#define aoSamples aoParameters[0].y /* UNUSED */
#define aoFactor aoParameters[0].z
#define aoInvSamples aoParameters[0].w /* UNUSED */
#define aoOffset aoParameters[1].x /* UNUSED */
#define aoBounceFac aoParameters[1].y
#define aoQuality aoParameters[1].z
#define aoSettings aoParameters[1].w
/* aoSettings flags */
#define USE_AO 1
#define USE_BENT_NORMAL 2

View File

@ -11,7 +11,6 @@
uniform mat4 ProjectionMatrix;
uniform mat4 ViewProjectionMatrix;
uniform mat4 ViewMatrixInverse;
uniform vec4 viewvecs[2];
#ifndef SHADOW_SHADER
uniform mat4 ViewMatrix;
#else
@ -31,8 +30,6 @@ flat in int shFace; /* Shadow layer we are rendering to. */
#define ViewMatrix FaceViewMatrix[shFace]
#endif
uniform vec2 mipRatio[10];
/* Buffers */
uniform sampler2D colorBuffer;
uniform sampler2D depthBuffer;
@ -304,7 +301,7 @@ float get_view_z_from_depth(float depth)
return -ProjectionMatrix[3][2] / (d + ProjectionMatrix[2][2]);
}
else {
return viewvecs[0].z + depth * viewvecs[1].z;
return viewVecs[0].z + depth * viewVecs[1].z;
}
}
@ -315,7 +312,7 @@ float get_depth_from_view_z(float z)
return d * 0.5 + 0.5;
}
else {
return (z - viewvecs[0].z) / viewvecs[1].z;
return (z - viewVecs[0].z) / viewVecs[1].z;
}
}
@ -328,10 +325,10 @@ vec2 get_uvs_from_view(vec3 view)
vec3 get_view_space_from_depth(vec2 uvcoords, float depth)
{
if (ProjectionMatrix[3][3] == 0.0) {
return (viewvecs[0].xyz + vec3(uvcoords, 0.0) * viewvecs[1].xyz) * get_view_z_from_depth(depth);
return (viewVecs[0].xyz + vec3(uvcoords, 0.0) * viewVecs[1].xyz) * get_view_z_from_depth(depth);
}
else {
return viewvecs[0].xyz + vec3(uvcoords, depth) * viewvecs[1].xyz;
return viewVecs[0].xyz + vec3(uvcoords, depth) * viewVecs[1].xyz;
}
}
@ -746,8 +743,6 @@ Closure closure_add(Closure cl1, Closure cl2)
return cl;
}
uniform bool sssToggle;
#if defined(MESH_SHADER) && !defined(USE_ALPHA_HASH) && !defined(USE_ALPHA_CLIP) && !defined(SHADOW_SHADER) && !defined(USE_MULTIPLY)
layout(location = 0) out vec4 fragColor;
#ifdef USE_SSS

View File

@ -0,0 +1,55 @@
layout(std140) uniform common_block {
mat4 pastViewProjectionMatrix;
vec4 viewVecs[2];
vec2 mipRatio[10]; /* To correct mip level texel mis-alignement */
/* Ambient Occlusion */
vec4 aoParameters[2];
/* Volumetric */
ivec4 volTexSize;
vec4 volDepthParameters; /* Parameters to the volume Z equation */
vec4 volInvTexSize;
vec4 volJitter;
vec4 volCoordScale; /* To convert volume uvs to screen uvs */
float volHistoryAlpha;
float volLightClamp;
float volShadowSteps;
bool volUseLights;
/* Screen Space Reflections */
vec4 ssrParameters;
float ssrBorderFac;
float ssrMaxRoughness;
float ssrFireflyFac;
float ssrBrdfBias;
bool ssrToggle;
/* SubSurface Scattering */
float sssJitterThreshold;
bool sssToggle;
/* Specular */
bool specToggle;
/* Lamps */
int laNumLight;
/* Probes */
int prbNumPlanar;
int prbNumRenderCube;
int prbNumRenderGrid;
int prbIrradianceVisSize;
float prbLodCubeMax;
float prbLodPlanarMax;
};
/* aoParameters */
#define aoDistance aoParameters[0].x
#define aoSamples aoParameters[0].y /* UNUSED */
#define aoFactor aoParameters[0].z
#define aoInvSamples aoParameters[0].w /* UNUSED */
#define aoOffset aoParameters[1].x /* UNUSED */
#define aoBounceFac aoParameters[1].y
#define aoQuality aoParameters[1].z
#define aoSettings aoParameters[1].w
/* ssrParameters */
#define ssrQuality ssrParameters.x
#define ssrThickness ssrParameters.y
#define ssrPixelSize ssrParameters.zw

View File

@ -10,9 +10,6 @@ uniform sampler2DArray utilTex;
#define MAX_MIP 9.0
uniform float brdfBias;
uniform float fireflyFactor;
uniform float maxRoughness;
uniform ivec2 halfresOffset;
ivec2 encode_hit_data(vec2 hit_pos, bool has_hit, bool is_planar)
@ -35,9 +32,6 @@ vec2 decode_hit_data(vec2 hit_data, out bool has_hit, out bool is_planar)
uniform sampler2D normalBuffer;
uniform sampler2D specroughBuffer;
uniform int planar_count;
uniform float noiseOffset;
layout(location = 0) out ivec2 hitData;
layout(location = 1) out float pdfData;
@ -125,7 +119,7 @@ void main()
float a2 = roughnessSquared * roughnessSquared;
/* Early out */
if (roughness > maxRoughness + 0.2)
if (roughness > ssrMaxRoughness + 0.2)
return;
vec4 rand = texelFetch(utilTex, ivec3(halfres_texel % LUT_SIZE, 2), 0);
@ -135,7 +129,7 @@ void main()
rand.xzw *= 0.0;
}
/* Importance sampling bias */
rand.x = mix(rand.x, 0.0, brdfBias);
rand.x = mix(rand.x, 0.0, ssrBrdfBias);
vec3 worldPosition = transform_point(ViewMatrixInverse, viewPosition);
vec3 wN = transform_direction(ViewMatrixInverse, N);
@ -144,7 +138,7 @@ void main()
make_orthonormal_basis(N, T, B); /* Generate tangent space */
/* Planar Reflections */
for (int i = 0; i < MAX_PLANAR && i < planar_count; ++i) {
for (int i = 0; i < MAX_PLANAR && i < prbNumPlanar; ++i) {
PlanarData pd = planars_data[i];
float fade = probe_attenuation_planar(pd, worldPosition, wN, 0.0);
@ -173,9 +167,6 @@ uniform sampler2D specroughBuffer;
uniform isampler2D hitBuffer;
uniform sampler2D pdfBuffer;
uniform int probe_count;
uniform int planar_count;
uniform int neighborOffset;
const ivec2 neighbors[32] = ivec2[32](
@ -190,8 +181,6 @@ const ivec2 neighbors[32] = ivec2[32](
ivec2( 0, 0), ivec2( 2, 2), ivec2( 2, -2), ivec2(-1, 0)
);
uniform mat4 PastViewProjectionMatrix;
out vec4 fragColor;
void fallback_cubemap(
@ -206,7 +195,7 @@ void fallback_cubemap(
final_ao = specular_occlusion(dot(N, V), final_ao, roughness);
/* Starts at 1 because 0 is world probe */
for (int i = 1; i < MAX_PROBE && i < probe_count && spec_accum.a < 0.999; ++i) {
for (int i = 1; i < MAX_PROBE && i < prbNumRenderCube && spec_accum.a < 0.999; ++i) {
CubeData cd = probes_data[i];
float fade = probe_attenuation_cube(cd, W);
@ -257,7 +246,7 @@ float brightness(vec3 c)
vec2 get_reprojected_reflection(vec3 hit, vec3 pos, vec3 N)
{
/* TODO real reprojection with motion vectors, etc... */
return project_point(PastViewProjectionMatrix, hit).xy * 0.5 + 0.5;
return project_point(pastViewProjectionMatrix, hit).xy * 0.5 + 0.5;
}
float get_sample_depth(vec2 hit_co, bool is_planar, float planar_index)
@ -296,7 +285,7 @@ vec3 get_hit_vector(
vec3 get_scene_color(vec2 ref_uvs, float mip, float planar_index, bool is_planar)
{
if (is_planar) {
return textureLod(probePlanars, vec3(ref_uvs, planar_index), min(mip, lodPlanarMax)).rgb;
return textureLod(probePlanars, vec3(ref_uvs, planar_index), min(mip, prbLodPlanarMax)).rgb;
}
else {
return textureLod(prevColorBuffer, ref_uvs, mip).rgb;
@ -361,7 +350,7 @@ vec4 get_ssr_samples(
/* Compute cone footprint in screen space. */
vec4 cone_footprint = hit_dist * cone_tan;
cone_footprint = brdfBias * 0.5 * cone_footprint * max(ProjectionMatrix[0][0], ProjectionMatrix[1][1]) / homcoord;
cone_footprint = ssrBrdfBias * 0.5 * cone_footprint * max(ProjectionMatrix[0][0], ProjectionMatrix[1][1]) / homcoord;
/* Estimate a cone footprint to sample a corresponding mipmap level. */
vec4 mip = log2(cone_footprint * max_v2(vec2(textureSize(depthBuffer, 0))));
@ -395,7 +384,7 @@ vec4 get_ssr_samples(
luma.z = brightness(sample[2]);
luma.w = brightness(sample[3]);
luma = max(vec4(1e-8), luma);
luma = 1.0 - max(vec4(0.0), luma - fireflyFactor) / luma;
luma = 1.0 - max(vec4(0.0), luma - ssrFireflyFac) / luma;
sample[0] *= luma.x;
sample[1] *= luma.y;
@ -474,7 +463,7 @@ void main()
/* Find Planar Reflections affecting this pixel */
PlanarData pd;
float planar_index;
for (int i = 0; i < MAX_PLANAR && i < planar_count; ++i) {
for (int i = 0; i < MAX_PLANAR && i < prbNumPlanar; ++i) {
pd = planars_data[i];
float fade = probe_attenuation_planar(pd, worldPosition, N, 0.0);
@ -495,12 +484,12 @@ void main()
float cone_tan = sqrt(1 - cone_cos * cone_cos) / cone_cos;
cone_tan *= mix(saturate(dot(N, -V) * 2.0), 1.0, roughness); /* Elongation fit */
vec2 source_uvs = project_point(PastViewProjectionMatrix, worldPosition).xy * 0.5 + 0.5;
vec2 source_uvs = project_point(pastViewProjectionMatrix, worldPosition).xy * 0.5 + 0.5;
vec4 ssr_accum = vec4(0.0);
float weight_acc = 0.0;
if (roughness < maxRoughness + 0.2) {
if (roughness < ssrMaxRoughness + 0.2) {
ssr_accum += get_ssr_samples(hit_pdf, hit_data, pd, planar_index, worldPosition, N, V,
roughnessSquared, cone_tan, source_uvs, weight_acc);
}
@ -509,7 +498,7 @@ void main()
if (weight_acc > 0.0) {
ssr_accum /= weight_acc;
/* fade between 0.5 and 1.0 roughness */
ssr_accum.a *= smoothstep(maxRoughness + 0.2, maxRoughness, roughness);
ssr_accum.a *= smoothstep(ssrMaxRoughness + 0.2, ssrMaxRoughness, roughness);
accumulate_light(ssr_accum.rgb, ssr_accum.a, spec_accum);
}

View File

@ -8,7 +8,6 @@ layout(std140) uniform sssProfile {
int sss_samples;
};
uniform float jitterThreshold;
uniform sampler2D depthBuffer;
uniform sampler2D sssData;
uniform sampler2D sssAlbedo;
@ -22,7 +21,6 @@ uniform sampler2DArray utilTex;
out vec4 FragColor;
uniform mat4 ProjectionMatrix;
uniform vec4 viewvecs[2];
float get_view_z_from_depth(float depth)
{
@ -31,7 +29,7 @@ float get_view_z_from_depth(float depth)
return -ProjectionMatrix[3][2] / (d + ProjectionMatrix[2][2]);
}
else {
return viewvecs[0].z + depth * viewvecs[1].z;
return viewVecs[0].z + depth * viewVecs[1].z;
}
}
@ -66,7 +64,7 @@ void main(void)
vec3 accum = sss_data.rgb * kernel[0].rgb;
for (int i = 1; i < sss_samples && i < MAX_SSS_SAMPLES; i++) {
vec2 sample_uv = uvs + kernel[i].a * finalStep * ((abs(kernel[i].a) > jitterThreshold) ? dir : dir_rand);
vec2 sample_uv = uvs + kernel[i].a * finalStep * ((abs(kernel[i].a) > sssJitterThreshold) ? dir : dir_rand);
vec3 color = texture(sssData, sample_uv).rgb;
float sample_depth = texture(depthBuffer, sample_uv).r;
sample_depth = get_view_z_from_depth(sample_depth);

View File

@ -1,6 +1,5 @@
uniform sampler2DArray irradianceGrid;
uniform int irradianceVisibilitySize;
#define IRRADIANCE_LIB
@ -81,8 +80,8 @@ IrradianceData load_irradiance_cell(int cell, vec3 N)
float load_visibility_cell(int cell, vec3 L, float dist, float bias, float bleed_bias, float range)
{
/* Keep in sync with diffuse_filter_probe() */
ivec2 cell_co = ivec2(irradianceVisibilitySize);
ivec2 cell_per_row_col = textureSize(irradianceGrid, 0).xy / irradianceVisibilitySize;
ivec2 cell_co = ivec2(prbIrradianceVisSize);
ivec2 cell_per_row_col = textureSize(irradianceGrid, 0).xy / prbIrradianceVisSize;
cell_co.x *= (cell % cell_per_row_col.x);
cell_co.y *= (cell / cell_per_row_col.x) % cell_per_row_col.y;
float layer = 1.0 + float((cell / cell_per_row_col.x) / cell_per_row_col.y);
@ -90,8 +89,8 @@ float load_visibility_cell(int cell, vec3 L, float dist, float bias, float bleed
vec2 texel_size = 1.0 / vec2(textureSize(irradianceGrid, 0).xy);
vec2 co = vec2(cell_co) * texel_size;
vec2 uv = mapping_octahedron(-L, vec2(1.0 / float(irradianceVisibilitySize)));
uv *= vec2(irradianceVisibilitySize) * texel_size;
vec2 uv = mapping_octahedron(-L, vec2(1.0 / float(prbIrradianceVisSize)));
uv *= vec2(prbIrradianceVisSize) * texel_size;
vec4 data = texture(irradianceGrid, vec3(co + uv, layer));

View File

@ -11,5 +11,5 @@ void main()
? normalize(cameraPos - worldPosition)
: cameraForward;
vec3 N = normalize(worldNormal);
FragColor = vec4(textureLod_octahedron(probeCubes, vec4(reflect(-V, N), pid), 0.0, lodCubeMax).rgb, 1.0);
FragColor = vec4(textureLod_octahedron(probeCubes, vec4(reflect(-V, N), pid), 0.0, prbLodCubeMax).rgb, 1.0);
}

View File

@ -1,10 +1,7 @@
/* ----------- Uniforms --------- */
uniform sampler2DArray probePlanars;
uniform float lodPlanarMax;
uniform sampler2DArray probeCubes;
uniform float lodCubeMax;
/* ----------- Structures --------- */
@ -162,12 +159,12 @@ vec3 probe_evaluate_cube(float id, CubeData cd, vec3 W, vec3 R, float roughness)
float fac = saturate(original_roughness * 2.0 - 1.0);
R = mix(intersection, R, fac * fac);
return textureLod_octahedron(probeCubes, vec4(R, id), roughness * lodCubeMax, lodCubeMax).rgb;
return textureLod_octahedron(probeCubes, vec4(R, id), roughness * prbLodCubeMax, prbLodCubeMax).rgb;
}
vec3 probe_evaluate_world_spec(vec3 R, float roughness)
{
return textureLod_octahedron(probeCubes, vec4(R, 0.0), roughness * lodCubeMax, lodCubeMax).rgb;
return textureLod_octahedron(probeCubes, vec4(R, 0.0), roughness * prbLodCubeMax, prbLodCubeMax).rgb;
}
vec3 probe_evaluate_planar(

View File

@ -2,14 +2,6 @@
#ifndef LIT_SURFACE_UNIFORM
#define LIT_SURFACE_UNIFORM
uniform int light_count;
uniform int probe_count;
uniform int grid_count;
uniform int planar_count;
uniform bool specToggle;
uniform bool ssrToggle;
uniform float refractionDepth;
#ifndef UTIL_TEX
@ -29,8 +21,6 @@ in vec3 worldNormal;
in vec3 viewNormal;
#endif
uniform float maxRoughness;
#endif /* LIT_SURFACE_UNIFORM */
/** AUTO CONFIG
@ -187,7 +177,7 @@ void CLOSURE_NAME(
norm_view = normalize(cross(norm_view, N)); /* Normal facing view */
#endif
for (int i = 0; i < MAX_LIGHT && i < light_count; ++i) {
for (int i = 0; i < MAX_LIGHT && i < laNumLight; ++i) {
LightData ld = lights_data[i];
vec4 l_vector; /* Non-Normalized Light Vector with length in last component. */
@ -266,7 +256,7 @@ void CLOSURE_NAME(
/* Planar Reflections */
/* ---------------------------- */
for (int i = 0; i < MAX_PLANAR && i < planar_count && spec_accum.a < 0.999; ++i) {
for (int i = 0; i < MAX_PLANAR && i < prbNumPlanar && spec_accum.a < 0.999; ++i) {
PlanarData pd = planars_data[i];
/* Fade on geometric normal. */
@ -312,11 +302,11 @@ void CLOSURE_NAME(
/* Screen Space Refraction */
/* ---------------------------- */
#ifdef USE_REFRACTION
if (ssrToggle && roughness < maxRoughness + 0.2) {
if (ssrToggle && roughness < ssrMaxRoughness + 0.2) {
/* Find approximated position of the 2nd refraction event. */
vec3 refr_vpos = (refractionDepth > 0.0) ? transform_point(ViewMatrix, refr_pos) : viewPosition;
vec4 trans = screen_space_refraction(refr_vpos, N, refr_V, final_ior, roughnessSquared, rand);
trans.a *= smoothstep(maxRoughness + 0.2, maxRoughness, roughness);
trans.a *= smoothstep(ssrMaxRoughness + 0.2, ssrMaxRoughness, roughness);
accumulate_light(trans.rgb, trans.a, refr_accum);
}
#endif
@ -336,7 +326,7 @@ void CLOSURE_NAME(
#endif
/* Starts at 1 because 0 is world probe */
for (int i = 1; ACCUM.a < 0.999 && i < probe_count && i < MAX_PROBE; ++i) {
for (int i = 1; ACCUM.a < 0.999 && i < prbNumRenderCube && i < MAX_PROBE; ++i) {
CubeData cd = probes_data[i];
float fade = probe_attenuation_cube(cd, worldPosition);
@ -448,7 +438,7 @@ void CLOSURE_NAME(
/* Irradiance Grids */
/* ---------------------------- */
/* Start at 1 because 0 is world irradiance */
for (int i = 1; i < MAX_GRID && i < grid_count && diff_accum.a < 0.999; ++i) {
for (int i = 1; i < MAX_GRID && i < prbNumRenderGrid && diff_accum.a < 0.999; ++i) {
GridData gd = grids_data[i];
vec3 localpos;
@ -463,7 +453,7 @@ void CLOSURE_NAME(
/* ---------------------------- */
/* World Diffuse */
/* ---------------------------- */
if (diff_accum.a < 0.999 && grid_count > 0) {
if (diff_accum.a < 0.999 && prbNumRenderGrid > 0) {
vec3 diff = probe_evaluate_world_diff(bent_normal);
accumulate_light(diff, 1.0, diff_accum);
}

View File

@ -1,13 +1,5 @@
#define MAX_STEP 256
uniform vec4 ssrParameters;
#define ssrQuality ssrParameters.x
#define ssrThickness ssrParameters.y
#define ssrPixelSize ssrParameters.zw
uniform float borderFadeFactor;
float sample_depth(vec2 uv, int index, float lod)
{
#ifdef PLANAR_PROBE_RAYTRACE
@ -233,7 +225,7 @@ vec3 raycast(
float screen_border_mask(vec2 hit_co)
{
const float margin = 0.003;
float atten = borderFadeFactor + margin; /* Screen percentage */
float atten = ssrBorderFac + margin; /* Screen percentage */
hit_co = smoothstep(margin, atten, hit_co) * (1 - smoothstep(1.0 - atten, 1.0 - margin, hit_co));
float screenfade = hit_co.x * hit_co.y;

View File

@ -4,9 +4,6 @@
#define NODETREE_EXEC
uniform ivec3 volumeTextureSize;
uniform vec3 volume_jitter;
#ifdef MESH_SHADER
uniform mat4 volumeObjectMatrix;
uniform vec3 volumeOrcoLoc;
@ -33,7 +30,7 @@ layout(location = 3) out vec4 volumePhase;
void main()
{
ivec3 volume_cell = ivec3(gl_FragCoord.xy, slice);
vec3 ndc_cell = volume_to_ndc((vec3(volume_cell) + volume_jitter) / volumeTextureSize);
vec3 ndc_cell = volume_to_ndc((vec3(volume_cell) + volJitter.xyz) * volInvTexSize.xyz);
viewPosition = get_view_space_from_depth(ndc_cell.xy, ndc_cell.z);
worldPosition = transform_point(ViewMatrixInverse, viewPosition);

View File

@ -2,22 +2,16 @@
/* Based on Frosbite Unified Volumetric.
* https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite */
uniform float volume_light_clamp;
uniform vec3 volume_param; /* Parameters to the volume Z equation */
uniform vec2 volume_uv_ratio; /* To convert volume uvs to screen uvs */
/* Volume slice to view space depth. */
float volume_z_to_view_z(float z)
{
if (ProjectionMatrix[3][3] == 0.0) {
/* Exponential distribution */
return (exp2(z / volume_param.z) - volume_param.x) / volume_param.y;
return (exp2(z / volDepthParameters.z) - volDepthParameters.x) / volDepthParameters.y;
}
else {
/* Linear distribution */
return mix(volume_param.x, volume_param.y, z);
return mix(volDepthParameters.x, volDepthParameters.y, z);
}
}
@ -25,11 +19,11 @@ float view_z_to_volume_z(float depth)
{
if (ProjectionMatrix[3][3] == 0.0) {
/* Exponential distribution */
return volume_param.z * log2(depth * volume_param.y + volume_param.x);
return volDepthParameters.z * log2(depth * volDepthParameters.y + volDepthParameters.x);
}
else {
/* Linear distribution */
return (depth - volume_param.x) * volume_param.z;
return (depth - volDepthParameters.x) * volDepthParameters.z;
}
}
@ -38,7 +32,7 @@ vec3 volume_to_ndc(vec3 cos)
{
cos.z = volume_z_to_view_z(cos.z);
cos.z = get_depth_from_view_z(cos.z);
cos.xy /= volume_uv_ratio;
cos.xy /= volCoordScale.xy;
return cos;
}
@ -46,7 +40,7 @@ vec3 ndc_to_volume(vec3 cos)
{
cos.z = get_view_z_from_depth(cos.z);
cos.z = view_z_to_volume_z(cos.z);
cos.xy *= volume_uv_ratio;
cos.xy *= volCoordScale.xy;
return cos;
}
@ -90,15 +84,13 @@ vec3 light_volume(LightData ld, vec4 l_vector)
power /= (l_vector.w * l_vector.w);
lum = min(lum * power, volume_light_clamp);
lum = min(lum * power, volLightClamp);
return tint * lum;
}
#define VOLUMETRIC_SHADOW_MAX_STEP 32.0
uniform float volume_shadows_steps;
vec3 participating_media_extinction(vec3 wpos, sampler3D volume_extinction)
{
/* Waiting for proper volume shadowmaps and out of frustum shadow map. */
@ -113,11 +105,11 @@ vec3 light_volume_shadow(LightData ld, vec3 ray_wpos, vec4 l_vector, sampler3D v
{
#if defined(VOLUME_SHADOW)
/* Heterogeneous volume shadows */
float dd = l_vector.w / volume_shadows_steps;
float dd = l_vector.w / volShadowSteps;
vec3 L = l_vector.xyz * l_vector.w;
vec3 shadow = vec3(1.0);
for (float s = 0.5; s < VOLUMETRIC_SHADOW_MAX_STEP && s < (volume_shadows_steps - 0.1); s += 1.0) {
vec3 pos = ray_wpos + L * (s / volume_shadows_steps);
for (float s = 0.5; s < VOLUMETRIC_SHADOW_MAX_STEP && s < (volShadowSteps - 0.1); s += 1.0) {
vec3 pos = ray_wpos + L * (s / volShadowSteps);
vec3 s_extinction = participating_media_extinction(pos, volume_extinction);
shadow *= exp(-s_extinction * dd);
}

View File

@ -13,28 +13,20 @@ uniform sampler3D volumePhase;
uniform sampler3D historyScattering;
uniform sampler3D historyTransmittance;
uniform vec3 volume_jitter;
uniform float volume_history_alpha;
uniform int light_count;
uniform mat4 PastViewProjectionMatrix;
flat in int slice;
layout(location = 0) out vec4 outScattering;
layout(location = 1) out vec4 outTransmittance;
#define VOLUME_LIGHTING
void main()
{
vec3 volume_tex_size = vec3(textureSize(volumeScattering, 0));
ivec3 volume_cell = ivec3(gl_FragCoord.xy, slice);
/* Emission */
outScattering = texelFetch(volumeEmission, volume_cell, 0);
outTransmittance = texelFetch(volumeExtinction, volume_cell, 0);
vec3 s_scattering = texelFetch(volumeScattering, volume_cell, 0).rgb;
vec3 volume_ndc = volume_to_ndc((vec3(volume_cell) + volume_jitter) / volume_tex_size);
vec3 volume_ndc = volume_to_ndc((vec3(volume_cell) + volJitter.xyz) * volInvTexSize.xyz);
vec3 worldPosition = get_world_space_from_depth(volume_ndc.xy, volume_ndc.z);
vec3 wdir = cameraVec;
@ -45,7 +37,7 @@ void main()
outScattering.rgb += irradiance_volumetric(worldPosition) * s_scattering * phase_function_isotropic();
#ifdef VOLUME_LIGHTING /* Lights */
for (int i = 0; i < MAX_LIGHT && i < light_count; ++i) {
for (int i = 0; i < MAX_LIGHT && i < laNumLight; ++i) {
LightData ld = lights_data[i];
@ -63,16 +55,16 @@ void main()
/* Temporal supersampling */
/* Note : this uses the cell non-jittered position (texel center). */
vec3 curr_ndc = volume_to_ndc(vec3(gl_FragCoord.xy, float(slice) + 0.5) / volume_tex_size);
vec3 curr_ndc = volume_to_ndc(vec3(gl_FragCoord.xy, float(slice) + 0.5) * volInvTexSize.xyz);
vec3 wpos = get_world_space_from_depth(curr_ndc.xy, curr_ndc.z);
vec3 prev_ndc = project_point(PastViewProjectionMatrix, wpos);
vec3 prev_ndc = project_point(pastViewProjectionMatrix, wpos);
vec3 prev_volume = ndc_to_volume(prev_ndc * 0.5 + 0.5);
if ((volume_history_alpha > 0.0) && all(greaterThan(prev_volume, vec3(0.0))) && all(lessThan(prev_volume, vec3(1.0)))) {
if ((volHistoryAlpha > 0.0) && all(greaterThan(prev_volume, vec3(0.0))) && all(lessThan(prev_volume, vec3(1.0)))) {
vec4 h_Scattering = texture(historyScattering, prev_volume);
vec4 h_Transmittance = texture(historyTransmittance, prev_volume);
outScattering = mix(outScattering, h_Scattering, volume_history_alpha);
outTransmittance = mix(outTransmittance, h_Transmittance, volume_history_alpha);
outScattering = mix(outScattering, h_Scattering, volHistoryAlpha);
outTransmittance = mix(outTransmittance, h_Transmittance, volHistoryAlpha);
}
/* Catch NaNs */