Eevee: Refraction: Make it available for opaque materials.

Theses Materials are rendered after the SSR pass.
The only difference with previous method is that they have a depth prepass (less overdraw) and are not sorted.
This commit is contained in:
Clément Foucault
2017-08-09 23:48:42 +02:00
parent 7ef8a49ad5
commit 7641f92710
6 changed files with 74 additions and 19 deletions

View File

@@ -1182,7 +1182,8 @@ class EEVEE_MATERIAL_PT_options(MaterialButtonsPanel, Panel):
if mat.blend_method not in {"OPAQUE", "CLIP", "HASHED"}:
layout.prop(mat, "transparent_hide_backside")
layout.prop(mat, "transparent_refraction")
layout.prop(mat, "transparent_screen_refraction")

View File

@@ -194,23 +194,30 @@ static void EEVEE_draw_scene(void *vedata)
DRW_draw_pass(psl->probe_display);
/* Volumetrics */
DRW_stats_group_start("Volumetrics");
EEVEE_effects_do_volumetrics(sldata, vedata);
DRW_stats_group_end();
/* Prepare Refraction */
EEVEE_effects_do_refraction(sldata, vedata);
/* Restore main FB */
DRW_framebuffer_bind(fbl->main);
/* Opaque refraction */
DRW_stats_group_start("Opaque Refraction");
DRW_draw_pass(psl->refract_depth_pass);
DRW_draw_pass(psl->refract_depth_pass_cull);
DRW_draw_pass(psl->refract_pass);
DRW_stats_group_end();
/* Transparent */
DRW_pass_sort_shgroup_z(psl->transparent_pass);
DRW_stats_group_start("Transparent");
DRW_draw_pass(psl->transparent_pass);
DRW_stats_group_end();
/* Volumetrics */
DRW_stats_group_start("Volumetrics");
EEVEE_effects_do_volumetrics(sldata, vedata);
DRW_stats_group_end();
/* Post Process */
DRW_stats_group_start("Post FX");
EEVEE_draw_effects(vedata);

View File

@@ -854,6 +854,29 @@ void EEVEE_materials_cache_init(EEVEE_Data *vedata)
psl->material_pass = DRW_pass_create("Material Shader Pass", state);
}
{
DRWState state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_WIRE;
psl->refract_depth_pass = DRW_pass_create("Refract Depth Pass", state);
stl->g_data->refract_depth_shgrp = DRW_shgroup_create(e_data.default_prepass_sh, psl->refract_depth_pass);
state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CULL_BACK;
psl->refract_depth_pass_cull = DRW_pass_create("Refract Depth Pass Cull", state);
stl->g_data->refract_depth_shgrp_cull = DRW_shgroup_create(e_data.default_prepass_sh, psl->refract_depth_pass_cull);
state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CLIP_PLANES | DRW_STATE_WIRE;
psl->refract_depth_pass_clip = DRW_pass_create("Refract Depth Pass Clip", state);
stl->g_data->refract_depth_shgrp_clip = DRW_shgroup_create(e_data.default_prepass_clip_sh, psl->refract_depth_pass_clip);
state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CLIP_PLANES | DRW_STATE_CULL_BACK;
psl->refract_depth_pass_clip_cull = DRW_pass_create("Refract Depth Pass Cull Clip", state);
stl->g_data->refract_depth_shgrp_clip_cull = DRW_shgroup_create(e_data.default_prepass_clip_sh, psl->refract_depth_pass_clip_cull);
}
{
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_CLIP_PLANES | DRW_STATE_WIRE;
psl->refract_pass = DRW_pass_create("Opaque Refraction Pass", state);
}
{
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS | DRW_STATE_CLIP_PLANES | DRW_STATE_WIRE;
psl->transparent_pass = DRW_pass_create("Material Transparent Pass", state);
@@ -897,6 +920,7 @@ static void material_opaque(
float *rough_p = &ma->gloss_mir;
const bool use_gpumat = (ma->use_nodes && ma->nodetree);
const bool use_refract = ((ma->blend_flag & MA_BL_SS_REFRACTION) != 0) && ((stl->effects->enabled_effects & EFFECT_REFRACT) != 0);
EeveeMaterialShadingGroups *emsg = BLI_ghash_lookup(material_hash, (const void *)ma);
@@ -907,7 +931,7 @@ static void material_opaque(
/* This will have been created already, just perform a lookup. */
*gpumat = (use_gpumat) ? EEVEE_material_mesh_get(
scene, ma, stl->effects->use_ao, stl->effects->use_bent_normals, false, false, false) : NULL;
scene, ma, stl->effects->use_ao, stl->effects->use_bent_normals, false, false, use_refract) : NULL;
*gpumat_depth = (use_gpumat) ? EEVEE_material_mesh_depth_get(
scene, ma, (ma->blend_method == MA_BM_HASHED), false) : NULL;
return;
@@ -916,13 +940,14 @@ static void material_opaque(
if (use_gpumat) {
/* Shading */
*gpumat = EEVEE_material_mesh_get(scene, ma,
stl->effects->use_ao, stl->effects->use_bent_normals, false, false, false);
stl->effects->use_ao, stl->effects->use_bent_normals, false, false, use_refract);
*shgrp = DRW_shgroup_material_create(*gpumat, psl->material_pass);
*shgrp = DRW_shgroup_material_create(*gpumat, use_refract ? psl->refract_pass : psl->material_pass);
if (*shgrp) {
static int ssr_id;
static float refract_thickness = 0.0f; /* TODO Param */
ssr_id = (stl->effects->use_ssr) ? 0 : -1;
add_standard_uniforms(*shgrp, sldata, vedata, &ssr_id, NULL);
add_standard_uniforms(*shgrp, sldata, vedata, &ssr_id, (use_refract) ? &refract_thickness : NULL);
}
else {
/* Shader failed : pink color */
@@ -939,8 +964,14 @@ static void material_opaque(
*gpumat_depth = EEVEE_material_mesh_depth_get(scene, ma,
(ma->blend_method == MA_BM_HASHED), false);
*shgrp_depth = DRW_shgroup_material_create(*gpumat_depth, do_cull ? psl->depth_pass_cull : psl->depth_pass);
*shgrp_depth_clip = DRW_shgroup_material_create(*gpumat_depth, do_cull ? psl->depth_pass_clip_cull : psl->depth_pass_clip);
if (use_refract) {
*shgrp_depth = DRW_shgroup_material_create(*gpumat_depth, (do_cull) ? psl->refract_depth_pass_cull : psl->refract_depth_pass);
*shgrp_depth_clip = DRW_shgroup_material_create(*gpumat_depth, (do_cull) ? psl->refract_depth_pass_clip_cull : psl->refract_depth_pass_clip);
}
else {
*shgrp_depth = DRW_shgroup_material_create(*gpumat_depth, (do_cull) ? psl->depth_pass_cull : psl->depth_pass);
*shgrp_depth_clip = DRW_shgroup_material_create(*gpumat_depth, (do_cull) ? psl->depth_pass_clip_cull : psl->depth_pass_clip);
}
if (*shgrp != NULL) {
if (ma->blend_method == MA_BM_CLIP) {
@@ -963,8 +994,14 @@ static void material_opaque(
/* Fallback default depth prepass */
if (*shgrp_depth == NULL) {
*shgrp_depth = do_cull ? stl->g_data->depth_shgrp_cull : stl->g_data->depth_shgrp;
*shgrp_depth_clip = do_cull ? stl->g_data->depth_shgrp_clip_cull : stl->g_data->depth_shgrp_clip;
if (use_refract) {
*shgrp_depth = (do_cull) ? stl->g_data->refract_depth_shgrp_cull : stl->g_data->refract_depth_shgrp;
*shgrp_depth_clip = (do_cull) ? stl->g_data->refract_depth_shgrp_clip_cull : stl->g_data->refract_depth_shgrp_clip;
}
else {
*shgrp_depth = (do_cull) ? stl->g_data->depth_shgrp_cull : stl->g_data->depth_shgrp;
*shgrp_depth_clip = (do_cull) ? stl->g_data->depth_shgrp_clip_cull : stl->g_data->depth_shgrp_clip;
}
}
emsg = MEM_mallocN(sizeof("EeveeMaterialShadingGroups"), "EeveeMaterialShadingGroups");
@@ -983,7 +1020,7 @@ static void material_transparent(
EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
const bool use_refract = ((ma->blend_flag & MA_BL_REFRACTION) != 0) && ((stl->effects->enabled_effects & EFFECT_REFRACT) != 0);
const bool use_refract = ((ma->blend_flag & MA_BL_SS_REFRACTION) != 0) && ((stl->effects->enabled_effects & EFFECT_REFRACT) != 0);
float *color_p = &ma->r;
float *metal_p = &ma->ray_mirror;

View File

@@ -125,8 +125,13 @@ typedef struct EEVEE_PassList {
struct DRWPass *depth_pass_cull;
struct DRWPass *depth_pass_clip;
struct DRWPass *depth_pass_clip_cull;
struct DRWPass *refract_depth_pass;
struct DRWPass *refract_depth_pass_cull;
struct DRWPass *refract_depth_pass_clip;
struct DRWPass *refract_depth_pass_clip_cull;
struct DRWPass *default_pass[VAR_MAT_MAX];
struct DRWPass *material_pass;
struct DRWPass *refract_pass;
struct DRWPass *transparent_pass;
struct DRWPass *background_pass;
} EEVEE_PassList;
@@ -462,6 +467,10 @@ typedef struct EEVEE_PrivateData {
struct DRWShadingGroup *depth_shgrp_cull;
struct DRWShadingGroup *depth_shgrp_clip;
struct DRWShadingGroup *depth_shgrp_clip_cull;
struct DRWShadingGroup *refract_depth_shgrp;
struct DRWShadingGroup *refract_depth_shgrp_cull;
struct DRWShadingGroup *refract_depth_shgrp_clip;
struct DRWShadingGroup *refract_depth_shgrp_clip_cull;
struct DRWShadingGroup *cube_display_shgrp;
struct DRWShadingGroup *planar_downsample;
struct GHash *material_hash;

View File

@@ -511,7 +511,7 @@ enum {
/* blend_flag */
enum {
MA_BL_HIDE_BACKSIDE = (1 << 0),
MA_BL_REFRACTION = (1 << 1),
MA_BL_SS_REFRACTION = (1 << 1),
};
/* blend_shadow */

View File

@@ -1869,9 +1869,10 @@ void RNA_def_material(BlenderRNA *brna)
"(avoids transparency sorting problems)");
RNA_def_property_update(prop, 0, "rna_Material_draw_update");
prop = RNA_def_property(srna, "transparent_refraction", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "blend_flag", MA_BL_REFRACTION);
RNA_def_property_ui_text(prop, "Screen Space Refraction" , "Use raytraced screen space refraction");
prop = RNA_def_property(srna, "transparent_screen_refraction", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "blend_flag", MA_BL_SS_REFRACTION);
RNA_def_property_ui_text(prop, "Screen Space Refraction" , "Use raytraced screen space refractions");
RNA_def_property_update(prop, 0, "rna_Material_draw_update");
RNA_def_property_update(prop, 0, "rna_Material_draw_update");
/* For Preview Render */