Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2017-06-26 21:37:41 +0300
committerClément Foucault <foucault.clem@gmail.com>2017-06-26 22:04:53 +0300
commit0394c04a7f0301803a5084ee5a5cb2f294d5de70 (patch)
tree9e58f018dd66f95175e5e6f40b1be6acca5b1b1e /source/blender/draw/engines/eevee
parentdaf02baaeaaf8f0a7c68ae236a2d0782c08aea2f (diff)
Eevee: Add Planar reflection blurring.
This method is very cheap and inaccurate. This will fill the gap untill better model is supported.
Diffstat (limited to 'source/blender/draw/engines/eevee')
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c3
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightprobes.c53
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h6
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl1
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_frag.glsl27
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_geom.glsl24
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_vert.glsl10
-rw-r--r--source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl16
8 files changed, 135 insertions, 5 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index c024eb609b3..88f16e41d6b 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -71,12 +71,11 @@ static void EEVEE_engine_init(void *ved)
static void EEVEE_cache_init(void *vedata)
{
EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
- EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
EEVEE_SceneLayerData *sldata = EEVEE_scene_layer_data_get();
EEVEE_materials_cache_init(vedata);
EEVEE_lights_cache_init(sldata, psl);
- EEVEE_lightprobes_cache_init(sldata, psl, stl);
+ EEVEE_lightprobes_cache_init(sldata, vedata);
EEVEE_effects_cache_init(vedata);
}
diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c
index 8ec603030c5..b85116adc81 100644
--- a/source/blender/draw/engines/eevee/eevee_lightprobes.c
+++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c
@@ -57,6 +57,7 @@ static struct {
struct GPUShader *probe_filter_diffuse_sh;
struct GPUShader *probe_grid_display_sh;
struct GPUShader *probe_planar_display_sh;
+ struct GPUShader *probe_planar_downsample_sh;
struct GPUShader *probe_cube_display_sh;
struct GPUTexture *hammersley;
@@ -78,6 +79,9 @@ extern char datatoc_lightprobe_geom_glsl[];
extern char datatoc_lightprobe_vert_glsl[];
extern char datatoc_lightprobe_planar_display_frag_glsl[];
extern char datatoc_lightprobe_planar_display_vert_glsl[];
+extern char datatoc_lightprobe_planar_downsample_frag_glsl[];
+extern char datatoc_lightprobe_planar_downsample_geom_glsl[];
+extern char datatoc_lightprobe_planar_downsample_vert_glsl[];
extern char datatoc_lightprobe_cube_display_frag_glsl[];
extern char datatoc_lightprobe_cube_display_vert_glsl[];
extern char datatoc_lightprobe_grid_display_frag_glsl[];
@@ -254,6 +258,12 @@ void EEVEE_lightprobes_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *UNUSED(ved
MEM_freeN(shader_str);
+ e_data.probe_planar_downsample_sh = DRW_shader_create(
+ datatoc_lightprobe_planar_downsample_vert_glsl,
+ datatoc_lightprobe_planar_downsample_geom_glsl,
+ datatoc_lightprobe_planar_downsample_frag_glsl,
+ NULL);
+
e_data.hammersley = create_hammersley_sample_texture(1024);
}
@@ -296,8 +306,11 @@ void EEVEE_lightprobes_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *UNUSED(ved
}
}
-void EEVEE_lightprobes_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl, EEVEE_StorageList *stl)
+void EEVEE_lightprobes_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
{
+ EEVEE_TextureList *txl = vedata->txl;
+ EEVEE_PassList *psl = vedata->psl;
+ EEVEE_StorageList *stl = vedata->stl;
EEVEE_LightProbesInfo *pinfo = sldata->probes;
pinfo->num_cube = 1; /* at least one for the world */
@@ -406,6 +419,15 @@ void EEVEE_lightprobes_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_PassList *
DRW_shgroup_uniform_float(grp, "lodMax", &sldata->probes->lodmax, 1);
DRW_shgroup_uniform_buffer(grp, "probeCubes", &sldata->probe_pool);
}
+
+ {
+ psl->probe_planar_downsample_ps = DRW_pass_create("LightProbe Planar Downsample", DRW_STATE_WRITE_COLOR);
+
+ struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get();
+ DRWShadingGroup *grp = stl->g_data->planar_downsample = DRW_shgroup_instance_create(e_data.probe_planar_downsample_sh, psl->probe_planar_downsample_ps, geom);
+ DRW_shgroup_uniform_buffer(grp, "source", &txl->planar_pool);
+ DRW_shgroup_uniform_vec2(grp, "texelSize", stl->g_data->texel_size, 1);
+ }
}
void EEVEE_lightprobes_cache_add(EEVEE_SceneLayerData *sldata, Object *ob)
@@ -688,6 +710,7 @@ static void EEVEE_lightprobes_updates(EEVEE_SceneLayerData *sldata, EEVEE_PassLi
void EEVEE_lightprobes_cache_finish(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
{
+ EEVEE_StorageList *stl = vedata->stl;
EEVEE_LightProbesInfo *pinfo = sldata->probes;
Object *ob;
@@ -705,6 +728,9 @@ void EEVEE_lightprobes_cache_finish(EEVEE_SceneLayerData *sldata, EEVEE_Data *ve
/* XXX this should be run each frame as it ensure planar_depth is set */
planar_pool_ensure_alloc(vedata, pinfo->num_planar);
+ /* Setup planar filtering pass */
+ DRW_shgroup_set_instance_count(stl->g_data->planar_downsample, pinfo->num_planar);
+
if (!sldata->probe_pool) {
sldata->probe_pool = DRW_texture_create_2D_array(PROBE_OCTAHEDRON_SIZE, PROBE_OCTAHEDRON_SIZE, max_ff(1, pinfo->num_cube),
DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL);
@@ -772,6 +798,24 @@ void EEVEE_lightprobes_cache_finish(EEVEE_SceneLayerData *sldata, EEVEE_Data *ve
DRW_uniformbuffer_update(sldata->planar_ubo, &sldata->probes->planar_data);
}
+static void downsample_planar(void *vedata, int level)
+{
+ EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
+ EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
+
+ const float *size = DRW_viewport_size_get();
+ copy_v2_v2(stl->g_data->texel_size, size);
+ for (int i = 0; i < level - 1; ++i) {
+ stl->g_data->texel_size[0] /= 2.0f;
+ stl->g_data->texel_size[1] /= 2.0f;
+ min_ff(floorf(stl->g_data->texel_size[0]), 1.0f);
+ min_ff(floorf(stl->g_data->texel_size[1]), 1.0f);
+ }
+ invert_v2(stl->g_data->texel_size);
+
+ DRW_draw_pass(psl->probe_planar_downsample_ps);
+}
+
/* Glossy filter probe_rt to probe_pool at index probe_idx */
static void glossy_filter_probe(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl, int probe_idx)
{
@@ -1099,6 +1143,7 @@ static void lightprobe_cell_location_get(EEVEE_LightGrid *egrid, int cell_idx, f
void EEVEE_lightprobes_refresh(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
{
+ EEVEE_TextureList *txl = vedata->txl;
EEVEE_PassList *psl = vedata->psl;
EEVEE_LightProbesInfo *pinfo = sldata->probes;
Object *ob;
@@ -1246,6 +1291,11 @@ update_planar:
ped->probe_id = i;
}
}
+
+ /* If there is at least one planar probe */
+ if (pinfo->num_planar > 0) {
+ DRW_framebuffer_recursive_downsample(vedata->fbl->minmaxz_fb, txl->planar_pool, 5, &downsample_planar, vedata);
+ }
}
void EEVEE_lightprobes_free(void)
@@ -1255,6 +1305,7 @@ void EEVEE_lightprobes_free(void)
DRW_SHADER_FREE_SAFE(e_data.probe_filter_diffuse_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_grid_display_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_planar_display_sh);
+ DRW_SHADER_FREE_SAFE(e_data.probe_planar_downsample_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_cube_display_sh);
DRW_TEXTURE_FREE_SAFE(e_data.hammersley);
DRW_TEXTURE_FREE_SAFE(e_data.planar_pool_placeholder);
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index a1abb6c71e2..14b0d270dc9 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -78,6 +78,7 @@ typedef struct EEVEE_PassList {
struct DRWPass *probe_glossy_compute;
struct DRWPass *probe_diffuse_compute;
struct DRWPass *probe_display;
+ struct DRWPass *probe_planar_downsample_ps;
/* Effects */
struct DRWPass *motion_blur;
@@ -394,10 +395,13 @@ typedef struct EEVEE_PrivateData {
struct DRWShadingGroup *depth_shgrp_clip;
struct DRWShadingGroup *depth_shgrp_clip_cull;
struct DRWShadingGroup *cube_display_shgrp;
+ struct DRWShadingGroup *planar_downsample;
struct GHash *material_hash;
struct GHash *hair_material_hash;
struct GPUTexture *minmaxz;
float background_alpha; /* TODO find a better place for this. */
+ /* For planar probes */
+ float texel_size[2];
} EEVEE_PrivateData; /* Transient data */
/* eevee_data.c */
@@ -431,7 +435,7 @@ void EEVEE_lights_free(void);
/* eevee_lightprobes.c */
void EEVEE_lightprobes_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata);
-void EEVEE_lightprobes_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl, EEVEE_StorageList *stl);
+void EEVEE_lightprobes_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_lightprobes_cache_add(EEVEE_SceneLayerData *sldata, Object *ob);
void EEVEE_lightprobes_cache_finish(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_lightprobes_refresh(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata);
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 2aa51039e71..3327c5c4427 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
@@ -1,5 +1,6 @@
#define M_PI 3.14159265358979323846 /* pi */
+#define M_2PI 6.28318530717958647692 /* 2*pi */
#define M_PI_2 1.57079632679489661923 /* pi/2 */
#define M_1_PI 0.318309886183790671538 /* 1/pi */
#define M_1_2PI 0.159154943091895335768 /* 1/(2*pi) */
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_frag.glsl
new file mode 100644
index 00000000000..fa70fb5590f
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_frag.glsl
@@ -0,0 +1,27 @@
+/**
+ * Simple downsample shader. Takes the average of the 4 texels of lower mip.
+ **/
+
+uniform sampler2DArray source;
+uniform vec2 texelSize;
+
+in vec2 uvs;
+flat in float layer;
+
+out vec4 FragColor;
+
+void main()
+{
+ /* Reconstructing Target uvs like this avoid missing pixels */
+ vec2 uvs = floor(gl_FragCoord.xy) * 2.0 * texelSize + texelSize;
+
+ /* Downsample with a 4x4 box filter */
+ vec4 d = texelSize.xyxy * vec4(-1, -1, +1, +1);
+
+ FragColor = texture(source, vec3(uvs + d.xy, layer)).rgba;
+ FragColor += texture(source, vec3(uvs + d.zy, layer)).rgba;
+ FragColor += texture(source, vec3(uvs + d.xw, layer)).rgba;
+ FragColor += texture(source, vec3(uvs + d.zw, layer)).rgba;
+
+ FragColor /= 4.0;
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_geom.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_geom.glsl
new file mode 100644
index 00000000000..40b04c986f3
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_geom.glsl
@@ -0,0 +1,24 @@
+
+layout(triangles) in;
+layout(triangle_strip, max_vertices=3) out;
+
+in int instance[];
+in vec2 vPos[];
+
+flat out float layer;
+
+void main() {
+ gl_Layer = instance[0];
+ layer = float(instance[0]);
+
+ gl_Position = vec4(vPos[0], 0.0, 0.0);
+ EmitVertex();
+
+ gl_Position = vec4(vPos[1], 0.0, 0.0);
+ EmitVertex();
+
+ gl_Position = vec4(vPos[2], 0.0, 0.0);
+ EmitVertex();
+
+ EndPrimitive();
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_vert.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_vert.glsl
new file mode 100644
index 00000000000..ac4e3da4158
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_vert.glsl
@@ -0,0 +1,10 @@
+
+in vec2 pos;
+
+out int instance;
+out vec2 vPos;
+
+void main() {
+ instance = gl_InstanceID;
+ vPos = pos;
+} \ No newline at end of file
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 8202acc959a..d6cc170f025 100644
--- a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
@@ -409,7 +409,21 @@ vec3 eevee_surface_lit(vec3 world_normal, vec3 albedo, vec3 f0, float roughness,
refco = pd.reflectionmat * vec4(ref_pos, 1.0);
refco.xy /= refco.w;
- vec3 sample = textureLod(probePlanars, vec3(refco.xy, i), 0.0).rgb;
+ /* Distance to roughness */
+ float linear_roughness = sqrt(roughness);
+ float distance_roughness = min(linear_roughness, ref_depth * linear_roughness);
+ linear_roughness = mix(distance_roughness, linear_roughness, linear_roughness);
+
+ /* Decrease influence for high roughness */
+ influ_spec *= saturate((1.0 - linear_roughness) * 5.0 - 2.0);
+
+ float lod = linear_roughness * 2.5 * 5.0;
+ vec3 sample = textureLod(probePlanars, vec3(refco.xy, i), lod).rgb;
+
+ /* Use a second sample randomly rotated to blur out the lowres aspect */
+ vec2 rot_sample = (1.0 / vec2(textureSize(probePlanars, 0).xy)) * vec2(cos(rand.a * M_2PI), sin(rand.a * M_2PI)) * lod;
+ sample += textureLod(probePlanars, vec3(refco.xy + rot_sample, i), lod).rgb;
+ sample *= 0.5;
spec_accum.rgb += sample * influ_spec;
spec_accum.a += influ_spec;