EEVEE: Render Passes

This patch adds new render passes to EEVEE. These passes include:

* Emission
* Diffuse Light
* Diffuse Color
* Glossy Light
* Glossy Color
* Environment
* Volume Scattering
* Volume Transmission
* Bloom
* Shadow

With these passes it will be possible to use EEVEE effectively for
compositing. During development we kept a close eye on how to get similar
results compared to cycles render passes there are some differences that
are related to how EEVEE works. For EEVEE we combined the passes to
`Diffuse` and `Specular`. There are no transmittance or sss passes anymore.
Cycles will be changed accordingly.

Cycles volume transmittance is added to multiple surface col passes. For
EEVEE we left the volume transmittance as a separate pass.

Known Limitations

* All materials that use alpha blending will not be rendered in the render
  passes. Other transparency modes are supported.
* More GPU memory is required to store the render passes. When rendering
  a HD image with all render passes enabled at max extra 570MB GPU memory is
  required.

Implementation Details

An overview of render passes have been described in
https://wiki.blender.org/wiki/Source/Render/EEVEE/RenderPasses

Future Developments

* In this implementation the materials are re-rendered for Diffuse/Glossy
  and Emission passes. We could use multi target rendering to improve the
  render speed.
* Other passes can be added later
* Don't render material based passes when only requesting AO or Shadow.
* Add more passes to the system. These could include Cryptomatte, AOV's, Vector,
  ObjectID, MaterialID, UV.

Reviewed By: Clément Foucault

Differential Revision: https://developer.blender.org/D6331
This commit is contained in:
Jeroen Bakker 2020-02-20 14:53:53 +01:00 committed by Jeroen Bakker
parent 1f8f4c8cfe
commit be2bc97eba
45 changed files with 1933 additions and 406 deletions

View File

@ -58,15 +58,26 @@ class VIEWLAYER_PT_eevee_layer_passes(ViewLayerButtonsPanel, Panel):
bl_label = "Passes"
COMPAT_ENGINES = {'BLENDER_EEVEE'}
def draw(self, context):
pass
class VIEWLAYER_PT_eevee_layer_passes_data(ViewLayerButtonsPanel, Panel):
bl_label = "Data"
bl_parent_id = "VIEWLAYER_PT_eevee_layer_passes"
COMPAT_ENGINES = {'BLENDER_EEVEE'}
def draw(self, context):
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = False
flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
scene = context.scene
rd = scene.render
view_layer = context.view_layer
flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
col = flow.column()
col.prop(view_layer, "use_pass_combined")
col = flow.column()
@ -75,17 +86,83 @@ class VIEWLAYER_PT_eevee_layer_passes(ViewLayerButtonsPanel, Panel):
col.prop(view_layer, "use_pass_mist")
col = flow.column()
col.prop(view_layer, "use_pass_normal")
col = flow.column()
col.prop(view_layer, "use_pass_ambient_occlusion")
col = flow.column()
col.prop(view_layer, "use_pass_subsurface_direct", text="Subsurface Direct")
col = flow.column()
col.prop(view_layer, "use_pass_subsurface_color", text="Subsurface Color")
class VIEWLAYER_PT_eevee_layer_passes_light(ViewLayerButtonsPanel, Panel):
bl_label = "Light"
bl_parent_id = "VIEWLAYER_PT_eevee_layer_passes"
COMPAT_ENGINES = {'BLENDER_EEVEE'}
def draw(self, context):
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = False
view_layer = context.view_layer
view_layer_eevee = view_layer.eevee
scene = context.scene
scene_eevee = scene.eevee
split = layout.split(factor=0.35)
split.use_property_split = False
split.label(text="Diffuse")
row = split.row(align=True)
row.prop(view_layer, "use_pass_diffuse_direct", text="Light", toggle=True)
row.prop(view_layer, "use_pass_diffuse_color", text="Color", toggle=True)
split = layout.split(factor=0.35)
split.use_property_split = False
split.label(text="Specular")
row = split.row(align=True)
row.prop(view_layer, "use_pass_glossy_direct", text="Light", toggle=True)
row.prop(view_layer, "use_pass_glossy_color", text="Color", toggle=True)
split = layout.split(factor=0.35)
split.use_property_split = False
split.label(text="Volume")
row = split.row(align=True)
row.prop(view_layer_eevee, "use_pass_volume_transmittance", text="Transmittance", toggle=True)
row.prop(view_layer_eevee, "use_pass_volume_scatter", text="Scatter", toggle=True)
flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
col = layout.column(align=True)
col.prop(view_layer, "use_pass_emit", text="Emission")
col.prop(view_layer, "use_pass_environment")
col.prop(view_layer, "use_pass_shadow")
row = col.row()
row.prop(view_layer, "use_pass_ambient_occlusion", text="Ambient Occlusion")
row.active = scene_eevee.use_gtao
class VIEWLAYER_PT_eevee_layer_passes_effects(ViewLayerButtonsPanel, Panel):
bl_label = "Effects"
bl_parent_id = "VIEWLAYER_PT_eevee_layer_passes"
COMPAT_ENGINES = {'BLENDER_EEVEE'}
def draw(self, context):
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = False
flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
view_layer = context.view_layer
view_layer_eevee = view_layer.eevee
scene = context.scene
scene_eevee = scene.eevee
col = flow.column()
col.prop(view_layer_eevee, "use_pass_bloom", text="Bloom")
col.active = scene_eevee.use_bloom
classes = (
VIEWLAYER_PT_layer,
VIEWLAYER_PT_eevee_layer_passes,
VIEWLAYER_PT_eevee_layer_passes_data,
VIEWLAYER_PT_eevee_layer_passes_light,
VIEWLAYER_PT_eevee_layer_passes_effects,
)
if __name__ == "__main__": # only for live edit.

View File

@ -219,6 +219,8 @@ data_to_c_simple(engines/eevee/shaders/lightprobe_planar_downsample_geom.glsl SR
data_to_c_simple(engines/eevee/shaders/lightprobe_planar_downsample_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/prepass_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/prepass_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/shadow_accum_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/shadow_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/shadow_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/bsdf_lut_frag.glsl SRC)
@ -232,6 +234,7 @@ data_to_c_simple(engines/eevee/shaders/renderpass_postprocess_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/ltc_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/ssr_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/update_noise_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/volumetric_accum_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/volumetric_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/volumetric_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/volumetric_geom.glsl SRC)

View File

@ -40,6 +40,8 @@ static struct {
extern char datatoc_effect_bloom_frag_glsl[];
const bool use_highres = true;
static void eevee_create_shader_bloom(void)
{
e_data.bloom_blit_sh[0] = DRW_shader_create_fullscreen(datatoc_effect_bloom_frag_glsl,
@ -179,7 +181,8 @@ static DRWShadingGroup *eevee_create_bloom_pass(const char *name,
EEVEE_EffectsInfo *effects,
struct GPUShader *sh,
DRWPass **pass,
bool upsample)
bool upsample,
bool resolve)
{
struct GPUBatch *quad = DRW_cache_fullscreen_quad_get();
@ -193,6 +196,10 @@ static DRWShadingGroup *eevee_create_bloom_pass(const char *name,
DRW_shgroup_uniform_texture_ref(grp, "baseBuffer", &effects->unf_base_buffer);
DRW_shgroup_uniform_float(grp, "sampleScale", &effects->bloom_sample_scale, 1);
}
if (resolve) {
DRW_shgroup_uniform_vec3(grp, "bloomColor", effects->bloom_color, 1);
DRW_shgroup_uniform_bool_copy(grp, "bloomAddBase", true);
}
return grp;
}
@ -203,6 +210,8 @@ void EEVEE_bloom_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *ved
EEVEE_StorageList *stl = vedata->stl;
EEVEE_EffectsInfo *effects = stl->effects;
psl->bloom_accum_ps = NULL;
if ((effects->enabled_effects & EFFECT_BLOOM) != 0) {
/** Bloom algorithm
*
@ -234,29 +243,41 @@ void EEVEE_bloom_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *ved
* </pre>
*/
DRWShadingGroup *grp;
const bool use_highres = true;
const bool use_antiflicker = true;
eevee_create_bloom_pass("Bloom Downsample First",
effects,
e_data.bloom_downsample_sh[use_antiflicker],
&psl->bloom_downsample_first,
false,
false);
eevee_create_bloom_pass("Bloom Downsample",
effects,
e_data.bloom_downsample_sh[0],
&psl->bloom_downsample,
false,
false);
eevee_create_bloom_pass(
"Bloom Downsample", effects, e_data.bloom_downsample_sh[0], &psl->bloom_downsample, false);
eevee_create_bloom_pass("Bloom Upsample",
effects,
e_data.bloom_upsample_sh[use_highres],
&psl->bloom_upsample,
true);
true,
false);
grp = eevee_create_bloom_pass(
"Bloom Blit", effects, e_data.bloom_blit_sh[use_antiflicker], &psl->bloom_blit, false);
grp = eevee_create_bloom_pass("Bloom Blit",
effects,
e_data.bloom_blit_sh[use_antiflicker],
&psl->bloom_blit,
false,
false);
DRW_shgroup_uniform_vec4(grp, "curveThreshold", effects->bloom_curve_threshold, 1);
DRW_shgroup_uniform_float(grp, "clampIntensity", &effects->bloom_clamp, 1);
grp = eevee_create_bloom_pass(
"Bloom Resolve", effects, e_data.bloom_resolve_sh[use_highres], &psl->bloom_resolve, true);
DRW_shgroup_uniform_vec3(grp, "bloomColor", effects->bloom_color, 1);
grp = eevee_create_bloom_pass("Bloom Resolve",
effects,
e_data.bloom_resolve_sh[use_highres],
&psl->bloom_resolve,
true,
true);
}
}
@ -322,6 +343,47 @@ void EEVEE_bloom_draw(EEVEE_Data *vedata)
}
}
void EEVEE_bloom_output_init(EEVEE_ViewLayerData *UNUSED(sldata),
EEVEE_Data *vedata,
uint UNUSED(tot_samples))
{
EEVEE_FramebufferList *fbl = vedata->fbl;
EEVEE_TextureList *txl = vedata->txl;
EEVEE_PassList *psl = vedata->psl;
EEVEE_StorageList *stl = vedata->stl;
EEVEE_EffectsInfo *effects = stl->effects;
/* Create FrameBuffer. */
DRW_texture_ensure_fullscreen_2d(&txl->bloom_accum, GPU_R11F_G11F_B10F, 0);
GPU_framebuffer_ensure_config(&fbl->bloom_pass_accum_fb,
{GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->bloom_accum)});
/* Create Pass and shgroup. */
DRWShadingGroup *grp = eevee_create_bloom_pass("Bloom Accumulate",
effects,
e_data.bloom_resolve_sh[use_highres],
&psl->bloom_accum_ps,
true,
true);
DRW_shgroup_uniform_bool_copy(grp, "bloomAddBase", false);
}
void EEVEE_bloom_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
{
EEVEE_FramebufferList *fbl = vedata->fbl;
EEVEE_PassList *psl = vedata->psl;
EEVEE_StorageList *stl = vedata->stl;
if (stl->g_data->render_passes & EEVEE_RENDER_PASS_BLOOM) {
GPU_framebuffer_bind(fbl->bloom_pass_accum_fb);
DRW_draw_pass(psl->bloom_accum_ps);
/* Restore */
GPU_framebuffer_bind(fbl->main_fb);
}
}
void EEVEE_bloom_free(void)
{
for (int i = 0; i < 2; i++) {

View File

@ -54,6 +54,9 @@ void EEVEE_view_layer_data_free(void *storage)
DRW_UBO_FREE_SAFE(sldata->grid_ubo);
DRW_UBO_FREE_SAFE(sldata->planar_ubo);
DRW_UBO_FREE_SAFE(sldata->common_ubo);
for (int i = 0; i < MAX_MATERIAL_RENDER_PASSES_UBO; i++) {
DRW_UBO_FREE_SAFE(sldata->renderpass_ubo[i]);
}
}
EEVEE_ViewLayerData *EEVEE_view_layer_data_get(void)

View File

@ -170,7 +170,7 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata,
EEVEE_subsurface_init(sldata, vedata);
/* Force normal buffer creation. */
if (!minimal && (stl->g_data->render_passes & SCE_PASS_NORMAL) != 0) {
if (!minimal && (stl->g_data->render_passes & EEVEE_RENDER_PASS_NORMAL) != 0) {
effects->enabled_effects |= EFFECT_NORMAL_BUFFER;
}
@ -333,6 +333,8 @@ void EEVEE_effects_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
grp = DRW_shgroup_create(EEVEE_shaders_velocity_resolve_sh_get(), psl->velocity_resolve);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &e_data.depth_src);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_mat4(grp, "currPersinv", effects->velocity_curr_persinv);
DRW_shgroup_uniform_mat4(grp, "pastPersmat", effects->velocity_past_persmat);
DRW_shgroup_call(grp, quad, NULL);
@ -513,7 +515,7 @@ static void EEVEE_velocity_resolve(EEVEE_Data *vedata)
DRW_view_persmat_get(view, effects->velocity_past_persmat, false);
}
void EEVEE_draw_effects(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
void EEVEE_draw_effects(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_TextureList *txl = vedata->txl;
EEVEE_FramebufferList *fbl = vedata->fbl;
@ -541,6 +543,10 @@ void EEVEE_draw_effects(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
EEVEE_temporal_sampling_draw(vedata);
EEVEE_bloom_draw(vedata);
/* Post effect render passes are done here just after the drawing of the effects and just before
* the swapping of the buffers. */
EEVEE_renderpasses_output_accumulate(sldata, vedata, true);
/* Save the final texture and framebuffer for final transformation or read. */
effects->final_tx = effects->source_buffer;
effects->final_fb = (effects->target_buffer != fbl->main_color_fb) ? fbl->main_fb :

View File

@ -151,7 +151,8 @@ void EEVEE_cache_populate(void *vedata, Object *ob)
static void eevee_cache_finish(void *vedata)
{
EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
EEVEE_PrivateData *g_data = ((EEVEE_Data *)vedata)->stl->g_data;
EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
EEVEE_PrivateData *g_data = stl->g_data;
const DRWContextState *draw_ctx = DRW_context_state_get();
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
@ -176,6 +177,9 @@ static void eevee_cache_finish(void *vedata)
if (g_data->queued_shaders_count != g_data->queued_shaders_count_prev) {
g_data->queued_shaders_count_prev = g_data->queued_shaders_count;
EEVEE_temporal_sampling_reset(vedata);
/* At this moment the TAA sampling will be redrawn in the next iteration.
* we set the taa_current_sample to 0 so the next iteration will use sample 1 */
stl->effects->taa_current_sample = 0;
}
}
@ -307,6 +311,9 @@ static void eevee_draw_scene(void *vedata)
/* Volumetrics Resolve Opaque */
EEVEE_volumes_resolve(sldata, vedata);
/* Renderpasses */
EEVEE_renderpasses_output_accumulate(sldata, vedata, false);
/* Transparent */
/* TODO(fclem): should be its own Framebuffer.
* This is needed because dualsource blending only works with 1 color buffer. */
@ -321,8 +328,6 @@ static void eevee_draw_scene(void *vedata)
EEVEE_draw_effects(sldata, vedata);
DRW_stats_group_end();
EEVEE_renderpasses_output_accumulate(sldata, vedata);
DRW_view_set_active(NULL);
if (DRW_state_is_image_render() && (stl->effects->enabled_effects & EFFECT_SSR) &&
@ -336,7 +341,7 @@ static void eevee_draw_scene(void *vedata)
}
}
if ((stl->g_data->render_passes & SCE_PASS_COMBINED) > 0) {
if ((stl->g_data->render_passes & EEVEE_RENDER_PASS_COMBINED) != 0) {
/* Transfer result to default framebuffer. */
GPU_framebuffer_bind(dfbl->default_fb);
DRW_transform_none(stl->effects->final_tx);

View File

@ -251,6 +251,8 @@ void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata,
// DRW_shgroup_uniform_texture(grp, "texJitter", e_data.jitter);
DRW_shgroup_uniform_texture(grp, "probeHdr", rt_color);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
struct GPUBatch *geom = DRW_cache_fullscreen_quad_get();
DRW_shgroup_call(grp, geom, NULL);
@ -272,6 +274,8 @@ void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata,
DRW_shgroup_uniform_float(grp, "intensityFac", &pinfo->intensity_fac, 1);
DRW_shgroup_uniform_texture(grp, "probeHdr", rt_color);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
struct GPUBatch *geom = DRW_cache_fullscreen_quad_get();
DRW_shgroup_call(grp, geom, NULL);
@ -292,6 +296,8 @@ void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata,
DRW_shgroup_uniform_texture(grp, "texHammersley", e_data.hammersley);
DRW_shgroup_uniform_texture(grp, "probeDepth", rt_depth);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
struct GPUBatch *geom = DRW_cache_fullscreen_quad_get();
DRW_shgroup_call(grp, geom, NULL);
@ -360,6 +366,8 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
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, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_call(grp, geom, NULL);
break;
case GPU_MAT_QUEUED:
@ -403,6 +411,8 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
/* TODO (fclem) get rid of those UBO. */
DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_call_procedural_triangles(grp, NULL, cube_len * 2);
}
@ -429,6 +439,8 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
DRW_shgroup_uniform_block(shgrp, "planar_block", sldata->planar_ubo);
DRW_shgroup_uniform_block(shgrp, "grid_block", sldata->grid_ubo);
DRW_shgroup_uniform_block(shgrp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
shgrp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
int tri_count = egrid->resolution[0] * egrid->resolution[1] * egrid->resolution[2] * 2;
DRW_shgroup_call_procedural_triangles(shgrp, NULL, tri_count);
}
@ -446,6 +458,8 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
DRWShadingGroup *grp = DRW_shgroup_create(EEVEE_shaders_probe_planar_display_sh_get(),
psl->probe_display);
DRW_shgroup_uniform_texture_ref(grp, "probePlanars", &txl->planar_pool);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
stl->g_data->planar_display_shgrp = DRW_shgroup_call_buffer_instance(
grp, e_data.format_probe_display_planar, DRW_cache_quad_get());

File diff suppressed because it is too large Load Diff

View File

@ -114,6 +114,8 @@ void EEVEE_mist_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRWShadingGroup *grp = DRW_shgroup_create(e_data.mist_sh, psl->mist_accum_ps);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_vec3(grp, "mistSettings", &g_data->mist_start, 1);
DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}

View File

@ -170,6 +170,8 @@ void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata
DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input);
DRW_shgroup_uniform_texture_ref(grp, "horizonBuffer", &effects->gtao_horizons);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
else {
@ -207,6 +209,8 @@ void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "maxzBuffer", &txl->maxzbuffer);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &effects->ao_src_depth);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_call(grp, quad, NULL);
DRW_PASS_CREATE(psl->ao_horizon_search_layer, DRW_STATE_WRITE_COLOR);
@ -215,6 +219,8 @@ void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "maxzBuffer", &txl->maxzbuffer);
DRW_shgroup_uniform_texture_ref(grp, "depthBufferLayered", &effects->ao_src_depth);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_int(grp, "layer", &stl->effects->ao_depth_layer, 1);
DRW_shgroup_call(grp, quad, NULL);
@ -227,6 +233,8 @@ void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input);
DRW_shgroup_uniform_texture_ref(grp, "horizonBuffer", &effects->gtao_horizons);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_call(grp, quad, NULL);
}
}

View File

@ -141,6 +141,13 @@ extern struct DrawEngineType draw_engine_eevee_type;
#define MIN_CUBE_LOD_LEVEL 3
#define MAX_PLANAR_LOD_LEVEL 9
/* All the renderpasses that use the GPUMaterial for accumulation */
#define EEVEE_RENDERPASSES_MATERIAL \
(EEVEE_RENDER_PASS_EMIT | EEVEE_RENDER_PASS_DIFFUSE_COLOR | EEVEE_RENDER_PASS_DIFFUSE_LIGHT | \
EEVEE_RENDER_PASS_SPECULAR_COLOR | EEVEE_RENDER_PASS_SPECULAR_LIGHT | \
EEVEE_RENDER_PASS_ENVIRONMENT)
#define MAX_MATERIAL_RENDER_PASSES 6
#define MAX_MATERIAL_RENDER_PASSES_UBO 6
/* World shader variations */
enum {
VAR_WORLD_BACKGROUND = 0,
@ -198,6 +205,7 @@ typedef struct EEVEE_BoundBox {
typedef struct EEVEE_PassList {
/* Shadows */
struct DRWPass *shadow_pass;
struct DRWPass *shadow_accum_pass;
/* Probes */
struct DRWPass *probe_background;
@ -220,6 +228,7 @@ typedef struct EEVEE_PassList {
struct DRWPass *bloom_downsample;
struct DRWPass *bloom_upsample;
struct DRWPass *bloom_resolve;
struct DRWPass *bloom_accum_ps;
struct DRWPass *dof_down;
struct DRWPass *dof_scatter;
struct DRWPass *dof_resolve;
@ -228,11 +237,11 @@ typedef struct EEVEE_PassList {
struct DRWPass *volumetric_scatter_ps;
struct DRWPass *volumetric_integration_ps;
struct DRWPass *volumetric_resolve_ps;
struct DRWPass *volumetric_accum_ps;
struct DRWPass *ssr_raytrace;
struct DRWPass *ssr_resolve;
struct DRWPass *sss_blur_ps;
struct DRWPass *sss_resolve_ps;
struct DRWPass *sss_accum_ps;
struct DRWPass *sss_translucency_ps;
struct DRWPass *color_downsample_ps;
struct DRWPass *color_downsample_cube_ps;
@ -264,6 +273,7 @@ typedef struct EEVEE_PassList {
struct DRWPass *sss_pass_cull;
struct DRWPass *material_pass;
struct DRWPass *material_pass_cull;
struct DRWPass *material_accum_pass[MAX_MATERIAL_RENDER_PASSES];
struct DRWPass *refract_pass;
struct DRWPass *transparent_pass;
struct DRWPass *background_pass;
@ -281,6 +291,9 @@ typedef struct EEVEE_FramebufferList {
struct GPUFrameBuffer *bloom_blit_fb;
struct GPUFrameBuffer *bloom_down_fb[MAX_BLOOM_STEP];
struct GPUFrameBuffer *bloom_accum_fb[MAX_BLOOM_STEP - 1];
struct GPUFrameBuffer *bloom_pass_accum_fb;
struct GPUFrameBuffer *shadow_accum_fb;
struct GPUFrameBuffer *ssr_accum_fb;
struct GPUFrameBuffer *sss_blur_fb;
struct GPUFrameBuffer *sss_blit_fb;
struct GPUFrameBuffer *sss_resolve_fb;
@ -292,9 +305,11 @@ typedef struct EEVEE_FramebufferList {
struct GPUFrameBuffer *volumetric_fb;
struct GPUFrameBuffer *volumetric_scat_fb;
struct GPUFrameBuffer *volumetric_integ_fb;
struct GPUFrameBuffer *volumetric_accum_fb;
struct GPUFrameBuffer *screen_tracing_fb;
struct GPUFrameBuffer *refract_fb;
struct GPUFrameBuffer *mist_accum_fb;
struct GPUFrameBuffer *material_accum_fb;
struct GPUFrameBuffer *renderpass_fb;
struct GPUFrameBuffer *ao_accum_fb;
struct GPUFrameBuffer *velocity_resolve_fb;
@ -320,8 +335,11 @@ typedef struct EEVEE_TextureList {
struct GPUTexture *color_post; /* R16_G16_B16 */
struct GPUTexture *mist_accum;
struct GPUTexture *ao_accum;
struct GPUTexture *sss_dir_accum;
struct GPUTexture *sss_col_accum;
struct GPUTexture *sss_accum;
struct GPUTexture *material_accum[MAX_MATERIAL_RENDER_PASSES];
struct GPUTexture *bloom_accum;
struct GPUTexture *ssr_accum;
struct GPUTexture *shadow_accum;
struct GPUTexture *refract_color;
struct GPUTexture *taa_history;
@ -333,6 +351,8 @@ typedef struct EEVEE_TextureList {
struct GPUTexture *volume_transmit;
struct GPUTexture *volume_scatter_history;
struct GPUTexture *volume_transmit_history;
struct GPUTexture *volume_scatter_accum;
struct GPUTexture *volume_transmittance_accum;
struct GPUTexture *lookdev_grid_tx;
struct GPUTexture *lookdev_cube_tx;
@ -361,6 +381,17 @@ typedef struct EEVEE_StorageList {
LightCacheTexture *lookdev_cube_mips;
} EEVEE_StorageList;
/* ************ RENDERPASS UBO ************* */
typedef struct EEVEE_RenderPassData {
int renderPassDiffuse;
int renderPassDiffuseLight;
int renderPassGlossy;
int renderPassGlossyLight;
int renderPassEmit;
int renderPassSSSColor;
int _pad[2];
} EEVEE_RenderPassData;
/* ************ LIGHT UBO ************* */
typedef struct EEVEE_Light {
float position[3], invsqrdist;
@ -408,6 +439,7 @@ BLI_STATIC_ASSERT_ALIGN(EEVEE_Light, 16)
BLI_STATIC_ASSERT_ALIGN(EEVEE_Shadow, 16)
BLI_STATIC_ASSERT_ALIGN(EEVEE_ShadowCube, 16)
BLI_STATIC_ASSERT_ALIGN(EEVEE_ShadowCascade, 16)
BLI_STATIC_ASSERT_ALIGN(EEVEE_RenderPassData, 16)
BLI_STATIC_ASSERT(sizeof(EEVEE_Shadow) * MAX_SHADOW +
sizeof(EEVEE_ShadowCascade) * MAX_SHADOW_CASCADE +
@ -708,6 +740,10 @@ typedef struct EEVEE_ViewLayerData {
struct GPUUniformBuffer *grid_ubo;
struct GPUUniformBuffer *planar_ubo;
/* Material Render passes */
struct EEVEE_RenderPassData renderpass_data[MAX_MATERIAL_RENDER_PASSES_UBO];
struct GPUUniformBuffer *renderpass_ubo[MAX_MATERIAL_RENDER_PASSES_UBO];
/* Common Uniform Buffer */
struct EEVEE_CommonUniformBuffer common_data;
struct GPUUniformBuffer *common_ubo;
@ -759,6 +795,7 @@ typedef struct EEVEE_Data {
typedef struct EEVEE_PrivateData {
struct DRWShadingGroup *shadow_shgrp;
struct DRWShadingGroup *shadow_accum_shgrp;
struct DRWShadingGroup *depth_shgrp;
struct DRWShadingGroup *depth_shgrp_cull;
struct DRWShadingGroup *depth_shgrp_clip;
@ -803,12 +840,17 @@ typedef struct EEVEE_PrivateData {
/* Renderpasses */
/* Bitmask containing the active render_passes */
eScenePassType render_passes;
eViewLayerEEVEEPassType render_passes;
/* Uniform references that are referenced inside the `renderpass_pass`. They are updated
* to reuse the drawing pass and the shading group. */
int renderpass_type;
int renderpass_postprocess;
int renderpass_current_sample;
GPUTexture *renderpass_input;
GPUTexture *renderpass_col_input;
GPUTexture *renderpass_light_input;
/* The number of active material based render passes */
uint render_passes_material_count;
/** For rendering shadows. */
struct DRWView *cube_views[6];
@ -860,11 +902,20 @@ struct GPUMaterial *EEVEE_material_mesh_depth_get(struct Scene *scene,
bool use_hashed_alpha,
bool is_shadow);
struct GPUMaterial *EEVEE_material_hair_get(struct Scene *scene, Material *ma);
struct GPUUniformBuffer *EEVEE_material_default_render_pass_ubo_get(EEVEE_ViewLayerData *sldata);
void EEVEE_materials_free(void);
void EEVEE_materials_draw_opaque(EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl);
void EEVEE_update_noise(EEVEE_PassList *psl, EEVEE_FramebufferList *fbl, const double offsets[3]);
void EEVEE_update_viewvecs(float invproj[4][4], float winmat[4][4], float (*r_viewvecs)[4]);
void EEVEE_material_renderpasses_init(EEVEE_Data *vedata);
void EEVEE_material_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, uint tot_samples);
void EEVEE_material_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
int EEVEE_material_output_pass_index_get(EEVEE_ViewLayerData *UNUSED(sldata),
EEVEE_Data *vedata,
eViewLayerEEVEEPassType renderpass_type);
int EEVEE_material_output_color_pass_index_get(EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
eViewLayerEEVEEPassType renderpass_type);
/* eevee_lights.c */
void eevee_light_matrix_get(const EEVEE_Light *evli, float r_mat[4][4]);
void EEVEE_lights_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
@ -896,6 +947,8 @@ void EEVEE_shadows_draw_cascades(EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
DRWView *view,
int cascade_index);
void EEVEE_shadow_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, uint tot_samples);
void EEVEE_shadow_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_shadows_free(void);
/* eevee_sampling.c */
@ -995,6 +1048,8 @@ void EEVEE_depth_of_field_free(void);
int EEVEE_bloom_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_bloom_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_bloom_draw(EEVEE_Data *vedata);
void EEVEE_bloom_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, uint tot_samples);
void EEVEE_bloom_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_bloom_free(void);
/* eevee_occlusion.c */
@ -1016,6 +1071,11 @@ int EEVEE_screen_raytrace_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_screen_raytrace_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_refraction_compute(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_reflection_compute(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_reflection_output_init(EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
uint tot_samples);
void EEVEE_reflection_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_screen_raytrace_free(void);
/* eevee_subsurface.c */
@ -1055,10 +1115,12 @@ void EEVEE_renderpasses_init(EEVEE_Data *vedata);
void EEVEE_renderpasses_output_init(EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
uint tot_samples);
void EEVEE_renderpasses_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_renderpasses_output_accumulate(EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
bool post_effect);
void EEVEE_renderpasses_postprocess(EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
eScenePassType renderpass_type);
eViewLayerEEVEEPassType renderpass_type);
void EEVEE_renderpasses_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_renderpasses_draw_debug(EEVEE_Data *vedata);
void EEVEE_renderpasses_free(void);
@ -1087,6 +1149,8 @@ void EEVEE_volumes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
void EEVEE_volumes_draw_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_volumes_compute(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_volumes_resolve(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_volumes_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, uint tot_samples);
void EEVEE_volumes_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_volumes_free_smoke_textures(void);
void EEVEE_volumes_free(void);

View File

@ -230,6 +230,9 @@ static void eevee_render_color_result(RenderLayer *rl,
EEVEE_Data *vedata)
{
RenderPass *rp = RE_pass_find_by_name(rl, render_pass_name, viewname);
if (rp == NULL) {
return;
}
GPU_framebuffer_bind(framebuffer);
GPU_framebuffer_read_color(framebuffer,
vedata->stl->g_data->overscan_pixels + rect->xmin,
@ -251,35 +254,6 @@ static void eevee_render_result_combined(RenderLayer *rl,
rl, viewname, rect, RE_PASSNAME_COMBINED, 4, vedata->stl->effects->final_fb, vedata);
}
static void eevee_render_result_subsurface(RenderLayer *rl,
const char *viewname,
const rcti *rect,
EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata)
{
if (vedata->fbl->sss_accum_fb == NULL) {
/* SSS is not enabled. */
return;
}
if ((vedata->stl->g_data->render_passes & SCE_PASS_SUBSURFACE_COLOR) != 0) {
EEVEE_renderpasses_postprocess(sldata, vedata, SCE_PASS_SUBSURFACE_COLOR);
eevee_render_color_result(
rl, viewname, rect, RE_PASSNAME_SUBSURFACE_COLOR, 3, vedata->fbl->renderpass_fb, vedata);
}
if ((vedata->stl->g_data->render_passes & SCE_PASS_SUBSURFACE_DIRECT) != 0) {
EEVEE_renderpasses_postprocess(sldata, vedata, SCE_PASS_SUBSURFACE_DIRECT);
eevee_render_color_result(
rl, viewname, rect, RE_PASSNAME_SUBSURFACE_DIRECT, 3, vedata->fbl->renderpass_fb, vedata);
}
if ((vedata->stl->g_data->render_passes & SCE_PASS_SUBSURFACE_INDIRECT) != 0) {
/* Do nothing as all the lighting is in the direct pass.
* TODO : Separate Direct from indirect lighting. */
}
}
static void eevee_render_result_normal(RenderLayer *rl,
const char *viewname,
const rcti *rect,
@ -293,8 +267,8 @@ static void eevee_render_result_normal(RenderLayer *rl,
return;
}
if ((vedata->stl->g_data->render_passes & SCE_PASS_NORMAL) != 0) {
EEVEE_renderpasses_postprocess(sldata, vedata, SCE_PASS_NORMAL);
if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_NORMAL) != 0) {
EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_NORMAL);
eevee_render_color_result(
rl, viewname, rect, RE_PASSNAME_NORMAL, 3, vedata->fbl->renderpass_fb, vedata);
}
@ -313,8 +287,8 @@ static void eevee_render_result_z(RenderLayer *rl,
return;
}
if ((vedata->stl->g_data->render_passes & SCE_PASS_Z) != 0) {
EEVEE_renderpasses_postprocess(sldata, vedata, SCE_PASS_Z);
if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_Z) != 0) {
EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_Z);
eevee_render_color_result(
rl, viewname, rect, RE_PASSNAME_Z, 1, vedata->fbl->renderpass_fb, vedata);
}
@ -326,31 +300,142 @@ static void eevee_render_result_mist(RenderLayer *rl,
EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata)
{
if ((vedata->stl->g_data->render_passes & SCE_PASS_MIST) != 0) {
EEVEE_renderpasses_postprocess(sldata, vedata, SCE_PASS_MIST);
if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_MIST) != 0) {
EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_MIST);
eevee_render_color_result(
rl, viewname, rect, RE_PASSNAME_MIST, 1, vedata->fbl->renderpass_fb, vedata);
}
}
static void eevee_render_result_shadow(RenderLayer *rl,
const char *viewname,
const rcti *rect,
EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata)
{
if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_SHADOW) != 0) {
EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_SHADOW);
eevee_render_color_result(
rl, viewname, rect, RE_PASSNAME_SHADOW, 3, vedata->fbl->renderpass_fb, vedata);
}
}
static void eevee_render_result_occlusion(RenderLayer *rl,
const char *viewname,
const rcti *rect,
EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata)
{
if (vedata->fbl->ao_accum_fb == NULL) {
if ((vedata->stl->effects->enabled_effects & EFFECT_GTAO) == 0) {
/* AO is not enabled. */
return;
}
if ((vedata->stl->g_data->render_passes & SCE_PASS_AO) != 0) {
EEVEE_renderpasses_postprocess(sldata, vedata, SCE_PASS_AO);
if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_AO) != 0) {
EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_AO);
eevee_render_color_result(
rl, viewname, rect, RE_PASSNAME_AO, 3, vedata->fbl->renderpass_fb, vedata);
}
}
static void eevee_render_result_bloom(RenderLayer *rl,
const char *viewname,
const rcti *rect,
EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata)
{
if ((vedata->stl->effects->enabled_effects & EFFECT_BLOOM) == 0) {
/* Bloom is not enabled. */
return;
}
if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_BLOOM) != 0) {
EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_BLOOM);
eevee_render_color_result(
rl, viewname, rect, RE_PASSNAME_BLOOM, 3, vedata->fbl->renderpass_fb, vedata);
}
}
#define EEVEE_RENDER_RESULT_MATERIAL_PASS(pass_name, eevee_pass_type) \
if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_##eevee_pass_type) != 0) { \
EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_##eevee_pass_type); \
eevee_render_color_result( \
rl, viewname, rect, RE_PASSNAME_##pass_name, 3, vedata->fbl->renderpass_fb, vedata); \
}
static void eevee_render_result_diffuse_color(RenderLayer *rl,
const char *viewname,
const rcti *rect,
EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata)
{
EEVEE_RENDER_RESULT_MATERIAL_PASS(DIFFUSE_COLOR, DIFFUSE_COLOR)
}
static void eevee_render_result_diffuse_direct(RenderLayer *rl,
const char *viewname,
const rcti *rect,
EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata)
{
EEVEE_RENDER_RESULT_MATERIAL_PASS(DIFFUSE_DIRECT, DIFFUSE_LIGHT)
}
static void eevee_render_result_specular_color(RenderLayer *rl,
const char *viewname,
const rcti *rect,
EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata)
{
EEVEE_RENDER_RESULT_MATERIAL_PASS(GLOSSY_COLOR, SPECULAR_COLOR)
}
static void eevee_render_result_specular_direct(RenderLayer *rl,
const char *viewname,
const rcti *rect,
EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata)
{
EEVEE_RENDER_RESULT_MATERIAL_PASS(GLOSSY_DIRECT, SPECULAR_LIGHT)
}
static void eevee_render_result_emission(RenderLayer *rl,
const char *viewname,
const rcti *rect,
EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata)
{
EEVEE_RENDER_RESULT_MATERIAL_PASS(EMIT, EMIT)
}
static void eevee_render_result_environment(RenderLayer *rl,
const char *viewname,
const rcti *rect,
EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata)
{
EEVEE_RENDER_RESULT_MATERIAL_PASS(ENVIRONMENT, ENVIRONMENT)
}
static void eevee_render_result_volume_scatter(RenderLayer *rl,
const char *viewname,
const rcti *rect,
EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata)
{
EEVEE_RENDER_RESULT_MATERIAL_PASS(VOLUME_SCATTER, VOLUME_SCATTER)
}
static void eevee_render_result_volume_transmittance(RenderLayer *rl,
const char *viewname,
const rcti *rect,
EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata)
{
EEVEE_RENDER_RESULT_MATERIAL_PASS(VOLUME_TRANSMITTANCE, VOLUME_TRANSMITTANCE)
}
#undef EEVEE_RENDER_RESULT_MATERIAL_PASS
static void eevee_render_draw_background(EEVEE_Data *vedata)
{
EEVEE_FramebufferList *fbl = vedata->fbl;
@ -508,7 +593,7 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl
/* Volumetrics Resolve Opaque */
EEVEE_volumes_resolve(sldata, vedata);
/* Subsurface output, Occlusion output, Mist output */
EEVEE_renderpasses_output_accumulate(sldata, vedata);
EEVEE_renderpasses_output_accumulate(sldata, vedata, false);
/* Transparent */
GPU_framebuffer_texture_attach(fbl->main_color_fb, dtxl->depth, 0, 0);
GPU_framebuffer_bind(fbl->main_color_fb);
@ -527,9 +612,18 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl
}
eevee_render_result_combined(rl, viewname, rect, vedata, sldata);
eevee_render_result_subsurface(rl, viewname, rect, vedata, sldata);
eevee_render_result_mist(rl, viewname, rect, vedata, sldata);
eevee_render_result_occlusion(rl, viewname, rect, vedata, sldata);
eevee_render_result_shadow(rl, viewname, rect, vedata, sldata);
eevee_render_result_diffuse_color(rl, viewname, rect, vedata, sldata);
eevee_render_result_diffuse_direct(rl, viewname, rect, vedata, sldata);
eevee_render_result_specular_color(rl, viewname, rect, vedata, sldata);
eevee_render_result_specular_direct(rl, viewname, rect, vedata, sldata);
eevee_render_result_emission(rl, viewname, rect, vedata, sldata);
eevee_render_result_environment(rl, viewname, rect, vedata, sldata);
eevee_render_result_bloom(rl, viewname, rect, vedata, sldata);
eevee_render_result_volume_scatter(rl, viewname, rect, vedata, sldata);
eevee_render_result_volume_transmittance(rl, viewname, rect, vedata, sldata);
/* Restore original viewport size. */
DRW_render_viewport_size_set((int[2]){g_data->size_orig[0], g_data->size_orig[1]});
@ -537,29 +631,35 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl
void EEVEE_render_update_passes(RenderEngine *engine, Scene *scene, ViewLayer *view_layer)
{
int type;
RE_engine_register_pass(engine, scene, view_layer, RE_PASSNAME_COMBINED, 4, "RGBA", SOCK_RGBA);
#define CHECK_PASS(name, channels, chanid) \
#define CHECK_PASS_LEGACY(name, type, channels, chanid) \
if (view_layer->passflag & (SCE_PASS_##name)) { \
if (channels == 4) \
type = SOCK_RGBA; \
else if (channels == 3) \
type = SOCK_VECTOR; \
else \
type = SOCK_FLOAT; \
RE_engine_register_pass( \
engine, scene, view_layer, RE_PASSNAME_##name, channels, chanid, type); \
} \
((void)0)
#define CHECK_PASS_EEVEE(name, type, channels, chanid) \
if (view_layer->eevee.render_passes & (EEVEE_RENDER_PASS_##name)) { \
RE_engine_register_pass( \
engine, scene, view_layer, RE_PASSNAME_##name, channels, chanid, type); \
} \
((void)0)
CHECK_PASS(Z, 1, "Z");
CHECK_PASS(MIST, 1, "Z");
CHECK_PASS(NORMAL, 3, "XYZ");
CHECK_PASS(AO, 3, "RGB");
CHECK_PASS(SUBSURFACE_COLOR, 3, "RGB");
CHECK_PASS(SUBSURFACE_DIRECT, 3, "RGB");
CHECK_PASS_LEGACY(Z, SOCK_FLOAT, 1, "Z");
CHECK_PASS_LEGACY(MIST, SOCK_FLOAT, 1, "Z");
CHECK_PASS_LEGACY(NORMAL, SOCK_VECTOR, 3, "XYZ");
CHECK_PASS_LEGACY(SHADOW, SOCK_RGBA, 3, "RGB");
CHECK_PASS_LEGACY(AO, SOCK_RGBA, 3, "RGB");
CHECK_PASS_LEGACY(DIFFUSE_COLOR, SOCK_RGBA, 3, "RGB");
CHECK_PASS_LEGACY(DIFFUSE_DIRECT, SOCK_RGBA, 3, "RGB");
CHECK_PASS_LEGACY(GLOSSY_COLOR, SOCK_RGBA, 3, "RGB");
CHECK_PASS_LEGACY(GLOSSY_DIRECT, SOCK_RGBA, 3, "RGB");
CHECK_PASS_LEGACY(EMIT, SOCK_RGBA, 3, "RGB");
CHECK_PASS_LEGACY(ENVIRONMENT, SOCK_RGBA, 3, "RGB");
CHECK_PASS_EEVEE(VOLUME_SCATTER, SOCK_RGBA, 3, "RGB");
CHECK_PASS_EEVEE(VOLUME_TRANSMITTANCE, SOCK_RGBA, 3, "RGB");
CHECK_PASS_EEVEE(BLOOM, SOCK_RGBA, 3, "RGB");
#undef CHECK_PASS
}

View File

@ -42,19 +42,35 @@ static struct {
struct GPUShader *postprocess_sh;
} e_data = {NULL}; /* Engine data */
typedef enum eRenderPassPostProcessType {
PASS_POST_UNDEFINED = 0,
PASS_POST_ACCUMULATED_COLOR = 1,
PASS_POST_ACCUMULATED_LIGHT = 2,
PASS_POST_ACCUMULATED_VALUE = 3,
PASS_POST_DEPTH = 4,
PASS_POST_AO = 5,
PASS_POST_NORMAL = 6,
PASS_POST_TWO_LIGHT_BUFFERS = 7,
} eRenderPassPostProcessType;
/* bitmask containing all renderpasses that need post-processing */
#define EEVEE_RENDERPASSES_WITH_POST_PROCESSING \
(SCE_PASS_Z | SCE_PASS_MIST | SCE_PASS_NORMAL | SCE_PASS_AO | SCE_PASS_SUBSURFACE_COLOR | \
SCE_PASS_SUBSURFACE_DIRECT)
(EEVEE_RENDER_PASS_Z | EEVEE_RENDER_PASS_MIST | EEVEE_RENDER_PASS_NORMAL | \
EEVEE_RENDER_PASS_AO | EEVEE_RENDER_PASS_BLOOM | EEVEE_RENDER_PASS_VOLUME_SCATTER | \
EEVEE_RENDER_PASS_VOLUME_TRANSMITTANCE | EEVEE_RENDER_PASS_SHADOW | \
EEVEE_RENDERPASSES_MATERIAL)
#define EEVEE_RENDERPASSES_SUBSURFACE \
(SCE_PASS_SUBSURFACE_COLOR | SCE_PASS_SUBSURFACE_DIRECT | SCE_PASS_SUBSURFACE_INDIRECT)
#define EEVEE_RENDERPASSES_ALL \
(EEVEE_RENDERPASSES_WITH_POST_PROCESSING | EEVEE_RENDER_PASS_COMBINED)
#define EEVEE_RENDERPASSES_ALL (EEVEE_RENDERPASSES_WITH_POST_PROCESSING | SCE_PASS_COMBINED)
#define EEVEE_RENDERPASSES_POST_PROCESS_ON_FIRST_SAMPLE \
(EEVEE_RENDER_PASS_Z | EEVEE_RENDER_PASS_NORMAL)
#define EEVEE_RENDERPASSES_POST_PROCESS_ON_FIRST_SAMPLE (SCE_PASS_Z | SCE_PASS_NORMAL)
#define EEVEE_RENDERPASSES_COLOR_PASS (SCE_PASS_SUBSURFACE_COLOR | SCE_PASS_SUBSURFACE_DIRECT)
#define EEVEE_RENDERPASSES_COLOR_PASS \
(EEVEE_RENDER_PASS_DIFFUSE_COLOR | EEVEE_RENDER_PASS_SPECULAR_COLOR | EEVEE_RENDER_PASS_EMIT | \
EEVEE_RENDER_PASS_BLOOM)
#define EEVEE_RENDERPASSES_LIGHT_PASS \
(EEVEE_RENDER_PASS_DIFFUSE_LIGHT | EEVEE_RENDER_PASS_SPECULAR_LIGHT)
bool EEVEE_renderpasses_only_first_sample_pass_active(EEVEE_Data *vedata)
{
@ -75,8 +91,33 @@ void EEVEE_renderpasses_init(EEVEE_Data *vedata)
g_data->render_passes = v3d->shading.render_pass;
}
else {
g_data->render_passes = (view_layer->passflag & EEVEE_RENDERPASSES_ALL) | SCE_PASS_COMBINED;
eViewLayerEEVEEPassType enabled_render_passes = view_layer->eevee.render_passes;
#define ENABLE_FROM_LEGACY(name_legacy, name_eevee) \
SET_FLAG_FROM_TEST(enabled_render_passes, \
(view_layer->passflag & SCE_PASS_##name_legacy) != 0, \
EEVEE_RENDER_PASS_##name_eevee);
ENABLE_FROM_LEGACY(Z, Z)
ENABLE_FROM_LEGACY(MIST, MIST)
ENABLE_FROM_LEGACY(NORMAL, NORMAL)
ENABLE_FROM_LEGACY(SHADOW, SHADOW)
ENABLE_FROM_LEGACY(AO, AO)
ENABLE_FROM_LEGACY(EMIT, EMIT)
ENABLE_FROM_LEGACY(ENVIRONMENT, ENVIRONMENT)
ENABLE_FROM_LEGACY(DIFFUSE_COLOR, DIFFUSE_COLOR)
ENABLE_FROM_LEGACY(GLOSSY_COLOR, SPECULAR_COLOR)
ENABLE_FROM_LEGACY(DIFFUSE_DIRECT, DIFFUSE_LIGHT)
ENABLE_FROM_LEGACY(GLOSSY_DIRECT, SPECULAR_LIGHT)
ENABLE_FROM_LEGACY(ENVIRONMENT, ENVIRONMENT)
#undef ENABLE_FROM_LEGACY
g_data->render_passes = (enabled_render_passes & EEVEE_RENDERPASSES_ALL) |
EEVEE_RENDER_PASS_COMBINED;
}
EEVEE_material_renderpasses_init(vedata);
}
void EEVEE_renderpasses_output_init(EEVEE_ViewLayerData *sldata,
@ -87,6 +128,7 @@ void EEVEE_renderpasses_output_init(EEVEE_ViewLayerData *sldata,
EEVEE_TextureList *txl = vedata->txl;
EEVEE_PassList *psl = vedata->psl;
EEVEE_StorageList *stl = vedata->stl;
EEVEE_EffectsInfo *effects = stl->effects;
EEVEE_PrivateData *g_data = stl->g_data;
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
@ -106,33 +148,54 @@ void EEVEE_renderpasses_output_init(EEVEE_ViewLayerData *sldata,
/* Should be enough to store the data needs for a single pass.
* Some passes will use less, but it is only relevant for final renderings and
* when renderpasses other than `SCE_PASS_COMBINED` are requested */
* when renderpasses other than `EEVEE_RENDER_PASS_COMBINED` are requested */
DRW_texture_ensure_fullscreen_2d(&txl->renderpass, GPU_RGBA16F, 0);
GPU_framebuffer_ensure_config(&fbl->renderpass_fb,
{GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->renderpass)});
if ((g_data->render_passes & EEVEE_RENDERPASSES_SUBSURFACE) != 0) {
EEVEE_subsurface_output_init(sldata, vedata, tot_samples);
if ((g_data->render_passes & EEVEE_RENDERPASSES_MATERIAL) != 0) {
EEVEE_material_output_init(sldata, vedata, tot_samples);
}
if ((g_data->render_passes & SCE_PASS_MIST) != 0) {
if ((g_data->render_passes & EEVEE_RENDER_PASS_MIST) != 0) {
EEVEE_mist_output_init(sldata, vedata);
}
if ((g_data->render_passes & EEVEE_RENDER_PASS_SHADOW) != 0) {
EEVEE_shadow_output_init(sldata, vedata, tot_samples);
}
if ((g_data->render_passes & SCE_PASS_AO) != 0) {
if ((g_data->render_passes & EEVEE_RENDER_PASS_AO) != 0) {
EEVEE_occlusion_output_init(sldata, vedata, tot_samples);
}
if ((g_data->render_passes & EEVEE_RENDER_PASS_BLOOM) != 0 &&
(effects->enabled_effects & EFFECT_BLOOM) != 0) {
EEVEE_bloom_output_init(sldata, vedata, tot_samples);
}
if ((g_data->render_passes &
(EEVEE_RENDER_PASS_VOLUME_TRANSMITTANCE | EEVEE_RENDER_PASS_VOLUME_SCATTER)) != 0) {
EEVEE_volumes_output_init(sldata, vedata, tot_samples);
}
/* Create Pass. */
DRW_PASS_CREATE(psl->renderpass_pass, DRW_STATE_WRITE_COLOR);
DRWShadingGroup *grp = DRW_shgroup_create(e_data.postprocess_sh, psl->renderpass_pass);
/* We set a default texture as not all post processes uses the inputBuffer. */
g_data->renderpass_input = txl->color;
g_data->renderpass_col_input = txl->color;
g_data->renderpass_light_input = txl->color;
DRW_shgroup_uniform_texture_ref(grp, "inputBuffer", &g_data->renderpass_input);
DRW_shgroup_uniform_texture_ref(grp, "inputColorBuffer", &g_data->renderpass_col_input);
DRW_shgroup_uniform_texture_ref(
grp, "inputSecondLightBuffer", &g_data->renderpass_light_input);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_int(grp, "currentSample", &g_data->renderpass_current_sample, 1);
DRW_shgroup_uniform_int(grp, "renderpassType", &g_data->renderpass_type, 1);
DRW_shgroup_uniform_int(grp, "postProcessType", &g_data->renderpass_postprocess, 1);
DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
else {
@ -152,12 +215,13 @@ void EEVEE_renderpasses_output_init(EEVEE_ViewLayerData *sldata,
* Only invoke this function for passes that need post-processing.
*
* After invoking this function the active framebuffer is set to `vedata->fbl->renderpass_fb`. */
void EEVEE_renderpasses_postprocess(EEVEE_ViewLayerData *UNUSED(sldata),
void EEVEE_renderpasses_postprocess(EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
eScenePassType renderpass_type)
eViewLayerEEVEEPassType renderpass_type)
{
EEVEE_PassList *psl = vedata->psl;
EEVEE_TextureList *txl = vedata->txl;
EEVEE_FramebufferList *fbl = vedata->fbl;
EEVEE_StorageList *stl = vedata->stl;
EEVEE_PrivateData *g_data = stl->g_data;
EEVEE_EffectsInfo *effects = stl->effects;
@ -165,51 +229,133 @@ void EEVEE_renderpasses_postprocess(EEVEE_ViewLayerData *UNUSED(sldata),
const int current_sample = effects->taa_current_sample;
g_data->renderpass_current_sample = current_sample;
g_data->renderpass_type = renderpass_type;
g_data->renderpass_postprocess = PASS_POST_UNDEFINED;
switch (renderpass_type) {
case SCE_PASS_AO: {
case EEVEE_RENDER_PASS_Z: {
g_data->renderpass_postprocess = PASS_POST_DEPTH;
break;
}
case EEVEE_RENDER_PASS_AO: {
g_data->renderpass_postprocess = PASS_POST_AO;
g_data->renderpass_input = txl->ao_accum;
break;
}
case SCE_PASS_NORMAL: {
case EEVEE_RENDER_PASS_NORMAL: {
g_data->renderpass_postprocess = PASS_POST_NORMAL;
g_data->renderpass_input = effects->ssr_normal_input;
break;
}
case SCE_PASS_MIST: {
case EEVEE_RENDER_PASS_MIST: {
g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_VALUE;
g_data->renderpass_input = txl->mist_accum;
break;
}
case SCE_PASS_SUBSURFACE_DIRECT: {
g_data->renderpass_input = txl->sss_dir_accum;
case EEVEE_RENDER_PASS_VOLUME_SCATTER: {
g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_COLOR;
g_data->renderpass_input = txl->volume_scatter_accum;
break;
}
case SCE_PASS_SUBSURFACE_COLOR: {
g_data->renderpass_input = txl->sss_col_accum;
case EEVEE_RENDER_PASS_VOLUME_TRANSMITTANCE: {
g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_COLOR;
g_data->renderpass_input = txl->volume_transmittance_accum;
break;
}
case EEVEE_RENDER_PASS_SHADOW: {
g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_VALUE;
g_data->renderpass_input = txl->shadow_accum;
break;
}
case EEVEE_RENDER_PASS_DIFFUSE_COLOR:
case EEVEE_RENDER_PASS_SPECULAR_COLOR:
case EEVEE_RENDER_PASS_ENVIRONMENT:
case EEVEE_RENDER_PASS_EMIT: {
g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_COLOR;
int renderpass_index = EEVEE_material_output_pass_index_get(sldata, vedata, renderpass_type);
g_data->renderpass_input = txl->material_accum[renderpass_index];
break;
}
case EEVEE_RENDER_PASS_SPECULAR_LIGHT: {
g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_LIGHT;
int renderpass_index = EEVEE_material_output_pass_index_get(sldata, vedata, renderpass_type);
int renderpass_index_color = EEVEE_material_output_color_pass_index_get(
sldata, vedata, renderpass_type);
g_data->renderpass_input = txl->material_accum[renderpass_index];
g_data->renderpass_col_input = txl->material_accum[renderpass_index_color];
if ((stl->effects->enabled_effects & EFFECT_SSR) != 0) {
g_data->renderpass_postprocess = PASS_POST_TWO_LIGHT_BUFFERS;
g_data->renderpass_light_input = txl->ssr_accum;
}
else {
g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_LIGHT;
}
break;
}
case EEVEE_RENDER_PASS_DIFFUSE_LIGHT: {
g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_LIGHT;
int renderpass_index = EEVEE_material_output_pass_index_get(sldata, vedata, renderpass_type);
int renderpass_index_color = EEVEE_material_output_color_pass_index_get(
sldata, vedata, renderpass_type);
g_data->renderpass_input = txl->material_accum[renderpass_index];
g_data->renderpass_col_input = txl->material_accum[renderpass_index_color];
if ((stl->effects->enabled_effects & EFFECT_SSS) != 0) {
g_data->renderpass_postprocess = PASS_POST_TWO_LIGHT_BUFFERS;
g_data->renderpass_light_input = txl->sss_accum;
}
else {
g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_LIGHT;
}
break;
}
case EEVEE_RENDER_PASS_BLOOM: {
g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_COLOR;
g_data->renderpass_input = txl->bloom_accum;
g_data->renderpass_current_sample = 1;
break;
}
default: {
break;
}
}
GPU_framebuffer_bind(vedata->fbl->renderpass_fb);
GPU_framebuffer_bind(fbl->renderpass_fb);
DRW_draw_pass(psl->renderpass_pass);
}
void EEVEE_renderpasses_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
void EEVEE_renderpasses_output_accumulate(EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
bool post_effect)
{
EEVEE_StorageList *stl = vedata->stl;
EEVEE_EffectsInfo *effects = stl->effects;
eScenePassType render_pass = stl->g_data->render_passes;
eViewLayerEEVEEPassType render_pass = stl->g_data->render_passes;
if ((render_pass & SCE_PASS_MIST) != 0) {
EEVEE_mist_output_accumulate(sldata, vedata);
if (!post_effect) {
if ((render_pass & EEVEE_RENDER_PASS_MIST) != 0) {
EEVEE_mist_output_accumulate(sldata, vedata);
}
if ((render_pass & EEVEE_RENDER_PASS_DIFFUSE_LIGHT) != 0 &&
(effects->enabled_effects & EFFECT_SSS) != 0) {
EEVEE_subsurface_output_accumulate(sldata, vedata);
}
if ((render_pass & EEVEE_RENDER_PASS_AO) != 0) {
EEVEE_occlusion_output_accumulate(sldata, vedata);
}
if ((render_pass & EEVEE_RENDER_PASS_SHADOW) != 0) {
EEVEE_shadow_output_accumulate(sldata, vedata);
}
if ((render_pass & EEVEE_RENDERPASSES_MATERIAL) != 0) {
EEVEE_material_output_accumulate(sldata, vedata);
}
if ((render_pass &
(EEVEE_RENDER_PASS_VOLUME_TRANSMITTANCE | EEVEE_RENDER_PASS_VOLUME_SCATTER)) != 0) {
EEVEE_volumes_output_accumulate(sldata, vedata);
}
}
if ((effects->enabled_effects & EFFECT_SSS) &&
(render_pass & EEVEE_RENDERPASSES_SUBSURFACE) != 0) {
EEVEE_subsurface_output_accumulate(sldata, vedata);
}
if ((render_pass & SCE_PASS_AO) != 0) {
EEVEE_occlusion_output_accumulate(sldata, vedata);
else {
if ((render_pass & EEVEE_RENDER_PASS_BLOOM) != 0 &&
(effects->enabled_effects & EFFECT_BLOOM) != 0) {
EEVEE_bloom_output_accumulate(sldata, vedata);
}
}
}
@ -220,7 +366,13 @@ void EEVEE_renderpasses_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
EEVEE_StorageList *stl = vedata->stl;
EEVEE_EffectsInfo *effects = stl->effects;
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
eScenePassType render_pass = stl->g_data->render_passes;
/* We can only draw a single renderpass. Lightpasses also select their color pass (a second
pass). We mask the light pass when a light pass is selected. */
const eViewLayerEEVEEPassType render_pass =
((stl->g_data->render_passes & EEVEE_RENDERPASSES_LIGHT_PASS) != 0) ?
(stl->g_data->render_passes & EEVEE_RENDERPASSES_LIGHT_PASS) :
stl->g_data->render_passes;
const DRWContextState *draw_ctx = DRW_context_state_get();
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
@ -229,14 +381,14 @@ void EEVEE_renderpasses_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_state_is_opengl_render();
UNUSED_VARS(needs_color_transfer);
/* When SSS isn't available, but the pass is requested, we mark it as invalid */
if ((render_pass & EEVEE_RENDERPASSES_SUBSURFACE) != 0 &&
(effects->enabled_effects & EFFECT_SSS) == 0) {
if ((render_pass & EEVEE_RENDER_PASS_BLOOM) != 0 &&
(effects->enabled_effects & EFFECT_BLOOM) == 0) {
is_valid = false;
}
/* When SSS isn't available, but the pass is requested, we mark it as invalid */
if ((render_pass & SCE_PASS_AO) != 0 && (scene_eval->eevee.flag & SCE_EEVEE_GTAO_ENABLED) == 0) {
if ((render_pass & EEVEE_RENDER_PASS_AO) != 0 &&
(scene_eval->eevee.flag & SCE_EEVEE_GTAO_ENABLED) == 0) {
is_valid = false;
}
@ -254,7 +406,7 @@ void EEVEE_renderpasses_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
}
else {
/* Draw state is not valid for this pass, clear the buffer */
static float clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
static float clear_color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
GPU_framebuffer_bind(dfbl->default_fb);
GPU_framebuffer_clear_color(dfbl->default_fb, clear_color);
}

View File

@ -235,6 +235,8 @@ void EEVEE_screen_raytrace_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *v
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_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
if (!effects->reflection_trace_full) {
DRW_shgroup_uniform_ivec2(grp, "halfresOffset", effects->ssr_halfres_ofs, 1);
}
@ -255,6 +257,8 @@ void EEVEE_screen_raytrace_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *v
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_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_int(grp, "neighborOffset", &effects->ssr_neighbor_ofs, 1);
if ((effects->enabled_effects & EFFECT_GTAO) != 0) {
DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
@ -335,6 +339,43 @@ void EEVEE_reflection_compute(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *v
}
}
void EEVEE_reflection_output_init(EEVEE_ViewLayerData *UNUSED(sldata),
EEVEE_Data *vedata,
uint tot_samples)
{
EEVEE_FramebufferList *fbl = vedata->fbl;
EEVEE_TextureList *txl = vedata->txl;
EEVEE_StorageList *stl = vedata->stl;
EEVEE_EffectsInfo *effects = stl->effects;
float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
/* Create FrameBuffer. */
const eGPUTextureFormat texture_format = (tot_samples > 256) ? GPU_RGBA32F : GPU_RGBA16F;
DRW_texture_ensure_fullscreen_2d(&txl->ssr_accum, texture_format, 0);
GPU_framebuffer_ensure_config(&fbl->ssr_accum_fb,
{GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->ssr_accum)});
/* Clear texture. */
if (DRW_state_is_image_render() || effects->taa_current_sample == 1) {
GPU_framebuffer_bind(fbl->ssr_accum_fb);
GPU_framebuffer_clear_color(fbl->ssr_accum_fb, clear);
}
}
void EEVEE_reflection_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
{
EEVEE_FramebufferList *fbl = vedata->fbl;
EEVEE_PassList *psl = vedata->psl;
EEVEE_StorageList *stl = vedata->stl;
if (stl->g_data->valid_double_buffer) {
GPU_framebuffer_bind(fbl->ssr_accum_fb);
DRW_draw_pass(psl->ssr_resolve);
}
}
void EEVEE_screen_raytrace_free(void)
{
for (int i = 0; i < SSR_MAX_SHADER; i++) {

View File

@ -21,6 +21,7 @@
*/
#include "BLI_sys_types.h" /* bool */
#include "BLI_string_utils.h"
// #include "BLI_dynstr.h"
// #include "BLI_rand.h"
@ -35,11 +36,17 @@
static struct {
struct GPUShader *shadow_sh;
struct GPUShader *shadow_accum_sh;
} e_data = {NULL}; /* Engine data */
extern char datatoc_shadow_vert_glsl[];
extern char datatoc_shadow_frag_glsl[];
extern char datatoc_shadow_accum_frag_glsl[];
extern char datatoc_common_view_lib_glsl[];
extern char datatoc_common_uniforms_lib_glsl[];
extern char datatoc_bsdf_common_lib_glsl[];
extern char datatoc_lights_lib_glsl[];
extern char datatoc_raytrace_lib_glsl[];
void eevee_contact_shadow_setup(const Light *la, EEVEE_Shadow *evsh)
{
@ -65,6 +72,18 @@ void EEVEE_shadows_init(EEVEE_ViewLayerData *sldata)
NULL);
}
if (!e_data.shadow_accum_sh) {
char *frag_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
datatoc_common_uniforms_lib_glsl,
datatoc_bsdf_common_lib_glsl,
datatoc_raytrace_lib_glsl,
datatoc_lights_lib_glsl,
datatoc_shadow_accum_frag_glsl);
e_data.shadow_accum_sh = DRW_shader_create_fullscreen(frag_str, SHADER_DEFINES);
MEM_freeN(frag_str);
}
if (!sldata->lights) {
sldata->lights = MEM_callocN(sizeof(EEVEE_LightsInfo), "EEVEE_LightsInfo");
sldata->light_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_Light) * MAX_LIGHT, NULL);
@ -170,6 +189,8 @@ void EEVEE_shadows_caster_material_add(EEVEE_ViewLayerData *sldata,
DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
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, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
if (alpha_threshold != NULL) {
@ -406,7 +427,75 @@ void EEVEE_shadows_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, DRWView
}
}
/* -------------------------------------------------------------------- */
/** \name Render Passes
* \{ */
void EEVEE_shadow_output_init(EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
uint UNUSED(tot_samples))
{
EEVEE_FramebufferList *fbl = vedata->fbl;
EEVEE_TextureList *txl = vedata->txl;
EEVEE_PassList *psl = vedata->psl;
EEVEE_StorageList *stl = vedata->stl;
EEVEE_EffectsInfo *effects = stl->effects;
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
/* Create FrameBuffer. */
const eGPUTextureFormat texture_format = GPU_R32F;
DRW_texture_ensure_fullscreen_2d(&txl->shadow_accum, texture_format, 0);
GPU_framebuffer_ensure_config(&fbl->shadow_accum_fb,
{GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->shadow_accum)});
/* Clear texture. */
if (DRW_state_is_image_render() || effects->taa_current_sample == 1) {
GPU_framebuffer_bind(fbl->shadow_accum_fb);
GPU_framebuffer_clear_color(fbl->shadow_accum_fb, clear);
}
/* Create Pass and shgroup. */
DRW_PASS_CREATE(psl->shadow_accum_pass,
DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_ALWAYS | DRW_STATE_BLEND_ADD_FULL);
DRWShadingGroup *grp = DRW_shgroup_create(e_data.shadow_accum_sh, psl->shadow_accum_pass);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
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, "grid_block", sldata->grid_ubo);
DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
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);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_texture_ref(grp, "shadowCubeTexture", &sldata->shadow_cube_pool);
DRW_shgroup_uniform_texture_ref(grp, "shadowCascadeTexture", &sldata->shadow_cascade_pool);
DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
void EEVEE_shadow_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
{
EEVEE_FramebufferList *fbl = vedata->fbl;
EEVEE_PassList *psl = vedata->psl;
if (fbl->shadow_accum_fb != NULL) {
GPU_framebuffer_bind(fbl->shadow_accum_fb);
DRW_draw_pass(psl->shadow_accum_pass);
/* Restore */
GPU_framebuffer_bind(fbl->main_fb);
}
}
/* \} */
void EEVEE_shadows_free(void)
{
DRW_SHADER_FREE_SAFE(e_data.shadow_sh);
DRW_SHADER_FREE_SAFE(e_data.shadow_accum_sh);
}

View File

@ -33,7 +33,7 @@
#include "GPU_extensions.h"
static struct {
struct GPUShader *sss_sh[4];
struct GPUShader *sss_sh[3];
} e_data = {{NULL}}; /* Engine data */
extern char datatoc_common_view_lib_glsl[];
@ -64,8 +64,7 @@ static void eevee_create_shader_subsurface(void)
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 RESULT_ACCUM\n");
e_data.sss_sh[3] = DRW_shader_create_fullscreen(frag_translucent_str,
e_data.sss_sh[2] = DRW_shader_create_fullscreen(frag_translucent_str,
"#define EEVEE_TRANSLUCENCY\n" SHADER_DEFINES);
MEM_freeN(frag_translucent_str);
@ -85,9 +84,10 @@ void EEVEE_subsurface_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
common_data->sss_jitter_threshold = scene_eval->eevee.sss_jitter_threshold;
}
void EEVEE_subsurface_draw_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
void EEVEE_subsurface_draw_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_EffectsInfo *effects = vedata->stl->effects;
EEVEE_StorageList *stl = vedata->stl;
EEVEE_FramebufferList *fbl = vedata->fbl;
EEVEE_TextureList *txl = vedata->txl;
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
@ -138,72 +138,64 @@ void EEVEE_subsurface_draw_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data
{GPU_ATTACHMENT_NONE,
GPU_ATTACHMENT_TEXTURE(effects->sss_irradiance),
GPU_ATTACHMENT_TEXTURE(effects->sss_radius)});
if ((stl->g_data->render_passes & EEVEE_RENDER_PASS_DIFFUSE_LIGHT) != 0) {
EEVEE_subsurface_output_init(sldata, vedata, 0);
}
else {
GPU_FRAMEBUFFER_FREE_SAFE(fbl->sss_accum_fb);
txl->sss_accum = NULL;
}
}
else {
/* Cleanup to release memory */
GPU_FRAMEBUFFER_FREE_SAFE(fbl->sss_blur_fb);
GPU_FRAMEBUFFER_FREE_SAFE(fbl->sss_resolve_fb);
GPU_FRAMEBUFFER_FREE_SAFE(fbl->sss_clear_fb);
GPU_FRAMEBUFFER_FREE_SAFE(fbl->sss_accum_fb);
effects->sss_stencil = NULL;
effects->sss_blur = NULL;
effects->sss_irradiance = NULL;
effects->sss_radius = NULL;
txl->sss_accum = NULL;
}
}
static void set_shgrp_stencil(void *UNUSED(userData), DRWShadingGroup *shgrp)
{
DRW_shgroup_stencil_mask(shgrp, 255);
}
void EEVEE_subsurface_output_init(EEVEE_ViewLayerData *UNUSED(sldata),
EEVEE_Data *vedata,
uint tot_samples)
uint UNUSED(tot_samples))
{
EEVEE_FramebufferList *fbl = vedata->fbl;
EEVEE_TextureList *txl = vedata->txl;
EEVEE_StorageList *stl = vedata->stl;
EEVEE_EffectsInfo *effects = stl->effects;
if (effects->enabled_effects & EFFECT_SSS) {
const eGPUTextureFormat texture_format_light = (tot_samples > 128) ? GPU_RGBA32F : GPU_RGBA16F;
const eGPUTextureFormat texture_format_color = (tot_samples > 512) ? GPU_RGBA32F : GPU_RGBA16F;
DRW_texture_ensure_fullscreen_2d(&txl->sss_dir_accum, texture_format_light, 0);
DRW_texture_ensure_fullscreen_2d(&txl->sss_col_accum, texture_format_color, 0);
const eGPUTextureFormat texture_format_light = GPU_RGBA32F;
const bool texture_created = txl->sss_accum == NULL;
DRW_texture_ensure_fullscreen_2d(&txl->sss_accum, texture_format_light, 0);
GPUTexture *stencil_tex = effects->sss_stencil;
GPUTexture *stencil_tex = effects->sss_stencil;
if (GPU_depth_blitting_workaround()) {
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
/* Blitting stencil buffer does not work on macOS + Radeon Pro.
* Blit depth instead and use sss_stencil's depth as depth texture,
* and dtxl->depth as stencil mask. */
stencil_tex = dtxl->depth;
}
GPU_framebuffer_ensure_config(&fbl->sss_accum_fb,
{GPU_ATTACHMENT_TEXTURE(stencil_tex),
GPU_ATTACHMENT_TEXTURE(txl->sss_dir_accum),
GPU_ATTACHMENT_TEXTURE(txl->sss_col_accum)});
/* Clear texture. */
if (DRW_state_is_image_render() || effects->taa_current_sample == 1) {
float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
GPU_framebuffer_bind(fbl->sss_accum_fb);
GPU_framebuffer_clear_color(fbl->sss_accum_fb, clear);
}
/* Make the opaque refraction pass mask the sss. */
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_CLIP_PLANES |
DRW_STATE_WRITE_STENCIL | DRW_STATE_STENCIL_ALWAYS;
DRW_pass_state_set(vedata->psl->refract_pass, state);
DRW_pass_foreach_shgroup(vedata->psl->refract_pass, &set_shgrp_stencil, NULL);
if (GPU_depth_blitting_workaround()) {
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
/* Blitting stencil buffer does not work on macOS + Radeon Pro.
* Blit depth instead and use sss_stencil's depth as depth texture,
* and dtxl->depth as stencil mask. */
stencil_tex = dtxl->depth;
}
else {
/* Cleanup to release memory */
DRW_TEXTURE_FREE_SAFE(txl->sss_dir_accum);
DRW_TEXTURE_FREE_SAFE(txl->sss_col_accum);
GPU_FRAMEBUFFER_FREE_SAFE(fbl->sss_accum_fb);
GPU_framebuffer_ensure_config(
&fbl->sss_accum_fb,
{GPU_ATTACHMENT_TEXTURE(stencil_tex), GPU_ATTACHMENT_TEXTURE(txl->sss_accum)});
/* Clear texture.
* Due to the late initialization of the SSS it can happen that the `taa_current_sample` is
* already higher than one. This is noticeable when loading a file that has the diffuse light
* pass in look dev mode active. `texture_created` will make sure that newly created textures
* are cleared. */
if (DRW_state_is_image_render() || effects->taa_current_sample == 1 || texture_created) {
float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
GPU_framebuffer_bind(fbl->sss_accum_fb);
GPU_framebuffer_clear_color(fbl->sss_accum_fb, clear);
}
}
@ -222,7 +214,6 @@ void EEVEE_subsurface_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_STENCIL_EQUAL;
DRW_PASS_CREATE(psl->sss_blur_ps, state);
DRW_PASS_CREATE(psl->sss_resolve_ps, state | DRW_STATE_BLEND_ADD);
DRW_PASS_CREATE(psl->sss_accum_ps, state | DRW_STATE_BLEND_ADD);
DRW_PASS_CREATE(psl->sss_translucency_ps, state | DRW_STATE_BLEND_ADD);
}
@ -245,6 +236,8 @@ void EEVEE_subsurface_add_pass(EEVEE_ViewLayerData *sldata,
DRW_shgroup_uniform_texture_ref(grp, "sssRadius", &effects->sss_radius);
DRW_shgroup_uniform_block(grp, "sssProfile", sss_profile);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_stencil_mask(grp, sss_id);
DRW_shgroup_call(grp, quad, NULL);
@ -256,22 +249,10 @@ void EEVEE_subsurface_add_pass(EEVEE_ViewLayerData *sldata,
DRW_shgroup_uniform_texture_ref(grp, "sssRadius", &effects->sss_radius);
DRW_shgroup_uniform_block(grp, "sssProfile", sss_profile);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_stencil_mask(grp, sss_id);
DRW_shgroup_call(grp, quad, NULL);
if ((stl->g_data->render_passes & (SCE_PASS_SUBSURFACE_COLOR | SCE_PASS_SUBSURFACE_DIRECT)) !=
0) {
grp = DRW_shgroup_create(e_data.sss_sh[2], psl->sss_accum_ps);
DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", depth_src);
DRW_shgroup_uniform_texture_ref(grp, "sssIrradiance", &effects->sss_blur);
DRW_shgroup_uniform_texture_ref(grp, "sssAlbedo", &effects->sss_albedo);
DRW_shgroup_uniform_texture_ref(grp, "sssRadius", &effects->sss_radius);
DRW_shgroup_uniform_block(grp, "sssProfile", sss_profile);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_stencil_mask(grp, sss_id);
DRW_shgroup_call(grp, quad, NULL);
}
}
void EEVEE_subsurface_translucency_add_pass(EEVEE_ViewLayerData *sldata,
@ -287,7 +268,7 @@ void EEVEE_subsurface_translucency_add_pass(EEVEE_ViewLayerData *sldata,
struct GPUBatch *quad = DRW_cache_fullscreen_quad_get();
GPUTexture **depth_src = GPU_depth_blitting_workaround() ? &effects->sss_stencil : &dtxl->depth;
DRWShadingGroup *grp = DRW_shgroup_create(e_data.sss_sh[3], psl->sss_translucency_ps);
DRWShadingGroup *grp = DRW_shgroup_create(e_data.sss_sh[2], psl->sss_translucency_ps);
DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
DRW_shgroup_uniform_texture(grp, "sssTexProfile", sss_tex_profile);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", depth_src);
@ -298,6 +279,8 @@ void EEVEE_subsurface_translucency_add_pass(EEVEE_ViewLayerData *sldata,
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);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_stencil_mask(grp, sss_id);
DRW_shgroup_call(grp, quad, NULL);
}
@ -408,11 +391,11 @@ void EEVEE_subsurface_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EEV
if (((effects->enabled_effects & EFFECT_SSS) != 0) && (fbl->sss_accum_fb != NULL)) {
/* Copy stencil channel, could be avoided (see EEVEE_subsurface_init) */
GPU_framebuffer_blit(fbl->main_fb, 0, fbl->sss_blur_fb, 0, GPU_STENCIL_BIT);
GPU_framebuffer_blit(fbl->main_fb, 0, fbl->sss_accum_fb, 0, GPU_STENCIL_BIT);
/* Only do vertical pass + Resolve */
GPU_framebuffer_bind(fbl->sss_accum_fb);
DRW_draw_pass(psl->sss_accum_ps);
DRW_draw_pass(psl->sss_resolve_ps);
/* Restore */
GPU_framebuffer_bind(fbl->main_fb);
@ -424,5 +407,4 @@ void EEVEE_subsurface_free(void)
DRW_SHADER_FREE_SAFE(e_data.sss_sh[0]);
DRW_SHADER_FREE_SAFE(e_data.sss_sh[1]);
DRW_SHADER_FREE_SAFE(e_data.sss_sh[2]);
DRW_SHADER_FREE_SAFE(e_data.sss_sh[3]);
}

View File

@ -290,6 +290,8 @@ void EEVEE_temporal_sampling_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data
DRW_shgroup_uniform_texture_ref(grp, "colorHistoryBuffer", &txl->taa_history);
DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", &effects->source_buffer);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
if (effects->enabled_effects & EFFECT_TAA_REPROJECT) {
// DefaultTextureList *dtxl = DRW_viewport_texture_list_get();

View File

@ -54,6 +54,7 @@ static struct {
struct GPUShader *scatter_with_lights_sh;
struct GPUShader *volumetric_integration_sh;
struct GPUShader *volumetric_resolve_sh;
struct GPUShader *volumetric_accum_sh;
GPUTexture *depth_src;
@ -73,6 +74,7 @@ extern char datatoc_common_view_lib_glsl[];
extern char datatoc_octahedron_lib_glsl[];
extern char datatoc_irradiance_lib_glsl[];
extern char datatoc_lights_lib_glsl[];
extern char datatoc_volumetric_accum_frag_glsl[];
extern char datatoc_volumetric_frag_glsl[];
extern char datatoc_volumetric_geom_glsl[];
extern char datatoc_volumetric_vert_glsl[];
@ -136,6 +138,8 @@ static void eevee_create_shader_volumes(void)
datatoc_volumetric_resolve_frag_glsl,
e_data.volumetric_common_lib,
NULL);
e_data.volumetric_accum_sh = DRW_shader_create_fullscreen(datatoc_volumetric_accum_frag_glsl,
NULL);
float color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
e_data.dummy_density = DRW_texture_create_3d(1, 1, 1, GPU_RGBA8, DRW_TEX_WRAP, color);
@ -359,6 +363,8 @@ void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
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, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
/* Fix principle volumetric not working with world materials. */
DRW_shgroup_uniform_texture(grp, "sampdensity", e_data.dummy_density);
@ -375,6 +381,8 @@ void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
/* If no world or volume material is present just clear the buffer with this drawcall */
grp = DRW_shgroup_create(e_data.volumetric_clear_sh, psl->volumetric_world_ps);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_call_procedural_triangles(grp, NULL, common_data->vol_tex_size[2]);
}
@ -430,8 +438,12 @@ void EEVEE_volumes_cache_object_add(EEVEE_ViewLayerData *sldata,
DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_vec3(grp, "volumeOrcoLoc", texcoloc, 1);
DRW_shgroup_uniform_vec3(grp, "volumeOrcoSize", texcosize, 1);
@ -522,6 +534,8 @@ void EEVEE_volumes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
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);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_call_procedural_triangles(grp, NULL, common_data->vol_tex_size[2]);
@ -530,6 +544,8 @@ void EEVEE_volumes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "volumeScattering", &txl->volume_scatter);
DRW_shgroup_uniform_texture_ref(grp, "volumeExtinction", &txl->volume_transmit);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_call_procedural_triangles(
grp, NULL, USE_VOLUME_OPTI ? 1 : common_data->vol_tex_size[2]);
@ -540,6 +556,8 @@ void EEVEE_volumes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "inTransmittance", &txl->volume_transmit);
DRW_shgroup_uniform_texture_ref(grp, "inSceneDepth", &e_data.depth_src);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
}
@ -729,4 +747,75 @@ void EEVEE_volumes_free(void)
DRW_SHADER_FREE_SAFE(e_data.scatter_with_lights_sh);
DRW_SHADER_FREE_SAFE(e_data.volumetric_integration_sh);
DRW_SHADER_FREE_SAFE(e_data.volumetric_resolve_sh);
DRW_SHADER_FREE_SAFE(e_data.volumetric_accum_sh);
}
/* -------------------------------------------------------------------- */
/** \name Render Passes
* \{ */
void EEVEE_volumes_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, uint tot_samples)
{
EEVEE_FramebufferList *fbl = vedata->fbl;
EEVEE_TextureList *txl = vedata->txl;
EEVEE_StorageList *stl = vedata->stl;
EEVEE_PassList *psl = vedata->psl;
EEVEE_EffectsInfo *effects = stl->effects;
float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
/* Create FrameBuffer. */
/* Should be enough precision for many samples. */
const eGPUTextureFormat texture_format_accum = (tot_samples > 128) ? GPU_RGBA32F : GPU_RGBA16F;
DRW_texture_ensure_fullscreen_2d(&txl->volume_scatter_accum, texture_format_accum, 0);
DRW_texture_ensure_fullscreen_2d(&txl->volume_transmittance_accum, texture_format_accum, 0);
GPU_framebuffer_ensure_config(&fbl->volumetric_accum_fb,
{GPU_ATTACHMENT_NONE,
GPU_ATTACHMENT_TEXTURE(txl->volume_scatter_accum),
GPU_ATTACHMENT_TEXTURE(txl->volume_transmittance_accum)});
/* Clear texture. */
if (DRW_state_is_image_render() || effects->taa_current_sample == 1) {
GPU_framebuffer_bind(fbl->volumetric_accum_fb);
GPU_framebuffer_clear_color(fbl->volumetric_accum_fb, clear);
}
/* Create Pass and shgroup. */
DRW_PASS_CREATE(psl->volumetric_accum_ps, DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ADD_FULL);
DRWShadingGroup *grp = NULL;
if ((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) {
grp = DRW_shgroup_create(e_data.volumetric_resolve_sh, psl->volumetric_accum_ps);
DRW_shgroup_uniform_texture_ref(grp, "inScattering", &txl->volume_scatter);
DRW_shgroup_uniform_texture_ref(grp, "inTransmittance", &txl->volume_transmit);
DRW_shgroup_uniform_texture_ref(grp, "inSceneDepth", &e_data.depth_src);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
}
else {
/* There is no volumetrics in the scene. Use a shader to fill the accum textures with a default
* value. */
grp = DRW_shgroup_create(e_data.volumetric_accum_sh, psl->volumetric_accum_ps);
}
DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
void EEVEE_volumes_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
{
EEVEE_FramebufferList *fbl = vedata->fbl;
EEVEE_PassList *psl = vedata->psl;
if (fbl->volumetric_accum_fb != NULL) {
/* Accum pass */
GPU_framebuffer_bind(fbl->volumetric_accum_fb);
DRW_draw_pass(psl->volumetric_accum_ps);
/* Restore */
GPU_framebuffer_bind(fbl->main_fb);
}
}
/* \} */

View File

@ -85,6 +85,37 @@ struct ShadowCascadeData {
#define sh_shadow_vec shadow_vec_id.xyz
#define sh_tex_index shadow_vec_id.w
/* ------ Render Passes ----- */
layout(std140) uniform renderpass_block
{
bool renderPassDiffuse;
bool renderPassDiffuseLight;
bool renderPassGlossy;
bool renderPassGlossyLight;
bool renderPassEmit;
bool renderPassSSSColor;
};
vec3 render_pass_diffuse_mask(vec3 diffuse_color, vec3 diffuse_light)
{
return renderPassDiffuse ? (renderPassDiffuseLight ? diffuse_light : diffuse_color) : vec3(0.0);
}
vec3 render_pass_sss_mask(vec3 sss_color)
{
return renderPassSSSColor ? sss_color : vec3(0.0);
}
vec3 render_pass_glossy_mask(vec3 specular_color, vec3 specular_light)
{
return renderPassGlossy ? (renderPassGlossyLight ? specular_light : specular_color) : vec3(0.0);
}
vec3 render_pass_emission_mask(vec3 emission_light)
{
return renderPassEmit ? emission_light : vec3(0.0);
}
/* ------- Convenience functions --------- */
vec3 mul(mat3 m, vec3 v)
@ -833,11 +864,12 @@ void closure_load_sss_data(
cl.sss_radius = radius;
cl.sss_albedo = sss_albedo;
cl.flag |= CLOSURE_SSS_FLAG;
cl.radiance += render_pass_diffuse_mask(sss_albedo, vec3(0));
}
else
# endif
{
cl.radiance += sss_irradiance * sss_albedo;
cl.radiance += render_pass_diffuse_mask(sss_albedo, sss_irradiance * sss_albedo);
}
}

View File

@ -34,7 +34,8 @@ Closure nodetree_exec(void)
eevee_closure_default(N, albedo, f0, f90, 1, roughness, 1.0, true, out_diff, out_spec, ssr_spec);
Closure cl = CLOSURE_DEFAULT;
cl.radiance = out_spec + out_diff * albedo;
cl.radiance = render_pass_glossy_mask(vec3(1.0), out_spec) +
render_pass_diffuse_mask(albedo, out_diff * albedo);
closure_load_ssr_data(ssr_spec, roughness, N, viewCameraVec, 1, cl);
#ifdef LOOKDEV

View File

@ -40,6 +40,7 @@ uniform float sampleScale;
/* Step Resolve */
uniform vec3 bloomColor;
uniform bool bloomAddBase;
in vec4 uvcoordsvar;
@ -201,9 +202,9 @@ vec4 step_resolve(void)
#else
vec3 blur = upsample_filter(sourceBuffer, uvcoordsvar.xy, sourceBufferTexelSize);
#endif
vec4 base = textureLod(baseBuffer, uvcoordsvar.xy, 0.0);
vec3 cout = base.rgb + blur * bloomColor;
return vec4(cout, base.a);
vec3 base = bloomAddBase ? textureLod(baseBuffer, uvcoordsvar.xy, 0.0).rgb : vec3(0.0);
vec3 cout = base + blur * bloomColor;
return vec4(cout, 1.0);
}
void main(void)

View File

@ -20,13 +20,7 @@ uniform sampler2DArray utilTex;
# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
#endif /* UTIL_TEX */
#ifdef RESULT_ACCUM
/* Render Passes Accumulation */
layout(location = 0) out vec4 sssDirect;
layout(location = 1) out vec4 sssColor;
#else
layout(location = 0) out vec4 sssRadiance;
#endif
float get_view_z_from_depth(float depth)
{
@ -87,10 +81,7 @@ void main(void)
accum += kernel[i].rgb * mix(color, sss_irradiance, s);
}
#ifdef RESULT_ACCUM
sssDirect = vec4(accum, 1.0);
sssColor = vec4(texture(sssAlbedo, uvs).rgb, 1.0);
#elif defined(FIRST_PASS)
#if defined(FIRST_PASS)
sssRadiance = vec4(accum, 1.0);
#else /* SECOND_PASS */
sssRadiance = vec4(accum * texture(sssAlbedo, uvs).rgb, 1.0);

View File

@ -173,19 +173,17 @@ float light_attenuation(LightData ld, vec4 l_vector)
return vis;
}
float light_visibility(LightData ld,
vec3 W,
float light_shadowing(LightData ld,
vec3 W,
#ifndef VOLUMETRICS
vec3 viewPosition,
float tracing_depth,
vec3 true_normal,
float rand_x,
const bool use_contact_shadows,
vec3 viewPosition,
float tracing_depth,
vec3 true_normal,
float rand_x,
const bool use_contact_shadows,
#endif
vec4 l_vector)
float vis)
{
float vis = light_attenuation(ld, l_vector);
#if !defined(VOLUMETRICS) || defined(VOLUME_SHADOW)
/* shadowing */
if (ld.l_shadowid >= 0.0 && vis > 0.001) {
@ -236,6 +234,30 @@ float light_visibility(LightData ld,
return vis;
}
float light_visibility(LightData ld,
vec3 W,
#ifndef VOLUMETRICS
vec3 viewPosition,
float tracing_depth,
vec3 true_normal,
float rand_x,
const bool use_contact_shadows,
#endif
vec4 l_vector)
{
float l_atten = light_attenuation(ld, l_vector);
return light_shadowing(ld,
W,
#ifndef VOLUMETRICS
viewPosition,
tracing_depth,
true_normal,
rand_x,
use_contact_shadows,
#endif
l_atten);
}
#ifdef USE_LTC
float light_diffuse(LightData ld, vec3 N, vec3 V, vec4 l_vector)
{

View File

@ -1,15 +1,17 @@
#define SCE_PASS_Z (1 << 1)
#define SCE_PASS_AO (1 << 6)
#define SCE_PASS_NORMAL (1 << 8)
#define SCE_PASS_MIST (1 << 14)
#define SCE_PASS_SUBSURFACE_DIRECT (1 << 28)
#define SCE_PASS_SUBSURFACE_COLOR (1 << 30)
#define PASS_POST_UNDEFINED 0
#define PASS_POST_ACCUMULATED_COLOR 1
#define PASS_POST_ACCUMULATED_LIGHT 2
#define PASS_POST_ACCUMULATED_VALUE 3
#define PASS_POST_DEPTH 4
#define PASS_POST_AO 5
#define PASS_POST_NORMAL 6
#define PASS_POST_TWO_LIGHT_BUFFERS 7
#define ACCUMULATED_COLOR_PASSES (SCE_PASS_SUBSURFACE_DIRECT | SCE_PASS_SUBSURFACE_COLOR)
#define ACCUMULATED_VALUE_PASSES (SCE_PASS_MIST)
uniform int renderpassType;
uniform int postProcessType;
uniform int currentSample;
uniform sampler2D inputBuffer;
uniform sampler2D inputSecondLightBuffer;
uniform sampler2D inputColorBuffer;
out vec4 fragColor;
@ -17,7 +19,7 @@ void main()
{
ivec2 texel = ivec2(gl_FragCoord.xy);
if (renderpassType == SCE_PASS_Z) {
if (postProcessType == PASS_POST_DEPTH) {
float depth = texelFetch(depthBuffer, texel, 0).r;
if (depth == 1.0f) {
depth = 1e10;
@ -27,17 +29,15 @@ void main()
}
fragColor.r = depth;
}
else if (renderpassType == SCE_PASS_AO) {
else if (postProcessType == PASS_POST_AO) {
float ao_accum = texelFetch(inputBuffer, texel, 0).r;
fragColor = vec4(vec3(min(1.0, ao_accum / currentSample)), 1.0);
}
else if (renderpassType == SCE_PASS_NORMAL) {
else if (postProcessType == PASS_POST_NORMAL) {
float depth = texelFetch(depthBuffer, texel, 0).r;
vec2 encoded_normal = texelFetch(inputBuffer, texel, 0).rg;
/* decode the normals only when they are valid. otherwise the result buffer will be filled with
* NaN's */
/* decode the normals only when they are valid. otherwise the result buffer will be filled
* with NaN's */
if (depth != 1.0 && any(notEqual(encoded_normal, vec2(0.0)))) {
vec3 decoded_normal = normal_decode(texelFetch(inputBuffer, texel, 0).rg, vec3(0.0));
vec3 world_normal = mat3(ViewMatrixInverse) * decoded_normal;
@ -47,18 +47,55 @@ void main()
fragColor = vec4(0.0, 0.0, 0.0, 1.0);
}
}
else if ((renderpassType & ACCUMULATED_VALUE_PASSES) != 0) {
else if (postProcessType == PASS_POST_ACCUMULATED_VALUE) {
float accumulated_value = texelFetch(inputBuffer, texel, 0).r;
fragColor = vec4(vec3(accumulated_value / currentSample), 1.0);
}
else if ((renderpassType & ACCUMULATED_COLOR_PASSES) != 0) {
else if (postProcessType == PASS_POST_ACCUMULATED_COLOR) {
vec3 accumulated_color = texelFetch(inputBuffer, texel, 0).rgb;
fragColor = vec4(accumulated_color / currentSample, 1.0);
}
else if (postProcessType == PASS_POST_ACCUMULATED_LIGHT) {
vec3 accumulated_light = texelFetch(inputBuffer, texel, 0).rgb;
vec3 accumulated_color = texelFetch(inputColorBuffer, texel, 0).rgb;
/* Fix INF in the case a color component is 0.0 */
if (accumulated_color.r == 0.0) {
accumulated_color.r = 1.0;
accumulated_light.r = 0.0;
}
if (accumulated_color.g == 0.0) {
accumulated_color.g = 1.0;
accumulated_light.g = 0.0;
}
if (accumulated_color.b == 0.0) {
accumulated_color.b = 1.0;
accumulated_light.b = 0.0;
}
fragColor = vec4(accumulated_light / accumulated_color, 1.0);
}
else if (postProcessType == PASS_POST_TWO_LIGHT_BUFFERS) {
vec3 accumulated_light = texelFetch(inputBuffer, texel, 0).rgb +
texelFetch(inputSecondLightBuffer, texel, 0).rgb;
vec3 accumulated_color = texelFetch(inputColorBuffer, texel, 0).rgb;
/* Fix INF in the case a color component is 0.0 */
if (accumulated_color.r == 0.0) {
accumulated_color.r = 1.0;
accumulated_light.r = 0.0;
}
if (accumulated_color.g == 0.0) {
accumulated_color.g = 1.0;
accumulated_light.g = 0.0;
}
if (accumulated_color.b == 0.0) {
accumulated_color.b = 1.0;
accumulated_light.b = 0.0;
}
fragColor = vec4(accumulated_light / accumulated_color, 1.0);
}
else {
/* Output error color: Unknown how to post process this pass. */
fragColor = vec4(1.0, 0.0, 1.0, 1.0);
}
}

View File

@ -0,0 +1,58 @@
out vec4 fragColor;
#ifndef UTIL_TEX
# define UTIL_TEX
uniform sampler2DArray utilTex;
# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
#endif /* UTIL_TEX */
void main()
{
if (laNumLight == 0) {
/* Early exit: No lights in scene */
fragColor.r = 0.0;
return;
}
ivec2 texel = ivec2(gl_FragCoord.xy);
float depth = texelFetch(depthBuffer, texel, 0).r;
if (depth == 1.0f) {
/* Early exit background does not receive shadows */
fragColor.r = 1.0;
return;
}
vec2 texel_size = 1.0 / vec2(textureSize(depthBuffer, 0)).xy;
vec2 uvs = saturate(gl_FragCoord.xy * texel_size);
vec4 rand = texelfetch_noise_tex(texel);
float accum_light = 0.0;
float tracing_depth = depth;
/* Constant bias (due to depth buffer precision) */
/* Magic numbers for 24bits of precision.
* From http://terathon.com/gdc07_lengyel.pdf (slide 26) */
tracing_depth -= mix(2.4e-7, 4.8e-7, depth);
/* Convert to view Z. */
tracing_depth = get_view_z_from_depth(tracing_depth);
vec3 viewPosition = get_view_space_from_depth(uvs, depth);
vec3 worldPosition = transform_point(ViewMatrixInverse, viewPosition);
vec3 true_normal = normalize(cross(dFdx(viewPosition), dFdy(viewPosition)));
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. */
l_vector.xyz = ld.l_position - worldPosition;
l_vector.w = length(l_vector.xyz);
float l_vis = light_shadowing(
ld, worldPosition, viewPosition, tracing_depth, true_normal, rand.x, true, 1.0);
accum_light += l_vis;
}
fragColor.r = accum_light / float(laNumLight);
}

View File

@ -0,0 +1,11 @@
/* This shader is used to add default values to the volume accum textures.
* so it looks similar (transmittance = 1, scattering = 0) */
layout(location = 0, index = 0) out vec4 FragColor0;
layout(location = 0, index = 1) out vec4 FragColor1;
void main()
{
FragColor0 = vec4(0.0);
FragColor1 = vec4(1.0);
}

View File

@ -4,8 +4,8 @@ void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out Closure result)
N = normalize(N);
result = CLOSURE_DEFAULT;
eevee_closure_diffuse(N, color.rgb, 1.0, true, result.radiance);
result.radiance = render_pass_diffuse_mask(color.rgb, result.radiance * color.rgb);
closure_load_ssr_data(vec3(0.0), 0.0, N, viewCameraVec, -1, result);
result.radiance *= color.rgb;
}
#else
/* Stub diffuse because it is not compatible with volumetrics. */

View File

@ -32,7 +32,9 @@ void node_eevee_specular(vec4 diffuse,
float alpha = 1.0 - transp;
result = CLOSURE_DEFAULT;
result.radiance = out_diff * diffuse.rgb + out_spec + emissive.rgb;
result.radiance = render_pass_diffuse_mask(diffuse.rgb, out_diff * diffuse.rgb);
result.radiance += render_pass_glossy_mask(vec3(1.0), out_spec);
result.radiance += render_pass_emission_mask(emissive.rgb);
result.radiance *= alpha;
result.transmittance = vec3(transp);

View File

@ -2,7 +2,7 @@ void node_emission(vec4 color, float strength, vec3 vN, out Closure result)
{
result = CLOSURE_DEFAULT;
#ifndef VOLUMETRICS
result.radiance = color.rgb * strength;
result.radiance = render_pass_emission_mask(color.rgb) * strength;
result.ssr_normal = normal_encode(vN, viewCameraVec);
#else
result.emission = color.rgb * strength;

View File

@ -17,12 +17,12 @@ void node_bsdf_glass(
out_spec,
out_refr,
ssr_spec);
out_refr *= refr_color;
out_spec *= color.rgb;
float fresnel = F_eta(ior, dot(N, cameraVec));
vec3 vN = mat3(ViewMatrix) * N;
result = CLOSURE_DEFAULT;
result.radiance = mix(out_refr, out_spec, fresnel);
result.radiance = render_pass_glossy_mask(refr_color, out_refr * refr_color) * (1.0 - fresnel);
result.radiance += render_pass_glossy_mask(color.rgb, out_spec * color.rgb) * fresnel;
closure_load_ssr_data(
ssr_spec * color.rgb * fresnel, roughness, N, viewCameraVec, int(ssr_id), result);
}

View File

@ -7,7 +7,7 @@ void node_bsdf_glossy(vec4 color, float roughness, vec3 N, float ssr_id, out Clo
N, vec3(1.0), vec3(1.0), int(ssr_id), roughness, 1.0, true, out_spec, ssr_spec);
vec3 vN = mat3(ViewMatrix) * N;
result = CLOSURE_DEFAULT;
result.radiance = out_spec * color.rgb;
result.radiance = render_pass_glossy_mask(vec3(1.0), out_spec) * color.rgb;
closure_load_ssr_data(ssr_spec * color.rgb, roughness, N, viewCameraVec, int(ssr_id), result);
}
#else

View File

@ -18,15 +18,22 @@ void convert_metallic_to_specular_tinted(vec3 basecol,
diffuse = basecol * (1.0 - metallic);
}
vec3 principled_sheen(float NV, vec3 basecol_tint, float sheen_tint)
/* Output sheen is to be multiplied by sheen_color. */
void principled_sheen(float NV,
vec3 basecol_tint,
float sheen,
float sheen_tint,
out float out_sheen,
out vec3 sheen_color)
{
float f = 1.0 - NV;
/* Temporary fix for T59784. Normal map seems to contain NaNs for tangent space normal maps,
* therefore we need to clamp value. */
f = clamp(f, 0.0, 1.0);
/* Empirical approximation (manual curve fitting). Can be refined. */
float sheen = f * f * f * 0.077 + f * 0.01 + 0.00026;
return sheen * mix(vec3(1.0), basecol_tint, sheen_tint);
out_sheen = f * f * f * 0.077 + f * 0.01 + 0.00026;
sheen_color = sheen * mix(vec3(1.0), basecol_tint, sheen_tint);
}
void node_bsdf_principled(vec4 base_color,
@ -61,18 +68,23 @@ void node_bsdf_principled(vec4 base_color,
ior = max(ior, 1e-5);
metallic = saturate(metallic);
transmission = saturate(transmission);
float m_transmission = 1.0 - transmission;
float dielectric = 1.0 - metallic;
transmission *= dielectric;
sheen *= dielectric;
subsurface_color *= dielectric;
vec3 diffuse, f0, out_diff, out_spec, out_refr, ssr_spec;
vec3 diffuse, f0, out_diff, out_spec, out_refr, ssr_spec, sheen_color;
float out_sheen;
vec3 ctint = tint_from_color(base_color.rgb);
convert_metallic_to_specular_tinted(
base_color.rgb, ctint, metallic, specular, specular_tint, diffuse, f0);
float NV = dot(N, cameraVec);
vec3 out_sheen = sheen * principled_sheen(NV, ctint, sheen_tint);
principled_sheen(NV, ctint, sheen, sheen_tint, out_sheen, sheen_color);
vec3 f90 = mix(vec3(1.0), f0, (1.0 - specular) * metallic);
/* Far from being accurate, but 2 glossy evaluation is too expensive.
* Most noticeable difference is at grazing angles since the bsdf lut
@ -81,8 +93,12 @@ void node_bsdf_principled(vec4 base_color,
float fresnel = F_eta(ior, NV);
vec3 spec_col = F_color_blend(ior, fresnel, f0_glass) * fresnel;
f0 = mix(f0, spec_col, transmission);
f90 = mix(f90, spec_col, transmission);
vec3 f90 = mix(vec3(1.0), f0, (1.0 - specular) * metallic);
/* Really poor approximation but needed to workaround issues with renderpasses. */
spec_col = mix(vec3(1.0), spec_col, transmission);
/* Match cycles. */
spec_col += float(clearcoat > 1e-5);
vec3 mixed_ss_base_color = mix(diffuse, subsurface_color.rgb, subsurface);
@ -108,19 +124,22 @@ void node_bsdf_principled(vec4 base_color,
vec3 refr_color = base_color.rgb;
refr_color *= (refractionDepth > 0.0) ? refr_color :
vec3(1.0); /* Simulate 2 transmission event */
out_refr *= refr_color * (1.0 - fresnel) * transmission;
refr_color *= saturate(1.0 - fresnel) * transmission;
sheen_color *= m_transmission;
mixed_ss_base_color *= m_transmission;
result = CLOSURE_DEFAULT;
result.radiance = out_spec + out_refr;
result.radiance += out_diff * out_sheen; /* Coarse approx. */
result.radiance += emission.rgb;
result.radiance = render_pass_glossy_mask(refr_color, out_refr * refr_color);
result.radiance += render_pass_glossy_mask(spec_col, out_spec);
/* Coarse approx. */
result.radiance += render_pass_diffuse_mask(sheen_color, out_diff * out_sheen * sheen_color);
result.radiance += render_pass_emission_mask(emission.rgb);
result.radiance *= alpha;
closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result);
mixed_ss_base_color *= alpha * (1.0 - transmission);
mixed_ss_base_color *= alpha;
closure_load_sss_data(sss_scalef, out_diff, mixed_ss_base_color, int(sss_id), result);
result.transmittance = vec3(1.0 - alpha);
}
@ -156,22 +175,26 @@ void node_bsdf_principled_dielectric(vec4 base_color,
metallic = saturate(metallic);
float dielectric = 1.0 - metallic;
vec3 diffuse, f0, out_diff, out_spec, ssr_spec;
vec3 diffuse, f0, out_diff, out_spec, ssr_spec, sheen_color;
float out_sheen;
vec3 ctint = tint_from_color(base_color.rgb);
convert_metallic_to_specular_tinted(
base_color.rgb, ctint, metallic, specular, specular_tint, diffuse, f0);
vec3 f90 = mix(vec3(1.0), f0, (1.0 - specular) * metallic);
float NV = dot(N, cameraVec);
vec3 out_sheen = sheen * principled_sheen(NV, ctint, sheen_tint);
principled_sheen(NV, ctint, sheen, sheen_tint, out_sheen, sheen_color);
eevee_closure_default(
N, diffuse, f0, vec3(1.0), int(ssr_id), roughness, 1.0, true, out_diff, out_spec, ssr_spec);
N, diffuse, f0, f90, int(ssr_id), roughness, 1.0, true, out_diff, out_spec, ssr_spec);
result = CLOSURE_DEFAULT;
result.radiance = out_spec + out_diff * (diffuse + out_sheen);
result.radiance += emission.rgb;
result.radiance = render_pass_glossy_mask(vec3(1.0), out_spec);
result.radiance += render_pass_diffuse_mask(sheen_color, out_diff * out_sheen * sheen_color);
result.radiance += render_pass_diffuse_mask(diffuse, out_diff * diffuse);
result.radiance += render_pass_emission_mask(emission.rgb);
result.radiance *= alpha;
closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result);
result.transmittance = vec3(1.0 - alpha);
@ -214,10 +237,9 @@ void node_bsdf_principled_metallic(vec4 base_color,
N, base_color.rgb, f90, int(ssr_id), roughness, 1.0, true, out_spec, ssr_spec);
result = CLOSURE_DEFAULT;
result.radiance = out_spec;
result.radiance += emission.rgb;
result.radiance = render_pass_glossy_mask(vec3(1.0), out_spec);
result.radiance += render_pass_emission_mask(emission.rgb);
result.radiance *= alpha;
closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result);
result.transmittance = vec3(1.0 - alpha);
@ -268,10 +290,12 @@ void node_bsdf_principled_clearcoat(vec4 base_color,
true,
out_spec,
ssr_spec);
/* Match cycles. */
float spec_col = 1.0 + float(clearcoat > 1e-5);
result = CLOSURE_DEFAULT;
result.radiance = out_spec;
result.radiance += emission.rgb;
result.radiance = render_pass_glossy_mask(vec3(spec_col), out_spec);
result.radiance += render_pass_emission_mask(emission.rgb);
result.radiance *= alpha;
closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result);
@ -310,7 +334,8 @@ void node_bsdf_principled_subsurface(vec4 base_color,
metallic = saturate(metallic);
N = normalize(N);
vec3 diffuse, f0, out_diff, out_spec, ssr_spec;
vec3 diffuse, f0, out_diff, out_spec, ssr_spec, sheen_color;
float out_sheen;
vec3 ctint = tint_from_color(base_color.rgb);
convert_metallic_to_specular_tinted(
base_color.rgb, ctint, metallic, specular, specular_tint, diffuse, f0);
@ -320,7 +345,7 @@ void node_bsdf_principled_subsurface(vec4 base_color,
float sss_scalef = avg(sss_scale) * subsurface;
float NV = dot(N, cameraVec);
vec3 out_sheen = sheen * principled_sheen(NV, ctint, sheen_tint);
principled_sheen(NV, ctint, sheen, sheen_tint, out_sheen, sheen_color);
vec3 f90 = mix(vec3(1.0), base_color.rgb, (1.0 - specular) * metallic);
@ -338,14 +363,14 @@ void node_bsdf_principled_subsurface(vec4 base_color,
ssr_spec);
result = CLOSURE_DEFAULT;
result.radiance = out_spec;
result.radiance += out_diff * out_sheen;
result.radiance += emission.rgb;
result.radiance = render_pass_glossy_mask(vec3(1.0), out_spec);
result.radiance += render_pass_diffuse_mask(sheen_color, out_diff * out_sheen * sheen_color);
result.radiance += render_pass_emission_mask(emission.rgb);
result.radiance *= alpha;
closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result);
mixed_ss_base_color *= alpha * (1.0 - transmission);
mixed_ss_base_color *= alpha;
closure_load_sss_data(sss_scalef, out_diff, mixed_ss_base_color, int(sss_id), result);
result.transmittance = vec3(1.0 - alpha);
@ -400,16 +425,18 @@ void node_bsdf_principled_glass(vec4 base_color,
vec3 refr_color = base_color.rgb;
refr_color *= (refractionDepth > 0.0) ? refr_color :
vec3(1.0); /* Simulate 2 transmission events */
out_refr *= refr_color;
float fresnel = F_eta(ior, dot(N, cameraVec));
vec3 spec_col = F_color_blend(ior, fresnel, f0);
out_spec *= spec_col;
ssr_spec *= spec_col * fresnel;
spec_col *= fresnel;
refr_color *= (1.0 - fresnel);
ssr_spec *= spec_col;
result = CLOSURE_DEFAULT;
result.radiance = mix(out_refr, out_spec, fresnel);
result.radiance += emission.rgb;
result.radiance = render_pass_glossy_mask(refr_color, out_refr * refr_color);
result.radiance += render_pass_glossy_mask(spec_col, out_spec * spec_col);
result.radiance += render_pass_emission_mask(emission.rgb);
result.radiance *= alpha;
closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result);
result.transmittance = vec3(1.0 - alpha);

View File

@ -8,7 +8,7 @@ void node_bsdf_refraction(vec4 color, float roughness, float ior, vec3 N, out Cl
vec3 vN = mat3(ViewMatrix) * N;
result = CLOSURE_DEFAULT;
result.ssr_normal = normal_encode(vN, viewCameraVec);
result.radiance = out_refr * color.rgb;
result.radiance = render_pass_glossy_mask(color.rgb, out_refr * color.rgb);
}
#else
/* Stub refraction because it is not compatible with volumetrics. */

View File

@ -19,6 +19,7 @@ void node_subsurface_scattering(vec4 color,
/* Not perfect for texture_blur not exactly equal to 0.0 or 1.0. */
vec3 sss_albedo = mix(color.rgb, vec3(1.0), texture_blur);
out_diff *= mix(vec3(1.0), color.rgb, texture_blur);
result.radiance = render_pass_sss_mask(sss_albedo);
closure_load_sss_data(scale, out_diff, sss_albedo, int(sss_id), result);
}
#else

View File

@ -5,7 +5,7 @@ void node_bsdf_translucent(vec4 color, vec3 N, out Closure result)
result = CLOSURE_DEFAULT;
eevee_closure_diffuse(-N, color.rgb, 1.0, false, result.radiance);
closure_load_ssr_data(vec3(0.0), 0.0, N, viewCameraVec, -1, result);
result.radiance *= color.rgb;
result.radiance = render_pass_diffuse_mask(color.rgb, result.radiance * color.rgb);
}
#else
/* Stub translucent because it is not compatible with volumetrics. */

View File

@ -28,6 +28,26 @@ extern "C" {
#include "DNA_freestyle_types.h"
#include "DNA_listBase.h"
/* Renderpasses for EEVEE.
* ViewLayerEEVEE.render_passes */
typedef enum eViewLayerEEVEEPassType {
EEVEE_RENDER_PASS_COMBINED = (1 << 0),
EEVEE_RENDER_PASS_Z = (1 << 1),
EEVEE_RENDER_PASS_MIST = (1 << 2),
EEVEE_RENDER_PASS_NORMAL = (1 << 3),
EEVEE_RENDER_PASS_DIFFUSE_LIGHT = (1 << 4),
EEVEE_RENDER_PASS_DIFFUSE_COLOR = (1 << 5),
EEVEE_RENDER_PASS_SPECULAR_LIGHT = (1 << 6),
EEVEE_RENDER_PASS_SPECULAR_COLOR = (1 << 7),
EEVEE_RENDER_PASS_VOLUME_TRANSMITTANCE = (1 << 8),
EEVEE_RENDER_PASS_VOLUME_SCATTER = (1 << 9),
EEVEE_RENDER_PASS_EMIT = (1 << 10),
EEVEE_RENDER_PASS_ENVIRONMENT = (1 << 11),
EEVEE_RENDER_PASS_SHADOW = (1 << 12),
EEVEE_RENDER_PASS_AO = (1 << 13),
EEVEE_RENDER_PASS_BLOOM = (1 << 14),
} eViewLayerEEVEEPassType;
typedef struct Base {
struct Base *next, *prev;
@ -76,6 +96,12 @@ typedef struct LayerCollection {
short _pad2[3];
} LayerCollection;
/* Type containing EEVEE settings per view-layer */
typedef struct ViewLayerEEVEE {
int render_passes;
int _pad[1];
} ViewLayerEEVEE;
typedef struct ViewLayer {
struct ViewLayer *next, *prev;
/** MAX_NAME. */
@ -106,6 +132,7 @@ typedef struct ViewLayer {
struct IDProperty *id_properties;
struct FreestyleConfig freestyle_config;
struct ViewLayerEEVEE eevee;
/* Runtime data */
/** ViewLayerEngineData. */

View File

@ -318,6 +318,9 @@ typedef enum eScenePassType {
#define RE_PASSNAME_SUBSURFACE_COLOR "SubsurfaceCol"
#define RE_PASSNAME_FREESTYLE "Freestyle"
#define RE_PASSNAME_BLOOM "BloomCol"
#define RE_PASSNAME_VOLUME_TRANSMITTANCE "VolumeTransmCol"
#define RE_PASSNAME_VOLUME_SCATTER "VolumeScatterCol"
/* View - MultiView */
typedef struct SceneRenderView {

View File

@ -677,6 +677,7 @@ extern StructRNA RNA_View3DCursor;
extern StructRNA RNA_View3DOverlay;
extern StructRNA RNA_View3DShading;
extern StructRNA RNA_ViewLayer;
extern StructRNA RNA_ViewLayerEEVEE;
extern StructRNA RNA_VoronoiTexture;
extern StructRNA RNA_WalkNavigation;
extern StructRNA RNA_WarpModifier;

View File

@ -3756,6 +3756,30 @@ static void rna_def_unit_settings(BlenderRNA *brna)
RNA_def_property_update(prop, NC_WINDOW, NULL);
}
static void rna_def_view_layer_eevee(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
srna = RNA_def_struct(brna, "ViewLayerEEVEE", NULL);
RNA_def_struct_ui_text(srna, "EEVEE Settings", "View layer settings for EEVEE");
prop = RNA_def_property(srna, "use_pass_volume_scatter", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "render_passes", EEVEE_RENDER_PASS_VOLUME_SCATTER);
RNA_def_property_ui_text(prop, "Volume Scatter", "Deliver volume scattering pass");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update");
prop = RNA_def_property(srna, "use_pass_volume_transmittance", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(
prop, NULL, "render_passes", EEVEE_RENDER_PASS_VOLUME_TRANSMITTANCE);
RNA_def_property_ui_text(prop, "Volume Transmittance", "Deliver volume transmittance pass");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update");
prop = RNA_def_property(srna, "use_pass_bloom", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "render_passes", EEVEE_RENDER_PASS_BLOOM);
RNA_def_property_ui_text(prop, "Bloom", "Deliver bloom pass");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update");
}
void rna_def_view_layer_common(StructRNA *srna, const bool scene)
{
PropertyRNA *prop;
@ -3801,6 +3825,11 @@ void rna_def_view_layer_common(StructRNA *srna, const bool scene)
"Z, Index, normal, UV and vector passes are only affected by surfaces with "
"alpha transparency equal to or higher than this threshold");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
prop = RNA_def_property(srna, "eevee", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_struct_type(prop, "ViewLayerEEVEE");
RNA_def_property_ui_text(prop, "EEVEE Settings", "View layer settings for EEVEE");
}
/* layer options */
@ -7546,6 +7575,7 @@ void RNA_def_scene(BlenderRNA *brna)
rna_def_display_safe_areas(brna);
rna_def_scene_display(brna);
rna_def_scene_eevee(brna);
rna_def_view_layer_eevee(brna);
RNA_define_animate_sdna(true);
/* *** Animated *** */
rna_def_scene_render_data(brna);

View File

@ -382,14 +382,32 @@ static const EnumPropertyItem rna_enum_studio_light_items[] = {
};
static const EnumPropertyItem rna_enum_view3dshading_render_pass_type_items[] = {
{SCE_PASS_COMBINED, "COMBINED", 0, "Combined", ""},
/* {SCE_PASS_Z, "Z", 0, "Z", ""},*/
{SCE_PASS_AO, "AO", 0, "Ambient Occlusion", ""},
{SCE_PASS_NORMAL, "NORMAL", 0, "Normal", ""},
{SCE_PASS_MIST, "MIST", 0, "Mist", ""},
{SCE_PASS_SUBSURFACE_DIRECT, "SUBSURFACE_DIRECT", 0, "Subsurface Direct", ""},
/* {SCE_PASS_SUBSURFACE_INDIRECT, "SUBSURFACE_INDIRECT", 0, "Subsurface Indirect", ""}, */
{SCE_PASS_SUBSURFACE_COLOR, "SUBSURFACE_COLOR", 0, "Subsurface Color", ""},
{0, "", ICON_NONE, "General", ""},
{EEVEE_RENDER_PASS_COMBINED, "COMBINED", 0, "Combined", ""},
{EEVEE_RENDER_PASS_EMIT, "EMISSION", 0, "Emission", ""},
{EEVEE_RENDER_PASS_ENVIRONMENT, "ENVIRONMENT", 0, "Environment", ""},
{EEVEE_RENDER_PASS_AO, "AO", 0, "Ambient Occlusion", ""},
{EEVEE_RENDER_PASS_SHADOW, "SHADOW", 0, "Shadow", ""},
{0, "", ICON_NONE, "Light", ""},
{EEVEE_RENDER_PASS_DIFFUSE_LIGHT, "DIFFUSE_LIGHT", 0, "Diffuse Light", ""},
{EEVEE_RENDER_PASS_DIFFUSE_COLOR, "DIFFUSE_COLOR", 0, "Diffuse Color", ""},
{EEVEE_RENDER_PASS_SPECULAR_LIGHT, "SPECULAR_LIGHT", 0, "Specular Light", ""},
{EEVEE_RENDER_PASS_SPECULAR_COLOR, "SPECULAR_COLOR", 0, "Specular Color", ""},
{EEVEE_RENDER_PASS_VOLUME_TRANSMITTANCE,
"VOLUME_TRANSMITTANCE",
0,
"Volume Transmittance",
""},
{EEVEE_RENDER_PASS_VOLUME_SCATTER, "VOLUME_SCATTER", 0, "Volume Scattering", ""},
{0, "", ICON_NONE, "Effects", ""},
{EEVEE_RENDER_PASS_BLOOM, "BLOOM", 0, "Bloom", ""},
{0, "", ICON_NONE, "Data", ""},
{EEVEE_RENDER_PASS_NORMAL, "NORMAL", 0, "Normal", ""},
{EEVEE_RENDER_PASS_MIST, "MIST", 0, "Mist", ""},
{0, NULL, 0, NULL, NULL},
};
@ -1242,6 +1260,30 @@ static const EnumPropertyItem *rna_View3DShading_studio_light_itemf(bContext *UN
return item;
}
static const EnumPropertyItem *rna_3DViewShading_render_pass_itemf(bContext *C,
PointerRNA *UNUSED(ptr),
PropertyRNA *UNUSED(prop),
bool *r_free)
{
Scene *scene = CTX_data_scene(C);
const bool ao_enabled = scene->eevee.flag & SCE_EEVEE_GTAO_ENABLED;
const bool bloom_enabled = scene->eevee.flag & SCE_EEVEE_BLOOM_ENABLED;
int totitem = 0;
EnumPropertyItem *result = NULL;
for (int i = 0; rna_enum_view3dshading_render_pass_type_items[i].identifier != NULL; i++) {
const EnumPropertyItem *item = &rna_enum_view3dshading_render_pass_type_items[i];
if (!((!ao_enabled && item->value == EEVEE_RENDER_PASS_AO) ||
(!bloom_enabled &&
(item->value == EEVEE_RENDER_PASS_BLOOM || STREQ(item->name, "Effects"))))) {
RNA_enum_item_add(&result, &totitem, item);
}
}
*r_free = true;
return result;
}
static void rna_SpaceView3D_use_local_collections_update(bContext *C, PointerRNA *ptr)
{
Main *bmain = CTX_data_main(C);
@ -3328,6 +3370,7 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "render_pass");
RNA_def_property_enum_items(prop, rna_enum_view3dshading_render_pass_type_items);
RNA_def_property_ui_text(prop, "Render Pass", "Render Pass to show in the viewport");
RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_3DViewShading_render_pass_itemf");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
}

View File

@ -281,8 +281,11 @@ void ntreeCompositUpdateRLayers(bNodeTree *ntree)
}
}
void ntreeCompositRegisterPass(
bNodeTree *ntree, Scene *scene, ViewLayer *view_layer, const char *name, int type)
void ntreeCompositRegisterPass(bNodeTree *ntree,
Scene *scene,
ViewLayer *view_layer,
const char *name,
eNodeSocketDatatype type)
{
bNode *node;

View File

@ -72,13 +72,14 @@ static bNodeSocketTemplate cmp_node_rlayers_out[] = {
{SOCK_RGBA, 0, N_(RE_PASSNAME_SUBSURFACE_COLOR), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{-1, 0, ""},
};
#define MAX_LEGACY_SOCKET_INDEX 30
static void cmp_node_image_add_pass_output(bNodeTree *ntree,
bNode *node,
const char *name,
const char *passname,
int rres_index,
int type,
eNodeSocketDatatype type,
int is_rlayers,
LinkNodePair *available_sockets,
int *prev_index)
@ -94,8 +95,8 @@ static void cmp_node_image_add_pass_output(bNodeTree *ntree,
* New sockets are placed behind the previously traversed one,
* but always after the first 31. */
int after_index = *prev_index;
if (is_rlayers && after_index < 30) {
after_index = 30;
if (is_rlayers && after_index < MAX_LEGACY_SOCKET_INDEX) {
after_index = MAX_LEGACY_SOCKET_INDEX;
}
if (rres_index >= 0) {
@ -238,8 +239,12 @@ typedef struct RLayerUpdateData {
int prev_index;
} RLayerUpdateData;
void node_cmp_rlayers_register_pass(
bNodeTree *ntree, bNode *node, Scene *scene, ViewLayer *view_layer, const char *name, int type)
void node_cmp_rlayers_register_pass(bNodeTree *ntree,
bNode *node,
Scene *scene,
ViewLayer *view_layer,
const char *name,
eNodeSocketDatatype type)
{
RLayerUpdateData *data = node->storage;
@ -389,7 +394,7 @@ static void cmp_node_image_verify_outputs(bNodeTree *ntree, bNode *node, bool rl
break;
}
}
if (!link && (!rlayer || sock_index > 30)) {
if (!link && (!rlayer || sock_index > MAX_LEGACY_SOCKET_INDEX)) {
MEM_freeN(sock->storage);
nodeRemoveSocket(ntree, node, sock);
}
@ -508,7 +513,7 @@ const char *node_cmp_rlayers_sock_to_pass(int sock_index)
RE_PASSNAME_SUBSURFACE_INDIRECT,
RE_PASSNAME_SUBSURFACE_COLOR,
};
if (sock_index > 30) {
if (sock_index > MAX_LEGACY_SOCKET_INDEX) {
return NULL;
}
return sock_to_passname[sock_index];

View File

@ -26,6 +26,7 @@
#include "DNA_listBase.h"
#include "DNA_scene_types.h"
#include "DNA_node_types.h"
#include "RNA_types.h"
#include "RE_bake.h"
@ -117,7 +118,7 @@ typedef void (*update_render_passes_cb_t)(void *userdata,
const char *name,
int channels,
const char *chanid,
int type);
eNodeSocketDatatype type);
typedef struct RenderEngine {
RenderEngineType *type;
@ -212,7 +213,7 @@ void RE_engine_register_pass(struct RenderEngine *engine,
const char *name,
int channels,
const char *chanid,
int type);
eNodeSocketDatatype type);
/* Engine Types */

View File

@ -863,7 +863,7 @@ void RE_engine_register_pass(struct RenderEngine *engine,
const char *name,
int channels,
const char *chanid,
int type)
eNodeSocketDatatype type)
{
if (!(scene && view_layer && engine && engine->update_render_passes_cb)) {
return;

View File

@ -442,6 +442,15 @@ RenderResult *render_result_new(Render *re,
if (view_layer->passflag & SCE_PASS_SUBSURFACE_COLOR) {
RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_SUBSURFACE_COLOR, view, "RGB");
}
if (view_layer->eevee.render_passes & EEVEE_RENDER_PASS_BLOOM) {
RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_BLOOM, view, "RGB");
}
if (view_layer->eevee.render_passes & EEVEE_RENDER_PASS_VOLUME_SCATTER) {
RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_VOLUME_SCATTER, view, "RGB");
}
if (view_layer->eevee.render_passes & EEVEE_RENDER_PASS_VOLUME_TRANSMITTANCE) {
RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_VOLUME_TRANSMITTANCE, view, "RGB");
}
#undef RENDER_LAYER_ADD_PASS_SAFE
}
}