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.
This commit is contained in:
		@@ -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_frag.glsl SRC)
 | 
				
			||||||
data_to_c_simple(engines/eevee/shaders/lit_surface_vert.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/tonemap_frag.glsl SRC)
 | 
				
			||||||
data_to_c_simple(engines/eevee/shaders/bsdf_direct_lib.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)
 | 
					data_to_c_simple(engines/eevee/shaders/bsdf_common_lib.glsl SRC)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -38,8 +38,10 @@ static struct {
 | 
				
			|||||||
	struct GPUShader *default_lit;
 | 
						struct GPUShader *default_lit;
 | 
				
			||||||
	struct GPUShader *depth_sh;
 | 
						struct GPUShader *depth_sh;
 | 
				
			||||||
	struct GPUShader *tonemap;
 | 
						struct GPUShader *tonemap;
 | 
				
			||||||
 | 
						struct GPUShader *shadow_sh;
 | 
				
			||||||
	struct GPUTexture *ltc_mat;
 | 
						struct GPUTexture *ltc_mat;
 | 
				
			||||||
	struct GPUTexture *ltc_mag;
 | 
						struct GPUTexture *ltc_mag;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	float camera_pos[3];
 | 
						float camera_pos[3];
 | 
				
			||||||
} e_data = {NULL}; /* Engine data */
 | 
					} 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_frag_glsl[];
 | 
				
			||||||
extern char datatoc_lit_surface_vert_glsl[];
 | 
					extern char datatoc_lit_surface_vert_glsl[];
 | 
				
			||||||
extern char datatoc_tonemap_frag_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 *********** */
 | 
					/* *********** FUNCTIONS *********** */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -79,11 +84,20 @@ static void EEVEE_engine_init(void *vedata)
 | 
				
			|||||||
		lib_str = BLI_dynstr_get_cstring(ds_vert);
 | 
							lib_str = BLI_dynstr_get_cstring(ds_vert);
 | 
				
			||||||
		BLI_dynstr_free(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);
 | 
							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) {
 | 
						if (!e_data.tonemap) {
 | 
				
			||||||
		e_data.tonemap = DRW_shader_create_fullscreen(datatoc_tonemap_frag_glsl, NULL);
 | 
							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);
 | 
							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_init(stl);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// EEVEE_lights_update(stl);
 | 
						// EEVEE_lights_update(stl);
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@@ -119,6 +134,14 @@ static void EEVEE_cache_init(void *vedata)
 | 
				
			|||||||
		stl->g_data = MEM_mallocN(sizeof(g_data), "g_data");
 | 
							stl->g_data = MEM_mallocN(sizeof(g_data), "g_data");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							/* 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);
 | 
							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);
 | 
							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);
 | 
							psl->pass = DRW_pass_create("Default Light Pass", state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		stl->g_data->default_lit_grp = DRW_shgroup_create(e_data.default_lit, psl->pass);
 | 
							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_block(stl->g_data->default_lit_grp, "light_block", stl->light_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, "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_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, "ltcMat", e_data.ltc_mat, 0);
 | 
				
			||||||
		DRW_shgroup_uniform_texture(stl->g_data->default_lit_grp, "ltcMag", e_data.ltc_mag, 1);
 | 
							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((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->default_lit_grp, geom, ob->obmat);
 | 
				
			||||||
 | 
							DRW_shgroup_call_add(stl->g_data->shadow_shgrp, geom, ob->obmat);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else if (ob->type == OB_LAMP) {
 | 
						else if (ob->type == OB_LAMP) {
 | 
				
			||||||
		EEVEE_lights_cache_add(stl, ob);
 | 
							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)
 | 
					static void EEVEE_cache_finish(void *vedata)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
 | 
						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)
 | 
					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();
 | 
						DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
 | 
				
			||||||
	DefaultTextureList *dtxl = DRW_viewport_texture_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 */	
 | 
						/* Attach depth to the hdr buffer and bind it */	
 | 
				
			||||||
	DRW_framebuffer_texture_detach(dtxl->depth);
 | 
						DRW_framebuffer_texture_detach(dtxl->depth);
 | 
				
			||||||
	DRW_framebuffer_texture_attach(fbl->main, dtxl->depth, 0);
 | 
						DRW_framebuffer_texture_attach(fbl->main, dtxl->depth, 0);
 | 
				
			||||||
@@ -197,7 +232,7 @@ static void EEVEE_draw_scene(void *vedata)
 | 
				
			|||||||
	/* Clear Depth */
 | 
						/* Clear Depth */
 | 
				
			||||||
	/* TODO do background */
 | 
						/* TODO do background */
 | 
				
			||||||
	float clearcol[4] = {0.0f, 0.0f, 0.0f, 1.0f};
 | 
						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);
 | 
				
			||||||
	DRW_draw_pass(psl->depth_pass_cull);
 | 
						DRW_draw_pass(psl->depth_pass_cull);
 | 
				
			||||||
@@ -215,6 +250,8 @@ static void EEVEE_engine_free(void)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	if (e_data.default_lit)
 | 
						if (e_data.default_lit)
 | 
				
			||||||
		DRW_shader_free(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)
 | 
						if (e_data.tonemap)
 | 
				
			||||||
		DRW_shader_free(e_data.tonemap);
 | 
							DRW_shader_free(e_data.tonemap);
 | 
				
			||||||
	if (e_data.ltc_mat)
 | 
						if (e_data.ltc_mat)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,71 +25,160 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "DRW_render.h"
 | 
					#include "DRW_render.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "eevee.h"
 | 
				
			||||||
#include "eevee_private.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 {
 | 
					typedef struct EEVEE_ShadowCubeData {
 | 
				
			||||||
	float position[3], dist;
 | 
						short light_id, shadow_id;
 | 
				
			||||||
	float color[3], spec;
 | 
						float viewprojmat[6][4][4];
 | 
				
			||||||
	float spotsize, spotblend, radius, shadowid;
 | 
					} EEVEE_ShadowCubeData;
 | 
				
			||||||
	float rightvec[3], sizex;
 | 
					 | 
				
			||||||
	float upvec[3], sizey;
 | 
					 | 
				
			||||||
	float forwardvec[3], lamptype;
 | 
					 | 
				
			||||||
} EEVEE_Light;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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)
 | 
					void EEVEE_lights_init(EEVEE_StorageList *stl)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stl->lights_info = MEM_callocN(sizeof(EEVEE_LightsInfo), "EEVEE_LightsInfo");
 | 
						const unsigned int shadow_ubo_size = sizeof(EEVEE_ShadowCube) * MAX_SHADOW_CUBE +
 | 
				
			||||||
	stl->lights_data = MEM_mallocN(sizeof(EEVEE_Light) * MAX_LIGHT, "EEVEE_LightsUboStorage");
 | 
						                                     sizeof(EEVEE_ShadowMap) * MAX_SHADOW_MAP +
 | 
				
			||||||
	stl->lights_ref  = MEM_mallocN(sizeof(Object *) * MAX_LIGHT, "EEVEE lights_ref");
 | 
						                                     sizeof(EEVEE_ShadowCascade) * MAX_SHADOW_CASCADE;
 | 
				
			||||||
	stl->lights_ubo  = DRW_uniformbuffer_create(sizeof(EEVEE_Light) * MAX_LIGHT, NULL);
 | 
					
 | 
				
			||||||
 | 
						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)
 | 
					void EEVEE_lights_cache_init(EEVEE_StorageList *stl)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	BLI_listbase_clear(&stl->g_data->lamps);
 | 
						EEVEE_LampsInfo *linfo = stl->lamps;
 | 
				
			||||||
	stl->lights_info->light_count = 0;
 | 
					
 | 
				
			||||||
 | 
						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_add(EEVEE_StorageList *stl, Object *ob)
 | 
					void EEVEE_lights_cache_add(EEVEE_StorageList *stl, Object *ob)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	BLI_addtail(&stl->g_data->lamps, BLI_genericNodeN(ob));
 | 
						EEVEE_LampsInfo *linfo = stl->lamps;
 | 
				
			||||||
	stl->lights_info->light_count += 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
void EEVEE_lights_cache_finish(EEVEE_StorageList *stl)
 | 
						/* Step 1 find all lamps in the scene and setup them */
 | 
				
			||||||
{
 | 
						if (linfo->num_light > MAX_LIGHT) {
 | 
				
			||||||
	int light_ct = stl->lights_info->light_count;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (light_ct > MAX_LIGHT) {
 | 
					 | 
				
			||||||
		printf("Too much lamps in the scene !!!\n");
 | 
							printf("Too much lamps in the scene !!!\n");
 | 
				
			||||||
		stl->lights_info->light_count = MAX_LIGHT;
 | 
							linfo->num_light = MAX_LIGHT;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							Lamp *la = (Lamp *)ob->data;
 | 
				
			||||||
 | 
							EEVEE_LampEngineData *led = (EEVEE_LampEngineData *)DRW_lamp_engine_data_get(ob, &viewport_eevee_type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							DRW_lamp_engine_data_free((void *)led);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (la->mode & (LA_SHAD_BUF | LA_SHAD_RAY)) {
 | 
				
			||||||
 | 
								if (la->type == LA_SUN && linfo->num_map < MAX_SHADOW_MAP) {
 | 
				
			||||||
 | 
									led->sto = MEM_mallocN(sizeof(EEVEE_ShadowMapData), "EEVEE_ShadowMapData");
 | 
				
			||||||
 | 
									((EEVEE_ShadowMapData *)led->sto)->shadow_id = linfo->num_map;
 | 
				
			||||||
 | 
									linfo->shadow_map_ref[linfo->num_map] = ob;
 | 
				
			||||||
 | 
									linfo->num_map++;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else if ((la->type == LA_SPOT || la->type == LA_LOCAL || la->type == LA_AREA)
 | 
				
			||||||
 | 
								          && linfo->num_cube < MAX_SHADOW_CUBE) {
 | 
				
			||||||
 | 
									led->sto = MEM_mallocN(sizeof(EEVEE_ShadowCubeData), "EEVEE_ShadowCubeData");
 | 
				
			||||||
 | 
									((EEVEE_ShadowCubeData *)led->sto)->shadow_id = linfo->num_cube;
 | 
				
			||||||
 | 
									linfo->shadow_cube_ref[linfo->num_cube] = ob;
 | 
				
			||||||
 | 
									linfo->num_cube++;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (light_ct > 0) {
 | 
							if (!led->sto) {
 | 
				
			||||||
		int i = 0;
 | 
								led->sto = MEM_mallocN(sizeof(EEVEE_LightData), "EEVEE_LightData");
 | 
				
			||||||
		for (LinkData *link = stl->g_data->lamps.first; link && i < MAX_LIGHT; link = link->next, i++) {
 | 
								((EEVEE_LightData *)led->sto)->shadow_id = -1;
 | 
				
			||||||
			Object *ob = (Object *)link->data;
 | 
					 | 
				
			||||||
			stl->lights_ref[i] = ob;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	BLI_freelistN(&stl->g_data->lamps);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* We changed light data so we need to upload it */
 | 
							((EEVEE_LightData *)led->sto)->light_id = linfo->num_light;
 | 
				
			||||||
	EEVEE_lights_update(stl);
 | 
							linfo->light_ref[linfo->num_light] = ob;
 | 
				
			||||||
 | 
							linfo->num_light++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void EEVEE_lights_update(EEVEE_StorageList *stl)
 | 
					void EEVEE_lights_cache_finish(EEVEE_StorageList *stl, EEVEE_TextureList *txl, EEVEE_FramebufferList *fbl)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int light_ct = stl->lights_info->light_count;
 | 
						EEVEE_LampsInfo *linfo = stl->lamps;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Step 4 Update Lamp UBOs */
 | 
				
			||||||
 | 
						EEVEE_lights_update(stl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Step 5 Setup enough layers */
 | 
				
			||||||
 | 
						/* Free textures if number mismatch */
 | 
				
			||||||
 | 
						if (linfo->num_cube != linfo->cache_num_cube) {
 | 
				
			||||||
 | 
							if (txl->shadow_depth_cube_pool) {
 | 
				
			||||||
 | 
								DRW_texture_free(txl->shadow_depth_cube_pool);
 | 
				
			||||||
 | 
								txl->shadow_depth_cube_pool = NULL;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							linfo->cache_num_cube = linfo->num_cube;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (linfo->num_map != linfo->cache_num_map) {
 | 
				
			||||||
 | 
							if (txl->shadow_depth_map_pool) {
 | 
				
			||||||
 | 
								DRW_texture_free(txl->shadow_depth_map_pool);
 | 
				
			||||||
 | 
								txl->shadow_depth_map_pool = NULL;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							linfo->cache_num_map = linfo->num_map;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (linfo->num_cascade != linfo->cache_num_cascade) {
 | 
				
			||||||
 | 
							if (txl->shadow_depth_cascade_pool) {
 | 
				
			||||||
 | 
								DRW_texture_free(txl->shadow_depth_cascade_pool);
 | 
				
			||||||
 | 
								txl->shadow_depth_cascade_pool = NULL;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							linfo->cache_num_cascade = linfo->num_cascade;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Initialize Textures Arrays first so DRW_framebuffer_init just bind them */
 | 
				
			||||||
 | 
						if (!txl->shadow_depth_cube_pool) {
 | 
				
			||||||
 | 
							txl->shadow_depth_cube_pool = DRW_texture_create_2D_array(512, 512, MAX2(1, linfo->num_cube * 6), DRW_TEX_DEPTH_24, DRW_TEX_FILTER | DRW_TEX_COMPARE, NULL);
 | 
				
			||||||
 | 
							if (fbl->shadow_cube_fb)
 | 
				
			||||||
 | 
								DRW_framebuffer_texture_attach(fbl->shadow_cube_fb, txl->shadow_depth_cube_pool, 0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (!txl->shadow_depth_map_pool) {
 | 
				
			||||||
 | 
							txl->shadow_depth_map_pool = DRW_texture_create_2D_array(512, 512, MAX2(1, linfo->num_map), DRW_TEX_DEPTH_24, DRW_TEX_FILTER | DRW_TEX_COMPARE, NULL);
 | 
				
			||||||
 | 
							if (fbl->shadow_map_fb)
 | 
				
			||||||
 | 
								DRW_framebuffer_texture_attach(fbl->shadow_map_fb, txl->shadow_depth_map_pool, 0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (!txl->shadow_depth_cascade_pool) {
 | 
				
			||||||
 | 
							txl->shadow_depth_cascade_pool = DRW_texture_create_2D_array(512, 512, MAX2(1, linfo->num_cascade), DRW_TEX_DEPTH_24, DRW_TEX_FILTER | DRW_TEX_COMPARE, NULL);
 | 
				
			||||||
 | 
							if (fbl->shadow_cascade_fb)
 | 
				
			||||||
 | 
								DRW_framebuffer_texture_attach(fbl->shadow_cascade_fb, txl->shadow_depth_map_pool, 0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DRWFboTexture tex_cube = {&txl->shadow_depth_cube_pool, DRW_BUF_DEPTH_24, DRW_TEX_FILTER | DRW_TEX_COMPARE};
 | 
				
			||||||
 | 
						DRW_framebuffer_init(&fbl->shadow_cube_fb, 512, 512, &tex_cube, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DRWFboTexture tex_map = {&txl->shadow_depth_map_pool, DRW_BUF_DEPTH_24, DRW_TEX_FILTER | DRW_TEX_COMPARE};
 | 
				
			||||||
 | 
						DRW_framebuffer_init(&fbl->shadow_map_fb, 512, 512, &tex_map, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DRWFboTexture tex_cascade = {&txl->shadow_depth_cascade_pool, DRW_BUF_DEPTH_24, DRW_TEX_FILTER | DRW_TEX_COMPARE};
 | 
				
			||||||
 | 
						DRW_framebuffer_init(&fbl->shadow_cascade_fb, 512, 512, &tex_cascade, 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Update buffer with lamp data */
 | 
				
			||||||
 | 
					static void eevee_light_setup(Object *ob, EEVEE_LampsInfo *linfo, EEVEE_LampEngineData *led)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
	/* TODO only update if data changes */
 | 
						/* TODO only update if data changes */
 | 
				
			||||||
	/* Update buffer with lamp data */
 | 
						EEVEE_LightData *evld = led->sto;
 | 
				
			||||||
	for (int i = 0; i < light_ct; ++i) {
 | 
						EEVEE_Light *evli = linfo->light_data + evld->light_id;
 | 
				
			||||||
		EEVEE_Light *evli = stl->lights_data + i;
 | 
					 | 
				
			||||||
		Object *ob = stl->lights_ref[i];
 | 
					 | 
				
			||||||
	Lamp *la = (Lamp *)ob->data;
 | 
						Lamp *la = (Lamp *)ob->data;
 | 
				
			||||||
	float mat[4][4], scale[3], power;
 | 
						float mat[4][4], scale[3], power;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -122,6 +211,7 @@ void EEVEE_lights_update(EEVEE_StorageList *stl)
 | 
				
			|||||||
		evli->sizey = scale[1] / scale[2];
 | 
							evli->sizey = scale[1] / scale[2];
 | 
				
			||||||
		evli->spotsize = cosf(la->spotsize * 0.5f);
 | 
							evli->spotsize = cosf(la->spotsize * 0.5f);
 | 
				
			||||||
		evli->spotblend = (1.0f - evli->spotsize) * la->spotblend;
 | 
							evli->spotblend = (1.0f - evli->spotsize) * la->spotblend;
 | 
				
			||||||
 | 
							evli->radius = MAX2(0.001f, la->area_size);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else if (la->type == LA_AREA) {
 | 
						else if (la->type == LA_AREA) {
 | 
				
			||||||
		evli->sizex = MAX2(0.0001f, la->area_size * scale[0] * 0.5f);
 | 
							evli->sizex = MAX2(0.0001f, la->area_size * scale[0] * 0.5f);
 | 
				
			||||||
@@ -133,7 +223,7 @@ void EEVEE_lights_update(EEVEE_StorageList *stl)
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else {
 | 
						else {
 | 
				
			||||||
			evli->sizex = MAX2(0.001f, la->area_size);
 | 
							evli->radius = MAX2(0.001f, la->area_size);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Make illumination power constant */
 | 
						/* Make illumination power constant */
 | 
				
			||||||
@@ -142,7 +232,7 @@ void EEVEE_lights_update(EEVEE_StorageList *stl)
 | 
				
			|||||||
		        * 80.0f; /* XXX : Empirical, Fit cycles power */
 | 
							        * 80.0f; /* XXX : Empirical, Fit cycles power */
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else if (la->type == LA_SPOT || la->type == LA_LOCAL) {
 | 
						else if (la->type == LA_SPOT || la->type == LA_LOCAL) {
 | 
				
			||||||
			power = 1.0f / (4.0f * evli->sizex * evli->sizex * M_PI * M_PI) /* 1/(4*r²*Pi²) */
 | 
							power = 1.0f / (4.0f * evli->radius * evli->radius * M_PI * M_PI) /* 1/(4*r²*Pi²) */
 | 
				
			||||||
		        * M_PI * M_PI * M_PI * 10.0; /* XXX : Empirical, Fit cycles power */
 | 
							        * M_PI * M_PI * M_PI * 10.0; /* XXX : Empirical, Fit cycles power */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* for point lights (a.k.a radius == 0.0) */
 | 
							/* for point lights (a.k.a radius == 0.0) */
 | 
				
			||||||
@@ -155,8 +245,173 @@ void EEVEE_lights_update(EEVEE_StorageList *stl)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	/* Lamp Type */
 | 
						/* Lamp Type */
 | 
				
			||||||
	evli->lamptype = (float)la->type;
 | 
						evli->lamptype = (float)la->type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* No shadow by default */
 | 
				
			||||||
 | 
						evli->shadowid = -1.0f;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static float texcomat[4][4] = { /* From NDC to TexCo */
 | 
				
			||||||
 | 
						{0.5, 0.0, 0.0, 0.0},
 | 
				
			||||||
 | 
						{0.0, 0.5, 0.0, 0.0},
 | 
				
			||||||
 | 
						{0.0, 0.0, 0.5, 0.0},
 | 
				
			||||||
 | 
						{0.5, 0.5, 0.5, 1.0}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static float cubefacemat[6][4][4] = {
 | 
				
			||||||
 | 
						/* Pos X */
 | 
				
			||||||
 | 
						{{0.0, 0.0, -1.0, 0.0},
 | 
				
			||||||
 | 
						 {0.0, -1.0, 0.0, 0.0},
 | 
				
			||||||
 | 
						 {-1.0, 0.0, 0.0, 0.0},
 | 
				
			||||||
 | 
						 {0.0, 0.0, 0.0, 1.0}},
 | 
				
			||||||
 | 
						/* Neg X */
 | 
				
			||||||
 | 
						{{0.0, 0.0, 1.0, 0.0},
 | 
				
			||||||
 | 
						 {0.0, -1.0, 0.0, 0.0},
 | 
				
			||||||
 | 
						 {1.0, 0.0, 0.0, 0.0},
 | 
				
			||||||
 | 
						 {0.0, 0.0, 0.0, 1.0}},
 | 
				
			||||||
 | 
						/* Pos Y */
 | 
				
			||||||
 | 
						{{1.0, 0.0, 0.0, 0.0},
 | 
				
			||||||
 | 
						 {0.0, 0.0, 1.0, 0.0},
 | 
				
			||||||
 | 
						 {0.0, -1.0, 0.0, 0.0},
 | 
				
			||||||
 | 
						 {0.0, 0.0, 0.0, 1.0}},
 | 
				
			||||||
 | 
						/* Neg Y */
 | 
				
			||||||
 | 
						{{1.0, 0.0, 0.0, 0.0},
 | 
				
			||||||
 | 
						 {0.0, 0.0, -1.0, 0.0},
 | 
				
			||||||
 | 
						 {0.0, 1.0, 0.0, 0.0},
 | 
				
			||||||
 | 
						 {0.0, 0.0, 0.0, 1.0}},
 | 
				
			||||||
 | 
						/* Pos Z */
 | 
				
			||||||
 | 
						{{1.0, 0.0, 0.0, 0.0},
 | 
				
			||||||
 | 
						 {0.0, -1.0, 0.0, 0.0},
 | 
				
			||||||
 | 
						 {0.0, 0.0, -1.0, 0.0},
 | 
				
			||||||
 | 
						 {0.0, 0.0, 0.0, 1.0}},
 | 
				
			||||||
 | 
						/* Neg Z */
 | 
				
			||||||
 | 
						{{-1.0, 0.0, 0.0, 0.0},
 | 
				
			||||||
 | 
						 {0.0, -1.0, 0.0, 0.0},
 | 
				
			||||||
 | 
						 {0.0, 0.0, 1.0, 0.0},
 | 
				
			||||||
 | 
						 {0.0, 0.0, 0.0, 1.0}},
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void eevee_shadow_cube_setup(Object *ob, EEVEE_LampsInfo *linfo, EEVEE_LampEngineData *led)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						float projmat[4][4];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						EEVEE_ShadowCubeData *evsmp = (EEVEE_ShadowCubeData *)led->sto;
 | 
				
			||||||
 | 
						EEVEE_Light *evli = linfo->light_data + evsmp->light_id;
 | 
				
			||||||
 | 
						EEVEE_ShadowCube *evsh = linfo->shadow_cube_data + evsmp->shadow_id;
 | 
				
			||||||
 | 
						Lamp *la = (Lamp *)ob->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						perspective_m4(projmat, -la->clipsta, la->clipsta, -la->clipsta, la->clipsta, la->clipsta, la->clipend);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (int i = 0; i < 6; ++i) {
 | 
				
			||||||
 | 
							float tmp[4][4];
 | 
				
			||||||
 | 
							unit_m4(tmp);
 | 
				
			||||||
 | 
							negate_v3_v3(tmp[3], ob->obmat[3]);
 | 
				
			||||||
 | 
							mul_m4_m4m4(tmp, cubefacemat[i], tmp);
 | 
				
			||||||
 | 
							mul_m4_m4m4(evsmp->viewprojmat[i], projmat, tmp);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Upload buffer to GPU */
 | 
						evsh->bias = 0.05f * la->bias;
 | 
				
			||||||
	DRW_uniformbuffer_update(stl->lights_ubo, stl->lights_data);
 | 
						evsh->near = la->clipsta;
 | 
				
			||||||
 | 
						evsh->far = la->clipend;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						evli->shadowid = (float)(evsmp->shadow_id);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void eevee_shadow_map_setup(Object *ob, EEVEE_LampsInfo *linfo, EEVEE_LampEngineData *led)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						float viewmat[4][4], projmat[4][4];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						EEVEE_ShadowMapData *evsmp = (EEVEE_ShadowMapData *)led->sto;
 | 
				
			||||||
 | 
						EEVEE_Light *evli = linfo->light_data + evsmp->light_id;
 | 
				
			||||||
 | 
						EEVEE_ShadowMap *evsh = linfo->shadow_map_data + evsmp->shadow_id;
 | 
				
			||||||
 | 
						Lamp *la = (Lamp *)ob->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						invert_m4_m4(viewmat, ob->obmat);
 | 
				
			||||||
 | 
						normalize_v3(viewmat[0]);
 | 
				
			||||||
 | 
						normalize_v3(viewmat[1]);
 | 
				
			||||||
 | 
						normalize_v3(viewmat[2]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						float wsize = la->shadow_frustum_size;
 | 
				
			||||||
 | 
						orthographic_m4(projmat, -wsize, wsize, -wsize, wsize, la->clipsta, la->clipend);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mul_m4_m4m4(evsmp->viewprojmat, projmat, viewmat);
 | 
				
			||||||
 | 
						mul_m4_m4m4(evsh->shadowmat, texcomat, evsmp->viewprojmat);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						evsh->bias = 0.005f * la->bias;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						evli->shadowid = (float)(MAX_SHADOW_CUBE + evsmp->shadow_id);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void EEVEE_lights_update(EEVEE_StorageList *stl)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						EEVEE_LampsInfo *linfo = stl->lamps;
 | 
				
			||||||
 | 
						Object *ob;
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; (ob = linfo->light_ref[i]) && (i < MAX_LIGHT); i++) {
 | 
				
			||||||
 | 
							EEVEE_LampEngineData *led = (EEVEE_LampEngineData *)DRW_lamp_engine_data_get(ob, &viewport_eevee_type);
 | 
				
			||||||
 | 
							eevee_light_setup(ob, linfo, led);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						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_shadow_cube_setup(ob, linfo, led);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						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_shadow_map_setup(ob, linfo, led);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// for (i = 0; (ob = linfo->shadow_cascade_ref[i]) && (i < MAX_SHADOW_CASCADE); i++) {
 | 
				
			||||||
 | 
						// 	EEVEE_LampEngineData *led = (EEVEE_LampEngineData *)DRW_lamp_engine_data_get(ob, &viewport_eevee_type);
 | 
				
			||||||
 | 
						// 	eevee_shadow_map_setup(ob, linfo, led);
 | 
				
			||||||
 | 
						// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DRW_uniformbuffer_update(stl->light_ubo, &linfo->light_data);
 | 
				
			||||||
 | 
						DRW_uniformbuffer_update(stl->shadow_ubo, &linfo->shadow_cube_data); /* Update all data at once */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* this refresh lamps shadow buffers */
 | 
				
			||||||
 | 
					void EEVEE_draw_shadows(EEVEE_Data *vedata)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						EEVEE_StorageList *stl = vedata->stl;
 | 
				
			||||||
 | 
						EEVEE_FramebufferList *fbl = vedata->fbl;
 | 
				
			||||||
 | 
						EEVEE_LampsInfo *linfo = stl->lamps;
 | 
				
			||||||
 | 
						Object *ob;
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Cube Shadow Maps */
 | 
				
			||||||
 | 
						/* For old hardware support, we render each face of the shadow map
 | 
				
			||||||
 | 
						 * onto 6 layer of a big 2D texture array and sample manualy the right layer
 | 
				
			||||||
 | 
						 * in the fragment shader. */
 | 
				
			||||||
 | 
						DRW_framebuffer_bind(fbl->shadow_cube_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_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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							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);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Standard Shadow Maps */
 | 
				
			||||||
 | 
						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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							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);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,8 +25,16 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
struct Object;
 | 
					struct Object;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Minimum UBO is 16384 bytes */
 | 
				
			||||||
 | 
					#define MAX_LIGHT 128 /* TODO : find size by dividing UBO max size by light data size */
 | 
				
			||||||
 | 
					#define MAX_SHADOW_CUBE 42 /* TODO : Make this depends on GL_MAX_ARRAY_TEXTURE_LAYERS */
 | 
				
			||||||
 | 
					#define MAX_SHADOW_MAP 64
 | 
				
			||||||
 | 
					#define MAX_SHADOW_CASCADE 8
 | 
				
			||||||
 | 
					#define MAX_CASCADE_NUM 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* keep it under MAX_PASSES */
 | 
					/* keep it under MAX_PASSES */
 | 
				
			||||||
typedef struct EEVEE_PassList {
 | 
					typedef struct EEVEE_PassList {
 | 
				
			||||||
 | 
						struct DRWPass *shadow_pass;
 | 
				
			||||||
	struct DRWPass *depth_pass;
 | 
						struct DRWPass *depth_pass;
 | 
				
			||||||
	struct DRWPass *depth_pass_cull;
 | 
						struct DRWPass *depth_pass_cull;
 | 
				
			||||||
	struct DRWPass *pass;
 | 
						struct DRWPass *pass;
 | 
				
			||||||
@@ -36,26 +44,78 @@ typedef struct EEVEE_PassList {
 | 
				
			|||||||
/* keep it under MAX_BUFFERS */
 | 
					/* keep it under MAX_BUFFERS */
 | 
				
			||||||
typedef struct EEVEE_FramebufferList {
 | 
					typedef struct EEVEE_FramebufferList {
 | 
				
			||||||
	struct GPUFrameBuffer *main; /* HDR */
 | 
						struct GPUFrameBuffer *main; /* HDR */
 | 
				
			||||||
 | 
						struct GPUFrameBuffer *shadow_cube_fb;
 | 
				
			||||||
 | 
						struct GPUFrameBuffer *shadow_map_fb;
 | 
				
			||||||
 | 
						struct GPUFrameBuffer *shadow_cascade_fb;
 | 
				
			||||||
} EEVEE_FramebufferList;
 | 
					} EEVEE_FramebufferList;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* keep it under MAX_TEXTURES */
 | 
					/* keep it under MAX_TEXTURES */
 | 
				
			||||||
typedef struct EEVEE_TextureList {
 | 
					typedef struct EEVEE_TextureList {
 | 
				
			||||||
	struct GPUTexture *color; /* R11_G11_B10 */
 | 
						struct GPUTexture *color; /* R11_G11_B10 */
 | 
				
			||||||
 | 
						struct GPUTexture *shadow_depth_cube_pool;
 | 
				
			||||||
 | 
						struct GPUTexture *shadow_depth_map_pool;
 | 
				
			||||||
 | 
						struct GPUTexture *shadow_depth_cascade_pool;
 | 
				
			||||||
} EEVEE_TextureList;
 | 
					} EEVEE_TextureList;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* keep it under MAX_STORAGE */
 | 
					/* keep it under MAX_STORAGE */
 | 
				
			||||||
typedef struct EEVEE_StorageList {
 | 
					typedef struct EEVEE_StorageList {
 | 
				
			||||||
	/* Lights */
 | 
						/* Lamps */
 | 
				
			||||||
	struct EEVEE_LightsInfo *lights_info;       /* Number of lights, ... */
 | 
						/* XXX this should be per-scenelayer and not per_viewport */
 | 
				
			||||||
	struct EEVEE_Light *lights_data;            /* Array, Packed lights data info, duplication of what is in the Uniform Buffer in Vram */
 | 
						struct EEVEE_LampsInfo *lamps;
 | 
				
			||||||
	struct Object **lights_ref;                 /* List of all lights in the buffer. */
 | 
						struct GPUUniformBuffer *light_ubo;
 | 
				
			||||||
	struct GPUUniformBuffer *lights_ubo;
 | 
						struct GPUUniformBuffer *shadow_ubo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct g_data *g_data;
 | 
						struct g_data *g_data;
 | 
				
			||||||
} EEVEE_StorageList;
 | 
					} EEVEE_StorageList;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct EEVEE_LightsInfo {
 | 
					/* ************ LIGHT UBO ************* */
 | 
				
			||||||
	int light_count;
 | 
					typedef struct EEVEE_Light {
 | 
				
			||||||
} EEVEE_LightsInfo;
 | 
						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_ShadowCube {
 | 
				
			||||||
 | 
						float near, far, bias, pad;
 | 
				
			||||||
 | 
					} EEVEE_ShadowCube;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct EEVEE_ShadowMap {
 | 
				
			||||||
 | 
						float shadowmat[4][4]; /* World->Lamp->NDC->Tex : used for sampling the shadow map. */
 | 
				
			||||||
 | 
						float near, far, bias, pad;
 | 
				
			||||||
 | 
					} EEVEE_ShadowMap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct EEVEE_ShadowCascade {
 | 
				
			||||||
 | 
						float shadowmat[MAX_CASCADE_NUM][4][4]; /* World->Lamp->NDC->Tex : used for sampling the shadow map. */
 | 
				
			||||||
 | 
						float bias, count, pad[2];
 | 
				
			||||||
 | 
						float near[MAX_CASCADE_NUM];
 | 
				
			||||||
 | 
						float far[MAX_CASCADE_NUM];
 | 
				
			||||||
 | 
					} EEVEE_ShadowCascade;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ************ 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;
 | 
				
			||||||
 | 
						int num_cascade, cache_num_cascade;
 | 
				
			||||||
 | 
						/* List of lights in the scene. */
 | 
				
			||||||
 | 
						struct Object *light_ref[MAX_LIGHT];
 | 
				
			||||||
 | 
						struct Object *shadow_cube_ref[MAX_SHADOW_CUBE];
 | 
				
			||||||
 | 
						struct Object *shadow_map_ref[MAX_SHADOW_MAP];
 | 
				
			||||||
 | 
						struct Object *shadow_cascade_ref[MAX_SHADOW_CASCADE];
 | 
				
			||||||
 | 
						/* UBO Storage : data used by UBO */
 | 
				
			||||||
 | 
						struct EEVEE_Light         light_data[MAX_LIGHT];
 | 
				
			||||||
 | 
						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];
 | 
				
			||||||
 | 
					} EEVEE_LampsInfo;
 | 
				
			||||||
 | 
					/* *********************************** */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct EEVEE_Data {
 | 
					typedef struct EEVEE_Data {
 | 
				
			||||||
	void *engine_type;
 | 
						void *engine_type;
 | 
				
			||||||
@@ -65,8 +125,15 @@ typedef struct EEVEE_Data {
 | 
				
			|||||||
	EEVEE_StorageList *stl;
 | 
						EEVEE_StorageList *stl;
 | 
				
			||||||
} EEVEE_Data;
 | 
					} EEVEE_Data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Keep it sync with MAX_LAMP_DATA */
 | 
				
			||||||
 | 
					typedef struct EEVEE_LampEngineData {
 | 
				
			||||||
 | 
						void *sto;
 | 
				
			||||||
 | 
						void *pad;
 | 
				
			||||||
 | 
					} EEVEE_LampEngineData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct g_data{
 | 
					typedef struct g_data{
 | 
				
			||||||
	struct DRWShadingGroup *default_lit_grp;
 | 
						struct DRWShadingGroup *default_lit_grp;
 | 
				
			||||||
 | 
						struct DRWShadingGroup *shadow_shgrp;
 | 
				
			||||||
	struct DRWShadingGroup *depth_shgrp;
 | 
						struct DRWShadingGroup *depth_shgrp;
 | 
				
			||||||
	struct DRWShadingGroup *depth_shgrp_select;
 | 
						struct DRWShadingGroup *depth_shgrp_select;
 | 
				
			||||||
	struct DRWShadingGroup *depth_shgrp_active;
 | 
						struct DRWShadingGroup *depth_shgrp_active;
 | 
				
			||||||
@@ -81,5 +148,6 @@ typedef struct g_data{
 | 
				
			|||||||
void EEVEE_lights_init(EEVEE_StorageList *stl);
 | 
					void EEVEE_lights_init(EEVEE_StorageList *stl);
 | 
				
			||||||
void EEVEE_lights_cache_init(EEVEE_StorageList *stl);
 | 
					void EEVEE_lights_cache_init(EEVEE_StorageList *stl);
 | 
				
			||||||
void EEVEE_lights_cache_add(EEVEE_StorageList *stl, struct Object *ob);
 | 
					void EEVEE_lights_cache_add(EEVEE_StorageList *stl, struct Object *ob);
 | 
				
			||||||
void EEVEE_lights_cache_finish(EEVEE_StorageList *stl);
 | 
					void EEVEE_lights_cache_finish(EEVEE_StorageList *stl, EEVEE_TextureList *txl, EEVEE_FramebufferList *fbl);
 | 
				
			||||||
void EEVEE_lights_update(EEVEE_StorageList *stl);
 | 
					void EEVEE_lights_update(EEVEE_StorageList *stl);
 | 
				
			||||||
 | 
					void EEVEE_draw_shadows(EEVEE_Data *vedata);
 | 
				
			||||||
@@ -9,9 +9,9 @@
 | 
				
			|||||||
struct LightData {
 | 
					struct LightData {
 | 
				
			||||||
	vec4 position_influence;      /* w : InfluenceRadius */
 | 
						vec4 position_influence;      /* w : InfluenceRadius */
 | 
				
			||||||
	vec4 color_spec;              /* w : Spec Intensity */
 | 
						vec4 color_spec;              /* w : Spec Intensity */
 | 
				
			||||||
	vec4 spotdata_shadow;  /* x : spot size, y : spot blend */
 | 
						vec4 spotdata_radius_shadow;  /* x : spot size, y : spot blend, z : radius, w: shadow id */
 | 
				
			||||||
	vec4 rightvec_sizex;         /* xyz: Normalized up vector, w: Lamp Type */
 | 
						vec4 rightvec_sizex;          /* xyz: Normalized up vector, w: area size X or spot scale X */
 | 
				
			||||||
	vec4 upvec_sizey;      /* xyz: Normalized right vector, w: Lamp Type */
 | 
						vec4 upvec_sizey;             /* xyz: Normalized right vector, w: area size Y or spot scale Y */
 | 
				
			||||||
	vec4 forwardvec_type;         /* xyz: Normalized forward vector, w: Lamp Type */
 | 
						vec4 forwardvec_type;         /* xyz: Normalized forward vector, w: Lamp Type */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -21,14 +21,48 @@ struct LightData {
 | 
				
			|||||||
#define l_position     position_influence.xyz
 | 
					#define l_position     position_influence.xyz
 | 
				
			||||||
#define l_influence    position_influence.w
 | 
					#define l_influence    position_influence.w
 | 
				
			||||||
#define l_sizex        rightvec_sizex.w
 | 
					#define l_sizex        rightvec_sizex.w
 | 
				
			||||||
#define l_radius       rightvec_sizex.w
 | 
					 | 
				
			||||||
#define l_sizey        upvec_sizey.w
 | 
					#define l_sizey        upvec_sizey.w
 | 
				
			||||||
#define l_right        rightvec_sizex.xyz
 | 
					#define l_right        rightvec_sizex.xyz
 | 
				
			||||||
#define l_up           upvec_sizey.xyz
 | 
					#define l_up           upvec_sizey.xyz
 | 
				
			||||||
#define l_forward      forwardvec_type.xyz
 | 
					#define l_forward      forwardvec_type.xyz
 | 
				
			||||||
#define l_type         forwardvec_type.w
 | 
					#define l_type         forwardvec_type.w
 | 
				
			||||||
#define l_spot_size    spotdata_shadow.x
 | 
					#define l_spot_size    spotdata_radius_shadow.x
 | 
				
			||||||
#define l_spot_blend   spotdata_shadow.y
 | 
					#define l_spot_blend   spotdata_radius_shadow.y
 | 
				
			||||||
 | 
					#define l_radius       spotdata_radius_shadow.z
 | 
				
			||||||
 | 
					#define l_shadowid     spotdata_radius_shadow.w
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct ShadowCubeData {
 | 
				
			||||||
 | 
						vec4 near_far_bias;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* convenience aliases */
 | 
				
			||||||
 | 
					#define sh_cube_near   near_far_bias.x
 | 
				
			||||||
 | 
					#define sh_cube_far    near_far_bias.y
 | 
				
			||||||
 | 
					#define sh_cube_bias   near_far_bias.z
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct ShadowMapData {
 | 
				
			||||||
 | 
						mat4 shadowmat;
 | 
				
			||||||
 | 
						vec4 near_far_bias;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* convenience aliases */
 | 
				
			||||||
 | 
					#define sh_map_near   near_far_bias.x
 | 
				
			||||||
 | 
					#define sh_map_far    near_far_bias.y
 | 
				
			||||||
 | 
					#define sh_map_bias   near_far_bias.z
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct ShadowCascadeData {
 | 
				
			||||||
 | 
						mat4 shadowmat[MAX_CASCADE_NUM];
 | 
				
			||||||
 | 
						vec4 bias_count;
 | 
				
			||||||
 | 
						float near[MAX_CASCADE_NUM];
 | 
				
			||||||
 | 
						float far[MAX_CASCADE_NUM];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* convenience aliases */
 | 
				
			||||||
 | 
					#define sh_cascade_bias   bias_count.x
 | 
				
			||||||
 | 
					#define sh_cascade_count  bias_count.y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct AreaData {
 | 
					struct AreaData {
 | 
				
			||||||
	vec3 corner[4];
 | 
						vec3 corner[4];
 | 
				
			||||||
@@ -64,6 +98,26 @@ float hypot(float x, float y) { return sqrt(x*x + y*y); }
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
float inverse_distance(vec3 V) { return max( 1 / length(V), 1e-8); }
 | 
					float inverse_distance(vec3 V) { return max( 1 / length(V), 1e-8); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					float linear_depth(float z, float zf, float zn)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (gl_ProjectionMatrix[3][3] == 0.0) {
 | 
				
			||||||
 | 
							return (zn  * zf) / (z * (zn - zf) + zf);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							return (z * 2.0 - 1.0) * zf;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					float buffer_depth(float z, float zf, float zn)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (gl_ProjectionMatrix[3][3] == 0.0) {
 | 
				
			||||||
 | 
							return (zf * (zn - z)) / (z * (zn - zf));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							return (z / (zf * 2.0)) + 0.5;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
float line_plane_intersect_dist(vec3 lineorigin, vec3 linedirection, vec3 planeorigin, vec3 planenormal)
 | 
					float line_plane_intersect_dist(vec3 lineorigin, vec3 linedirection, vec3 planeorigin, vec3 planenormal)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return dot(planenormal, planeorigin - lineorigin) / dot(planenormal, linedirection);
 | 
						return dot(planenormal, planeorigin - lineorigin) / dot(planenormal, linedirection);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,12 +3,20 @@ uniform int light_count;
 | 
				
			|||||||
uniform vec3 cameraPos;
 | 
					uniform vec3 cameraPos;
 | 
				
			||||||
uniform vec3 eye;
 | 
					uniform vec3 eye;
 | 
				
			||||||
uniform mat4 ProjectionMatrix;
 | 
					uniform mat4 ProjectionMatrix;
 | 
				
			||||||
 | 
					uniform sampler2DArrayShadow shadowCubes;
 | 
				
			||||||
 | 
					uniform sampler2DArrayShadow shadowMaps;
 | 
				
			||||||
 | 
					// uniform sampler2DArrayShadow shadowCascades;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
layout(std140) uniform light_block {
 | 
					layout(std140) uniform light_block {
 | 
				
			||||||
	LightData lights_data[MAX_LIGHT];
 | 
						LightData lights_data[MAX_LIGHT];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					layout(std140) uniform shadow_block {
 | 
				
			||||||
 | 
						ShadowCubeData    shadows_cube_data[MAX_SHADOW_CUBE];
 | 
				
			||||||
 | 
						ShadowMapData     shadows_map_data[MAX_SHADOW_MAP];
 | 
				
			||||||
 | 
						ShadowCascadeData shadows_cascade_data[MAX_SHADOW_CASCADE];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
in vec3 worldPosition;
 | 
					in vec3 worldPosition;
 | 
				
			||||||
in vec3 worldNormal;
 | 
					in vec3 worldNormal;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -69,6 +77,80 @@ float light_visibility(LightData ld, ShadingData sd)
 | 
				
			|||||||
		vis *= step(0.0, -dot(sd.L, ld.l_forward));
 | 
							vis *= step(0.0, -dot(sd.L, ld.l_forward));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* shadowing */
 | 
				
			||||||
 | 
						if (ld.l_shadowid >= (MAX_SHADOW_MAP + MAX_SHADOW_CUBE)) {
 | 
				
			||||||
 | 
							/* Shadow Cascade */
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else if (ld.l_shadowid >= MAX_SHADOW_CUBE) {
 | 
				
			||||||
 | 
							/* Shadow Map */
 | 
				
			||||||
 | 
							float shid = ld.l_shadowid - MAX_SHADOW_CUBE;
 | 
				
			||||||
 | 
							ShadowMapData smd = shadows_map_data[int(shid)];
 | 
				
			||||||
 | 
							vec4 shpos = smd.shadowmat * vec4(sd.W, 1.0);
 | 
				
			||||||
 | 
							shpos.z -= smd.sh_map_bias * shpos.w;
 | 
				
			||||||
 | 
							shpos.xyz /= shpos.w;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (shpos.w > 0.0 && min(shpos.x, shpos.y) > 0.0 && max(shpos.x, shpos.y) < 1.0) {
 | 
				
			||||||
 | 
								vis *= texture(shadowMaps, vec4(shpos.xy, shid, shpos.z));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							/* Shadow Cube */
 | 
				
			||||||
 | 
							float shid = ld.l_shadowid;
 | 
				
			||||||
 | 
							ShadowCubeData scd = shadows_cube_data[int(shid)];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							float face;
 | 
				
			||||||
 | 
							vec2 uvs;
 | 
				
			||||||
 | 
							vec3 Linv = sd.L;
 | 
				
			||||||
 | 
							vec3 Labs = abs(Linv);
 | 
				
			||||||
 | 
							vec3 maj_axis;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (max(Labs.y, Labs.z) < Labs.x) {
 | 
				
			||||||
 | 
								if (Linv.x > 0.0) {
 | 
				
			||||||
 | 
									face = 1.0;
 | 
				
			||||||
 | 
									uvs = vec2(1.0, -1.0) * Linv.zy / -Linv.x;
 | 
				
			||||||
 | 
									maj_axis = vec3(1.0, 0.0, 0.0);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else {
 | 
				
			||||||
 | 
									face = 0.0;
 | 
				
			||||||
 | 
									uvs = -Linv.zy / Linv.x;
 | 
				
			||||||
 | 
									maj_axis = vec3(-1.0, 0.0, 0.0);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else if (max(Labs.x, Labs.z) < Labs.y) {
 | 
				
			||||||
 | 
								if (Linv.y > 0.0) {
 | 
				
			||||||
 | 
									face = 2.0;
 | 
				
			||||||
 | 
									uvs = vec2(-1.0, 1.0) * Linv.xz / Linv.y;
 | 
				
			||||||
 | 
									maj_axis = vec3(0.0, 1.0, 0.0);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else {
 | 
				
			||||||
 | 
									face = 3.0;
 | 
				
			||||||
 | 
									uvs = -Linv.xz / -Linv.y;
 | 
				
			||||||
 | 
									maj_axis = vec3(0.0, -1.0, 0.0);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else {
 | 
				
			||||||
 | 
								if (Linv.z > 0.0) {
 | 
				
			||||||
 | 
									face = 5.0;
 | 
				
			||||||
 | 
									uvs = Linv.xy / Linv.z;
 | 
				
			||||||
 | 
									maj_axis = vec3(0.0, 0.0, 1.0);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else {
 | 
				
			||||||
 | 
									face = 4.0;
 | 
				
			||||||
 | 
									uvs = vec2(-1.0, 1.0) * Linv.xy / -Linv.z;
 | 
				
			||||||
 | 
									maj_axis = vec3(0.0, 0.0, -1.0);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							uvs = uvs * 0.5 + 0.5;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Depth in lightspace to compare against shadow map */
 | 
				
			||||||
 | 
							float w = dot(maj_axis, sd.l_vector);
 | 
				
			||||||
 | 
							w -= scd.sh_map_bias * w;
 | 
				
			||||||
 | 
							float shdepth = buffer_depth(w, scd.sh_cube_far, scd.sh_cube_near);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							vis *= texture(shadowCubes, vec4(uvs, shid * 6.0 + face, shdepth));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return vis;
 | 
						return vis;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -108,8 +190,8 @@ void main()
 | 
				
			|||||||
	sd.R = reflect(-sd.V, sd.N);
 | 
						sd.R = reflect(-sd.V, sd.N);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* hardcoded test vars */
 | 
						/* hardcoded test vars */
 | 
				
			||||||
	vec3 albedo = vec3(0.0);
 | 
						vec3 albedo = vec3(0.8);
 | 
				
			||||||
	vec3 specular = mix(vec3(1.0), vec3(1.0), pow(max(0.0, 1.0 - dot(sd.N, sd.V)), 5.0));
 | 
						vec3 specular = mix(vec3(0.03), vec3(1.0), pow(max(0.0, 1.0 - dot(sd.N, sd.V)), 5.0));
 | 
				
			||||||
	float roughness = 0.1;
 | 
						float roughness = 0.1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sd.spec_dominant_dir = get_specular_dominant_dir(sd.N, sd.R, roughness);
 | 
						sd.spec_dominant_dir = get_specular_dominant_dir(sd.N, sd.R, roughness);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					void main() {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										21
									
								
								source/blender/draw/engines/eevee/shaders/shadow_geom.glsl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								source/blender/draw/engines/eevee/shaders/shadow_geom.glsl
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					layout(triangles) in;
 | 
				
			||||||
 | 
					layout(triangle_strip, max_vertices=3) out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uniform mat4 ShadowMatrix;
 | 
				
			||||||
 | 
					uniform int Layer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					in vec4 vPos[];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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();
 | 
				
			||||||
 | 
						EndPrimitive();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										11
									
								
								source/blender/draw/engines/eevee/shaders/shadow_vert.glsl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								source/blender/draw/engines/eevee/shaders/shadow_vert.glsl
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					uniform mat4 ShadowMatrix;
 | 
				
			||||||
 | 
					uniform mat4 ModelMatrix;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					in vec3 pos;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					out vec4 vPos;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void main() {
 | 
				
			||||||
 | 
						vPos = ModelMatrix * vec4(pos, 1.0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -61,6 +61,8 @@ struct Object;
 | 
				
			|||||||
struct Batch;
 | 
					struct Batch;
 | 
				
			||||||
struct DefaultFramebufferList;
 | 
					struct DefaultFramebufferList;
 | 
				
			||||||
struct DefaultTextureList;
 | 
					struct DefaultTextureList;
 | 
				
			||||||
 | 
					struct LampEngineData;
 | 
				
			||||||
 | 
					struct RenderEngineType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct DRWUniform DRWUniform;
 | 
					typedef struct DRWUniform DRWUniform;
 | 
				
			||||||
typedef struct DRWInterface DRWInterface;
 | 
					typedef struct DRWInterface DRWInterface;
 | 
				
			||||||
@@ -252,6 +254,8 @@ struct DefaultTextureList     *DRW_viewport_texture_list_get(void);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* Objects */
 | 
					/* Objects */
 | 
				
			||||||
void **DRW_object_engine_data_get(Object *ob, DrawEngineType *det);
 | 
					void **DRW_object_engine_data_get(Object *ob, DrawEngineType *det);
 | 
				
			||||||
 | 
					struct LampEngineData *DRW_lamp_engine_data_get(Object *ob, struct RenderEngineType *engine_type);
 | 
				
			||||||
 | 
					void DRW_lamp_engine_data_free(struct LampEngineData *led);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Settings */
 | 
					/* Settings */
 | 
				
			||||||
bool DRW_is_object_renderable(struct Object *ob);
 | 
					bool DRW_is_object_renderable(struct Object *ob);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -50,6 +50,7 @@
 | 
				
			|||||||
#include "GPU_draw.h"
 | 
					#include "GPU_draw.h"
 | 
				
			||||||
#include "GPU_extensions.h"
 | 
					#include "GPU_extensions.h"
 | 
				
			||||||
#include "GPU_framebuffer.h"
 | 
					#include "GPU_framebuffer.h"
 | 
				
			||||||
 | 
					#include "GPU_lamp.h"
 | 
				
			||||||
#include "GPU_shader.h"
 | 
					#include "GPU_shader.h"
 | 
				
			||||||
#include "GPU_texture.h"
 | 
					#include "GPU_texture.h"
 | 
				
			||||||
#include "GPU_uniformbuffer.h"
 | 
					#include "GPU_uniformbuffer.h"
 | 
				
			||||||
@@ -1197,6 +1198,7 @@ void DRW_state_reset(void) {}
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#endif  /* WITH_CLAY_ENGINE */
 | 
					#endif  /* WITH_CLAY_ENGINE */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ****************************************** Settings ******************************************/
 | 
					/* ****************************************** Settings ******************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool DRW_is_object_renderable(Object *ob)
 | 
					bool DRW_is_object_renderable(Object *ob)
 | 
				
			||||||
@@ -1234,7 +1236,6 @@ static GPUTextureFormat convert_tex_format(int fbo_format, int *channels, bool *
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
void DRW_framebuffer_init(struct GPUFrameBuffer **fb, int width, int height, DRWFboTexture textures[MAX_FBO_TEX],
 | 
					void DRW_framebuffer_init(struct GPUFrameBuffer **fb, int width, int height, DRWFboTexture textures[MAX_FBO_TEX],
 | 
				
			||||||
                          int texnbr)
 | 
					                          int texnbr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -1431,6 +1432,21 @@ void DRW_object_engine_data_free(Object *ob)
 | 
				
			|||||||
	BLI_freelistN(&ob->drawdata);
 | 
						BLI_freelistN(&ob->drawdata);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LampEngineData *DRW_lamp_engine_data_get(Object *ob, RenderEngineType *engine_type)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						BLI_assert(ob->type == OB_LAMP);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Scene *scene = CTX_data_scene(DST.context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* TODO Dupliobjects */
 | 
				
			||||||
 | 
						return GPU_lamp_engine_data_get(scene, ob, NULL, engine_type);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void DRW_lamp_engine_data_free(LampEngineData *led)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return GPU_lamp_engine_data_free(led);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* **************************************** RENDERING ************************************** */
 | 
					/* **************************************** RENDERING ************************************** */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define TIMER_FALLOFF 0.1f
 | 
					#define TIMER_FALLOFF 0.1f
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -42,15 +42,17 @@ struct RenderEngineType;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
typedef struct GPULamp GPULamp;
 | 
					typedef struct GPULamp GPULamp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MAX_LAMP_DATA 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct LampEngineData {
 | 
					typedef struct LampEngineData {
 | 
				
			||||||
	struct GPUFrameBuffer *framebuffers[4];
 | 
						void *storage[MAX_LAMP_DATA];
 | 
				
			||||||
	struct GPUTexture *textures[4];
 | 
					 | 
				
			||||||
	void *storage[4];
 | 
					 | 
				
			||||||
} LampEngineData;
 | 
					} LampEngineData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GPULamp *GPU_lamp_from_engine(struct Scene *scene, struct Object *ob, Object *par, struct RenderEngineType *re);
 | 
					LampEngineData *GPU_lamp_engine_data_get(struct Scene *scene, struct Object *ob, struct Object *par, struct RenderEngineType *re);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GPULamp *GPU_lamp_from_blender(struct Scene *scene, struct Object *ob, struct Object *par);
 | 
					GPULamp *GPU_lamp_from_blender(struct Scene *scene, struct Object *ob, struct Object *par);
 | 
				
			||||||
void GPU_lamp_free(struct Object *ob);
 | 
					void GPU_lamp_free(struct Object *ob);
 | 
				
			||||||
 | 
					void GPU_lamp_engine_data_free(LampEngineData *led);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool GPU_lamp_override_visible(GPULamp *lamp, struct SceneRenderLayer *srl, struct Material *ma);
 | 
					bool GPU_lamp_override_visible(GPULamp *lamp, struct SceneRenderLayer *srl, struct Material *ma);
 | 
				
			||||||
bool GPU_lamp_has_shadow_buffer(GPULamp *lamp);
 | 
					bool GPU_lamp_has_shadow_buffer(GPULamp *lamp);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -44,7 +44,7 @@ typedef struct GPUViewport GPUViewport;
 | 
				
			|||||||
#define MAX_BUFFERS 8
 | 
					#define MAX_BUFFERS 8
 | 
				
			||||||
#define MAX_TEXTURES 16
 | 
					#define MAX_TEXTURES 16
 | 
				
			||||||
#define MAX_PASSES 16
 | 
					#define MAX_PASSES 16
 | 
				
			||||||
#define MAX_STORAGE 5 /* extend if needed */
 | 
					#define MAX_STORAGE 9 /* extend if needed */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* All FramebufferLists are just the same pointers with different names */
 | 
					/* All FramebufferLists are just the same pointers with different names */
 | 
				
			||||||
typedef struct FramebufferList {
 | 
					typedef struct FramebufferList {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -143,8 +143,7 @@ bool GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slo
 | 
				
			|||||||
	else
 | 
						else
 | 
				
			||||||
		attachment = GL_COLOR_ATTACHMENT0 + slot;
 | 
							attachment = GL_COLOR_ATTACHMENT0 + slot;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	glFramebufferTexture2D(GL_FRAMEBUFFER, attachment,
 | 
						glFramebufferTexture(GL_FRAMEBUFFER, attachment, GPU_texture_opengl_bindcode(tex), 0);
 | 
				
			||||||
		GPU_texture_target(tex), GPU_texture_opengl_bindcode(tex), 0);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (GPU_texture_depth(tex))
 | 
						if (GPU_texture_depth(tex))
 | 
				
			||||||
		fb->depthtex = tex;
 | 
							fb->depthtex = tex;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -214,7 +214,7 @@ static GPUTexture *gpu_lamp_create_vsm_shadow_map(int size)
 | 
				
			|||||||
	return GPU_texture_create_2D_custom(size, size, 2, GPU_RG32F, NULL, NULL);
 | 
						return GPU_texture_create_2D_custom(size, size, 2, GPU_RG32F, NULL, NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GPULamp *GPU_lamp_from_engine(Scene *scene, Object *ob, Object *par, struct RenderEngineType *re)
 | 
					LampEngineData *GPU_lamp_engine_data_get(Scene *scene, Object *ob, Object *par, struct RenderEngineType *re)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	GPULamp *lamp;
 | 
						GPULamp *lamp;
 | 
				
			||||||
	LinkData *link;
 | 
						LinkData *link;
 | 
				
			||||||
@@ -223,7 +223,7 @@ GPULamp *GPU_lamp_from_engine(Scene *scene, Object *ob, Object *par, struct Rend
 | 
				
			|||||||
		lamp = (GPULamp *)link->data;
 | 
							lamp = (GPULamp *)link->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if ((lamp->par == par) && (lamp->scene == scene) && (lamp->re == re))
 | 
							if ((lamp->par == par) && (lamp->scene == scene) && (lamp->re == re))
 | 
				
			||||||
			return link->data;
 | 
								return &lamp->data;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	lamp = MEM_callocN(sizeof(GPULamp), "GPULamp");
 | 
						lamp = MEM_callocN(sizeof(GPULamp), "GPULamp");
 | 
				
			||||||
@@ -238,7 +238,7 @@ GPULamp *GPU_lamp_from_engine(Scene *scene, Object *ob, Object *par, struct Rend
 | 
				
			|||||||
	lamp->la = ob->data;
 | 
						lamp->la = ob->data;
 | 
				
			||||||
	lamp->re = re;
 | 
						lamp->re = re;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return lamp;
 | 
						return &lamp->data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
 | 
					GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
 | 
				
			||||||
@@ -364,6 +364,16 @@ GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
 | 
				
			|||||||
	return lamp;
 | 
						return lamp;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void GPU_lamp_engine_data_free(LampEngineData *led)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						for (int i = 0; i < MAX_LAMP_DATA; ++i)	{
 | 
				
			||||||
 | 
							if (led->storage[i]) {
 | 
				
			||||||
 | 
								MEM_freeN(led->storage[i]);
 | 
				
			||||||
 | 
								led->storage[i] = NULL;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void GPU_lamp_free(Object *ob)
 | 
					void GPU_lamp_free(Object *ob)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	GPULamp *lamp;
 | 
						GPULamp *lamp;
 | 
				
			||||||
@@ -384,6 +394,7 @@ void GPU_lamp_free(Object *ob)
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		gpu_lamp_shadow_free(lamp);
 | 
							gpu_lamp_shadow_free(lamp);
 | 
				
			||||||
 | 
							GPU_lamp_engine_data_free(&lamp->data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		MEM_freeN(lamp);
 | 
							MEM_freeN(lamp);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -169,9 +169,11 @@ static bool GPU_texture_try_alloc(
 | 
				
			|||||||
		case GL_PROXY_TEXTURE_1D:
 | 
							case GL_PROXY_TEXTURE_1D:
 | 
				
			||||||
			glTexImage1D(proxy, 0, internalformat, tex->w, 0, format, data_format, NULL);
 | 
								glTexImage1D(proxy, 0, internalformat, tex->w, 0, format, data_format, NULL);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
							case GL_PROXY_TEXTURE_1D_ARRAY:
 | 
				
			||||||
		case GL_PROXY_TEXTURE_2D:
 | 
							case GL_PROXY_TEXTURE_2D:
 | 
				
			||||||
			glTexImage2D(proxy, 0, internalformat, tex->w, tex->h, 0, format, data_format, NULL);
 | 
								glTexImage2D(proxy, 0, internalformat, tex->w, tex->h, 0, format, data_format, NULL);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
							case GL_PROXY_TEXTURE_2D_ARRAY:
 | 
				
			||||||
		case GL_PROXY_TEXTURE_3D:
 | 
							case GL_PROXY_TEXTURE_3D:
 | 
				
			||||||
			glTexImage3D(proxy, 0, internalformat, tex->w, tex->h, tex->d, 0, format, data_format, NULL);
 | 
								glTexImage3D(proxy, 0, internalformat, tex->w, tex->h, tex->d, 0, format, data_format, NULL);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
@@ -279,14 +281,20 @@ static GPUTexture *GPU_texture_create_nD(
 | 
				
			|||||||
	glBindTexture(tex->target, tex->bindcode);
 | 
						glBindTexture(tex->target, tex->bindcode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Check if texture fit in VRAM */
 | 
						/* Check if texture fit in VRAM */
 | 
				
			||||||
	if (d > 0) {
 | 
						if (n == 1) {
 | 
				
			||||||
		proxy = GL_PROXY_TEXTURE_3D;
 | 
							if (h == 0)
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	else if (h > 0) {
 | 
					 | 
				
			||||||
		proxy = GL_PROXY_TEXTURE_2D;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	else {
 | 
					 | 
				
			||||||
			proxy = GL_PROXY_TEXTURE_1D;
 | 
								proxy = GL_PROXY_TEXTURE_1D;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								proxy = GL_PROXY_TEXTURE_1D_ARRAY;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else if (n == 2) {
 | 
				
			||||||
 | 
							if (d == 0)
 | 
				
			||||||
 | 
								proxy = GL_PROXY_TEXTURE_2D;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								proxy = GL_PROXY_TEXTURE_2D_ARRAY;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else if (n == 3) {
 | 
				
			||||||
 | 
							proxy = GL_PROXY_TEXTURE_3D;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	valid = GPU_texture_try_alloc(tex, proxy, internalformat, format, data_format, components, can_rescale, fpixels,
 | 
						valid = GPU_texture_try_alloc(tex, proxy, internalformat, format, data_format, components, can_rescale, fpixels,
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user