Commit: 7f3ea60aa73420765b589ced96d75e2678538f86 Author: Clément Foucault Date: Mon Jun 25 17:41:47 2018 +0200 Branches: temp-eeveelightcache https://developer.blender.org/rB7f3ea60aa73420765b589ced96d75e2678538f86
Eevee: Add back planar reflection. =================================================================== M source/blender/draw/engines/eevee/eevee_engine.c M source/blender/draw/engines/eevee/eevee_lightprobes.c M source/blender/draw/engines/eevee/eevee_materials.c M source/blender/draw/engines/eevee/eevee_private.h M source/blender/draw/engines/eevee/eevee_render.c M source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl M source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl =================================================================== diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c index 215bd183f7e..7e66752368b 100644 --- a/source/blender/draw/engines/eevee/eevee_engine.c +++ b/source/blender/draw/engines/eevee/eevee_engine.c @@ -146,7 +146,7 @@ void EEVEE_cache_populate(void *vedata, Object *ob) /* TODO: Special case for dupli objects because we cannot save the object pointer. */ } else { - EEVEE_lightprobes_cache_add(sldata, ob); + EEVEE_lightprobes_cache_add(sldata, vedata, ob); } } else if (ob->type == OB_LAMP) { @@ -282,7 +282,9 @@ static void eevee_draw_background(void *vedata) EEVEE_subsurface_compute(sldata, vedata); EEVEE_reflection_compute(sldata, vedata); EEVEE_occlusion_draw_debug(sldata, vedata); - DRW_draw_pass(psl->probe_display); + if (psl->probe_display) { + DRW_draw_pass(psl->probe_display); + } EEVEE_refraction_compute(sldata, vedata); /* Opaque refraction */ diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c index e10bdfb26b8..a8ad25bc7c6 100644 --- a/source/blender/draw/engines/eevee/eevee_lightprobes.c +++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c @@ -103,6 +103,33 @@ extern char datatoc_bsdf_sampling_lib_glsl[]; extern GlobalsUboStorage ts; /* *********** FUNCTIONS *********** */ + +/* TODO find a better way than this. This does not support dupli objects if + * the original object is hidden. */ +bool EEVEE_lightprobes_obj_visibility_cb(bool vis_in, void *user_data) +{ + EEVEE_ObjectEngineData *oed = (EEVEE_ObjectEngineData *)user_data; + + /* test disabled if group is NULL */ + if (oed->test_data->collection == NULL) + return vis_in; + + if (oed->test_data->cached == false) + oed->ob_vis_dirty = true; + + /* early out, don't need to compute ob_vis yet. */ + if (vis_in == false) + return vis_in; + + if (oed->ob_vis_dirty) { + oed->ob_vis_dirty = false; + oed->ob_vis = BKE_collection_has_object_recursive(oed->test_data->collection, oed->ob); + oed->ob_vis = (oed->test_data->invert) ? !oed->ob_vis : oed->ob_vis; + } + + return vis_in && oed->ob_vis; +} + static struct GPUTexture *create_hammersley_sample_texture(int samples) { struct GPUTexture *tex; @@ -122,6 +149,39 @@ static struct GPUTexture *create_hammersley_sample_texture(int samples) return tex; } +static void planar_pool_ensure_alloc(EEVEE_Data *vedata, int num_planar_ref) +{ + EEVEE_TextureList *txl = vedata->txl; + + /* XXX TODO OPTIMISATION : This is a complete waist of texture memory. + * Instead of allocating each planar probe for each viewport, + * only alloc them once using the biggest viewport resolution. */ + const float *viewport_size = DRW_viewport_size_get(); + + /* TODO get screen percentage from layer setting */ + // const DRWContextState *draw_ctx = DRW_context_state_get(); + // ViewLayer *view_layer = draw_ctx->view_layer; + float screen_percentage = 1.0f; + + int width = (int)(viewport_size[0] * screen_percentage); + int height = (int)(viewport_size[1] * screen_percentage); + + /* We need an Array texture so allocate it ourself */ + if (!txl->planar_pool) { + if (num_planar_ref > 0) { + txl->planar_pool = DRW_texture_create_2D_array(width, height, max_ff(1, num_planar_ref), + GPU_R11F_G11F_B10F, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL); + txl->planar_depth = DRW_texture_create_2D_array(width, height, max_ff(1, num_planar_ref), + GPU_DEPTH_COMPONENT24, 0, NULL); + } + else if (num_planar_ref == 0) { + /* Makes Opengl Happy : Create a placeholder texture that will never be sampled but still bound to shader. */ + txl->planar_pool = DRW_texture_create_2D_array(1, 1, 1, GPU_RGBA8, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL); + txl->planar_depth = DRW_texture_create_2D_array(1, 1, 1, GPU_DEPTH_COMPONENT24, 0, NULL); + } + } +} + static void lightprobe_shaders_init(void) { const char *filter_defines = "#define HAMMERSLEY_SIZE " STRINGIFY(HAMMERSLEY_SIZE) "\n" @@ -240,7 +300,6 @@ static void lightprobe_shaders_init(void) void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) { EEVEE_CommonUniformBuffer *common_data = &sldata->common_data; - EEVEE_TextureList *txl = vedata->txl; EEVEE_StorageList *stl = vedata->stl; const DRWContextState *draw_ctx = DRW_context_state_get(); @@ -281,10 +340,9 @@ void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) common_data->ssr_toggle = true; common_data->sss_toggle = true; - if (!txl->planar_pool) { - /* Makes Opengl Happy : Create a placeholder texture that will never be sampled but still bound to shader. */ - txl->planar_pool = DRW_texture_create_2D_array(1, 1, 1, GPU_RGBA8, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL); - txl->planar_depth = DRW_texture_create_2D_array(1, 1, 1, GPU_DEPTH_COMPONENT24, 0, NULL); + /* Placeholder planar pool: used when rendering planar reflections (avoid dependency loop). */ + if (!e_data.planar_pool_placeholder) { + e_data.planar_pool_placeholder = DRW_texture_create_2D_array(1, 1, 1, GPU_RGBA8, DRW_TEX_FILTER, NULL); } } @@ -374,6 +432,8 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat const DRWContextState *draw_ctx = DRW_context_state_get(); const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); + pinfo->num_planar = 0; + { psl->probe_background = DRW_pass_create("World Probe Background Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL); @@ -419,7 +479,7 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat } } - { + if (DRW_state_draw_support()) { DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_BACK; psl->probe_display = DRW_pass_create("LightProbe Display", state); @@ -468,6 +528,9 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat stl->g_data->planar_display_shgrp = grp; DRW_shgroup_uniform_texture_ref(grp, "probePlanars", &txl->planar_pool); } + else { + stl->g_data->planar_display_shgrp = NULL; + } { psl->probe_planar_downsample_ps = DRW_pass_create("LightProbe Planar Downsample", DRW_STATE_WRITE_COLOR); @@ -479,8 +542,66 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat } } -void EEVEE_lightprobes_cache_add(EEVEE_ViewLayerData *sldata, Object *ob) +static bool eevee_lightprobes_culling_test(Object *ob) { + LightProbe *probe = (LightProbe *)ob->data; + + switch (probe->type) { + case LIGHTPROBE_TYPE_PLANAR: + { + /* See if this planar probe is inside the view frustum. If not, no need to update it. */ + /* NOTE: this could be bypassed if we want feedback loop mirrors for rendering. */ + BoundBox bbox; float tmp[4][4]; + const float min[3] = {-1.0f, -1.0f, -1.0f}; + const float max[3] = { 1.0f, 1.0f, 1.0f}; + BKE_boundbox_init_from_minmax(&bbox, min, max); + + copy_m4_m4(tmp, ob->obmat); + normalize_v3(tmp[2]); + mul_v3_fl(tmp[2], probe->distinf); + + for (int v = 0; v < 8; ++v) { + mul_m4_v3(tmp, bbox.vec[v]); + } + return DRW_culling_box_test(&bbox); + } + case LIGHTPROBE_TYPE_CUBE: + return true; /* TODO */ + case LIGHTPROBE_TYPE_GRID: + return true; /* TODO */ + } + BLI_assert(0); + return true; +} + +void EEVEE_lightprobes_cache_add(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, Object *ob) +{ + EEVEE_LightProbesInfo *pinfo = sldata->probes; + LightProbe *probe = (LightProbe *)ob->data; + + if ((probe->type == LIGHTPROBE_TYPE_CUBE && pinfo->num_cube >= MAX_PROBE) || + (probe->type == LIGHTPROBE_TYPE_GRID && pinfo->num_grid >= MAX_PROBE) || + (probe->type == LIGHTPROBE_TYPE_PLANAR && pinfo->num_planar >= MAX_PLANAR)) + { + printf("Too many probes in the view !!!\n"); + return; + } + + if (probe->type == LIGHTPROBE_TYPE_PLANAR) { + if (!eevee_lightprobes_culling_test(ob)) { + return; /* Culled */ + } + EEVEE_lightprobes_planar_data_from_object(ob, + &pinfo->planar_data[pinfo->num_planar], + &pinfo->planar_vis_tests[pinfo->num_planar]); + /* Debug Display */ + DRWShadingGroup *grp = vedata->stl->g_data->planar_display_shgrp; + if (grp && (probe->flag & LIGHTPROBE_FLAG_SHOW_DATA)) { + DRW_shgroup_call_dynamic_add(grp, &pinfo->num_planar, ob->obmat); + } + + pinfo->num_planar++; + } } void EEVEE_lightprobes_grid_data_from_object(Object *ob, EEVEE_LightGrid *egrid, int *offset) @@ -573,6 +694,85 @@ void EEVEE_lightprobes_cube_data_from_object(Object *ob, EEVEE_LightProbe *eprob invert_m4(eprobe->parallaxmat); } +void EEVEE_lightprobes_planar_data_from_object(Object *ob, EEVEE_PlanarReflection *eplanar, EEVEE_LightProbeVisTest *vis_test) +{ + LightProbe *probe = (LightProbe *)ob->data; + float normat[4][4], imat[4][4]; + + vis_test->collection = probe->visibility_grp; + vis_test->invert = probe->flag & LIGHTPROBE_FLAG_INVERT_GROUP; + vis_test->cached = false; + + /* Computing mtx : matrix that mirror position around object's XY plane. */ + normalize_m4_m4(normat, ob->obmat); /* object > world */ + invert_m4_m4(imat, normat); /* world > object */ + /* XY reflection plane */ + imat[0][2] = -imat[0][2]; + imat[1][2] = -imat[1][2]; + imat[2][2] = -imat[2][2]; + imat[3][2] = -imat[3][2]; /* world > object > mirrored obj */ + mul_m4_m4m4(eplanar->mtx, normat, imat); /* world > object > mirrored obj > world */ + + /* Compute clip plane equation / normal. */ + copy_v3_v3(eplanar->plane_equation, ob->obmat[2]); + normalize_v3(eplanar->plane_equation); /* plane normal */ + eplanar->plane_equation[3] = -dot_v3v3(eplanar->plane_equation, ob->obmat[3]); + eplanar->clipsta = probe->clipsta; + + /* Compute XY clip planes. */ + normalize_v3_v3(eplanar->clip_vec_x, ob->obmat[0]); + normalize_v3_v3(eplanar->clip_vec_y, ob->obmat[1]); + + float vec[3] = {0.0f, 0.0f, 0.0f}; + vec[0] = 1.0f; vec[1] = 0.0f; vec[2] = 0.0f; + mul_m4_v3(ob->obmat, vec); /* Point on the edge */ + eplanar->clip_edge_x_pos = dot_v3v3(eplanar->clip_vec_x @@ 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