Commit: 1d00a66f5db787759fdf211322b4683bb5458318 Author: Clément Foucault Date: Mon Jul 17 13:39:03 2017 +0200 Branches: blender2.8 https://developer.blender.org/rB1d00a66f5db787759fdf211322b4683bb5458318
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. =================================================================== M source/blender/draw/engines/eevee/eevee_effects.c M source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl M source/blender/draw/engines/eevee/shaders/default_frag.glsl M source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl M source/blender/draw/engines/eevee/shaders/lamps_lib.glsl M source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl M source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_frag.glsl M source/blender/gpu/shaders/gpu_shader_material.glsl =================================================================== diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c index 6c190d8b917..419b70092a4 100644 --- a/source/blender/draw/engines/eevee/eevee_effects.c +++ b/source/blender/draw/engines/eevee/eevee_effects.c @@ -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); diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl index 50b3309e93b..4c0e521a7f0 100644 --- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl @@ -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 @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs