Eevee: SSR: Encode Normal in buffer and add cubemap fallback.
Normals can point away from the camera so we cannot just put XY in the buffer and reconstruct Z later as we would not know the sign of Z.
This commit is contained in:
@@ -46,6 +46,12 @@
|
||||
#include "eevee_private.h"
|
||||
#include "GPU_texture.h"
|
||||
|
||||
#define SHADER_DEFINES \
|
||||
"#define EEVEE_ENGINE\n" \
|
||||
"#define MAX_PROBE " STRINGIFY(MAX_PROBE) "\n" \
|
||||
"#define MAX_GRID " STRINGIFY(MAX_GRID) "\n" \
|
||||
"#define MAX_PLANAR " STRINGIFY(MAX_PLANAR) "\n"
|
||||
|
||||
typedef struct EEVEE_LightProbeData {
|
||||
short probe_id, shadow_id;
|
||||
} EEVEE_LightProbeData;
|
||||
@@ -80,6 +86,8 @@ static struct {
|
||||
struct GPUTexture *depth_src;
|
||||
} e_data = {NULL}; /* Engine data */
|
||||
|
||||
extern char datatoc_bsdf_common_lib_glsl[];
|
||||
extern char datatoc_octahedron_lib_glsl[];
|
||||
extern char datatoc_effect_ssr_frag_glsl[];
|
||||
extern char datatoc_effect_minmaxz_frag_glsl[];
|
||||
extern char datatoc_effect_motion_blur_frag_glsl[];
|
||||
@@ -87,6 +95,7 @@ extern char datatoc_effect_bloom_frag_glsl[];
|
||||
extern char datatoc_effect_dof_vert_glsl[];
|
||||
extern char datatoc_effect_dof_geom_glsl[];
|
||||
extern char datatoc_effect_dof_frag_glsl[];
|
||||
extern char datatoc_lightprobe_lib_glsl[];
|
||||
extern char datatoc_tonemap_frag_glsl[];
|
||||
extern char datatoc_volumetric_frag_glsl[];
|
||||
|
||||
@@ -163,8 +172,18 @@ 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");
|
||||
DynStr *ds_frag = BLI_dynstr_new();
|
||||
BLI_dynstr_append(ds_frag, datatoc_bsdf_common_lib_glsl);
|
||||
BLI_dynstr_append(ds_frag, datatoc_octahedron_lib_glsl);
|
||||
BLI_dynstr_append(ds_frag, datatoc_lightprobe_lib_glsl);
|
||||
BLI_dynstr_append(ds_frag, datatoc_effect_ssr_frag_glsl);
|
||||
char *ssr_shader_str = BLI_dynstr_get_cstring(ds_frag);
|
||||
BLI_dynstr_free(ds_frag);
|
||||
|
||||
e_data.ssr_raytrace_sh = DRW_shader_create_fullscreen(ssr_shader_str, SHADER_DEFINES "#define STEP_RAYTRACE\n");
|
||||
e_data.ssr_resolve_sh = DRW_shader_create_fullscreen(ssr_shader_str, SHADER_DEFINES "#define STEP_RESOLVE\n");
|
||||
|
||||
MEM_freeN(ssr_shader_str);
|
||||
|
||||
e_data.volumetric_upsample_sh = DRW_shader_create_fullscreen(datatoc_volumetric_frag_glsl, "#define STEP_UPSAMPLE\n");
|
||||
|
||||
@@ -612,20 +631,26 @@ 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);
|
||||
psl->ssr_raytrace = DRW_pass_create("SSR 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_uniform_buffer(grp, "normalBuffer", &txl->ssr_normal_input);
|
||||
DRW_shgroup_uniform_buffer(grp, "specRoughBuffer", &txl->ssr_specrough_input);
|
||||
DRW_shgroup_call_add(grp, quad, NULL);
|
||||
|
||||
psl->ssr_resolve = DRW_pass_create("Raytrace", DRW_STATE_WRITE_COLOR);
|
||||
psl->ssr_resolve = DRW_pass_create("SSR Resolve", DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE);
|
||||
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_uniform_vec4(grp, "viewvecs[0]", (float *)stl->g_data->viewvecs, 2);
|
||||
DRW_shgroup_uniform_int(grp, "probe_count", &sldata->probes->num_render_cube, 1);
|
||||
DRW_shgroup_uniform_float(grp, "lodCubeMax", &sldata->probes->lod_cube_max, 1);
|
||||
DRW_shgroup_uniform_float(grp, "lodPlanarMax", &sldata->probes->lod_planar_max, 1);
|
||||
DRW_shgroup_uniform_buffer(grp, "probeCubes", &sldata->probe_pool);
|
||||
DRW_shgroup_uniform_buffer(grp, "probePlanars", &vedata->txl->planar_pool);
|
||||
DRW_shgroup_call_add(grp, quad, NULL);
|
||||
}
|
||||
|
||||
@@ -789,7 +814,6 @@ 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;
|
||||
@@ -822,7 +846,7 @@ void EEVEE_effects_do_volumetrics(EEVEE_SceneLayerData *sldata, EEVEE_Data *veda
|
||||
}
|
||||
}
|
||||
|
||||
void EEVEE_effects_do_ssr(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
|
||||
void EEVEE_effects_do_ssr(EEVEE_SceneLayerData *UNUSED(sldata), EEVEE_Data *vedata)
|
||||
{
|
||||
EEVEE_PassList *psl = vedata->psl;
|
||||
EEVEE_FramebufferList *fbl = vedata->fbl;
|
||||
@@ -833,6 +857,8 @@ void EEVEE_effects_do_ssr(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
|
||||
if ((effects->enabled_effects & EFFECT_SSR) != 0) {
|
||||
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
|
||||
|
||||
e_data.depth_src = dtxl->depth;
|
||||
|
||||
/* Raytrace at halfres. */
|
||||
DRW_framebuffer_bind(fbl->screen_tracing_fb);
|
||||
DRW_draw_pass(psl->ssr_raytrace);
|
||||
|
||||
@@ -28,114 +28,10 @@ flat in int shFace; /* Shadow layer we are rendering to. */
|
||||
|
||||
#define cameraForward normalize(ViewMatrixInverse[2].xyz)
|
||||
#define cameraPos ViewMatrixInverse[3].xyz
|
||||
|
||||
#define cameraVec ((ProjectionMatrix[3][3] == 0.0) ? normalize(cameraPos - worldPosition) : cameraForward)
|
||||
#define viewCameraVec ((ProjectionMatrix[3][3] == 0.0) ? normalize(viewPosition) : vec3(0.0, 0.0, -1.0))
|
||||
|
||||
/* ------- Structures -------- */
|
||||
#ifdef VOLUMETRICS
|
||||
|
||||
struct Closure {
|
||||
vec3 absorption;
|
||||
vec3 scatter;
|
||||
vec3 emission;
|
||||
float anisotropy;
|
||||
};
|
||||
|
||||
#define CLOSURE_DEFAULT Closure(vec3(0.0), vec3(0.0), vec3(0.0), 0.0)
|
||||
|
||||
Closure closure_mix(Closure cl1, Closure cl2, float fac)
|
||||
{
|
||||
Closure cl;
|
||||
cl.absorption = mix(cl1.absorption, cl2.absorption, fac);
|
||||
cl.scatter = mix(cl1.scatter, cl2.scatter, fac);
|
||||
cl.emission = mix(cl1.emission, cl2.emission, fac);
|
||||
cl.anisotropy = mix(cl1.anisotropy, cl2.anisotropy, fac);
|
||||
return cl;
|
||||
}
|
||||
|
||||
Closure closure_add(Closure cl1, Closure cl2)
|
||||
{
|
||||
Closure cl;
|
||||
cl.absorption = cl1.absorption + cl2.absorption;
|
||||
cl.scatter = cl1.scatter + cl2.scatter;
|
||||
cl.emission = cl1.emission + cl2.emission;
|
||||
cl.anisotropy = (cl1.anisotropy + cl2.anisotropy) / 2.0; /* Average phase (no multi lobe) */
|
||||
return cl;
|
||||
}
|
||||
#else
|
||||
|
||||
struct Closure {
|
||||
vec3 radiance;
|
||||
float opacity;
|
||||
vec4 ssr_data;
|
||||
vec2 ssr_normal;
|
||||
int ssr_id;
|
||||
};
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
Closure closure_add(Closure cl1, Closure cl2)
|
||||
{
|
||||
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 */
|
||||
|
||||
/* TODO find a better place */
|
||||
#ifdef USE_MULTIPLY
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
#define NODETREE_EXEC
|
||||
void main()
|
||||
{
|
||||
Closure cl = nodetree_exec();
|
||||
fragColor = vec4(mix(vec3(1.0), cl.radiance, cl.opacity), 1.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct LightData {
|
||||
vec4 position_influence; /* w : InfluenceRadius */
|
||||
vec4 color_spec; /* w : Spec Intensity */
|
||||
@@ -194,8 +90,6 @@ struct ShadowCascadeData {
|
||||
vec4 bias;
|
||||
};
|
||||
|
||||
#define cameraVec ((ProjectionMatrix[3][3] == 0.0) ? normalize(cameraPos - worldPosition) : cameraForward)
|
||||
|
||||
/* ------- Convenience functions --------- */
|
||||
|
||||
vec3 mul(mat3 m, vec3 v) { return m * v; }
|
||||
@@ -364,6 +258,11 @@ vec3 get_view_space_from_depth(vec2 uvcoords, float depth)
|
||||
}
|
||||
}
|
||||
|
||||
vec3 get_world_space_from_depth(vec2 uvcoords, float depth)
|
||||
{
|
||||
return (ViewMatrixInverse * vec4(get_view_space_from_depth(uvcoords, depth), 1.0)).xyz;
|
||||
}
|
||||
|
||||
vec3 get_specular_dominant_dir(vec3 N, vec3 V, float roughness)
|
||||
{
|
||||
vec3 R = -reflect(V, N);
|
||||
@@ -377,6 +276,26 @@ float specular_occlusion(float NV, float AO, float roughness)
|
||||
return saturate(pow(NV + AO, roughness) - 1.0 + AO);
|
||||
}
|
||||
|
||||
/* ---- Encode / Decode Normal buffer data ---- */
|
||||
/* From http://aras-p.info/texts/CompactNormalStorage.html
|
||||
* Using Method #4: Spheremap Transform */
|
||||
vec2 normal_encode(vec3 n, vec3 view)
|
||||
{
|
||||
float p = sqrt(n.z * 8.0 + 8.0);
|
||||
return n.xy / p + 0.5;
|
||||
}
|
||||
|
||||
vec3 normal_decode(vec2 enc, vec3 view)
|
||||
{
|
||||
vec2 fenc = enc * 4.0 - 2.0;
|
||||
float f = dot(fenc, fenc);
|
||||
float g = sqrt(1.0 - f / 4.0);
|
||||
vec3 n;
|
||||
n.xy = fenc*g;
|
||||
n.z = 1 - f / 2;
|
||||
return n;
|
||||
}
|
||||
|
||||
/* Fresnel */
|
||||
vec3 F_schlick(vec3 f0, float cos_theta)
|
||||
{
|
||||
@@ -443,4 +362,110 @@ float bsdf_ggx(vec3 N, vec3 L, vec3 V, float roughness)
|
||||
void accumulate_light(vec3 light, float fac, inout vec4 accum)
|
||||
{
|
||||
accum += vec4(light, 1.0) * min(fac, (1.0 - accum.a));
|
||||
}
|
||||
}
|
||||
|
||||
/* --------- Closure ---------- */
|
||||
#ifdef VOLUMETRICS
|
||||
|
||||
struct Closure {
|
||||
vec3 absorption;
|
||||
vec3 scatter;
|
||||
vec3 emission;
|
||||
float anisotropy;
|
||||
};
|
||||
|
||||
#define CLOSURE_DEFAULT Closure(vec3(0.0), vec3(0.0), vec3(0.0), 0.0)
|
||||
|
||||
Closure closure_mix(Closure cl1, Closure cl2, float fac)
|
||||
{
|
||||
Closure cl;
|
||||
cl.absorption = mix(cl1.absorption, cl2.absorption, fac);
|
||||
cl.scatter = mix(cl1.scatter, cl2.scatter, fac);
|
||||
cl.emission = mix(cl1.emission, cl2.emission, fac);
|
||||
cl.anisotropy = mix(cl1.anisotropy, cl2.anisotropy, fac);
|
||||
return cl;
|
||||
}
|
||||
|
||||
Closure closure_add(Closure cl1, Closure cl2)
|
||||
{
|
||||
Closure cl;
|
||||
cl.absorption = cl1.absorption + cl2.absorption;
|
||||
cl.scatter = cl1.scatter + cl2.scatter;
|
||||
cl.emission = cl1.emission + cl2.emission;
|
||||
cl.anisotropy = (cl1.anisotropy + cl2.anisotropy) / 2.0; /* Average phase (no multi lobe) */
|
||||
return cl;
|
||||
}
|
||||
#else
|
||||
|
||||
struct Closure {
|
||||
vec3 radiance;
|
||||
float opacity;
|
||||
vec4 ssr_data;
|
||||
vec2 ssr_normal;
|
||||
int ssr_id;
|
||||
};
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
Closure closure_add(Closure cl1, Closure cl2)
|
||||
{
|
||||
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 */
|
||||
|
||||
/* TODO find a better place */
|
||||
#ifdef USE_MULTIPLY
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
#define NODETREE_EXEC
|
||||
void main()
|
||||
{
|
||||
Closure cl = nodetree_exec();
|
||||
fragColor = vec4(mix(vec3(1.0), cl.radiance, cl.opacity), 1.0);
|
||||
}
|
||||
#endif
|
||||
@@ -12,7 +12,7 @@ Closure nodetree_exec(void)
|
||||
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);
|
||||
Closure result = Closure(radiance, 1.0, vec4(ssr_spec, roughness), normal_encode(normalize(viewNormal), viewCameraVec), 0);
|
||||
|
||||
#if !defined(USE_ALPHA_BLEND)
|
||||
result.opacity = length(viewPosition);
|
||||
|
||||
@@ -10,6 +10,13 @@ layout(location = 1) out vec4 pdfData;
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 fullres_texel = ivec2(gl_FragCoord.xy) * 2;
|
||||
float depth = texelFetch(depthBuffer, fullres_texel, 0).r;
|
||||
|
||||
/* Early discard */
|
||||
if (depth == 1.0)
|
||||
discard;
|
||||
|
||||
hitData = vec4(0.2);
|
||||
pdfData = vec4(0.5);
|
||||
}
|
||||
@@ -23,14 +30,63 @@ uniform sampler2D specroughBuffer;
|
||||
uniform sampler2D hitBuffer;
|
||||
uniform sampler2D pdfBuffer;
|
||||
|
||||
uniform int probe_count;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
void fallback_cubemap(vec3 N, vec3 V, vec3 W, float roughness, float roughnessSquared, inout vec4 spec_accum)
|
||||
{
|
||||
/* 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];
|
||||
|
||||
float fade = probe_attenuation_cube(cd, W);
|
||||
|
||||
if (fade > 0.0) {
|
||||
vec3 spec = probe_evaluate_cube(float(i), cd, W, 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);
|
||||
}
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 halfres_texel = ivec2(gl_FragCoord.xy / 2.0);
|
||||
ivec2 fullres_texel = ivec2(gl_FragCoord.xy);
|
||||
vec2 uvs = gl_FragCoord.xy / vec2(textureSize(depthBuffer, 0));
|
||||
|
||||
fragColor = vec4(texelFetch(specroughBuffer, fullres_texel, 0).aaa, 1.0);
|
||||
float depth = textureLod(depthBuffer, uvs, 0.0).r;
|
||||
|
||||
/* Early discard */
|
||||
if (depth == 1.0)
|
||||
discard;
|
||||
|
||||
vec3 worldPosition = get_world_space_from_depth(uvs, depth);
|
||||
vec3 V = cameraVec;
|
||||
vec3 N = mat3(ViewMatrixInverse) * normal_decode(texelFetch(normalBuffer, fullres_texel, 0).rg, V);
|
||||
vec4 speccol_roughness = texelFetch(specroughBuffer, fullres_texel, 0).rgba;
|
||||
float roughness = speccol_roughness.a;
|
||||
float roughnessSquared = roughness * roughness;
|
||||
|
||||
vec4 spec_accum = vec4(0.0);
|
||||
|
||||
/* Resolve SSR and compute contribution */
|
||||
|
||||
/* If SSR contribution is not 1.0, blend with cubemaps */
|
||||
if (spec_accum.a < 1.0) {
|
||||
fallback_cubemap(N, V, worldPosition, roughness, roughnessSquared, spec_accum);
|
||||
}
|
||||
|
||||
fragColor = vec4(spec_accum.rgb * speccol_roughness.rgb, 1.0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -8,18 +8,6 @@ layout(std140) uniform shadow_block {
|
||||
ShadowCascadeData shadows_cascade_data[MAX_SHADOW_CASCADE];
|
||||
};
|
||||
|
||||
layout(std140) uniform probe_block {
|
||||
CubeData probes_data[MAX_PROBE];
|
||||
};
|
||||
|
||||
layout(std140) uniform grid_block {
|
||||
GridData grids_data[MAX_GRID];
|
||||
};
|
||||
|
||||
layout(std140) uniform planar_block {
|
||||
PlanarData planars_data[MAX_PLANAR];
|
||||
};
|
||||
|
||||
layout(std140) uniform light_block {
|
||||
LightData lights_data[MAX_LIGHT];
|
||||
};
|
||||
|
||||
@@ -60,6 +60,28 @@ struct GridData {
|
||||
#define g_resolution resolution_offset.xyz
|
||||
#define g_offset resolution_offset.w
|
||||
|
||||
#ifndef MAX_PROBE
|
||||
#define MAX_PROBE 1
|
||||
#endif
|
||||
#ifndef MAX_GRID
|
||||
#define MAX_GRID 1
|
||||
#endif
|
||||
#ifndef MAX_PLANAR
|
||||
#define MAX_PLANAR 1
|
||||
#endif
|
||||
|
||||
layout(std140) uniform probe_block {
|
||||
CubeData probes_data[MAX_PROBE];
|
||||
};
|
||||
|
||||
layout(std140) uniform grid_block {
|
||||
GridData grids_data[MAX_GRID];
|
||||
};
|
||||
|
||||
layout(std140) uniform planar_block {
|
||||
PlanarData planars_data[MAX_PLANAR];
|
||||
};
|
||||
|
||||
/* ----------- Functions --------- */
|
||||
|
||||
float probe_attenuation_cube(CubeData pd, vec3 W)
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
|
||||
uniform int probeIdx;
|
||||
|
||||
layout(std140) uniform planar_block {
|
||||
PlanarData planars_data[MAX_PLANAR];
|
||||
};
|
||||
|
||||
in vec3 worldPosition;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
@@ -2687,8 +2687,8 @@ void node_bsdf_glossy(vec4 color, float roughness, vec3 N, float ssr_id, out Clo
|
||||
#ifdef EEVEE_ENGINE
|
||||
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));
|
||||
vec3 vN = normalize(mat3(ViewMatrix) * N);
|
||||
result = Closure(L * color.rgb, 1.0, vec4(ssr_spec * color.rgb, roughness), normal_encode(vN, viewCameraVec), int(ssr_id));
|
||||
#else
|
||||
/* ambient light */
|
||||
vec3 L = vec3(0.2);
|
||||
@@ -2838,8 +2838,8 @@ void node_bsdf_principled_simple(vec4 base_color, float subsurface, vec3 subsurf
|
||||
convert_metallic_to_specular_tinted(base_color.rgb, metallic, specular, specular_tint, diffuse, f0);
|
||||
|
||||
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));
|
||||
vec3 vN = normalize(mat3(ViewMatrix) * N);
|
||||
result = Closure(L, 1.0, vec4(ssr_spec, roughness), normal_encode(vN, viewCameraVec), 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,
|
||||
@@ -2882,8 +2882,8 @@ void node_bsdf_principled_clearcoat(vec4 base_color, float subsurface, vec3 subs
|
||||
#else
|
||||
|
||||
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));
|
||||
vec3 vN = normalize(mat3(ViewMatrix) * N);
|
||||
result = Closure(L, 1.0, vec4(ssr_spec, roughness), normal_encode(vN, viewCameraVec), int(ssr_id));
|
||||
#endif
|
||||
|
||||
#else
|
||||
@@ -4047,8 +4047,8 @@ void node_eevee_metallic(
|
||||
convert_metallic_to_specular(basecol.rgb, metallic, specular, diffuse, f0);
|
||||
|
||||
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));
|
||||
vec3 vN = normalize(mat3(ViewMatrix) * normal);
|
||||
result = Closure(L + emissive.rgb, 1.0 - transp, vec4(ssr_spec, roughness), normal_encode(vN, viewCameraVec), int(ssr_id));
|
||||
}
|
||||
|
||||
void node_eevee_specular(
|
||||
@@ -4059,8 +4059,8 @@ void node_eevee_specular(
|
||||
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));
|
||||
vec3 vN = normalize(mat3(ViewMatrix) * normal);
|
||||
result = Closure(L + emissive.rgb, 1.0 - transp, vec4(ssr_spec, roughness), normal_encode(vN, viewCameraVec), int(ssr_id));
|
||||
}
|
||||
|
||||
void node_output_eevee_material(Closure surface, out Closure result)
|
||||
|
||||
Reference in New Issue
Block a user