Eevee: Add partial support for the Light Path Node

This makes it possible to tweak indirect lighting in the shader.

Only a subset of the outputs is supported and the ray depth has not exactly
the same meaning:

Is Camera : Supported.
Is Shadow : Supported.
Is Diffuse : Supported.
Is Glossy : Supported.
Is Singular : Not supported. Same as Is Glossy.
Is Reflection : Not supported. Same as Is Glossy.
Is Transmission : Not supported. Same as Is Glossy.
Ray Length : Not supported. Defaults to 1.0.
Ray Depth : Indicate the current bounce when baking the light cache.
Diffuse Depth : Same as Ray Depth but only when baking diffuse light.
Glossy Depth : Same as Ray Depth but only when baking specular light.
Transparent Depth : Not supported. Defaults to 0.
Transmission Depth : Not supported. Same as Glossy Depth.

Caveat: Is Glossy does not work with Screen Space Reflections but does work
with reflection planes (when used with SSR or not).
We have to render the world twice for that to work.
This commit is contained in:
Clément Foucault 2018-11-08 19:17:41 +01:00
parent 9d12a5aa9e
commit 4f11441913
8 changed files with 63 additions and 24 deletions

View File

@ -244,14 +244,16 @@ static void eevee_draw_background(void *vedata)
EEVEE_lightprobes_refresh_planar(sldata, vedata);
DRW_stats_group_end();
/* Update common buffer after probe rendering. */
DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
/* Refresh shadows */
DRW_stats_group_start("Shadows");
EEVEE_draw_shadows(sldata, vedata);
DRW_stats_group_end();
/* Set ray type. */
sldata->common_data.ray_type = EEVEE_RAY_CAMERA;
sldata->common_data.ray_depth = 0.0f;
DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
GPU_framebuffer_bind(fbl->main_fb);
GPUFrameBufferBits clear_bits = GPU_DEPTH_BIT;
clear_bits |= (DRW_state_draw_background()) ? 0 : GPU_COLOR_BIT;

View File

@ -865,6 +865,8 @@ static void eevee_lightbake_render_grid_sample(void *ved, void *user_data)
common_data->spec_toggle = false;
common_data->prb_num_planar = 0;
common_data->prb_num_render_cube = 0;
common_data->ray_type = EEVEE_RAY_DIFFUSE;
common_data->ray_depth = lbake->bounce_curr + 1;
if (lbake->bounce_curr == 0) {
common_data->prb_num_render_grid = 0;
}
@ -924,6 +926,8 @@ static void eevee_lightbake_render_probe_sample(void *ved, void *user_data)
common_data->spec_toggle = false;
common_data->prb_num_planar = 0;
common_data->prb_num_render_cube = 0;
common_data->ray_type = EEVEE_RAY_GLOSSY;
common_data->ray_depth = 1;
DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
EEVEE_lightbake_render_scene(sldata, vedata, lbake->rt_fb, eprobe->position, prb->clipsta, prb->clipend);
@ -1172,8 +1176,16 @@ void EEVEE_lightbake_update_world_quick(EEVEE_ViewLayerData *sldata, EEVEE_Data
EEVEE_lightbake_cache_init(sldata, vedata, lbake.rt_color, lbake.rt_depth);
sldata->common_data.ray_type = EEVEE_RAY_GLOSSY;
sldata->common_data.ray_depth = 1;
DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
EEVEE_lightbake_render_world(sldata, vedata, lbake.rt_fb);
EEVEE_lightbake_filter_glossy(sldata, vedata, lbake.rt_color, lbake.store_fb, 0, 1.0f, lcache->mips_len);
sldata->common_data.ray_type = EEVEE_RAY_DIFFUSE;
sldata->common_data.ray_depth = 1;
DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
EEVEE_lightbake_render_world(sldata, vedata, lbake.rt_fb);
EEVEE_lightbake_filter_diffuse(sldata, vedata, lbake.rt_color, lbake.store_fb, 0, 1.0f);
/* Don't hide grids if they are already rendered. */

View File

@ -1316,6 +1316,8 @@ void EEVEE_lightprobes_refresh_planar(EEVEE_ViewLayerData *sldata, EEVEE_Data *v
common_data->ssr_toggle = false;
common_data->sss_toggle = false;
common_data->ray_type = EEVEE_RAY_GLOSSY;
common_data->ray_depth = 1.0f;
DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
/* Rendering happens here! */

View File

@ -1182,6 +1182,11 @@ void EEVEE_draw_shadows(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
int i;
DRWMatrixState saved_mats;
int saved_ray_type = sldata->common_data.ray_type;
/* TODO: make it optionnal if we don't draw shadows. */
sldata->common_data.ray_type = EEVEE_RAY_SHADOW;
DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
/* Precompute all shadow/view test before rendering and trashing the culling cache. */
bool cube_visible[MAX_SHADOW_CUBE];
@ -1420,6 +1425,9 @@ void EEVEE_draw_shadows(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_uniformbuffer_update(sldata->light_ubo, &linfo->light_data);
DRW_uniformbuffer_update(sldata->shadow_ubo, &linfo->shadow_data); /* Update all data at once */
sldata->common_data.ray_type = saved_ray_type;
DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
}
void EEVEE_lights_free(void)

View File

@ -656,8 +656,16 @@ typedef struct EEVEE_CommonUniformBuffer {
float prb_lod_planar_max; /* float */
/* Misc */
int hiz_mip_offset; /* int */
int ray_type; /* int */
float ray_depth; /* float */
} EEVEE_CommonUniformBuffer;
/* ray_type (keep in sync with rayType) */
#define EEVEE_RAY_CAMERA 0
#define EEVEE_RAY_SHADOW 1
#define EEVEE_RAY_DIFFUSE 2
#define EEVEE_RAY_GLOSSY 3
/* ***************** CLIP PLANES DATA **************** */
typedef struct EEVEE_ClipPlanesUniformBuffer {

View File

@ -527,7 +527,6 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl
RE_engine_update_stats(engine, NULL, "Updating Probes");
EEVEE_lightprobes_refresh(sldata, vedata);
EEVEE_lightprobes_refresh_planar(sldata, vedata);
DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
char info[42];
BLI_snprintf(info, sizeof(info), "Rendering %u / %u samples", render_samples + 1, tot_sample);
@ -537,6 +536,11 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl
EEVEE_lights_update(sldata, vedata);
EEVEE_draw_shadows(sldata, vedata);
/* Set ray type. */
sldata->common_data.ray_type = EEVEE_RAY_CAMERA;
sldata->common_data.ray_depth = 0.0f;
DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
GPU_framebuffer_bind(fbl->main_fb);
GPU_framebuffer_clear_color_depth_stencil(fbl->main_fb, clear_col, clear_depth, clear_stencil);
/* Depth prepass */

View File

@ -38,8 +38,16 @@ layout(std140) uniform common_block {
float prbLodPlanarMax;
/* Misc*/
int hizMipOffset;
int rayType;
float rayDepth;
};
/* rayType (keep in sync with ray_type) */
#define EEVEE_RAY_CAMERA 0
#define EEVEE_RAY_SHADOW 1
#define EEVEE_RAY_DIFFUSE 2
#define EEVEE_RAY_GLOSSY 3
/* aoParameters */
#define aoDistance aoParameters[0].x
#define aoSamples aoParameters[0].y /* UNUSED */

View File

@ -2896,27 +2896,22 @@ void node_light_path(
out float transparent_depth,
out float transmission_depth)
{
#ifndef PROBE_CAPTURE
is_camera_ray = 1.0;
is_glossy_ray = 0.0;
is_diffuse_ray = 0.0;
is_reflection_ray = 0.0;
is_transmission_ray = 0.0;
#else
is_camera_ray = 0.0;
is_glossy_ray = 1.0;
is_diffuse_ray = 1.0;
is_reflection_ray = 1.0;
is_transmission_ray = 1.0;
#endif
is_shadow_ray = 0.0;
is_singular_ray = 0.0;
/* Supported. */
is_camera_ray = (rayType == EEVEE_RAY_CAMERA) ? 1.0 : 0.0;
is_shadow_ray = (rayType == EEVEE_RAY_SHADOW) ? 1.0 : 0.0;
is_diffuse_ray = (rayType == EEVEE_RAY_DIFFUSE) ? 1.0 : 0.0;
is_glossy_ray = (rayType == EEVEE_RAY_GLOSSY) ? 1.0 : 0.0;
/* Kind of supported. */
is_singular_ray = is_glossy_ray;
is_reflection_ray = is_glossy_ray;
is_transmission_ray = is_glossy_ray;
ray_depth = rayDepth;
diffuse_depth = (is_diffuse_ray == 1.0) ? rayDepth : 0.0;
glossy_depth = (is_glossy_ray == 1.0) ? rayDepth : 0.0;
transmission_depth = (is_transmission_ray == 1.0) ? glossy_depth : 0.0;
/* Not supported. */
ray_length = 1.0;
ray_depth = 1.0;
diffuse_depth = 1.0;
glossy_depth = 1.0;
transparent_depth = 1.0;
transmission_depth = 1.0;
transparent_depth = 0.0;
}
void node_light_falloff(float strength, float tsmooth, out float quadratic, out float linear, out float constant)