Eevee: Do shadow cube render in one pass.

This commit is contained in:
Clément Foucault
2017-04-19 22:07:53 +02:00
parent 3fa665f56d
commit b386828671
5 changed files with 69 additions and 38 deletions

View File

@@ -304,6 +304,18 @@ static DRWShadingGroup *eevee_cube_shgroup(struct GPUShader *sh, DRWPass *pass,
return grp;
}
static DRWShadingGroup *eevee_cube_shadow_shgroup(EEVEE_PassList *psl, EEVEE_StorageList *stl, struct Batch *geom, float (*obmat)[4])
{
DRWShadingGroup *grp = DRW_shgroup_instance_create(e_data.shadow_sh, psl->shadow_cube_pass, geom);
DRW_shgroup_uniform_block(grp, "shadow_render_block", stl->shadow_render_ubo, 0);
DRW_shgroup_uniform_mat4(grp, "ShadowModelMatrix", (float *)obmat);
for (int i = 0; i < 6; ++i)
DRW_shgroup_dynamic_call_add_empty(grp);
return grp;
}
static void EEVEE_cache_init(void *vedata)
{
EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
@@ -316,10 +328,14 @@ static void EEVEE_cache_init(void *vedata)
}
{
psl->shadow_pass = DRW_pass_create("Shadow Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
stl->g_data->shadow_shgrp = DRW_shgroup_create(e_data.shadow_sh, psl->shadow_pass);
DRW_shgroup_uniform_mat4(stl->g_data->shadow_shgrp, "ShadowMatrix", (float *)stl->lamps->shadowmat);
DRW_shgroup_uniform_int(stl->g_data->shadow_shgrp, "Layer", &stl->lamps->layer, 1);
psl->shadow_cube_pass = DRW_pass_create("Shadow Cube Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
}
{
// psl->shadow_pass = DRW_pass_create("Shadow Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
// stl->g_data->shadow_shgrp = DRW_shgroup_create(e_data.shadow_sh, psl->shadow_pass);
// DRW_shgroup_uniform_mat4(stl->g_data->shadow_shgrp, "ShadowMatrix", (float *)stl->lamps->shadowmat);
// DRW_shgroup_uniform_int(stl->g_data->shadow_shgrp, "Layer", &stl->lamps->layer, 1);
}
{
@@ -402,6 +418,7 @@ static void EEVEE_cache_init(void *vedata)
static void EEVEE_cache_populate(void *vedata, Object *ob)
{
EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
if (ob->type == OB_MESH) {
IDProperty *ces_mode_ob = BKE_object_collection_engine_get(ob, COLLECTION_MODE_OBJECT, "");
@@ -412,7 +429,8 @@ static void EEVEE_cache_populate(void *vedata, Object *ob)
DRW_shgroup_call_add((do_cull) ? stl->g_data->depth_shgrp_cull : stl->g_data->depth_shgrp, geom, ob->obmat);
DRW_shgroup_call_add(stl->g_data->default_lit_grp, geom, ob->obmat);
DRW_shgroup_call_add(stl->g_data->shadow_shgrp, geom, ob->obmat);
// DRW_shgroup_call_add(stl->g_data->shadow_shgrp, geom, ob->obmat);
eevee_cube_shadow_shgroup(psl, stl, geom, ob->obmat);
}
else if (ob->type == OB_LAMP) {
EEVEE_lights_cache_add(stl, ob);

View File

@@ -56,9 +56,10 @@ void EEVEE_lights_init(EEVEE_StorageList *stl)
sizeof(EEVEE_ShadowCascade) * MAX_SHADOW_CASCADE;
if (!stl->lamps) {
stl->lamps = MEM_callocN(sizeof(EEVEE_LampsInfo), "EEVEE_LampsInfo");
stl->light_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_Light) * MAX_LIGHT, NULL);
stl->shadow_ubo = DRW_uniformbuffer_create(shadow_ubo_size, NULL);
stl->lamps = MEM_callocN(sizeof(EEVEE_LampsInfo), "EEVEE_LampsInfo");
stl->light_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_Light) * MAX_LIGHT, NULL);
stl->shadow_ubo = DRW_uniformbuffer_create(shadow_ubo_size, NULL);
stl->shadow_render_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_ShadowRender), NULL);
}
}
@@ -325,6 +326,7 @@ void EEVEE_lights_update(EEVEE_StorageList *stl)
/* this refresh lamps shadow buffers */
void EEVEE_draw_shadows(EEVEE_Data *vedata)
{
EEVEE_PassList *psl = vedata->psl;
EEVEE_StorageList *stl = vedata->stl;
EEVEE_FramebufferList *fbl = vedata->fbl;
EEVEE_LampsInfo *linfo = stl->lamps;
@@ -342,27 +344,30 @@ void EEVEE_draw_shadows(EEVEE_Data *vedata)
for (i = 0; (ob = linfo->shadow_cube_ref[i]) && (i < MAX_SHADOW_CUBE); i++) {
EEVEE_LampEngineData *led = (EEVEE_LampEngineData *)DRW_lamp_engine_data_get(ob, &viewport_eevee_type);
EEVEE_ShadowCubeData *evscd = (EEVEE_ShadowCubeData *)led->sto;
EEVEE_ShadowRender *srd = &linfo->shadow_render_data;
srd->layer = i;
for (int j = 0; j < 6; ++j) {
linfo->layer = i * 6 + j;
copy_m4_m4(linfo->shadowmat, evscd->viewprojmat[j]);
DRW_draw_pass(vedata->psl->shadow_pass);
copy_m4_m4(srd->shadowmat[j], evscd->viewprojmat[j]);
}
DRW_uniformbuffer_update(stl->shadow_render_ubo, &linfo->shadow_render_data);
DRW_draw_pass(psl->shadow_cube_pass);
}
/* Standard Shadow Maps */
DRW_framebuffer_bind(fbl->shadow_map_fb);
DRW_framebuffer_clear(false, true, false, NULL, 1.0);
// DRW_framebuffer_bind(fbl->shadow_map_fb);
// DRW_framebuffer_clear(false, true, false, NULL, 1.0);
/* Render each shadow to one layer of the array */
for (i = 0; (ob = linfo->shadow_map_ref[i]) && (i < MAX_SHADOW_MAP); i++) {
EEVEE_LampEngineData *led = (EEVEE_LampEngineData *)DRW_lamp_engine_data_get(ob, &viewport_eevee_type);
EEVEE_ShadowMapData *evsmd = (EEVEE_ShadowMapData *)led->sto;
// /* Render each shadow to one layer of the array */
// for (i = 0; (ob = linfo->shadow_map_ref[i]) && (i < MAX_SHADOW_MAP); i++) {
// EEVEE_LampEngineData *led = (EEVEE_LampEngineData *)DRW_lamp_engine_data_get(ob, &viewport_eevee_type);
// EEVEE_ShadowMapData *evsmd = (EEVEE_ShadowMapData *)led->sto;
linfo->layer = i;
copy_m4_m4(linfo->shadowmat, evsmd->viewprojmat);
DRW_draw_pass(vedata->psl->shadow_pass);
}
// linfo->layer = i;
// copy_m4_m4(linfo->shadowmat, evsmd->viewprojmat);
// DRW_draw_pass(vedata->psl->shadow_pass);
// }
// DRW_framebuffer_bind(e_data.shadow_cascade_fb);
}

View File

@@ -35,6 +35,7 @@ struct Object;
typedef struct EEVEE_PassList {
/* Shadows */
struct DRWPass *shadow_pass;
struct DRWPass *shadow_cube_pass;
/* Probes */
struct DRWPass *probe_background;
@@ -80,6 +81,7 @@ typedef struct EEVEE_StorageList {
struct EEVEE_LampsInfo *lamps;
struct GPUUniformBuffer *light_ubo;
struct GPUUniformBuffer *shadow_ubo;
struct GPUUniformBuffer *shadow_render_ubo;
/* Probes */
struct EEVEE_ProbesInfo *probes;
@@ -114,12 +116,13 @@ typedef struct EEVEE_ShadowCascade {
float far[MAX_CASCADE_NUM];
} EEVEE_ShadowCascade;
typedef struct EEVEE_ShadowRender {
float shadowmat[6][4][4]; /* World->Lamp->NDC : used to render the shadow map. 6 frustrum for cubemap shadow */
int layer;
} EEVEE_ShadowRender;
/* ************ LIGHT DATA ************* */
typedef struct EEVEE_LampsInfo {
/* For rendering shadows */
float shadowmat[4][4];
int layer;
int num_light, cache_num_light;
int num_cube, cache_num_cube;
int num_map, cache_num_map;
@@ -131,6 +134,7 @@ typedef struct EEVEE_LampsInfo {
struct Object *shadow_cascade_ref[MAX_SHADOW_CASCADE];
/* UBO Storage : data used by UBO */
struct EEVEE_Light light_data[MAX_LIGHT];
struct EEVEE_ShadowRender shadow_render_data;
struct EEVEE_ShadowCube shadow_cube_data[MAX_SHADOW_CUBE];
struct EEVEE_ShadowMap shadow_map_data[MAX_SHADOW_MAP];
struct EEVEE_ShadowCascade shadow_cascade_data[MAX_SHADOW_CASCADE];

View File

@@ -2,20 +2,22 @@
layout(triangles) in;
layout(triangle_strip, max_vertices=3) out;
uniform mat4 ShadowMatrix;
uniform int Layer;
layout(std140) uniform shadow_render_block {
mat4 ShadowMatrix[6];
int Layer;
};
in vec4 vPos[];
in int face[];
void main() {
gl_Layer = Layer;
gl_Position = ShadowMatrix * vPos[0];
EmitVertex();
gl_Layer = Layer;
gl_Position = ShadowMatrix * vPos[1];
EmitVertex();
gl_Layer = Layer;
gl_Position = ShadowMatrix * vPos[2];
EmitVertex();
int f = face[0];
gl_Layer = Layer + f;
for (int v = 0; v < 3; ++v) {
gl_Position = ShadowMatrix[f] * vPos[v];
EmitVertex();
}
EndPrimitive();
}

View File

@@ -1,10 +1,12 @@
uniform mat4 ModelMatrix;
uniform mat4 ShadowModelMatrix;
in vec3 pos;
out vec4 vPos;
out int face;
void main() {
vPos = ModelMatrix * vec4(pos, 1.0);
vPos = ShadowModelMatrix * vec4(pos, 1.0);
face = gl_InstanceID;
}