Eevee: Probes: Add data display for cubemaps.

This commit is contained in:
Clément Foucault 2017-06-15 00:10:34 +02:00
parent 810464e5f7
commit cac851a00e
12 changed files with 115 additions and 14 deletions

@ -144,6 +144,10 @@ class DATA_PT_lightprobe_display(DataButtonsPanel, Panel):
col = split.column()
col.prop(probe, "show_clip")
row = layout.row()
row.prop(probe, "show_data")
row.prop(probe, "data_draw_size")
classes = (
DATA_PT_context_lightprobe,

@ -50,6 +50,7 @@ void BKE_lightprobe_init(LightProbe *probe)
probe->falloff = 0.2f;
probe->clipsta = 1.0f;
probe->clipend = 40.0f;
probe->data_draw_size = 1.0f;
}
void *BKE_lightprobe_add(Main *bmain, const char *name)

@ -122,6 +122,8 @@ data_to_c_simple(engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lightprobe_geom.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lightprobe_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lightprobe_cube_display_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lightprobe_cube_display_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lightprobe_grid_display_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lightprobe_grid_display_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lit_surface_frag.glsl SRC)

@ -74,7 +74,7 @@ static void EEVEE_cache_init(void *vedata)
EEVEE_materials_cache_init(vedata);
EEVEE_lights_cache_init(sldata, psl);
EEVEE_lightprobes_cache_init(sldata, psl);
EEVEE_lightprobes_cache_init(sldata, psl, stl);
EEVEE_effects_cache_init(vedata);
}
@ -115,11 +115,10 @@ static void EEVEE_cache_populate(void *vedata, Object *ob)
static void EEVEE_cache_finish(void *vedata)
{
EEVEE_SceneLayerData *sldata = EEVEE_scene_layer_data_get();
EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
EEVEE_materials_cache_finish(vedata);
EEVEE_lights_cache_finish(sldata);
EEVEE_lightprobes_cache_finish(sldata, psl);
EEVEE_lightprobes_cache_finish(sldata, vedata);
}
static void EEVEE_draw_scene(void *vedata)

@ -56,6 +56,7 @@ static struct {
struct GPUShader *probe_filter_glossy_sh;
struct GPUShader *probe_filter_diffuse_sh;
struct GPUShader *probe_grid_display_sh;
struct GPUShader *probe_cube_display_sh;
struct GPUTexture *hammersley;
@ -69,6 +70,8 @@ extern char datatoc_lightprobe_filter_glossy_frag_glsl[];
extern char datatoc_lightprobe_filter_diffuse_frag_glsl[];
extern char datatoc_lightprobe_geom_glsl[];
extern char datatoc_lightprobe_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[];
extern char datatoc_lightprobe_grid_display_vert_glsl[];
extern char datatoc_irradiance_lib_glsl[];
@ -173,6 +176,17 @@ void EEVEE_lightprobes_init(EEVEE_SceneLayerData *sldata)
MEM_freeN(shader_str);
ds_frag = BLI_dynstr_new();
BLI_dynstr_append(ds_frag, datatoc_octahedron_lib_glsl);
BLI_dynstr_append(ds_frag, datatoc_lightprobe_cube_display_frag_glsl);
shader_str = BLI_dynstr_get_cstring(ds_frag);
BLI_dynstr_free(ds_frag);
e_data.probe_cube_display_sh = DRW_shader_create(
datatoc_lightprobe_cube_display_vert_glsl, NULL, shader_str, NULL);
MEM_freeN(shader_str);
e_data.hammersley = create_hammersley_sample_texture(1024);
}
@ -195,7 +209,7 @@ void EEVEE_lightprobes_init(EEVEE_SceneLayerData *sldata)
DRW_framebuffer_init(&sldata->probe_fb, &draw_engine_eevee_type, PROBE_RT_SIZE, PROBE_RT_SIZE, tex_probe, 2);
}
void EEVEE_lightprobes_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl)
void EEVEE_lightprobes_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl, EEVEE_StorageList *stl)
{
EEVEE_LightProbesInfo *pinfo = sldata->probes;
@ -293,6 +307,14 @@ void EEVEE_lightprobes_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_PassList *
{
psl->probe_display = DRW_pass_create("LightProbe Display", DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
struct Batch *geom = DRW_cache_sphere_get();
DRWShadingGroup *grp = stl->g_data->cube_display_shgrp = DRW_shgroup_instance_create(e_data.probe_cube_display_sh, psl->probe_display, geom);
DRW_shgroup_attrib_float(grp, "probe_id", 1); /* XXX this works because we are still uploading 4bytes and using the right stride */
DRW_shgroup_attrib_float(grp, "probe_location", 3);
DRW_shgroup_attrib_float(grp, "sphere_size", 1);
DRW_shgroup_uniform_float(grp, "lodMax", &sldata->probes->lodmax, 1);
DRW_shgroup_uniform_buffer(grp, "probeCubes", &sldata->probe_pool);
}
}
@ -316,12 +338,14 @@ void EEVEE_lightprobes_cache_add(EEVEE_SceneLayerData *sldata, Object *ob)
if ((ob->deg_update_flag & DEG_RUNTIME_DATA_UPDATE) != 0) {
ped->need_update = true;
ped->updated_cells = 0;
ped->probe_id = 0;
pinfo->updated_bounce = 0;
}
if (e_data.update_world) {
ped->need_update = true;
ped->updated_cells = 0;
ped->probe_id = 0;
pinfo->updated_bounce = 0;
}
@ -335,7 +359,7 @@ void EEVEE_lightprobes_cache_add(EEVEE_SceneLayerData *sldata, Object *ob)
}
}
static void EEVEE_lightprobes_updates(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl)
static void EEVEE_lightprobes_updates(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl, EEVEE_StorageList *stl)
{
EEVEE_LightProbesInfo *pinfo = sldata->probes;
Object *ob;
@ -343,6 +367,7 @@ static void EEVEE_lightprobes_updates(EEVEE_SceneLayerData *sldata, EEVEE_PassLi
for (int i = 1; (ob = pinfo->probes_cube_ref[i]) && (i < MAX_PROBE); i++) {
LightProbe *probe = (LightProbe *)ob->data;
EEVEE_LightProbe *eprobe = &pinfo->probe_data[i];
EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_get(ob);
/* Update transforms */
copy_v3_v3(eprobe->position, ob->obmat[3]);
@ -371,6 +396,11 @@ static void EEVEE_lightprobes_updates(EEVEE_SceneLayerData *sldata, EEVEE_PassLi
scale_m4_fl(eprobe->parallaxmat, dist);
mul_m4_m4m4(eprobe->parallaxmat, ob->obmat, eprobe->parallaxmat);
invert_m4(eprobe->parallaxmat);
/* Debug Display */
if ((probe->flag & LIGHTPROBE_FLAG_SHOW_DATA) != 0) {
DRW_shgroup_call_dynamic_add(stl->g_data->cube_display_shgrp, &ped->probe_id, ob->obmat[3], &probe->data_draw_size);
}
}
int offset = 1; /* to account for the world probe */
@ -425,7 +455,7 @@ static void EEVEE_lightprobes_updates(EEVEE_SceneLayerData *sldata, EEVEE_PassLi
copy_v3_v3_int(egrid->resolution, &probe->grid_resolution_x);
/* Debug Display */
if ((probe->flag & LIGHTPROBE_FLAG_SHOW_INFLUENCE) != 0) {
if ((probe->flag & LIGHTPROBE_FLAG_SHOW_DATA) != 0) {
struct Batch *geom = DRW_cache_sphere_get();
DRWShadingGroup *grp = DRW_shgroup_instance_create(e_data.probe_grid_display_sh, psl->probe_display, geom);
DRW_shgroup_set_instance_count(grp, ped->num_cell);
@ -436,11 +466,12 @@ static void EEVEE_lightprobes_updates(EEVEE_SceneLayerData *sldata, EEVEE_PassLi
DRW_shgroup_uniform_vec3(grp, "increment_y", egrid->increment_y, 1);
DRW_shgroup_uniform_vec3(grp, "increment_z", egrid->increment_z, 1);
DRW_shgroup_uniform_buffer(grp, "irradianceGrid", &sldata->irradiance_pool);
DRW_shgroup_uniform_float(grp, "sphere_size", &probe->data_draw_size, 1);
}
}
}
void EEVEE_lightprobes_cache_finish(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl)
void EEVEE_lightprobes_cache_finish(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_LightProbesInfo *pinfo = sldata->probes;
Object *ob;
@ -469,6 +500,7 @@ void EEVEE_lightprobes_cache_finish(EEVEE_SceneLayerData *sldata, EEVEE_PassList
EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_get(ob);
ped->need_update = true;
ped->ready_to_shade = false;
ped->probe_id = 0;
}
}
@ -508,7 +540,7 @@ void EEVEE_lightprobes_cache_finish(EEVEE_SceneLayerData *sldata, EEVEE_PassList
}
}
EEVEE_lightprobes_updates(sldata, psl);
EEVEE_lightprobes_updates(sldata, vedata->psl, vedata->stl);
DRW_uniformbuffer_update(sldata->probe_ubo, &sldata->probes->probe_data);
DRW_uniformbuffer_update(sldata->grid_ubo, &sldata->probes->grid_data);
@ -856,6 +888,7 @@ void EEVEE_lightprobes_refresh(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl
glossy_filter_probe(sldata, psl, i);
ped->need_update = false;
ped->probe_id = i;
if (!ped->ready_to_shade) {
pinfo->num_render_cube++;
@ -877,5 +910,6 @@ void EEVEE_lightprobes_free(void)
DRW_SHADER_FREE_SAFE(e_data.probe_filter_glossy_sh);
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_cube_display_sh);
DRW_TEXTURE_FREE_SAFE(e_data.hammersley);
}

@ -319,6 +319,7 @@ typedef struct EEVEE_LightProbeEngineData {
bool ready_to_shade;
int updated_cells;
int num_cell;
int probe_id; /* Only used for display data */
struct ListBase captured_object_list;
} EEVEE_LightProbeEngineData;
@ -340,7 +341,7 @@ typedef struct EEVEE_PrivateData {
struct DRWShadingGroup *shadow_shgrp;
struct DRWShadingGroup *depth_shgrp;
struct DRWShadingGroup *depth_shgrp_cull;
struct DRWShadingGroup *grid_display_shgrp;
struct DRWShadingGroup *cube_display_shgrp;
struct GHash *material_hash;
struct GHash *hair_material_hash;
} EEVEE_PrivateData; /* Transient data */
@ -376,9 +377,9 @@ void EEVEE_lights_free(void);
/* eevee_lightprobes.c */
void EEVEE_lightprobes_init(EEVEE_SceneLayerData *sldata);
void EEVEE_lightprobes_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl);
void EEVEE_lightprobes_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl, EEVEE_StorageList *stl);
void EEVEE_lightprobes_cache_add(EEVEE_SceneLayerData *sldata, Object *ob);
void EEVEE_lightprobes_cache_finish(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl);
void EEVEE_lightprobes_cache_finish(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_lightprobes_refresh(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl);
void EEVEE_lightprobes_free(void);

@ -0,0 +1,24 @@
uniform mat4 ProjectionMatrix;
uniform mat4 ViewMatrixInverse;
uniform sampler2DArray probeCubes;
uniform float lodMax;
flat in int pid;
in vec3 worldNormal;
in vec3 worldPosition;
out vec4 FragColor;
#define cameraForward normalize(ViewMatrixInverse[2].xyz)
#define cameraPos ViewMatrixInverse[3].xyz
void main()
{
vec3 V = (ProjectionMatrix[3][3] == 0.0) /* if perspective */
? normalize(cameraPos - worldPosition)
: cameraForward;
vec3 N = normalize(worldNormal);
FragColor = vec4(textureLod_octahedron(probeCubes, vec4(reflect(-V, N), pid), 0.0, lodMax).rgb, 1.0);
}

@ -0,0 +1,22 @@
in vec3 pos;
in vec3 nor;
/* Instance attrib */
in int probe_id;
in vec3 probe_location;
in float sphere_size;
uniform mat4 ViewProjectionMatrix;
flat out int pid;
out vec3 worldNormal;
out vec3 worldPosition;
void main()
{
pid = probe_id;
worldPosition = pos * 0.1 * sphere_size + probe_location;
gl_Position = ViewProjectionMatrix * vec4(worldPosition, 1.0);
worldNormal = normalize(nor);
}

@ -4,6 +4,7 @@ in vec3 nor;
uniform mat4 ViewProjectionMatrix;
uniform float sphere_size;
uniform int offset;
uniform ivec3 grid_resolution;
uniform vec3 corner;
@ -29,6 +30,6 @@ void main()
increment_y * ls_cell_location.y +
increment_z * ls_cell_location.z);
gl_Position = ViewProjectionMatrix * vec4(pos * 0.02 + ws_cell_location, 1.0);
gl_Position = ViewProjectionMatrix * vec4(pos * 0.02 * sphere_size + ws_cell_location, 1.0);
worldNormal = normalize(nor);
}

@ -290,7 +290,6 @@ void DRW_shgroup_call_dynamic_add_array(DRWShadingGroup *shgroup, const void *at
void DRW_shgroup_set_instance_count(DRWShadingGroup *shgroup, int count);
void DRW_shgroup_state_enable(DRWShadingGroup *shgroup, DRWState state);
void DRW_shgroup_attrib_int(DRWShadingGroup *shgroup, const char *name, int size);
void DRW_shgroup_attrib_float(DRWShadingGroup *shgroup, const char *name, int size);
void DRW_shgroup_uniform_texture(DRWShadingGroup *shgroup, const char *name, const struct GPUTexture *tex);

@ -62,8 +62,10 @@ typedef struct LightProbe {
struct Object *parallax_ob; /* Object to use as a parallax origin */
struct Image *image; /* Image to use on as lighting data */
float data_draw_size;
/* Runtime display data */
float distfalloff, pad;
float distfalloff;
} LightProbe;
/* Probe->type */
@ -80,6 +82,7 @@ enum {
LIGHTPROBE_FLAG_SHOW_INFLUENCE = (1 << 1),
LIGHTPROBE_FLAG_SHOW_PARALLAX = (1 << 2),
LIGHTPROBE_FLAG_SHOW_CLIP_DIST = (1 << 3),
LIGHTPROBE_FLAG_SHOW_DATA = (1 << 4),
};
/* Probe->display */

@ -162,6 +162,17 @@ static void rna_def_lightprobe(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Resolution Z", "Number of sample along the z axis of the volume");
RNA_def_property_update(prop, NC_MATERIAL | ND_SHADING, "rna_LightProbe_recalc");
/* Data preview */
prop = RNA_def_property(srna, "show_data", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", LIGHTPROBE_FLAG_SHOW_DATA);
RNA_def_property_ui_text(prop, "Show Data", "Show captured lighting data into the 3D view for debuging purpose");
RNA_def_property_update(prop, NC_MATERIAL | ND_SHADING, NULL);
prop = RNA_def_property(srna, "data_draw_size", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.05f, 10.0f);
RNA_def_property_ui_text(prop, "Data Draw Size", "Size of the spheres to debug captured light");
RNA_def_property_update(prop, NC_MATERIAL | ND_SHADING, NULL);
/* common */
rna_def_animdata_common(srna);
}