Eevee: SSR: Output ssr datas to buffers.
Output in 2 buffers Normals, Specular Color and roughness. This way we can raytrace in a defered fashion and blend the exact contribution of the specular lobe on top of the opaque pass.
This commit is contained in:
@@ -710,6 +710,24 @@ class RENDER_PT_eevee_volumetric(RenderButtonsPanel, Panel):
|
||||
col.prop(props, "volumetric_colored_transmittance")
|
||||
|
||||
|
||||
class RENDER_PT_eevee_shading(RenderButtonsPanel, Panel):
|
||||
bl_label = "Shading"
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
scene = context.scene
|
||||
return scene and (scene.render.engine in cls.COMPAT_ENGINES)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
scene = context.scene
|
||||
props = scene.layer_properties['BLENDER_EEVEE']
|
||||
|
||||
col = layout.column()
|
||||
col.prop(props, "ssr_enable")
|
||||
|
||||
|
||||
classes = (
|
||||
RENDER_MT_presets,
|
||||
RENDER_MT_ffmpeg_presets,
|
||||
@@ -730,6 +748,7 @@ classes = (
|
||||
RENDER_PT_eevee_poststack_settings,
|
||||
RENDER_PT_eevee_postprocess_settings,
|
||||
RENDER_PT_eevee_volumetric,
|
||||
RENDER_PT_eevee_shading,
|
||||
)
|
||||
|
||||
if __name__ == "__main__": # only for live edit.
|
||||
|
||||
@@ -250,6 +250,26 @@ class RENDERLAYER_PT_eevee_volumetric(RenderLayerButtonsPanel, Panel):
|
||||
col.template_override_property(layer_props, scene_props, "volumetric_colored_transmittance")
|
||||
|
||||
|
||||
class RENDERLAYER_PT_eevee_shading(RenderLayerButtonsPanel, Panel):
|
||||
bl_label = "Shading"
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
scene = context.scene
|
||||
return scene and (scene.render.engine in cls.COMPAT_ENGINES)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
scene = context.scene
|
||||
scene_props = scene.layer_properties['BLENDER_EEVEE']
|
||||
layer = bpy.context.render_layer
|
||||
layer_props = layer.engine_overrides['BLENDER_EEVEE']
|
||||
|
||||
col = layout.column()
|
||||
col.template_override_property(layer_props, scene_props, "ssr_enable")
|
||||
|
||||
|
||||
classes = (
|
||||
RENDERLAYER_UL_renderlayers,
|
||||
RENDERLAYER_PT_layers,
|
||||
@@ -258,6 +278,7 @@ classes = (
|
||||
RENDERLAYER_PT_clay_settings,
|
||||
RENDERLAYER_PT_eevee_poststack_settings,
|
||||
RENDERLAYER_PT_eevee_postprocess_settings,
|
||||
RENDERLAYER_PT_eevee_shading,
|
||||
RENDERLAYER_PT_eevee_volumetric,
|
||||
)
|
||||
|
||||
|
||||
@@ -139,6 +139,7 @@ data_to_c_simple(engines/eevee/shaders/effect_dof_vert.glsl SRC)
|
||||
data_to_c_simple(engines/eevee/shaders/effect_dof_geom.glsl SRC)
|
||||
data_to_c_simple(engines/eevee/shaders/effect_dof_frag.glsl SRC)
|
||||
data_to_c_simple(engines/eevee/shaders/effect_motion_blur_frag.glsl SRC)
|
||||
data_to_c_simple(engines/eevee/shaders/effect_ssr_frag.glsl SRC)
|
||||
data_to_c_simple(engines/eevee/shaders/lightprobe_planar_downsample_frag.glsl SRC)
|
||||
data_to_c_simple(engines/eevee/shaders/lightprobe_planar_downsample_geom.glsl SRC)
|
||||
data_to_c_simple(engines/eevee/shaders/lightprobe_planar_downsample_vert.glsl SRC)
|
||||
|
||||
@@ -73,9 +73,14 @@ static struct {
|
||||
/* Volumetric */
|
||||
struct GPUShader *volumetric_upsample_sh;
|
||||
|
||||
/* Screen Space Reflection */
|
||||
struct GPUShader *ssr_raytrace_sh;
|
||||
struct GPUShader *ssr_resolve_sh;
|
||||
|
||||
struct GPUTexture *depth_src;
|
||||
} e_data = {NULL}; /* Engine data */
|
||||
|
||||
extern char datatoc_effect_ssr_frag_glsl[];
|
||||
extern char datatoc_effect_minmaxz_frag_glsl[];
|
||||
extern char datatoc_effect_motion_blur_frag_glsl[];
|
||||
extern char datatoc_effect_bloom_frag_glsl[];
|
||||
@@ -158,6 +163,9 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
|
||||
|
||||
/* Shaders */
|
||||
if (!e_data.motion_blur_sh) {
|
||||
e_data.ssr_raytrace_sh = DRW_shader_create_fullscreen(datatoc_effect_ssr_frag_glsl, "#define STEP_RAYTRACE\n");
|
||||
e_data.ssr_resolve_sh = DRW_shader_create_fullscreen(datatoc_effect_ssr_frag_glsl, "#define STEP_RESOLVE\n");
|
||||
|
||||
e_data.volumetric_upsample_sh = DRW_shader_create_fullscreen(datatoc_volumetric_frag_glsl, "#define STEP_UPSAMPLE\n");
|
||||
|
||||
e_data.minmaxz_downlevel_sh = DRW_shader_create_fullscreen(datatoc_effect_minmaxz_frag_glsl, NULL);
|
||||
@@ -478,6 +486,43 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (BKE_collection_engine_property_value_get_bool(props, "ssr_enable")) {
|
||||
effects->enabled_effects |= EFFECT_SSR;
|
||||
|
||||
int tracing_res[2] = {(int)viewport_size[0] / 2, (int)viewport_size[1] / 2};
|
||||
const bool record_two_hit = false;
|
||||
const bool high_qual_input = true; /* TODO dither low quality input */
|
||||
|
||||
/* MRT for the shading pass in order to output needed data for the SSR pass. */
|
||||
/* TODO create one texture layer per lobe */
|
||||
if (txl->ssr_normal_input == NULL) {
|
||||
DRWTextureFormat nor_format = DRW_TEX_RG_16;
|
||||
txl->ssr_normal_input = DRW_texture_create_2D((int)viewport_size[0], (int)viewport_size[1], nor_format, 0, NULL);
|
||||
DRW_framebuffer_texture_attach(fbl->main, txl->ssr_normal_input, 1, 0);
|
||||
}
|
||||
|
||||
if (txl->ssr_specrough_input == NULL) {
|
||||
DRWTextureFormat specrough_format = (high_qual_input) ? DRW_TEX_RGBA_16 : DRW_TEX_RGBA_8;
|
||||
txl->ssr_specrough_input = DRW_texture_create_2D((int)viewport_size[0], (int)viewport_size[1], specrough_format, 0, NULL);
|
||||
DRW_framebuffer_texture_attach(fbl->main, txl->ssr_specrough_input, 2, 0);
|
||||
}
|
||||
|
||||
/* Raytracing output */
|
||||
/* TODO try integer format for hit coord to increase precision */
|
||||
DRWFboTexture tex_output[2] = {{&txl->ssr_hit_output, (record_two_hit) ? DRW_TEX_RGBA_16 : DRW_TEX_RG_16, 0},
|
||||
{&txl->ssr_pdf_output, (record_two_hit) ? DRW_TEX_RG_16 : DRW_TEX_R_16, 0}};
|
||||
|
||||
DRW_framebuffer_init(&fbl->screen_tracing_fb, &draw_engine_eevee_type, tracing_res[0], tracing_res[1], tex_output, 2);
|
||||
}
|
||||
else {
|
||||
/* Cleanup to release memory */
|
||||
DRW_TEXTURE_FREE_SAFE(txl->ssr_normal_input);
|
||||
DRW_TEXTURE_FREE_SAFE(txl->ssr_specrough_input);
|
||||
DRW_TEXTURE_FREE_SAFE(txl->ssr_hit_output);
|
||||
DRW_TEXTURE_FREE_SAFE(txl->ssr_pdf_output);
|
||||
DRW_FRAMEBUFFER_FREE_SAFE(fbl->screen_tracing_fb);
|
||||
}
|
||||
}
|
||||
|
||||
static DRWShadingGroup *eevee_create_bloom_pass(const char *name, EEVEE_EffectsInfo *effects, struct GPUShader *sh, DRWPass **pass, bool upsample)
|
||||
@@ -566,6 +611,24 @@ void EEVEE_effects_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
|
||||
}
|
||||
}
|
||||
|
||||
if ((effects->enabled_effects & EFFECT_SSR) != 0) {
|
||||
psl->ssr_raytrace = DRW_pass_create("Raytrace", DRW_STATE_WRITE_COLOR);
|
||||
DRWShadingGroup *grp = DRW_shgroup_create(e_data.ssr_raytrace_sh, psl->ssr_raytrace);
|
||||
DRW_shgroup_uniform_buffer(grp, "depthBuffer", &e_data.depth_src);
|
||||
DRW_shgroup_uniform_buffer(grp, "normalBuffer", &stl->g_data->minmaxz);
|
||||
DRW_shgroup_uniform_buffer(grp, "specRoughBuffer", &stl->g_data->minmaxz);
|
||||
DRW_shgroup_call_add(grp, quad, NULL);
|
||||
|
||||
psl->ssr_resolve = DRW_pass_create("Raytrace", DRW_STATE_WRITE_COLOR);
|
||||
grp = DRW_shgroup_create(e_data.ssr_resolve_sh, psl->ssr_resolve);
|
||||
DRW_shgroup_uniform_buffer(grp, "depthBuffer", &e_data.depth_src);
|
||||
DRW_shgroup_uniform_buffer(grp, "normalBuffer", &txl->ssr_normal_input);
|
||||
DRW_shgroup_uniform_buffer(grp, "specroughBuffer", &txl->ssr_specrough_input);
|
||||
DRW_shgroup_uniform_buffer(grp, "hitBuffer", &txl->ssr_hit_output);
|
||||
DRW_shgroup_uniform_buffer(grp, "pdfBuffer", &txl->ssr_pdf_output);
|
||||
DRW_shgroup_call_add(grp, quad, NULL);
|
||||
}
|
||||
|
||||
{
|
||||
psl->minmaxz_downlevel = DRW_pass_create("HiZ Down Level", DRW_STATE_WRITE_COLOR);
|
||||
DRWShadingGroup *grp = DRW_shgroup_create(e_data.minmaxz_downlevel_sh, psl->minmaxz_downlevel);
|
||||
@@ -726,6 +789,7 @@ void EEVEE_effects_do_volumetrics(EEVEE_SceneLayerData *sldata, EEVEE_Data *veda
|
||||
EEVEE_EffectsInfo *effects = stl->effects;
|
||||
|
||||
if ((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) {
|
||||
return;
|
||||
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
|
||||
|
||||
e_data.depth_src = dtxl->depth;
|
||||
@@ -758,6 +822,35 @@ void EEVEE_effects_do_volumetrics(EEVEE_SceneLayerData *sldata, EEVEE_Data *veda
|
||||
}
|
||||
}
|
||||
|
||||
void EEVEE_effects_do_ssr(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
|
||||
{
|
||||
EEVEE_PassList *psl = vedata->psl;
|
||||
EEVEE_FramebufferList *fbl = vedata->fbl;
|
||||
EEVEE_StorageList *stl = vedata->stl;
|
||||
EEVEE_TextureList *txl = vedata->txl;
|
||||
EEVEE_EffectsInfo *effects = stl->effects;
|
||||
|
||||
if ((effects->enabled_effects & EFFECT_SSR) != 0) {
|
||||
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
|
||||
|
||||
/* Raytrace at halfres. */
|
||||
DRW_framebuffer_bind(fbl->screen_tracing_fb);
|
||||
DRW_draw_pass(psl->ssr_raytrace);
|
||||
|
||||
/* Resolve at fullres */
|
||||
DRW_framebuffer_texture_detach(dtxl->depth);
|
||||
DRW_framebuffer_texture_detach(txl->ssr_normal_input);
|
||||
DRW_framebuffer_texture_detach(txl->ssr_specrough_input);
|
||||
DRW_framebuffer_bind(fbl->main);
|
||||
DRW_draw_pass(psl->ssr_resolve);
|
||||
|
||||
/* Restore */
|
||||
DRW_framebuffer_texture_attach(fbl->main, dtxl->depth, 0, 0);
|
||||
DRW_framebuffer_texture_attach(fbl->main, txl->ssr_normal_input, 1, 0);
|
||||
DRW_framebuffer_texture_attach(fbl->main, txl->ssr_specrough_input, 2, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void EEVEE_draw_effects(EEVEE_Data *vedata)
|
||||
{
|
||||
EEVEE_PassList *psl = vedata->psl;
|
||||
@@ -881,6 +974,9 @@ void EEVEE_draw_effects(EEVEE_Data *vedata)
|
||||
|
||||
void EEVEE_effects_free(void)
|
||||
{
|
||||
DRW_SHADER_FREE_SAFE(e_data.ssr_raytrace_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.ssr_resolve_sh);
|
||||
|
||||
DRW_SHADER_FREE_SAFE(e_data.volumetric_upsample_sh);
|
||||
|
||||
DRW_SHADER_FREE_SAFE(e_data.minmaxz_downlevel_sh);
|
||||
|
||||
@@ -155,6 +155,7 @@ static void EEVEE_draw_scene(void *vedata)
|
||||
DRW_framebuffer_bind(fbl->main);
|
||||
DRW_framebuffer_clear(false, true, false, NULL, 1.0f);
|
||||
|
||||
/* TODO move background after depth pass to cut some overdraw */
|
||||
DRW_draw_pass(psl->background_pass);
|
||||
|
||||
/* Depth prepass */
|
||||
@@ -172,6 +173,9 @@ static void EEVEE_draw_scene(void *vedata)
|
||||
EEVEE_draw_default_passes(psl);
|
||||
DRW_draw_pass(psl->material_pass);
|
||||
|
||||
/* Screen Space Reflections */
|
||||
EEVEE_effects_do_ssr(sldata, vedata);
|
||||
|
||||
/* Volumetrics */
|
||||
EEVEE_effects_do_volumetrics(sldata, vedata);
|
||||
|
||||
@@ -206,6 +210,8 @@ static void EEVEE_scene_layer_settings_create(RenderEngine *UNUSED(engine), IDPr
|
||||
props->type == IDP_GROUP &&
|
||||
props->subtype == IDP_GROUP_SUB_ENGINE_RENDER);
|
||||
|
||||
BKE_collection_engine_property_add_bool(props, "ssr_enable", false);
|
||||
|
||||
BKE_collection_engine_property_add_bool(props, "volumetric_enable", false);
|
||||
BKE_collection_engine_property_add_float(props, "volumetric_start", 0.1f);
|
||||
BKE_collection_engine_property_add_float(props, "volumetric_end", 100.0f);
|
||||
|
||||
@@ -253,8 +253,15 @@ static char *eevee_get_volume_defines(int options)
|
||||
return str;
|
||||
}
|
||||
|
||||
static void add_standard_uniforms(DRWShadingGroup *shgrp, EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
|
||||
/**
|
||||
* ssr_id can be null to disable ssr contribution.
|
||||
**/
|
||||
static void add_standard_uniforms(DRWShadingGroup *shgrp, EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata, int *ssr_id)
|
||||
{
|
||||
if (ssr_id == NULL) {
|
||||
static int no_ssr = -1.0f;
|
||||
ssr_id = &no_ssr;
|
||||
}
|
||||
DRW_shgroup_uniform_block(shgrp, "probe_block", sldata->probe_ubo);
|
||||
DRW_shgroup_uniform_block(shgrp, "grid_block", sldata->grid_ubo);
|
||||
DRW_shgroup_uniform_block(shgrp, "planar_block", sldata->planar_ubo);
|
||||
@@ -273,6 +280,7 @@ static void add_standard_uniforms(DRWShadingGroup *shgrp, EEVEE_SceneLayerData *
|
||||
DRW_shgroup_uniform_buffer(shgrp, "irradianceGrid", &sldata->irradiance_pool);
|
||||
DRW_shgroup_uniform_buffer(shgrp, "shadowCubes", &sldata->shadow_depth_cube_pool);
|
||||
DRW_shgroup_uniform_buffer(shgrp, "shadowCascades", &sldata->shadow_depth_cascade_pool);
|
||||
DRW_shgroup_uniform_int(shgrp, "outputSsrId", ssr_id, 1);
|
||||
if (vedata->stl->effects->use_ao) {
|
||||
DRW_shgroup_uniform_vec4(shgrp, "viewvecs[0]", (float *)&vedata->stl->g_data->viewvecs, 2);
|
||||
DRW_shgroup_uniform_buffer(shgrp, "minMaxDepthTex", &vedata->stl->g_data->minmaxz);
|
||||
@@ -583,8 +591,10 @@ struct GPUMaterial *EEVEE_material_hair_get(
|
||||
**/
|
||||
static struct DRWShadingGroup *EEVEE_default_shading_group_create(
|
||||
EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata, DRWPass *pass,
|
||||
bool is_hair, bool is_flat_normal, bool use_ao, bool use_bent_normals, bool use_blend)
|
||||
bool is_hair, bool is_flat_normal, bool use_ao, bool use_bent_normals, bool use_blend, bool use_ssr)
|
||||
{
|
||||
static int ssr_id;
|
||||
ssr_id = (use_ssr) ? 0 : -1;
|
||||
int options = VAR_MAT_MESH;
|
||||
|
||||
if (is_hair) options |= VAR_MAT_HAIR;
|
||||
@@ -598,7 +608,7 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_create(
|
||||
}
|
||||
|
||||
DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.default_lit[options], pass);
|
||||
add_standard_uniforms(shgrp, sldata, vedata);
|
||||
add_standard_uniforms(shgrp, sldata, vedata, &ssr_id);
|
||||
|
||||
return shgrp;
|
||||
}
|
||||
@@ -608,8 +618,10 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_create(
|
||||
**/
|
||||
static struct DRWShadingGroup *EEVEE_default_shading_group_get(
|
||||
EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata,
|
||||
bool is_hair, bool is_flat_normal, bool use_ao, bool use_bent_normals)
|
||||
bool is_hair, bool is_flat_normal, bool use_ao, bool use_bent_normals, bool use_ssr)
|
||||
{
|
||||
static int ssr_id;
|
||||
ssr_id = (use_ssr) ? 0 : -1;
|
||||
int options = VAR_MAT_MESH;
|
||||
|
||||
if (is_hair) options |= VAR_MAT_HAIR;
|
||||
@@ -626,7 +638,7 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_get(
|
||||
vedata->psl->default_pass[options] = DRW_pass_create("Default Lit Pass", state);
|
||||
|
||||
DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.default_lit[options], vedata->psl->default_pass[options]);
|
||||
add_standard_uniforms(shgrp, sldata, vedata);
|
||||
add_standard_uniforms(shgrp, sldata, vedata, &ssr_id);
|
||||
}
|
||||
|
||||
return DRW_shgroup_create(e_data.default_lit[options], vedata->psl->default_pass[options]);
|
||||
@@ -638,12 +650,14 @@ void EEVEE_materials_cache_init(EEVEE_Data *vedata)
|
||||
EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
|
||||
|
||||
{
|
||||
/* Global AO Switch*/
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
SceneLayer *scene_layer = draw_ctx->scene_layer;
|
||||
IDProperty *props = BKE_scene_layer_engine_evaluated_get(scene_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE);
|
||||
/* Global AO Switch*/
|
||||
stl->effects->use_ao = BKE_collection_engine_property_value_get_bool(props, "gtao_enable");
|
||||
stl->effects->use_bent_normals = BKE_collection_engine_property_value_get_bool(props, "gtao_use_bent_normals");
|
||||
/* SSR switch */
|
||||
stl->effects->use_ssr = BKE_collection_engine_property_value_get_bool(props, "ssr_enable");
|
||||
}
|
||||
|
||||
/* Create Material Ghash */
|
||||
@@ -781,7 +795,9 @@ static void material_opaque(
|
||||
|
||||
*shgrp = DRW_shgroup_material_create(*gpumat, psl->material_pass);
|
||||
if (*shgrp) {
|
||||
add_standard_uniforms(*shgrp, sldata, vedata);
|
||||
static int ssr_id;
|
||||
ssr_id = (stl->effects->use_ssr) ? 0 : -1;
|
||||
add_standard_uniforms(*shgrp, sldata, vedata, &ssr_id);
|
||||
}
|
||||
else {
|
||||
/* Shader failed : pink color */
|
||||
@@ -813,7 +829,7 @@ static void material_opaque(
|
||||
/* Fallback to default shader */
|
||||
if (*shgrp == NULL) {
|
||||
*shgrp = EEVEE_default_shading_group_get(sldata, vedata, false, use_flat_nor,
|
||||
stl->effects->use_ao, stl->effects->use_bent_normals);
|
||||
stl->effects->use_ao, stl->effects->use_bent_normals, stl->effects->use_ssr);
|
||||
DRW_shgroup_uniform_vec3(*shgrp, "basecol", color_p, 1);
|
||||
DRW_shgroup_uniform_float(*shgrp, "metallic", metal_p, 1);
|
||||
DRW_shgroup_uniform_float(*shgrp, "specular", spec_p, 1);
|
||||
@@ -855,7 +871,8 @@ static void material_transparent(
|
||||
|
||||
*shgrp = DRW_shgroup_material_create(*gpumat, psl->transparent_pass);
|
||||
if (*shgrp) {
|
||||
add_standard_uniforms(*shgrp, sldata, vedata);
|
||||
static int ssr_id = -1; /* TODO transparent SSR */
|
||||
add_standard_uniforms(*shgrp, sldata, vedata, &ssr_id);
|
||||
}
|
||||
else {
|
||||
/* Shader failed : pink color */
|
||||
@@ -871,7 +888,7 @@ static void material_transparent(
|
||||
if (*shgrp == NULL) {
|
||||
*shgrp = EEVEE_default_shading_group_create(
|
||||
sldata, vedata, psl->transparent_pass,
|
||||
false, use_flat_nor, stl->effects->use_ao, stl->effects->use_bent_normals, true);
|
||||
false, use_flat_nor, stl->effects->use_ao, stl->effects->use_bent_normals, true, false);
|
||||
DRW_shgroup_uniform_vec3(*shgrp, "basecol", color_p, 1);
|
||||
DRW_shgroup_uniform_float(*shgrp, "metallic", metal_p, 1);
|
||||
DRW_shgroup_uniform_float(*shgrp, "specular", spec_p, 1);
|
||||
@@ -1089,7 +1106,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl
|
||||
|
||||
shgrp = DRW_shgroup_material_create(gpumat, psl->material_pass);
|
||||
if (shgrp) {
|
||||
add_standard_uniforms(shgrp, sldata, vedata);
|
||||
add_standard_uniforms(shgrp, sldata, vedata, NULL);
|
||||
|
||||
BLI_ghash_insert(material_hash, ma, shgrp);
|
||||
|
||||
@@ -1108,7 +1125,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl
|
||||
/* Fallback to default shader */
|
||||
if (shgrp == NULL) {
|
||||
shgrp = EEVEE_default_shading_group_get(sldata, vedata, true, false,
|
||||
stl->effects->use_ao, stl->effects->use_bent_normals);
|
||||
stl->effects->use_ao, stl->effects->use_bent_normals, stl->effects->use_ssr);
|
||||
DRW_shgroup_uniform_vec3(shgrp, "basecol", color_p, 1);
|
||||
DRW_shgroup_uniform_float(shgrp, "metallic", metal_p, 1);
|
||||
DRW_shgroup_uniform_float(shgrp, "specular", spec_p, 1);
|
||||
|
||||
@@ -109,6 +109,8 @@ typedef struct EEVEE_PassList {
|
||||
struct DRWPass *volumetric_integrate_ps;
|
||||
struct DRWPass *volumetric_resolve_ps;
|
||||
struct DRWPass *volumetric_resolve_transmit_ps;
|
||||
struct DRWPass *ssr_raytrace;
|
||||
struct DRWPass *ssr_resolve;
|
||||
|
||||
struct DRWPass *depth_pass;
|
||||
struct DRWPass *depth_pass_cull;
|
||||
@@ -131,6 +133,7 @@ typedef struct EEVEE_FramebufferList {
|
||||
struct GPUFrameBuffer *dof_scatter_far_fb;
|
||||
struct GPUFrameBuffer *dof_scatter_near_fb;
|
||||
struct GPUFrameBuffer *volumetric_fb;
|
||||
struct GPUFrameBuffer *screen_tracing_fb;
|
||||
|
||||
struct GPUFrameBuffer *planarref_fb;
|
||||
|
||||
@@ -149,6 +152,11 @@ typedef struct EEVEE_TextureList {
|
||||
struct GPUTexture *bloom_downsample[MAX_BLOOM_STEP]; /* R16_G16_B16 */
|
||||
struct GPUTexture *bloom_upsample[MAX_BLOOM_STEP-1]; /* R16_G16_B16 */
|
||||
|
||||
struct GPUTexture *ssr_normal_input;
|
||||
struct GPUTexture *ssr_specrough_input;
|
||||
struct GPUTexture *ssr_hit_output;
|
||||
struct GPUTexture *ssr_pdf_output;
|
||||
|
||||
struct GPUTexture *planar_pool;
|
||||
|
||||
struct GPUTexture *color; /* R16_G16_B16 */
|
||||
@@ -300,6 +308,9 @@ enum {
|
||||
typedef struct EEVEE_EffectsInfo {
|
||||
int enabled_effects;
|
||||
|
||||
/* SSR */
|
||||
bool use_ssr;
|
||||
|
||||
/* Ambient Occlusion */
|
||||
bool use_ao, use_bent_normals;
|
||||
float ao_dist, ao_samples, ao_factor;
|
||||
@@ -339,6 +350,7 @@ enum {
|
||||
EFFECT_BLOOM = (1 << 1),
|
||||
EFFECT_DOF = (1 << 2),
|
||||
EFFECT_VOLUMETRIC = (1 << 3),
|
||||
EFFECT_SSR = (1 << 4),
|
||||
};
|
||||
|
||||
/* ************** SCENE LAYER DATA ************** */
|
||||
@@ -486,6 +498,7 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata);
|
||||
void EEVEE_effects_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata);
|
||||
void EEVEE_create_minmax_buffer(EEVEE_Data *vedata, struct GPUTexture *depth_src);
|
||||
void EEVEE_effects_do_volumetrics(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata);
|
||||
void EEVEE_effects_do_ssr(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata);
|
||||
void EEVEE_draw_effects(EEVEE_Data *vedata);
|
||||
void EEVEE_effects_free(void);
|
||||
|
||||
|
||||
@@ -66,13 +66,28 @@ Closure closure_add(Closure cl1, Closure cl2)
|
||||
struct Closure {
|
||||
vec3 radiance;
|
||||
float opacity;
|
||||
vec4 ssr_data;
|
||||
vec2 ssr_normal;
|
||||
int ssr_id;
|
||||
};
|
||||
|
||||
#define CLOSURE_DEFAULT Closure(vec3(0.0), 1.0)
|
||||
#define CLOSURE_DEFAULT Closure(vec3(0.0), 1.0, vec4(0.0), vec2(0.0), -1)
|
||||
|
||||
uniform int outputSsrId;
|
||||
|
||||
Closure closure_mix(Closure cl1, Closure cl2, float fac)
|
||||
{
|
||||
Closure cl;
|
||||
if (cl1.ssr_id == outputSsrId) {
|
||||
cl.ssr_data = mix(cl1.ssr_data.xyzw, vec4(vec3(0.0), cl1.ssr_data.w), fac); /* do not blend roughness */
|
||||
cl.ssr_normal = cl1.ssr_normal;
|
||||
cl.ssr_id = cl1.ssr_id;
|
||||
}
|
||||
else {
|
||||
cl.ssr_data = mix(vec4(vec3(0.0), cl2.ssr_data.w), cl2.ssr_data.xyzw, fac); /* do not blend roughness */
|
||||
cl.ssr_normal = cl2.ssr_normal;
|
||||
cl.ssr_id = cl2.ssr_id;
|
||||
}
|
||||
cl.radiance = mix(cl1.radiance, cl2.radiance, fac);
|
||||
cl.opacity = mix(cl1.opacity, cl2.opacity, fac);
|
||||
return cl;
|
||||
@@ -80,12 +95,30 @@ Closure closure_mix(Closure cl1, Closure cl2, float fac)
|
||||
|
||||
Closure closure_add(Closure cl1, Closure cl2)
|
||||
{
|
||||
Closure cl;
|
||||
Closure cl = (cl1.ssr_id == outputSsrId) ? cl1 : cl2;
|
||||
cl.radiance = cl1.radiance + cl2.radiance;
|
||||
cl.opacity = cl1.opacity + cl2.opacity;
|
||||
return cl;
|
||||
}
|
||||
|
||||
#if defined(MESH_SHADER) && !defined(SHADOW_SHADER)
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
layout(location = 1) out vec4 ssrNormals;
|
||||
layout(location = 2) out vec4 ssrData;
|
||||
|
||||
Closure nodetree_exec(void); /* Prototype */
|
||||
|
||||
#define NODETREE_EXEC
|
||||
void main()
|
||||
{
|
||||
Closure cl = nodetree_exec();
|
||||
fragColor = vec4(cl.radiance, cl.opacity);
|
||||
ssrNormals = cl.ssr_normal.xyyy;
|
||||
ssrData = cl.ssr_data;
|
||||
}
|
||||
|
||||
#endif /* MESH_SHADER && !SHADOW_SHADER */
|
||||
|
||||
#endif /* VOLUMETRICS */
|
||||
|
||||
Closure nodetree_exec(void); /* Prototype */
|
||||
@@ -101,7 +134,6 @@ void main()
|
||||
Closure cl = nodetree_exec();
|
||||
fragColor = vec4(mix(vec3(1.0), cl.radiance, cl.opacity), 1.0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
struct LightData {
|
||||
|
||||
@@ -4,17 +4,19 @@ uniform float metallic;
|
||||
uniform float specular;
|
||||
uniform float roughness;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
Closure nodetree_exec(void)
|
||||
{
|
||||
vec3 dielectric = vec3(0.034) * specular * 2.0;
|
||||
vec3 diffuse = mix(basecol, vec3(0.0), metallic);
|
||||
vec3 f0 = mix(dielectric, basecol, metallic);
|
||||
vec3 radiance = eevee_surface_lit((gl_FrontFacing) ? worldNormal : -worldNormal, diffuse, f0, roughness, 1.0);
|
||||
#if defined(USE_ALPHA_BLEND)
|
||||
FragColor = vec4(radiance, 1.0);
|
||||
#else
|
||||
FragColor = vec4(radiance, length(viewPosition));
|
||||
vec3 ssr_spec;
|
||||
vec3 radiance = eevee_surface_lit((gl_FrontFacing) ? worldNormal : -worldNormal, diffuse, f0, roughness, 1.0, 0, ssr_spec);
|
||||
|
||||
Closure result = Closure(radiance, 1.0, vec4(ssr_spec, roughness), viewNormal.xy, 0);
|
||||
|
||||
#if !defined(USE_ALPHA_BLEND)
|
||||
result.opacity = length(viewPosition);
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
|
||||
#ifdef STEP_RAYTRACE
|
||||
|
||||
uniform sampler2D depthBuffer;
|
||||
uniform sampler2D normalBuffer;
|
||||
uniform sampler2D specroughBuffer;
|
||||
|
||||
layout(location = 0) out vec4 hitData;
|
||||
layout(location = 1) out vec4 pdfData;
|
||||
|
||||
void main()
|
||||
{
|
||||
hitData = vec4(0.2);
|
||||
pdfData = vec4(0.5);
|
||||
}
|
||||
|
||||
#else /* STEP_RESOLVE */
|
||||
|
||||
uniform sampler2D depthBuffer;
|
||||
uniform sampler2D normalBuffer;
|
||||
uniform sampler2D specroughBuffer;
|
||||
|
||||
uniform sampler2D hitBuffer;
|
||||
uniform sampler2D pdfBuffer;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 halfres_texel = ivec2(gl_FragCoord.xy / 2.0);
|
||||
ivec2 fullres_texel = ivec2(gl_FragCoord.xy);
|
||||
|
||||
fragColor = vec4(texelFetch(specroughBuffer, fullres_texel, 0).aaa, 1.0);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -24,7 +24,7 @@ in vec3 viewNormal;
|
||||
|
||||
/* ----------- default ----------- */
|
||||
|
||||
vec3 eevee_surface_lit(vec3 N, vec3 albedo, vec3 f0, float roughness, float ao, float ssr_id)
|
||||
vec3 eevee_surface_lit(vec3 N, vec3 albedo, vec3 f0, float roughness, float ao, int ssr_id, out vec3 ssr_spec)
|
||||
{
|
||||
/* Zero length vectors cause issues, see: T51979. */
|
||||
#if 0
|
||||
@@ -89,37 +89,40 @@ vec3 eevee_surface_lit(vec3 N, vec3 albedo, vec3 f0, float roughness, float ao,
|
||||
/* Accumulate light from all sources until accumulator is full. Then apply Occlusion and BRDF. */
|
||||
vec4 spec_accum = vec4(0.0);
|
||||
|
||||
/* Planar Reflections */
|
||||
for (int i = 0; i < MAX_PLANAR && i < planar_count && spec_accum.a < 0.999; ++i) {
|
||||
PlanarData pd = planars_data[i];
|
||||
/* SSR lobe is applied later in a defered style */
|
||||
if (ssr_id != outputSsrId) {
|
||||
/* Planar Reflections */
|
||||
for (int i = 0; i < MAX_PLANAR && i < planar_count && spec_accum.a < 0.999; ++i) {
|
||||
PlanarData pd = planars_data[i];
|
||||
|
||||
float fade = probe_attenuation_planar(pd, worldPosition, N);
|
||||
float fade = probe_attenuation_planar(pd, worldPosition, N);
|
||||
|
||||
if (fade > 0.0) {
|
||||
vec3 spec = probe_evaluate_planar(float(i), pd, worldPosition, N, V, rand.r, cameraPos, roughness, fade);
|
||||
accumulate_light(spec, fade, spec_accum);
|
||||
if (fade > 0.0) {
|
||||
vec3 spec = probe_evaluate_planar(float(i), pd, worldPosition, N, V, rand.r, cameraPos, roughness, fade);
|
||||
accumulate_light(spec, fade, spec_accum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Specular probes */
|
||||
vec3 spec_dir = get_specular_dominant_dir(N, V, roughnessSquared);
|
||||
/* Specular probes */
|
||||
vec3 spec_dir = get_specular_dominant_dir(N, V, roughnessSquared);
|
||||
|
||||
/* Starts at 1 because 0 is world probe */
|
||||
for (int i = 1; i < MAX_PROBE && i < probe_count && spec_accum.a < 0.999; ++i) {
|
||||
CubeData cd = probes_data[i];
|
||||
/* Starts at 1 because 0 is world probe */
|
||||
for (int i = 1; i < MAX_PROBE && i < probe_count && spec_accum.a < 0.999; ++i) {
|
||||
CubeData cd = probes_data[i];
|
||||
|
||||
float fade = probe_attenuation_cube(cd, worldPosition);
|
||||
float fade = probe_attenuation_cube(cd, worldPosition);
|
||||
|
||||
if (fade > 0.0) {
|
||||
vec3 spec = probe_evaluate_cube(float(i), cd, worldPosition, spec_dir, roughness);
|
||||
accumulate_light(spec, fade, spec_accum);
|
||||
if (fade > 0.0) {
|
||||
vec3 spec = probe_evaluate_cube(float(i), cd, worldPosition, spec_dir, roughness);
|
||||
accumulate_light(spec, fade, spec_accum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* World Specular */
|
||||
if (spec_accum.a < 0.999) {
|
||||
vec3 spec = probe_evaluate_world_spec(spec_dir, roughness);
|
||||
accumulate_light(spec, 1.0, spec_accum);
|
||||
/* World Specular */
|
||||
if (spec_accum.a < 0.999) {
|
||||
vec3 spec = probe_evaluate_world_spec(spec_dir, roughness);
|
||||
accumulate_light(spec, 1.0, spec_accum);
|
||||
}
|
||||
}
|
||||
|
||||
/* Ambient Occlusion */
|
||||
@@ -130,7 +133,8 @@ vec3 eevee_surface_lit(vec3 N, vec3 albedo, vec3 f0, float roughness, float ao,
|
||||
vec2 uv = lut_coords(dot(N, V), roughness);
|
||||
vec2 brdf_lut = texture(utilTex, vec3(uv, 1.0)).rg;
|
||||
|
||||
out_light += spec_accum.rgb * F_ibl(f0, brdf_lut) * specular_occlusion(dot(N, V), final_ao, roughness) * float(specToggle);
|
||||
ssr_spec = F_ibl(f0, brdf_lut) * specular_occlusion(dot(N, V), final_ao, roughness);
|
||||
out_light += spec_accum.rgb * ssr_spec * float(specToggle);
|
||||
|
||||
/* ---------------- DIFFUSE ENVIRONMENT LIGHTING ----------------- */
|
||||
|
||||
@@ -166,7 +170,7 @@ vec3 eevee_surface_lit(vec3 N, vec3 albedo, vec3 f0, float roughness, float ao,
|
||||
vec3 eevee_surface_clearcoat_lit(
|
||||
vec3 N, vec3 albedo, vec3 f0, float roughness,
|
||||
vec3 C_N, float C_intensity, float C_roughness, /* Clearcoat params */
|
||||
float ao, float ssr_id)
|
||||
float ao, int ssr_id, out vec3 ssr_spec)
|
||||
{
|
||||
roughness = clamp(roughness, 1e-8, 0.9999);
|
||||
float roughnessSquared = roughness * roughness;
|
||||
@@ -233,8 +237,10 @@ vec3 eevee_surface_clearcoat_lit(
|
||||
float fade = probe_attenuation_planar(pd, worldPosition, worldNormal);
|
||||
|
||||
if (fade > 0.0) {
|
||||
vec3 spec = probe_evaluate_planar(float(i), pd, worldPosition, N, V, rand.r, cameraPos, roughness, fade);
|
||||
accumulate_light(spec, fade, spec_accum);
|
||||
if (ssr_id != outputSsrId) {
|
||||
vec3 spec = probe_evaluate_planar(float(i), pd, worldPosition, N, V, rand.r, cameraPos, roughness, fade);
|
||||
accumulate_light(spec, fade, spec_accum);
|
||||
}
|
||||
|
||||
vec3 C_spec = probe_evaluate_planar(float(i), pd, worldPosition, C_N, V, rand.r, cameraPos, C_roughness, fade);
|
||||
accumulate_light(C_spec, fade, C_spec_accum);
|
||||
@@ -252,8 +258,10 @@ vec3 eevee_surface_clearcoat_lit(
|
||||
float fade = probe_attenuation_cube(cd, worldPosition);
|
||||
|
||||
if (fade > 0.0) {
|
||||
vec3 spec = probe_evaluate_cube(float(i), cd, worldPosition, spec_dir, roughness);
|
||||
accumulate_light(spec, fade, spec_accum);
|
||||
if (ssr_id != outputSsrId) {
|
||||
vec3 spec = probe_evaluate_cube(float(i), cd, worldPosition, spec_dir, roughness);
|
||||
accumulate_light(spec, fade, spec_accum);
|
||||
}
|
||||
|
||||
vec3 C_spec = probe_evaluate_cube(float(i), cd, worldPosition, C_spec_dir, C_roughness);
|
||||
accumulate_light(C_spec, fade, C_spec_accum);
|
||||
@@ -262,8 +270,10 @@ vec3 eevee_surface_clearcoat_lit(
|
||||
|
||||
/* World Specular */
|
||||
if (spec_accum.a < 0.999) {
|
||||
vec3 spec = probe_evaluate_world_spec(spec_dir, roughness);
|
||||
accumulate_light(spec, 1.0, spec_accum);
|
||||
if (ssr_id != outputSsrId) {
|
||||
vec3 spec = probe_evaluate_world_spec(spec_dir, roughness);
|
||||
accumulate_light(spec, 1.0, spec_accum);
|
||||
}
|
||||
|
||||
vec3 C_spec = probe_evaluate_world_spec(C_spec_dir, C_roughness);
|
||||
accumulate_light(C_spec, 1.0, C_spec_accum);
|
||||
@@ -277,7 +287,8 @@ vec3 eevee_surface_clearcoat_lit(
|
||||
vec2 uv = lut_coords(dot(N, V), roughness);
|
||||
vec2 brdf_lut = texture(utilTex, vec3(uv, 1.0)).rg;
|
||||
|
||||
out_light += spec_accum.rgb * F_ibl(f0, brdf_lut) * specular_occlusion(dot(N, V), final_ao, roughness) * float(specToggle);
|
||||
ssr_spec = F_ibl(f0, brdf_lut) * specular_occlusion(dot(N, V), final_ao, roughness);
|
||||
out_light += spec_accum.rgb * ssr_spec * float(specToggle);
|
||||
|
||||
uv = lut_coords(dot(C_N, V), C_roughness);
|
||||
brdf_lut = texture(utilTex, vec3(uv, 1.0)).rg;
|
||||
@@ -392,7 +403,7 @@ vec3 eevee_surface_diffuse_lit(vec3 N, vec3 albedo, float ao)
|
||||
|
||||
/* ----------- Glossy ----------- */
|
||||
|
||||
vec3 eevee_surface_glossy_lit(vec3 N, vec3 f0, float roughness, float ao)
|
||||
vec3 eevee_surface_glossy_lit(vec3 N, vec3 f0, float roughness, float ao, int ssr_id, out vec3 ssr_spec)
|
||||
{
|
||||
roughness = clamp(roughness, 1e-8, 0.9999);
|
||||
float roughnessSquared = roughness * roughness;
|
||||
@@ -442,37 +453,39 @@ vec3 eevee_surface_glossy_lit(vec3 N, vec3 f0, float roughness, float ao)
|
||||
/* Accumulate light from all sources until accumulator is full. Then apply Occlusion and BRDF. */
|
||||
vec4 spec_accum = vec4(0.0);
|
||||
|
||||
/* Planar Reflections */
|
||||
for (int i = 0; i < MAX_PLANAR && i < planar_count && spec_accum.a < 0.999; ++i) {
|
||||
PlanarData pd = planars_data[i];
|
||||
if (ssr_id != outputSsrId) {
|
||||
/* Planar Reflections */
|
||||
for (int i = 0; i < MAX_PLANAR && i < planar_count && spec_accum.a < 0.999; ++i) {
|
||||
PlanarData pd = planars_data[i];
|
||||
|
||||
float fade = probe_attenuation_planar(pd, worldPosition, N);
|
||||
float fade = probe_attenuation_planar(pd, worldPosition, N);
|
||||
|
||||
if (fade > 0.0) {
|
||||
vec3 spec = probe_evaluate_planar(float(i), pd, worldPosition, N, V, rand.r, cameraPos, roughness, fade);
|
||||
accumulate_light(spec, fade, spec_accum);
|
||||
if (fade > 0.0) {
|
||||
vec3 spec = probe_evaluate_planar(float(i), pd, worldPosition, N, V, rand.r, cameraPos, roughness, fade);
|
||||
accumulate_light(spec, fade, spec_accum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Specular probes */
|
||||
vec3 spec_dir = get_specular_dominant_dir(N, V, roughnessSquared);
|
||||
/* Specular probes */
|
||||
vec3 spec_dir = get_specular_dominant_dir(N, V, roughnessSquared);
|
||||
|
||||
/* Starts at 1 because 0 is world probe */
|
||||
for (int i = 1; i < MAX_PROBE && i < probe_count && spec_accum.a < 0.999; ++i) {
|
||||
CubeData cd = probes_data[i];
|
||||
/* Starts at 1 because 0 is world probe */
|
||||
for (int i = 1; i < MAX_PROBE && i < probe_count && spec_accum.a < 0.999; ++i) {
|
||||
CubeData cd = probes_data[i];
|
||||
|
||||
float fade = probe_attenuation_cube(cd, worldPosition);
|
||||
float fade = probe_attenuation_cube(cd, worldPosition);
|
||||
|
||||
if (fade > 0.0) {
|
||||
vec3 spec = probe_evaluate_cube(float(i), cd, worldPosition, spec_dir, roughness);
|
||||
accumulate_light(spec, fade, spec_accum);
|
||||
if (fade > 0.0) {
|
||||
vec3 spec = probe_evaluate_cube(float(i), cd, worldPosition, spec_dir, roughness);
|
||||
accumulate_light(spec, fade, spec_accum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* World Specular */
|
||||
if (spec_accum.a < 0.999) {
|
||||
vec3 spec = probe_evaluate_world_spec(spec_dir, roughness);
|
||||
accumulate_light(spec, 1.0, spec_accum);
|
||||
/* World Specular */
|
||||
if (spec_accum.a < 0.999) {
|
||||
vec3 spec = probe_evaluate_world_spec(spec_dir, roughness);
|
||||
accumulate_light(spec, 1.0, spec_accum);
|
||||
}
|
||||
}
|
||||
|
||||
/* Ambient Occlusion */
|
||||
@@ -483,7 +496,8 @@ vec3 eevee_surface_glossy_lit(vec3 N, vec3 f0, float roughness, float ao)
|
||||
vec2 uv = lut_coords(dot(N, V), roughness);
|
||||
vec2 brdf_lut = texture(utilTex, vec3(uv, 1.0)).rg;
|
||||
|
||||
out_light += spec_accum.rgb * F_ibl(f0, brdf_lut) * specular_occlusion(dot(N, V), final_ao, roughness) * float(specToggle);
|
||||
ssr_spec = F_ibl(f0, brdf_lut) * specular_occlusion(dot(N, V), final_ao, roughness);
|
||||
out_light += spec_accum.rgb * ssr_spec * float(specToggle);
|
||||
|
||||
return out_light;
|
||||
}
|
||||
|
||||
@@ -2663,6 +2663,8 @@ void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out Closure result)
|
||||
{
|
||||
#ifdef EEVEE_ENGINE
|
||||
vec3 L = eevee_surface_diffuse_lit(N, vec3(1.0), 1.0);
|
||||
|
||||
result = Closure(L * color.rgb, 1.0, vec4(0.0), vec2(0.0), -1);
|
||||
#else
|
||||
/* ambient light */
|
||||
vec3 L = vec3(0.2);
|
||||
@@ -2675,15 +2677,18 @@ void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out Closure result)
|
||||
float bsdf = max(dot(N, light_position), 0.0);
|
||||
L += light_diffuse * bsdf;
|
||||
}
|
||||
#endif
|
||||
|
||||
result = Closure(L * color.rgb, 1.0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void node_bsdf_glossy(vec4 color, float roughness, vec3 N, out Closure result)
|
||||
void node_bsdf_glossy(vec4 color, float roughness, vec3 N, float ssr_id, out Closure result)
|
||||
{
|
||||
#ifdef EEVEE_ENGINE
|
||||
vec3 L = eevee_surface_glossy_lit(N, vec3(1.0), roughness, 1.0);
|
||||
vec3 ssr_spec;
|
||||
vec3 L = eevee_surface_glossy_lit(N, vec3(1.0), roughness, 1.0, int(ssr_id), ssr_spec);
|
||||
vec3 vN = mat3(ViewMatrix) * N;
|
||||
result = Closure(L * color.rgb, 1.0, vec4(ssr_spec * color.rgb, roughness), vN.xy, int(ssr_id));
|
||||
#else
|
||||
/* ambient light */
|
||||
vec3 L = vec3(0.2);
|
||||
@@ -2702,9 +2707,9 @@ void node_bsdf_glossy(vec4 color, float roughness, vec3 N, out Closure result)
|
||||
bsdf += 0.5 * max(dot(N, light_position), 0.0);
|
||||
L += light_specular * bsdf;
|
||||
}
|
||||
#endif
|
||||
|
||||
result = Closure(L * color.rgb, 1.0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void node_bsdf_anisotropic(
|
||||
@@ -2724,6 +2729,7 @@ void node_bsdf_toon(vec4 color, float size, float tsmooth, vec3 N, out Closure r
|
||||
node_bsdf_diffuse(color, 0.0, N, result);
|
||||
}
|
||||
|
||||
#ifndef EEVEE_ENGINE
|
||||
void node_bsdf_principled(vec4 base_color, float subsurface, vec3 subsurface_radius, vec4 subsurface_color, float metallic, float specular,
|
||||
float specular_tint, float roughness, float anisotropic, float anisotropic_rotation, float sheen, float sheen_tint, float clearcoat,
|
||||
float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, out Closure result)
|
||||
@@ -2821,16 +2827,19 @@ void node_bsdf_principled(vec4 base_color, float subsurface, vec3 subsurface_rad
|
||||
|
||||
result = Closure(L, 1.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
void node_bsdf_principled_simple(vec4 base_color, float subsurface, vec3 subsurface_radius, vec4 subsurface_color, float metallic, float specular,
|
||||
float specular_tint, float roughness, float anisotropic, float anisotropic_rotation, float sheen, float sheen_tint, float clearcoat,
|
||||
float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, float ssr_id, out Closure result)
|
||||
{
|
||||
#ifdef EEVEE_ENGINE
|
||||
vec3 diffuse, f0;
|
||||
vec3 diffuse, f0, ssr_spec;
|
||||
convert_metallic_to_specular_tinted(base_color.rgb, metallic, specular, specular_tint, diffuse, f0);
|
||||
|
||||
result = Closure(eevee_surface_lit(N, diffuse, f0, roughness, 1.0, ssr_id), 1.0);
|
||||
vec3 L = eevee_surface_lit(N, diffuse, f0, roughness, 1.0, int(ssr_id), ssr_spec);
|
||||
vec3 vN = mat3(ViewMatrix) * N;
|
||||
result = Closure(L, 1.0, vec4(ssr_spec, roughness), vN.xy, int(ssr_id));
|
||||
#else
|
||||
node_bsdf_principled(base_color, subsurface, subsurface_radius, subsurface_color, metallic, specular,
|
||||
specular_tint, roughness, anisotropic, anisotropic_rotation, sheen, sheen_tint, clearcoat,
|
||||
@@ -2843,7 +2852,7 @@ void node_bsdf_principled_clearcoat(vec4 base_color, float subsurface, vec3 subs
|
||||
float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, float ssr_id, out Closure result)
|
||||
{
|
||||
#ifdef EEVEE_ENGINE
|
||||
vec3 diffuse, f0;
|
||||
vec3 diffuse, f0, ssr_spec;
|
||||
convert_metallic_to_specular_tinted(base_color.rgb, metallic, specular, specular_tint, diffuse, f0);
|
||||
|
||||
clearcoat *= 0.25;
|
||||
@@ -2871,7 +2880,10 @@ void node_bsdf_principled_clearcoat(vec4 base_color, float subsurface, vec3 subs
|
||||
}
|
||||
result = Closure(surface_color.rgb / surface_color.a, 1.0);
|
||||
#else
|
||||
result = Closure(eevee_surface_clearcoat_lit(N, diffuse, f0, roughness, CN, clearcoat, clearcoat_roughness, 1.0, ssr_id), 1.0);
|
||||
|
||||
vec3 L = eevee_surface_clearcoat_lit(N, diffuse, f0, roughness, CN, clearcoat, clearcoat_roughness, 1.0, int(ssr_id), ssr_spec);
|
||||
vec3 vN = mat3(ViewMatrix) * N;
|
||||
result = Closure(L, 1.0, vec4(ssr_spec, roughness), vN.xy, int(ssr_id));
|
||||
#endif
|
||||
|
||||
#else
|
||||
@@ -2905,6 +2917,8 @@ void node_subsurface_scattering(
|
||||
node_bsdf_diffuse(color, 0.0, N, result);
|
||||
}
|
||||
|
||||
/* Unsupported for now */
|
||||
#ifndef EEVEE_ENGINE
|
||||
void node_bsdf_hair(vec4 color, float offset, float roughnessu, float roughnessv, vec3 tangent, out Closure result)
|
||||
{
|
||||
result = Closure(color.rgb, color.a);
|
||||
@@ -2919,6 +2933,8 @@ void node_ambient_occlusion(vec4 color, out Closure result)
|
||||
{
|
||||
result = Closure(color.rgb, color.a);
|
||||
}
|
||||
#endif /* EEVEE_ENGINE */
|
||||
|
||||
#endif /* VOLUMETRICS */
|
||||
|
||||
/* emission */
|
||||
@@ -2927,7 +2943,11 @@ void node_emission(vec4 color, float strength, vec3 N, out Closure result)
|
||||
{
|
||||
#ifndef VOLUMETRICS
|
||||
color *= strength;
|
||||
#ifdef EEVEE_ENGINE
|
||||
result = Closure(color.rgb, color.a, vec4(0.0), vec2(0.0), -1);
|
||||
#else
|
||||
result = Closure(color.rgb, color.a);
|
||||
#endif
|
||||
#else
|
||||
result = Closure(vec3(0.0), vec3(0.0), color.rgb * strength, 0.0);
|
||||
#endif
|
||||
@@ -2952,7 +2972,11 @@ void node_background(vec4 color, float strength, out Closure result)
|
||||
{
|
||||
#ifndef VOLUMETRICS
|
||||
color *= strength;
|
||||
#ifdef EEVEE_ENGINE
|
||||
result = Closure(color.rgb, color.a, vec4(0.0), vec2(0.0), -1);
|
||||
#else
|
||||
result = Closure(color.rgb, color.a);
|
||||
#endif
|
||||
#else
|
||||
result = CLOSURE_DEFAULT;
|
||||
#endif
|
||||
@@ -3995,7 +4019,11 @@ uniform float backgroundAlpha;
|
||||
void node_output_world(Closure surface, Closure volume, out Closure result)
|
||||
{
|
||||
#ifndef VOLUMETRICS
|
||||
#ifdef EEVEE_ENGINE
|
||||
result = Closure(surface.radiance, backgroundAlpha, vec4(0.0), vec2(0.0), -1);
|
||||
#else
|
||||
result = Closure(surface.radiance, backgroundAlpha);
|
||||
#endif
|
||||
#else
|
||||
result = volume;
|
||||
#endif /* VOLUMETRICS */
|
||||
@@ -4015,10 +4043,12 @@ void node_eevee_metallic(
|
||||
float clearcoat, float clearcoat_roughness, vec3 clearcoat_normal,
|
||||
float occlusion, float ssr_id, out Closure result)
|
||||
{
|
||||
vec3 diffuse, f0;
|
||||
vec3 diffuse, f0, ssr_spec;
|
||||
convert_metallic_to_specular(basecol.rgb, metallic, specular, diffuse, f0);
|
||||
|
||||
result = Closure(eevee_surface_lit(normal, diffuse, f0, roughness, occlusion, ssr_id) + emissive.rgb, 1.0 - transp);
|
||||
vec3 L = eevee_surface_lit(normal, diffuse, f0, roughness, occlusion, int(ssr_id), ssr_spec);
|
||||
vec3 vN = mat3(ViewMatrix) * normal;
|
||||
result = Closure(L + emissive.rgb, 1.0 - transp, vec4(ssr_spec, roughness), vN.xy, int(ssr_id));
|
||||
}
|
||||
|
||||
void node_eevee_specular(
|
||||
@@ -4026,7 +4056,11 @@ void node_eevee_specular(
|
||||
float clearcoat, float clearcoat_roughness, vec3 clearcoat_normal,
|
||||
float occlusion, float ssr_id, out Closure result)
|
||||
{
|
||||
result = Closure(eevee_surface_lit(normal, diffuse.rgb, specular.rgb, roughness, occlusion, ssr_id) + emissive.rgb, 1.0 - transp);
|
||||
vec3 ssr_spec;
|
||||
|
||||
vec3 L = eevee_surface_lit(normal, diffuse.rgb, specular.rgb, roughness, occlusion, int(ssr_id), ssr_spec);
|
||||
vec3 vN = mat3(ViewMatrix) * normal;
|
||||
result = Closure(L + emissive.rgb, 1.0 - transp, vec4(ssr_spec, roughness), vN.xy, int(ssr_id));
|
||||
}
|
||||
|
||||
void node_output_eevee_material(Closure surface, out Closure result)
|
||||
@@ -4034,7 +4068,8 @@ void node_output_eevee_material(Closure surface, out Closure result)
|
||||
#if defined(USE_ALPHA_HASH) || defined(USE_ALPHA_CLIP) || defined(USE_ALPHA_BLEND)
|
||||
result = surface;
|
||||
#else
|
||||
result = Closure(surface.radiance, length(viewPosition));
|
||||
result = surface;
|
||||
result.opacity = length(viewPosition);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -2622,6 +2622,7 @@ RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(volumetric_light_clamp)
|
||||
RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(volumetric_shadows)
|
||||
RNA_LAYER_ENGINE_EEVEE_GET_SET_INT(volumetric_shadow_samples)
|
||||
RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(volumetric_colored_transmittance)
|
||||
RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(ssr_enable)
|
||||
|
||||
/* object engine */
|
||||
RNA_LAYER_MODE_OBJECT_GET_SET_BOOL(show_wire)
|
||||
@@ -6176,6 +6177,14 @@ static void rna_def_scene_layer_engine_settings_eevee(BlenderRNA *brna)
|
||||
|
||||
/* see RNA_LAYER_ENGINE_GET_SET macro */
|
||||
|
||||
/* Screen Space Reflection */
|
||||
prop = RNA_def_property(srna, "ssr_enable", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_Eevee_ssr_enable_get",
|
||||
"rna_LayerEngineSettings_Eevee_ssr_enable_set");
|
||||
RNA_def_property_ui_text(prop, "SSR", "Enable screen space reflection");
|
||||
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_SceneLayerEngineSettings_update");
|
||||
|
||||
/* Volumetrics */
|
||||
prop = RNA_def_property(srna, "volumetric_enable", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_Eevee_volumetric_enable_get",
|
||||
|
||||
@@ -51,7 +51,7 @@ static int node_shader_gpu_bsdf_glossy(GPUMaterial *mat, bNode *node, bNodeExecD
|
||||
if (!in[2].link)
|
||||
GPU_link(mat, "world_normals_get", &in[2].link);
|
||||
|
||||
return GPU_stack_link(mat, node, "node_bsdf_glossy", in, out);
|
||||
return GPU_stack_link(mat, node, "node_bsdf_glossy", in, out, GPU_uniform(&node->ssr_id));
|
||||
}
|
||||
|
||||
/* node type definition */
|
||||
|
||||
Reference in New Issue
Block a user