Eevee: Make MinmaxZ compatible with textureArray

This commit is contained in:
2017-07-23 20:33:29 +02:00
parent 85f1b7358a
commit 7585c82722
5 changed files with 53 additions and 13 deletions

View File

@@ -73,6 +73,8 @@ static struct {
struct GPUShader *maxz_downlevel_sh;
struct GPUShader *minz_downdepth_sh;
struct GPUShader *maxz_downdepth_sh;
struct GPUShader *minz_downdepth_layer_sh;
struct GPUShader *maxz_downdepth_layer_sh;
struct GPUShader *minz_copydepth_sh;
struct GPUShader *maxz_copydepth_sh;
@@ -101,6 +103,7 @@ static struct {
struct GPUTexture *depth_src;
struct GPUTexture *color_src;
int depth_src_layer;
float pixelprojmat[4][4];
} e_data = {NULL}; /* Engine data */
@@ -246,6 +249,12 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
"#define INPUT_DEPTH\n");
e_data.maxz_downdepth_sh = DRW_shader_create_fullscreen(datatoc_effect_minmaxz_frag_glsl, "#define MAX_PASS\n"
"#define INPUT_DEPTH\n");
e_data.minz_downdepth_layer_sh = DRW_shader_create_fullscreen(datatoc_effect_minmaxz_frag_glsl, "#define MIN_PASS\n"
"#define LAYERED\n"
"#define INPUT_DEPTH\n");
e_data.maxz_downdepth_layer_sh = DRW_shader_create_fullscreen(datatoc_effect_minmaxz_frag_glsl, "#define MAX_PASS\n"
"#define LAYERED\n"
"#define INPUT_DEPTH\n");
e_data.minz_copydepth_sh = DRW_shader_create_fullscreen(datatoc_effect_minmaxz_frag_glsl, "#define MIN_PASS\n"
"#define INPUT_DEPTH\n"
"#define COPY_DEPTH\n");
@@ -814,6 +823,18 @@ void EEVEE_effects_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_buffer(grp, "depthBuffer", &e_data.depth_src);
DRW_shgroup_call_add(grp, quad, NULL);
psl->minz_downdepth_layer_ps = DRW_pass_create("HiZ Min Copy DepthLayer Halfres", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS);
grp = DRW_shgroup_create(e_data.minz_downdepth_layer_sh, psl->minz_downdepth_layer_ps);
DRW_shgroup_uniform_buffer(grp, "depthBuffer", &e_data.depth_src);
DRW_shgroup_uniform_int(grp, "depthLayer", &e_data.depth_src_layer, 1);
DRW_shgroup_call_add(grp, quad, NULL);
psl->maxz_downdepth_layer_ps = DRW_pass_create("HiZ Max Copy DepthLayer Halfres", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS);
grp = DRW_shgroup_create(e_data.maxz_downdepth_layer_sh, psl->maxz_downdepth_layer_ps);
DRW_shgroup_uniform_buffer(grp, "depthBuffer", &e_data.depth_src);
DRW_shgroup_uniform_int(grp, "depthLayer", &e_data.depth_src_layer, 1);
DRW_shgroup_call_add(grp, quad, NULL);
/* Copy depth buffer to halfres top level of HiZ */
psl->minz_copydepth_ps = DRW_pass_create("HiZ Min Copy Depth Fullres", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS);
grp = DRW_shgroup_create(e_data.minz_copydepth_sh, psl->minz_copydepth_ps);
@@ -944,7 +965,7 @@ static void simple_downsample_cb(void *vedata, int UNUSED(level))
DRW_draw_pass(psl->color_downsample_ps);
}
void EEVEE_create_minmax_buffer(EEVEE_Data *vedata, GPUTexture *depth_src)
void EEVEE_create_minmax_buffer(EEVEE_Data *vedata, GPUTexture *depth_src, int layer)
{
EEVEE_PassList *psl = vedata->psl;
EEVEE_FramebufferList *fbl = vedata->fbl;
@@ -956,7 +977,13 @@ void EEVEE_create_minmax_buffer(EEVEE_Data *vedata, GPUTexture *depth_src)
/* Copy depth buffer to min texture top level */
DRW_framebuffer_texture_attach(fbl->downsample_fb, stl->g_data->minzbuffer, 0, 0);
DRW_framebuffer_bind(fbl->downsample_fb);
DRW_draw_pass(psl->minz_downdepth_ps);
if (layer >= 0) {
e_data.depth_src_layer = layer;
DRW_draw_pass(psl->minz_downdepth_layer_ps);
}
else {
DRW_draw_pass(psl->minz_downdepth_ps);
}
DRW_framebuffer_texture_detach(stl->g_data->minzbuffer);
/* Create lower levels */
@@ -965,7 +992,13 @@ void EEVEE_create_minmax_buffer(EEVEE_Data *vedata, GPUTexture *depth_src)
/* Copy depth buffer to max texture top level */
DRW_framebuffer_texture_attach(fbl->downsample_fb, txl->maxzbuffer, 0, 0);
DRW_framebuffer_bind(fbl->downsample_fb);
DRW_draw_pass(psl->maxz_downdepth_ps);
if (layer >= 0) {
e_data.depth_src_layer = layer;
DRW_draw_pass(psl->maxz_downdepth_layer_ps);
}
else {
DRW_draw_pass(psl->maxz_downdepth_ps);
}
DRW_framebuffer_texture_detach(txl->maxzbuffer);
/* Create lower levels */
@@ -1270,6 +1303,8 @@ void EEVEE_effects_free(void)
DRW_SHADER_FREE_SAFE(e_data.maxz_downlevel_sh);
DRW_SHADER_FREE_SAFE(e_data.minz_downdepth_sh);
DRW_SHADER_FREE_SAFE(e_data.maxz_downdepth_sh);
DRW_SHADER_FREE_SAFE(e_data.minz_downdepth_layer_sh);
DRW_SHADER_FREE_SAFE(e_data.maxz_downdepth_layer_sh);
DRW_SHADER_FREE_SAFE(e_data.minz_copydepth_sh);
DRW_SHADER_FREE_SAFE(e_data.maxz_copydepth_sh);

View File

@@ -169,7 +169,7 @@ static void EEVEE_draw_scene(void *vedata)
DRW_draw_pass(psl->depth_pass_cull);
/* Create minmax texture */
EEVEE_create_minmax_buffer(vedata, dtxl->depth);
EEVEE_create_minmax_buffer(vedata, dtxl->depth, -1);
/* Restore main FB */
DRW_framebuffer_bind(fbl->main);

View File

@@ -1071,12 +1071,8 @@ static void render_scene_to_planar(
/* XXX */
GPUTexture *tmp_planar_pool = txl->planar_pool;
GPUTexture *tmp_planar_depth = txl->planar_depth;
GPUTexture *tmp_minz = stl->g_data->minzbuffer;
GPUTexture *tmp_maxz = txl->maxzbuffer;
txl->planar_pool = e_data.planar_pool_placeholder;
stl->g_data->minzbuffer = e_data.depth_placeholder;
txl->planar_depth = e_data.depth_array_placeholder;
txl->maxzbuffer = e_data.depth_placeholder;
DRW_viewport_matrix_override_set(persmat, DRW_MAT_PERS);
DRW_viewport_matrix_override_set(persinv, DRW_MAT_PERSINV);
@@ -1095,7 +1091,7 @@ static void render_scene_to_planar(
DRW_draw_pass(psl->depth_pass_clip);
DRW_draw_pass(psl->depth_pass_clip_cull);
EEVEE_create_minmax_buffer(vedata, txl->planar_depth);
EEVEE_create_minmax_buffer(vedata, tmp_planar_depth, layer);
/* Rebind Planar FB */
DRW_framebuffer_bind(fbl->planarref_fb);
@@ -1110,8 +1106,6 @@ static void render_scene_to_planar(
/* Restore */
txl->planar_pool = tmp_planar_pool;
txl->planar_depth = tmp_planar_depth;
stl->g_data->minzbuffer = tmp_minz;
txl->maxzbuffer = tmp_maxz;
DRW_viewport_matrix_override_unset(DRW_MAT_PERS);
DRW_viewport_matrix_override_unset(DRW_MAT_PERSINV);
DRW_viewport_matrix_override_unset(DRW_MAT_VIEW);

View File

@@ -115,6 +115,8 @@ typedef struct EEVEE_PassList {
struct DRWPass *maxz_downlevel_ps;
struct DRWPass *minz_downdepth_ps;
struct DRWPass *maxz_downdepth_ps;
struct DRWPass *minz_downdepth_layer_ps;
struct DRWPass *maxz_downdepth_layer_ps;
struct DRWPass *minz_copydepth_ps;
struct DRWPass *maxz_copydepth_ps;
@@ -517,7 +519,7 @@ void EEVEE_lightprobes_free(void);
/* eevee_effects.c */
void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_effects_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_create_minmax_buffer(EEVEE_Data *vedata, struct GPUTexture *depth_src);
void EEVEE_create_minmax_buffer(EEVEE_Data *vedata, struct GPUTexture *depth_src, int layer);
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);

View File

@@ -4,11 +4,20 @@
* Adapted from http://rastergrid.com/blog/2010/10/hierarchical-z-map-based-occlusion-culling/
**/
#ifdef LAYERED
uniform sampler2DArray depthBuffer;
uniform int depthLayer;
#else
uniform sampler2D depthBuffer;
#endif
float sampleLowerMip(ivec2 texel)
{
#ifdef LAYERED
return texelFetch(depthBuffer, ivec3(texel, depthLayer), 0).r;
#else
return texelFetch(depthBuffer, texel, 0).r;
#endif
}
void minmax(inout float out_val, float in_val)
@@ -23,7 +32,7 @@ void minmax(inout float out_val, float in_val)
void main()
{
ivec2 texelPos = ivec2(gl_FragCoord.xy);
ivec2 mipsize = textureSize(depthBuffer, 0);
ivec2 mipsize = textureSize(depthBuffer, 0).xy;
#ifndef COPY_DEPTH
texelPos *= 2;