diff options
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/draw/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/draw/engines/eevee/eevee_effects.c | 22 | ||||
-rw-r--r-- | source/blender/draw/engines/eevee/eevee_engine.c | 8 | ||||
-rw-r--r-- | source/blender/draw/engines/eevee/eevee_materials.c | 51 | ||||
-rw-r--r-- | source/blender/draw/engines/eevee/eevee_private.h | 7 | ||||
-rw-r--r-- | source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl | 37 | ||||
-rw-r--r-- | source/blender/draw/engines/eevee/shaders/ssr_lib.glsl | 73 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_material_types.h | 3 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_material.c | 5 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_scene.c | 8 |
10 files changed, 201 insertions, 14 deletions
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 3293b4d7241..d5e4a402330 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -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) diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c index b01f46b1651..85bd15757dc 100644 --- a/source/blender/draw/engines/eevee/eevee_effects.c +++ b/source/blender/draw/engines/eevee/eevee_effects.c @@ -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; diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c index f2af9c53aa8..fd8c9c5ea4a 100644 --- a/source/blender/draw/engines/eevee/eevee_engine.c +++ b/source/blender/draw/engines/eevee/eevee_engine.c @@ -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); diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index 65e91a38053..b961591178a 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -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); diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index 4e17649ba42..04bcd02cb9c 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -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); diff --git a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl index 9e5b0472513..b3559e3d366 100644 --- a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl @@ -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]; diff --git a/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl b/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl new file mode 100644 index 00000000000..5b36da27e3f --- /dev/null +++ b/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl @@ -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); +} diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h index 41ad12e63f2..71d1cfc8e70 100644 --- a/source/blender/makesdna/DNA_material_types.h +++ b/source/blender/makesdna/DNA_material_types.h @@ -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 */ diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index d01ce407815..40c4345659c 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -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"); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 3bd104f1e7d..92b62e5c5ec 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -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"); |