[Bf-blender-cvs] [f2f16a2568c] blender2.8: Eevee: First Shadows implementation

Clément Foucault noreply at git.blender.org
Mon Apr 10 12:36:42 CEST 2017


Commit: f2f16a2568c2006b46ba0daa851961355a42f20b
Author: Clément Foucault
Date:   Mon Apr 10 12:06:17 2017 +0200
Branches: blender2.8
https://developer.blender.org/rBf2f16a2568c2006b46ba0daa851961355a42f20b

Eevee: First Shadows implementation

Using Texture Arrays to store shadow maps so less texture slots are used when shading. This means a large amount of shadows can be supported.

Support Projection Shadow Map for sun like in old BI/BGE.

Support Cube Shadow Map for Point/Spot/Area lights. the benefit of using it for spot light is that the spot angle does not change shadow resolution (at the cost of more memory used). The implementation of the cubemap sampling is targeted for 3.3 core. We rely on 2D texture arrays to store cubemaps faces and sample the right one manualy. Significant performance improvement can be done using Cubemap Arrays on supported hardware.

Shadows are only hardware filtered. Prefiltered shadows and settings comming next.

===================================================================

M	source/blender/draw/CMakeLists.txt
M	source/blender/draw/engines/eevee/eevee.c
M	source/blender/draw/engines/eevee/eevee_lights.c
M	source/blender/draw/engines/eevee/eevee_private.h
M	source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
M	source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
A	source/blender/draw/engines/eevee/shaders/shadow_frag.glsl
A	source/blender/draw/engines/eevee/shaders/shadow_geom.glsl
A	source/blender/draw/engines/eevee/shaders/shadow_vert.glsl
M	source/blender/draw/intern/DRW_render.h
M	source/blender/draw/intern/draw_manager.c
M	source/blender/gpu/GPU_lamp.h
M	source/blender/gpu/GPU_viewport.h
M	source/blender/gpu/intern/gpu_framebuffer.c
M	source/blender/gpu/intern/gpu_lamp.c
M	source/blender/gpu/intern/gpu_texture.c

===================================================================

diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index e921a65bfe8..67a1a6d5e88 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -103,6 +103,9 @@ data_to_c_simple(engines/clay/shaders/ssao_groundtruth.glsl SRC)
 
 data_to_c_simple(engines/eevee/shaders/lit_surface_frag.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/lit_surface_vert.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/shadow_frag.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/shadow_geom.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/shadow_vert.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/tonemap_frag.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/bsdf_direct_lib.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/bsdf_common_lib.glsl SRC)
diff --git a/source/blender/draw/engines/eevee/eevee.c b/source/blender/draw/engines/eevee/eevee.c
index 7588ebede0c..2013df35deb 100644
--- a/source/blender/draw/engines/eevee/eevee.c
+++ b/source/blender/draw/engines/eevee/eevee.c
@@ -38,8 +38,10 @@ static struct {
 	struct GPUShader *default_lit;
 	struct GPUShader *depth_sh;
 	struct GPUShader *tonemap;
+	struct GPUShader *shadow_sh;
 	struct GPUTexture *ltc_mat;
 	struct GPUTexture *ltc_mag;
+
 	float camera_pos[3];
 } e_data = {NULL}; /* Engine data */
 
@@ -49,6 +51,9 @@ extern char datatoc_bsdf_direct_lib_glsl[];
 extern char datatoc_lit_surface_frag_glsl[];
 extern char datatoc_lit_surface_vert_glsl[];
 extern char datatoc_tonemap_frag_glsl[];
+extern char datatoc_shadow_frag_glsl[];
+extern char datatoc_shadow_geom_glsl[];
+extern char datatoc_shadow_vert_glsl[];
 
 /* *********** FUNCTIONS *********** */
 
@@ -79,11 +84,20 @@ static void EEVEE_engine_init(void *vedata)
 		lib_str = BLI_dynstr_get_cstring(ds_vert);
 		BLI_dynstr_free(ds_vert);
 
-		e_data.default_lit = DRW_shader_create_with_lib(datatoc_lit_surface_vert_glsl, NULL, datatoc_lit_surface_frag_glsl, lib_str, "#define MAX_LIGHT 128\n");
+		e_data.default_lit = DRW_shader_create_with_lib(datatoc_lit_surface_vert_glsl, NULL, datatoc_lit_surface_frag_glsl, lib_str,
+		                                                "#define MAX_LIGHT 128\n"
+		                                                "#define MAX_SHADOW_CUBE 42\n"
+		                                                "#define MAX_SHADOW_MAP 64\n"
+		                                                "#define MAX_SHADOW_CASCADE 8\n"
+		                                                "#define MAX_CASCADE_NUM 4\n");
 
 		MEM_freeN(lib_str);
 	}
 
+	if (!e_data.shadow_sh) {
+		e_data.shadow_sh = DRW_shader_create(datatoc_shadow_vert_glsl, datatoc_shadow_geom_glsl, datatoc_shadow_frag_glsl, NULL);
+	}
+
 	if (!e_data.tonemap) {
 		e_data.tonemap = DRW_shader_create_fullscreen(datatoc_tonemap_frag_glsl, NULL);
 	}
@@ -96,8 +110,9 @@ static void EEVEE_engine_init(void *vedata)
 		e_data.ltc_mag = DRW_texture_create_2D(64, 64, DRW_TEX_R_16, DRW_TEX_FILTER, ltc_mag_ggx);
 	}
 
-	if (stl->lights_info == NULL)
+	if (stl->lamps == NULL) {
 		EEVEE_lights_init(stl);
+	}
 
 	// EEVEE_lights_update(stl);
 	{
@@ -120,6 +135,14 @@ static void EEVEE_cache_init(void *vedata)
 	}
 
 	{
+		/* Shadow Pass */
+		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->depth_pass = DRW_pass_create("Depth Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
 		stl->g_data->depth_shgrp = DRW_shgroup_create(e_data.depth_sh, psl->depth_pass);
 
@@ -132,11 +155,13 @@ static void EEVEE_cache_init(void *vedata)
 		psl->pass = DRW_pass_create("Default Light Pass", state);
 
 		stl->g_data->default_lit_grp = DRW_shgroup_create(e_data.default_lit, psl->pass);
-		DRW_shgroup_uniform_block(stl->g_data->default_lit_grp, "light_block", stl->lights_ubo, 0);
-		DRW_shgroup_uniform_int(stl->g_data->default_lit_grp, "light_count", &stl->lights_info->light_count, 1);
+		DRW_shgroup_uniform_block(stl->g_data->default_lit_grp, "light_block", stl->light_ubo, 0);
+		DRW_shgroup_uniform_block(stl->g_data->default_lit_grp, "shadow_block", stl->shadow_ubo, 1);
+		DRW_shgroup_uniform_int(stl->g_data->default_lit_grp, "light_count", &stl->lamps->num_light, 1);
 		DRW_shgroup_uniform_vec3(stl->g_data->default_lit_grp, "cameraPos", e_data.camera_pos, 1);
 		DRW_shgroup_uniform_texture(stl->g_data->default_lit_grp, "ltcMat", e_data.ltc_mat, 0);
 		DRW_shgroup_uniform_texture(stl->g_data->default_lit_grp, "ltcMag", e_data.ltc_mag, 1);
+		/* NOTE : Adding Shadow Map textures uniform in EEVEE_cache_finish */
 	}
 
 	{
@@ -167,6 +192,7 @@ 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);
 	}
 	else if (ob->type == OB_LAMP) {
 		EEVEE_lights_cache_add(stl, ob);
@@ -176,8 +202,14 @@ static void EEVEE_cache_populate(void *vedata, Object *ob)
 static void EEVEE_cache_finish(void *vedata)
 {
 	EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
+	EEVEE_TextureList *txl = ((EEVEE_Data *)vedata)->txl;
+	EEVEE_FramebufferList *fbl = ((EEVEE_Data *)vedata)->fbl;
 
-	EEVEE_lights_cache_finish(stl);
+	EEVEE_lights_cache_finish(stl, txl, fbl);
+
+	/* Shadows binding */
+	DRW_shgroup_uniform_texture(stl->g_data->default_lit_grp, "shadowMaps", txl->shadow_depth_map_pool, 2);
+	DRW_shgroup_uniform_texture(stl->g_data->default_lit_grp, "shadowCubes", txl->shadow_depth_cube_pool, 3);
 }
 
 static void EEVEE_draw_scene(void *vedata)
@@ -189,6 +221,9 @@ static void EEVEE_draw_scene(void *vedata)
 	DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
 	DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
 
+	/* Refresh shadows */
+	EEVEE_draw_shadows((EEVEE_Data *)vedata);
+
 	/* Attach depth to the hdr buffer and bind it */	
 	DRW_framebuffer_texture_detach(dtxl->depth);
 	DRW_framebuffer_texture_attach(fbl->main, dtxl->depth, 0);
@@ -197,7 +232,7 @@ static void EEVEE_draw_scene(void *vedata)
 	/* Clear Depth */
 	/* TODO do background */
 	float clearcol[4] = {0.0f, 0.0f, 0.0f, 1.0f};
-	DRW_framebuffer_clear(true, true, true, clearcol, 1.0f);
+	DRW_framebuffer_clear(true, true, false, clearcol, 1.0f);
 
 	DRW_draw_pass(psl->depth_pass);
 	DRW_draw_pass(psl->depth_pass_cull);
@@ -215,6 +250,8 @@ static void EEVEE_engine_free(void)
 {
 	if (e_data.default_lit)
 		DRW_shader_free(e_data.default_lit);
+	if (e_data.shadow_sh)
+		DRW_shader_free(e_data.shadow_sh);
 	if (e_data.tonemap)
 		DRW_shader_free(e_data.tonemap);
 	if (e_data.ltc_mat)
diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c
index 6a6947bdc3f..9a06c665ae2 100644
--- a/source/blender/draw/engines/eevee/eevee_lights.c
+++ b/source/blender/draw/engines/eevee/eevee_lights.c
@@ -25,138 +25,393 @@
 
 #include "DRW_render.h"
 
+#include "eevee.h"
 #include "eevee_private.h"
 
-#define MAX_LIGHT 210 /* TODO : find size by dividing UBO max size by light data size */
+typedef struct EEVEE_LightData {
+	short light_id, shadow_id;
+} EEVEE_LightData;
 
-typedef struct EEVEE_Light {
-	float position[3], dist;
-	float color[3], spec;
-	float spotsize, spotblend, radius, shadowid;
-	float rightvec[3], sizex;
-	float upvec[3], sizey;
-	float forwardvec[3], lamptype;
-} EEVEE_Light;
+typedef struct EEVEE_ShadowCubeData {
+	short light_id, shadow_id;
+	float viewprojmat[6][4][4];
+} EEVEE_ShadowCubeData;
 
+typedef struct EEVEE_ShadowMapData {
+	short light_id, shadow_id;
+	float viewprojmat[4][4]; /* World->Lamp->NDC : used for rendering the shadow map. */
+} EEVEE_ShadowMapData;
+
+typedef struct EEVEE_ShadowCascadeData {
+	short light_id, shadow_id;
+	float viewprojmat[MAX_CASCADE_NUM][4][4]; /* World->Lamp->NDC : used for rendering the shadow map. */
+} EEVEE_ShadowCascadeData;
+
+/* *********** FUNCTIONS *********** */
 
 void EEVEE_lights_init(EEVEE_StorageList *stl)
 {
-	stl->lights_info = MEM_callocN(sizeof(EEVEE_LightsInfo), "EEVEE_LightsInfo");
-	stl->lights_data = MEM_mallocN(sizeof(EEVEE_Light) * MAX_LIGHT, "EEVEE_LightsUboStorage");
-	stl->lights_ref  = MEM_mallocN(sizeof(Object *) * MAX_LIGHT, "EEVEE lights_ref");
-	stl->lights_ubo  = DRW_uniformbuffer_create(sizeof(EEVEE_Light) * MAX_LIGHT, NULL);
+	const unsigned int shadow_ubo_size = sizeof(EEVEE_ShadowCube) * MAX_SHADOW_CUBE +
+	                                     sizeof(EEVEE_ShadowMap) * MAX_SHADOW_MAP +
+	                                     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);
+	}
 }
 
 void EEVEE_lights_cache_init(EEVEE_StorageList *stl)
 {
-	BLI_listbase_clear(&stl->g_data->lamps);
-	stl->lights_info->light_count = 0;
-}
+	EEVEE_LampsInfo *linfo = stl->lamps;
 
-void EEVEE_lights_cache_add(EEVEE_StorageList *stl, Object *ob)
-{
-	BLI_addtail(&stl->g_data->lamps, BLI_genericNodeN(ob));
-	stl->lights_info->light_count += 1;
+	linfo->num_light = linfo->num_cube = linfo->num_map = linfo->num_cascade = 0;
+	memset(linfo->light_ref, 0, sizeof(linfo->light_ref));
+	memset(linfo->shadow_cube_ref, 0, sizeof(linfo->shadow_cube_ref));
+	memset(linfo->shadow_map_ref, 0, sizeof(linfo->shadow_map_ref));
+	memset(linfo->shadow_cascade_ref, 0, sizeof(linfo->shadow_cascade_ref));
 }
 
-void EEVEE_lights_cache_finish(EEVEE_StorageList *stl)
+void EEVEE_lights_cache_add(EEVEE_StorageList *stl, Object *ob)
 {
-	int light_ct = stl->lights_info->light_count;
+	EEVEE_LampsInfo *linfo = stl->lamps;
 
-	if (light_ct > MAX_LIGHT) {
+	/* Step 1 find all lamps in the scene and setup them */
+	if (linfo->num_light > MAX_LIGHT) {
 		

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list