Eevee: Add Screen Space Refraction.
For the moment the only way to enable this is to: - enable Screen Space REFLECTIONS. - enable Screen Space Refraction in the SSR parameters. - enable Screen Space Refraction in the material tab.
This commit is contained in:
parent
98a7f1b335
commit
d16342e5fd
|
@ -1182,6 +1182,7 @@ 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")
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -730,6 +730,7 @@ class RENDER_PT_eevee_screen_space_reflections(RenderButtonsPanel, Panel):
|
|||
props = scene.layer_properties['BLENDER_EEVEE']
|
||||
|
||||
col = layout.column()
|
||||
col.prop(props, "ssr_refraction")
|
||||
col.prop(props, "ssr_halfres")
|
||||
col.prop(props, "ssr_ray_count")
|
||||
col.prop(props, "ssr_quality")
|
||||
|
|
|
@ -276,6 +276,7 @@ class RENDERLAYER_PT_eevee_screen_space_reflections(RenderLayerButtonsPanel, Pan
|
|||
|
||||
col = layout.column()
|
||||
col.template_override_property(layer_props, scene_props, "ssr_halfres")
|
||||
col.template_override_property(layer_props, scene_props, "ssr_refraction")
|
||||
col.template_override_property(layer_props, scene_props, "ssr_ray_count")
|
||||
col.template_override_property(layer_props, scene_props, "ssr_quality")
|
||||
col.template_override_property(layer_props, scene_props, "ssr_max_roughness")
|
||||
|
|
|
@ -163,6 +163,7 @@ data_to_c_simple(engines/eevee/shaders/octahedron_lib.glsl SRC)
|
|||
data_to_c_simple(engines/eevee/shaders/bsdf_sampling_lib.glsl SRC)
|
||||
data_to_c_simple(engines/eevee/shaders/raytrace_lib.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/volumetric_frag.glsl SRC)
|
||||
|
||||
data_to_c_simple(modes/shaders/common_globals_lib.glsl SRC)
|
||||
|
|
|
@ -584,6 +584,14 @@ 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;
|
||||
|
||||
if (BKE_collection_engine_property_value_get_bool(props, "ssr_refraction")) {
|
||||
effects->enabled_effects |= EFFECT_REFRACT;
|
||||
|
||||
DRWFboTexture tex = {&txl->refract_color, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER | DRW_TEX_MIPMAP};
|
||||
|
||||
DRW_framebuffer_init(&fbl->refract_fb, &draw_engine_eevee_type, (int)viewport_size[0], (int)viewport_size[1], &tex, 1);
|
||||
}
|
||||
|
||||
/* Enable double buffering to be able to read previous frame color */
|
||||
effects->enabled_effects |= EFFECT_DOUBLE_BUFFER;
|
||||
|
||||
|
@ -1072,6 +1080,20 @@ void EEVEE_effects_do_volumetrics(EEVEE_SceneLayerData *sldata, EEVEE_Data *veda
|
|||
}
|
||||
}
|
||||
|
||||
void EEVEE_effects_do_refraction(EEVEE_SceneLayerData *UNUSED(sldata), EEVEE_Data *vedata)
|
||||
{
|
||||
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_REFRACT) != 0) {
|
||||
DRW_framebuffer_texture_attach(fbl->refract_fb, txl->refract_color, 0, 0);
|
||||
DRW_framebuffer_blit(fbl->main, fbl->refract_fb, false);
|
||||
EEVEE_downsample_buffer(vedata, fbl->downsample_fb, txl->refract_color, 9);
|
||||
}
|
||||
}
|
||||
|
||||
void EEVEE_effects_do_ssr(EEVEE_SceneLayerData *UNUSED(sldata), EEVEE_Data *vedata)
|
||||
{
|
||||
EEVEE_PassList *psl = vedata->psl;
|
||||
|
|
|
@ -199,6 +199,12 @@ static void EEVEE_draw_scene(void *vedata)
|
|||
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);
|
||||
|
||||
/* Transparent */
|
||||
DRW_pass_sort_shgroup_z(psl->transparent_pass);
|
||||
DRW_stats_group_start("Transparent");
|
||||
|
@ -235,7 +241,9 @@ 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, "ssr_refraction", false);
|
||||
BKE_collection_engine_property_add_bool(props, "ssr_halfres", true);
|
||||
BKE_collection_engine_property_add_int(props, "ssr_ray_count", 1);
|
||||
BKE_collection_engine_property_add_float(props, "ssr_quality", 0.25f);
|
||||
|
|
|
@ -98,6 +98,8 @@ extern char datatoc_irradiance_lib_glsl[];
|
|||
extern char datatoc_octahedron_lib_glsl[];
|
||||
extern char datatoc_lit_surface_frag_glsl[];
|
||||
extern char datatoc_lit_surface_vert_glsl[];
|
||||
extern char datatoc_raytrace_lib_glsl[];
|
||||
extern char datatoc_ssr_lib_glsl[];
|
||||
extern char datatoc_shadow_vert_glsl[];
|
||||
extern char datatoc_shadow_geom_glsl[];
|
||||
extern char datatoc_lightprobe_geom_glsl[];
|
||||
|
@ -307,6 +309,9 @@ static char *eevee_get_defines(int options)
|
|||
if ((options & VAR_MAT_MULT) != 0) {
|
||||
BLI_dynstr_appendf(ds, "#define USE_MULTIPLY\n");
|
||||
}
|
||||
if ((options & VAR_MAT_REFRACT) != 0) {
|
||||
BLI_dynstr_appendf(ds, "#define USE_REFRACTION\n");
|
||||
}
|
||||
|
||||
str = BLI_dynstr_get_cstring(ds);
|
||||
BLI_dynstr_free(ds);
|
||||
|
@ -346,7 +351,9 @@ static char *eevee_get_volume_defines(int options)
|
|||
/**
|
||||
* 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)
|
||||
static void add_standard_uniforms(
|
||||
DRWShadingGroup *shgrp, EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata,
|
||||
int *ssr_id, float *refract_thickness)
|
||||
{
|
||||
if (ssr_id == NULL) {
|
||||
static int no_ssr = -1.0f;
|
||||
|
@ -372,9 +379,20 @@ static void add_standard_uniforms(DRWShadingGroup *shgrp, EEVEE_SceneLayerData *
|
|||
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 || refract_thickness) {
|
||||
DRW_shgroup_uniform_vec4(shgrp, "viewvecs[0]", (float *)vedata->stl->g_data->viewvecs, 2);
|
||||
DRW_shgroup_uniform_buffer(shgrp, "maxzBuffer", &vedata->txl->maxzbuffer);
|
||||
}
|
||||
if (refract_thickness) {
|
||||
DRW_shgroup_uniform_buffer(shgrp, "colorBuffer", &vedata->txl->refract_color);
|
||||
DRW_shgroup_uniform_float(shgrp, "refractionThickness", refract_thickness, 1);
|
||||
DRW_shgroup_uniform_vec4(shgrp, "ssrParameters", &vedata->stl->effects->ssr_quality, 1);
|
||||
DRW_shgroup_uniform_float(shgrp, "borderFadeFactor", &vedata->stl->effects->ssr_border_fac, 1);
|
||||
DRW_shgroup_uniform_float(shgrp, "maxRoughness", &vedata->stl->effects->ssr_max_roughness, 1);
|
||||
DRW_shgroup_uniform_vec2(shgrp, "mipRatio[0]", (float *)vedata->stl->g_data->mip_ratio, 10);
|
||||
DRW_shgroup_uniform_int(shgrp, "rayCount", &vedata->stl->effects->ssr_ray_count, 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->txl->maxzbuffer);
|
||||
DRW_shgroup_uniform_vec3(shgrp, "aoParameters", &vedata->stl->effects->ao_dist, 1);
|
||||
}
|
||||
}
|
||||
|
@ -403,7 +421,10 @@ void EEVEE_materials_init(EEVEE_StorageList *stl)
|
|||
/* Shaders */
|
||||
DynStr *ds_frag = BLI_dynstr_new();
|
||||
BLI_dynstr_append(ds_frag, datatoc_bsdf_common_lib_glsl);
|
||||
BLI_dynstr_append(ds_frag, datatoc_bsdf_sampling_lib_glsl);
|
||||
BLI_dynstr_append(ds_frag, datatoc_ambient_occlusion_lib_glsl);
|
||||
BLI_dynstr_append(ds_frag, datatoc_raytrace_lib_glsl);
|
||||
BLI_dynstr_append(ds_frag, datatoc_ssr_lib_glsl);
|
||||
BLI_dynstr_append(ds_frag, datatoc_octahedron_lib_glsl);
|
||||
BLI_dynstr_append(ds_frag, datatoc_irradiance_lib_glsl);
|
||||
BLI_dynstr_append(ds_frag, datatoc_lightprobe_lib_glsl);
|
||||
|
@ -591,7 +612,8 @@ struct GPUMaterial *EEVEE_material_world_volume_get(
|
|||
|
||||
struct GPUMaterial *EEVEE_material_mesh_get(
|
||||
struct Scene *scene, Material *ma,
|
||||
bool use_ao, bool use_bent_normals, bool use_blend, bool use_multiply)
|
||||
bool use_ao, bool use_bent_normals, bool use_blend,
|
||||
bool use_multiply, bool use_refract)
|
||||
{
|
||||
const void *engine = &DRW_engine_viewport_eevee_type;
|
||||
int options = VAR_MAT_MESH;
|
||||
|
@ -600,6 +622,7 @@ struct GPUMaterial *EEVEE_material_mesh_get(
|
|||
if (use_bent_normals) options |= VAR_MAT_BENT;
|
||||
if (use_blend) options |= VAR_MAT_BLEND;
|
||||
if (use_multiply) options |= VAR_MAT_MULT;
|
||||
if (use_refract) options |= VAR_MAT_REFRACT;
|
||||
|
||||
GPUMaterial *mat = GPU_material_from_nodetree_find(&ma->gpumaterial, engine, options);
|
||||
if (mat) {
|
||||
|
@ -710,7 +733,7 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_create(
|
|||
}
|
||||
|
||||
DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.default_lit[options], pass);
|
||||
add_standard_uniforms(shgrp, sldata, vedata, &ssr_id);
|
||||
add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL);
|
||||
|
||||
return shgrp;
|
||||
}
|
||||
|
@ -740,7 +763,7 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_get(
|
|||
vedata->psl->default_pass[options] = DRW_pass_create("Default Lit Pass", state);
|
||||
|
||||
DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.default_lit[options], vedata->psl->default_pass[options]);
|
||||
add_standard_uniforms(shgrp, sldata, vedata, &ssr_id);
|
||||
add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL);
|
||||
}
|
||||
|
||||
return DRW_shgroup_create(e_data.default_lit[options], vedata->psl->default_pass[options]);
|
||||
|
@ -884,7 +907,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) : NULL;
|
||||
scene, ma, stl->effects->use_ao, stl->effects->use_bent_normals, false, false, false) : NULL;
|
||||
*gpumat_depth = (use_gpumat) ? EEVEE_material_mesh_depth_get(
|
||||
scene, ma, (ma->blend_method == MA_BM_HASHED), false) : NULL;
|
||||
return;
|
||||
|
@ -893,13 +916,13 @@ 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);
|
||||
stl->effects->use_ao, stl->effects->use_bent_normals, false, false, false);
|
||||
|
||||
*shgrp = DRW_shgroup_material_create(*gpumat, psl->material_pass);
|
||||
if (*shgrp) {
|
||||
static int ssr_id;
|
||||
ssr_id = (stl->effects->use_ssr) ? 0 : -1;
|
||||
add_standard_uniforms(*shgrp, sldata, vedata, &ssr_id);
|
||||
add_standard_uniforms(*shgrp, sldata, vedata, &ssr_id, NULL);
|
||||
}
|
||||
else {
|
||||
/* Shader failed : pink color */
|
||||
|
@ -960,6 +983,8 @@ 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);
|
||||
|
||||
float *color_p = &ma->r;
|
||||
float *metal_p = &ma->ray_mirror;
|
||||
float *spec_p = &ma->spec;
|
||||
|
@ -969,12 +994,14 @@ static void material_transparent(
|
|||
/* Shading */
|
||||
*gpumat = EEVEE_material_mesh_get(scene, ma,
|
||||
stl->effects->use_ao, stl->effects->use_bent_normals,
|
||||
true, (ma->blend_method == MA_BM_MULTIPLY));
|
||||
true, (ma->blend_method == MA_BM_MULTIPLY), use_refract);
|
||||
|
||||
*shgrp = DRW_shgroup_material_create(*gpumat, psl->transparent_pass);
|
||||
if (*shgrp) {
|
||||
static int ssr_id = -1; /* TODO transparent SSR */
|
||||
add_standard_uniforms(*shgrp, sldata, vedata, &ssr_id);
|
||||
static float refract_thickness = 0.0f; /* TODO Param */
|
||||
add_standard_uniforms(*shgrp, sldata, vedata, &ssr_id,
|
||||
(use_refract) ? &refract_thickness : NULL);
|
||||
}
|
||||
else {
|
||||
/* Shader failed : pink color */
|
||||
|
@ -1208,7 +1235,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, NULL);
|
||||
add_standard_uniforms(shgrp, sldata, vedata, NULL, NULL);
|
||||
|
||||
BLI_ghash_insert(material_hash, ma, shgrp);
|
||||
|
||||
|
|
|
@ -77,6 +77,7 @@ enum {
|
|||
VAR_MAT_HASH = (1 << 9),
|
||||
VAR_MAT_MULT = (1 << 10),
|
||||
VAR_MAT_SHADOW = (1 << 11),
|
||||
VAR_MAT_REFRACT = (1 << 12),
|
||||
};
|
||||
|
||||
typedef struct EEVEE_PassList {
|
||||
|
@ -142,6 +143,7 @@ typedef struct EEVEE_FramebufferList {
|
|||
struct GPUFrameBuffer *dof_scatter_near_fb;
|
||||
struct GPUFrameBuffer *volumetric_fb;
|
||||
struct GPUFrameBuffer *screen_tracing_fb;
|
||||
struct GPUFrameBuffer *refract_fb;
|
||||
|
||||
struct GPUFrameBuffer *planarref_fb;
|
||||
|
||||
|
@ -163,6 +165,7 @@ typedef struct EEVEE_TextureList {
|
|||
|
||||
struct GPUTexture *ssr_normal_input;
|
||||
struct GPUTexture *ssr_specrough_input;
|
||||
struct GPUTexture *refract_color;
|
||||
|
||||
struct GPUTexture *planar_pool;
|
||||
struct GPUTexture *planar_depth;
|
||||
|
@ -373,6 +376,7 @@ enum {
|
|||
EFFECT_VOLUMETRIC = (1 << 3),
|
||||
EFFECT_SSR = (1 << 4),
|
||||
EFFECT_DOUBLE_BUFFER = (1 << 5), /* Not really an effect but a feature */
|
||||
EFFECT_REFRACT = (1 << 6),
|
||||
};
|
||||
|
||||
/* ************** SCENE LAYER DATA ************** */
|
||||
|
@ -494,7 +498,7 @@ struct GPUMaterial *EEVEE_material_world_background_get(struct Scene *scene, str
|
|||
struct GPUMaterial *EEVEE_material_world_volume_get(
|
||||
struct Scene *scene, struct World *wo, bool use_lights, bool use_volume_shadows, bool is_homogeneous, bool use_color_transmit);
|
||||
struct GPUMaterial *EEVEE_material_mesh_get(
|
||||
struct Scene *scene, Material *ma, bool use_ao, bool use_bent_normals, bool use_blend, bool use_multiply);
|
||||
struct Scene *scene, Material *ma, bool use_ao, bool use_bent_normals, bool use_blend, bool use_multiply, bool use_refract);
|
||||
struct GPUMaterial *EEVEE_material_mesh_depth_get(struct Scene *scene, Material *ma, bool use_hashed_alpha, bool is_shadow);
|
||||
struct GPUMaterial *EEVEE_material_hair_get(struct Scene *scene, Material *ma, bool use_ao, bool use_bent_normals);
|
||||
void EEVEE_materials_free(void);
|
||||
|
@ -528,6 +532,7 @@ void EEVEE_create_minmax_buffer(EEVEE_Data *vedata, struct GPUTexture *depth_src
|
|||
void EEVEE_downsample_buffer(EEVEE_Data *vedata, struct GPUFrameBuffer *fb_src, struct GPUTexture *texture_src, int level);
|
||||
void EEVEE_effects_do_volumetrics(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata);
|
||||
void EEVEE_effects_do_ssr(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata);
|
||||
void EEVEE_effects_do_refraction(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata);
|
||||
void EEVEE_draw_effects(EEVEE_Data *vedata);
|
||||
void EEVEE_effects_free(void);
|
||||
|
||||
|
|
|
@ -7,6 +7,10 @@ uniform int planar_count;
|
|||
uniform bool specToggle;
|
||||
uniform bool ssrToggle;
|
||||
|
||||
#ifdef USE_REFRACTION
|
||||
uniform float refractionThickness;
|
||||
#endif
|
||||
|
||||
#ifndef UTIL_TEX
|
||||
#define UTIL_TEX
|
||||
uniform sampler2DArray utilTex;
|
||||
|
@ -577,7 +581,24 @@ vec3 eevee_surface_refraction(vec3 N, vec3 f0, float roughness, float ior, int s
|
|||
/* Accumulate light from all sources until accumulator is full. Then apply Occlusion and BRDF. */
|
||||
vec4 trans_accum = vec4(0.0);
|
||||
|
||||
#ifdef USE_REFRACTION
|
||||
/* Screen Space Refraction */
|
||||
if (ssrToggle && roughness < maxRoughness + 0.2) {
|
||||
vec3 rand = texture(utilTex, vec3(gl_FragCoord.xy / LUT_SIZE, 2.0)).xzw;
|
||||
|
||||
float ray_ofs = 1.0 / float(rayCount);
|
||||
vec4 spec = screen_space_refraction(viewPosition, N, V, ior, roughnessSquared, rand, 0.0);
|
||||
if (rayCount > 1) spec += screen_space_refraction(viewPosition, N, V, ior, roughnessSquared, rand.xyz * vec3(1.0, -1.0, -1.0), 1.0 * ray_ofs);
|
||||
if (rayCount > 2) spec += screen_space_refraction(viewPosition, N, V, ior, roughnessSquared, rand.xzy * vec3(1.0, 1.0, -1.0), 2.0 * ray_ofs);
|
||||
if (rayCount > 3) spec += screen_space_refraction(viewPosition, N, V, ior, roughnessSquared, rand.xzy * vec3(1.0, -1.0, 1.0), 3.0 * ray_ofs);
|
||||
spec /= float(rayCount);
|
||||
spec.a *= smoothstep(maxRoughness + 0.2, maxRoughness, roughness);
|
||||
accumulate_light(spec.rgb, spec.a, trans_accum);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Specular probes */
|
||||
/* NOTE: This bias the IOR */
|
||||
vec3 spec_dir = get_specular_refraction_dominant_dir(N, V, roughness, ior);
|
||||
|
||||
/* Starts at 1 because 0 is world probe */
|
||||
|
@ -685,6 +706,22 @@ vec3 eevee_surface_glass(vec3 N, vec3 transmission_col, float roughness, float i
|
|||
vec3 refr_dir = get_specular_refraction_dominant_dir(N, V, roughness, ior);
|
||||
vec4 trans_accum = vec4(0.0);
|
||||
|
||||
#ifdef USE_REFRACTION
|
||||
/* Screen Space Refraction */
|
||||
if (ssrToggle && roughness < maxRoughness + 0.2) {
|
||||
vec3 rand = texture(utilTex, vec3(gl_FragCoord.xy / LUT_SIZE, 2.0)).xzw;
|
||||
|
||||
float ray_ofs = 1.0 / float(rayCount);
|
||||
vec4 spec = screen_space_refraction(viewPosition, N, V, ior, roughnessSquared, rand, 0.0);
|
||||
if (rayCount > 1) spec += screen_space_refraction(viewPosition, N, V, ior, roughnessSquared, rand.xyz * vec3(1.0, -1.0, -1.0), 1.0 * ray_ofs);
|
||||
if (rayCount > 2) spec += screen_space_refraction(viewPosition, N, V, ior, roughnessSquared, rand.xzy * vec3(1.0, 1.0, -1.0), 2.0 * ray_ofs);
|
||||
if (rayCount > 3) spec += screen_space_refraction(viewPosition, N, V, ior, roughnessSquared, rand.xzy * vec3(1.0, -1.0, 1.0), 3.0 * ray_ofs);
|
||||
spec /= float(rayCount);
|
||||
spec.a *= smoothstep(maxRoughness + 0.2, maxRoughness, roughness);
|
||||
accumulate_light(spec.rgb, spec.a, trans_accum);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Starts at 1 because 0 is world probe */
|
||||
for (int i = 1; i < MAX_PROBE && i < probe_count && spec_accum.a < 0.999 && trans_accum.a < 0.999; ++i) {
|
||||
CubeData cd = probes_data[i];
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
/* ------------ Refraction ------------ */
|
||||
|
||||
#define BTDF_BIAS 0.85
|
||||
|
||||
vec4 screen_space_refraction(vec3 viewPosition, vec3 N, vec3 V, float ior, float roughnessSquared, vec3 rand, float ofs)
|
||||
{
|
||||
float a2 = roughnessSquared * roughnessSquared;
|
||||
float jitter = fract(rand.x + ofs);
|
||||
|
||||
/* Importance sampling bias */
|
||||
rand.x = mix(rand.x, 0.0, BTDF_BIAS);
|
||||
|
||||
vec3 T, B;
|
||||
float NH;
|
||||
make_orthonormal_basis(N, T, B);
|
||||
vec3 H = sample_ggx(rand, a2, N, T, B, NH); /* Microfacet normal */
|
||||
float pdf = pdf_ggx_reflect(NH, a2);
|
||||
|
||||
/* If ray is bad (i.e. going below the plane) regenerate. */
|
||||
if (F_eta(ior, dot(H, V)) < 1.0) {
|
||||
H = sample_ggx(rand * vec3(1.0, -1.0, -1.0), a2, N, T, B, NH); /* Microfacet normal */
|
||||
pdf = pdf_ggx_reflect(NH, a2);
|
||||
}
|
||||
|
||||
vec3 vV = viewCameraVec;
|
||||
float eta = 1.0/ior;
|
||||
if (dot(H, V) < 0.0) {
|
||||
H = -H;
|
||||
eta = ior;
|
||||
}
|
||||
|
||||
vec3 R = refract(-V, H, 1.0 / ior);
|
||||
|
||||
R = transform_direction(ViewMatrix, R);
|
||||
|
||||
vec3 hit_pos = raycast(-1, viewPosition, R, ssrThickness, jitter, roughnessSquared);
|
||||
|
||||
if ((hit_pos.z < 0.0) && (F_eta(ior, dot(H, V)) < 1.0)) {
|
||||
float hit_dist = distance(hit_pos, viewPosition);
|
||||
|
||||
float cone_cos = cone_cosine(roughnessSquared);
|
||||
float cone_tan = sqrt(1 - cone_cos * cone_cos) / cone_cos;
|
||||
|
||||
/* Empirical fit for refraction. */
|
||||
/* TODO find a better fit or precompute inside the LUT. */
|
||||
cone_tan *= 0.5 * fast_sqrt(f0_from_ior((ior < 1.0) ? 1.0 / ior : ior));
|
||||
|
||||
float cone_footprint = hit_dist * cone_tan;
|
||||
|
||||
/* find the offset in screen space by multiplying a point
|
||||
* in camera space at the depth of the point by the projection matrix. */
|
||||
float homcoord = ProjectionMatrix[2][3] * hit_pos.z + ProjectionMatrix[3][3];
|
||||
/* UV space footprint */
|
||||
cone_footprint = BTDF_BIAS * 0.5 * max(ProjectionMatrix[0][0], ProjectionMatrix[1][1]) * cone_footprint / homcoord;
|
||||
|
||||
vec2 hit_uvs = project_point(ProjectionMatrix, hit_pos).xy * 0.5 + 0.5;
|
||||
|
||||
/* Texel footprint */
|
||||
vec2 texture_size = vec2(textureSize(colorBuffer, 0).xy);
|
||||
float mip = clamp(log2(cone_footprint * max(texture_size.x, texture_size.y)), 0.0, 9.0);
|
||||
|
||||
/* Correct UVs for mipmaping mis-alignment */
|
||||
float low_mip = floor(mip);
|
||||
hit_uvs *= mix(mipRatio[int(low_mip)], mipRatio[int(low_mip + 1.0)], mip - low_mip);
|
||||
|
||||
vec3 spec = textureLod(colorBuffer, hit_uvs, mip).xyz;
|
||||
float mask = screen_border_mask(hit_uvs);
|
||||
|
||||
return vec4(spec, mask);
|
||||
}
|
||||
|
||||
return vec4(0.0);
|
||||
}
|
|
@ -510,7 +510,8 @@ enum {
|
|||
|
||||
/* blend_flag */
|
||||
enum {
|
||||
MA_BL_HIDE_BACKSIDE = (1 << 0),
|
||||
MA_BL_HIDE_BACKSIDE = (1 << 0),
|
||||
MA_BL_REFRACTION = (1 << 1),
|
||||
};
|
||||
|
||||
/* blend_shadow */
|
||||
|
|
|
@ -1869,6 +1869,11 @@ 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");
|
||||
RNA_def_property_update(prop, 0, "rna_Material_draw_update");
|
||||
|
||||
/* For Preview Render */
|
||||
prop = RNA_def_property(srna, "preview_render_type", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "pr_type");
|
||||
|
|
|
@ -2634,6 +2634,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_refraction)
|
||||
RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(ssr_enable)
|
||||
RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(ssr_halfres)
|
||||
RNA_LAYER_ENGINE_EEVEE_GET_SET_INT(ssr_ray_count)
|
||||
|
@ -6204,6 +6205,13 @@ static void rna_def_scene_layer_engine_settings_eevee(BlenderRNA *brna)
|
|||
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_SceneLayerEngineSettings_update");
|
||||
|
||||
prop = RNA_def_property(srna, "ssr_refraction", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_Eevee_ssr_refraction_get",
|
||||
"rna_LayerEngineSettings_Eevee_ssr_refraction_set");
|
||||
RNA_def_property_ui_text(prop, "Screen Space Refractions", "Enable screen space Refractions");
|
||||
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_SceneLayerEngineSettings_update");
|
||||
|
||||
prop = RNA_def_property(srna, "ssr_halfres", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_Eevee_ssr_halfres_get",
|
||||
"rna_LayerEngineSettings_Eevee_ssr_halfres_set");
|
||||
|
|
Loading…
Reference in New Issue