[Bf-blender-cvs] [80db7092500] blender2.8: Eevee: Spherical Harmonic diffuse.

Clément Foucault noreply at git.blender.org
Tue Apr 18 21:47:31 CEST 2017


Commit: 80db7092500abef075d981408cdc75f615ce0a34
Author: Clément Foucault
Date:   Tue Apr 18 21:02:02 2017 +0200
Branches: blender2.8
https://developer.blender.org/rB80db7092500abef075d981408cdc75f615ce0a34

Eevee: Spherical Harmonic diffuse.

For now it's done each frame and it's rather slow (16ms) but result will be cached soon.

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

M	source/blender/draw/CMakeLists.txt
M	source/blender/draw/engines/eevee/eevee.c
M	source/blender/draw/engines/eevee/eevee_private.h
M	source/blender/draw/engines/eevee/eevee_probes.c
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/probe_sh_frag.glsl
M	source/blender/draw/intern/DRW_render.h
M	source/blender/draw/intern/draw_manager.c

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

diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 22acc98a5ca..75dc9cadb60 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -105,6 +105,7 @@ 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/probe_filter_frag.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/probe_sh_frag.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/probe_frag.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/probe_geom.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/probe_vert.glsl SRC)
diff --git a/source/blender/draw/engines/eevee/eevee.c b/source/blender/draw/engines/eevee/eevee.c
index acfc51f83de..b496344478a 100644
--- a/source/blender/draw/engines/eevee/eevee.c
+++ b/source/blender/draw/engines/eevee/eevee.c
@@ -44,6 +44,7 @@ static struct {
 	/* Temp : use world shader */
 	struct GPUShader *probe_sh;
 	struct GPUShader *probe_filter_sh;
+	struct GPUShader *probe_spherical_harmonic_sh;
 
 	struct GPUTexture *ltc_mat;
 	struct GPUTexture *brdf_lut;
@@ -65,6 +66,7 @@ extern char datatoc_shadow_frag_glsl[];
 extern char datatoc_shadow_geom_glsl[];
 extern char datatoc_shadow_vert_glsl[];
 extern char datatoc_probe_filter_frag_glsl[];
+extern char datatoc_probe_sh_frag_glsl[];
 extern char datatoc_probe_frag_glsl[];
 extern char datatoc_probe_geom_glsl[];
 extern char datatoc_probe_vert_glsl[];
@@ -238,19 +240,24 @@ static void EEVEE_engine_init(void *ved)
 	}
 
 	if (!e_data.probe_filter_sh) {
-		char *lib_str = NULL;
+		char *shader_str = NULL;
 
-		DynStr *ds_vert = BLI_dynstr_new();
-		BLI_dynstr_append(ds_vert, datatoc_bsdf_common_lib_glsl);
-		BLI_dynstr_append(ds_vert, datatoc_bsdf_sampling_lib_glsl);
-		lib_str = BLI_dynstr_get_cstring(ds_vert);
-		BLI_dynstr_free(ds_vert);
+		DynStr *ds_frag = BLI_dynstr_new();
+		BLI_dynstr_append(ds_frag, datatoc_bsdf_common_lib_glsl);
+		BLI_dynstr_append(ds_frag, datatoc_bsdf_sampling_lib_glsl);
+		BLI_dynstr_append(ds_frag, datatoc_probe_filter_frag_glsl);
+		shader_str = BLI_dynstr_get_cstring(ds_frag);
+		BLI_dynstr_free(ds_frag);
 
-		e_data.probe_filter_sh = DRW_shader_create_with_lib(datatoc_probe_vert_glsl, datatoc_probe_geom_glsl, datatoc_probe_filter_frag_glsl, lib_str,
-		                                                    "#define HAMMERSLEY_SIZE 8192\n"
-		                                                    "#define NOISE_SIZE 64\n");
+		e_data.probe_filter_sh = DRW_shader_create(datatoc_probe_vert_glsl, datatoc_probe_geom_glsl, shader_str,
+		                                           "#define HAMMERSLEY_SIZE 8192\n"
+		                                           "#define NOISE_SIZE 64\n");
 
-		MEM_freeN(lib_str);
+		MEM_freeN(shader_str);
+	}
+
+	if (!e_data.probe_spherical_harmonic_sh) {
+		e_data.probe_spherical_harmonic_sh = DRW_shader_create_fullscreen(datatoc_probe_sh_frag_glsl, NULL);
 	}
 
 	if (!e_data.tonemap) {
@@ -341,6 +348,17 @@ static void EEVEE_cache_init(void *vedata)
 	}
 
 	{
+		psl->probe_sh_compute = DRW_pass_create("Probe SH Compute", DRW_STATE_WRITE_COLOR);
+
+		DRWShadingGroup *grp = DRW_shgroup_create(e_data.probe_spherical_harmonic_sh, psl->probe_sh_compute);
+		DRW_shgroup_uniform_int(grp, "probeSize", &stl->probes->shres, 1);
+		DRW_shgroup_uniform_texture(grp, "probeHdr", txl->probe_rt, 0);
+
+		struct Batch *geom = DRW_cache_fullscreen_quad_get();
+		DRW_shgroup_call_add(grp, geom, NULL);
+	}
+
+	{
 		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);
 
@@ -357,6 +375,7 @@ static void EEVEE_cache_init(void *vedata)
 		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_float(stl->g_data->default_lit_grp, "lodMax", &stl->probes->lodmax, 1);
+		DRW_shgroup_uniform_vec3(stl->g_data->default_lit_grp, "shCoefs[0]", (float *)stl->probes->shcoefs, 9);
 		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, "brdfLut", e_data.brdf_lut, 1);
@@ -455,6 +474,7 @@ static void EEVEE_engine_free(void)
 	DRW_SHADER_FREE_SAFE(e_data.shadow_sh);
 	DRW_SHADER_FREE_SAFE(e_data.probe_sh);
 	DRW_SHADER_FREE_SAFE(e_data.probe_filter_sh);
+	DRW_SHADER_FREE_SAFE(e_data.probe_spherical_harmonic_sh);
 	DRW_SHADER_FREE_SAFE(e_data.tonemap);
 	DRW_TEXTURE_FREE_SAFE(e_data.ltc_mat);
 	DRW_TEXTURE_FREE_SAFE(e_data.brdf_lut);
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index c98e0b6529b..8be09091df8 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -39,7 +39,7 @@ typedef struct EEVEE_PassList {
 	/* Probes */
 	struct DRWPass *probe_background;
 	struct DRWPass *probe_prefilter;
-	struct DRWPass *probe_sh;
+	struct DRWPass *probe_sh_compute;
 
 	struct DRWPass *depth_pass;
 	struct DRWPass *depth_pass_cull;
@@ -69,6 +69,7 @@ typedef struct EEVEE_TextureList {
 	struct GPUTexture *probe_rt; /* R16_G16_B16 */
 	struct GPUTexture *probe_depth_rt;
 	struct GPUTexture *probe_pool; /* R11_G11_B10 */
+	struct GPUTexture *probe_sh; /* R16_G16_B16 */
 
 	struct GPUTexture *color; /* R16_G16_B16 */
 } EEVEE_TextureList;
@@ -82,6 +83,7 @@ typedef struct EEVEE_StorageList {
 
 	/* Probes */
 	struct EEVEE_ProbesInfo *probes;
+	struct GPUUniformBuffer *probe_ubo;
 
 	struct g_data *g_data;
 } EEVEE_StorageList;
@@ -144,6 +146,9 @@ typedef struct EEVEE_ProbesInfo {
 	float roughness;
 	float lodfactor;
 	float lodmax;
+	int shres;
+	int shnbr;
+	float shcoefs[9][3]; /* Temp */
 	struct GPUTexture *backgroundtex;
 } EEVEE_ProbesInfo;
 
diff --git a/source/blender/draw/engines/eevee/eevee_probes.c b/source/blender/draw/engines/eevee/eevee_probes.c
index 78e1a0cf52f..809e175938e 100644
--- a/source/blender/draw/engines/eevee/eevee_probes.c
+++ b/source/blender/draw/engines/eevee/eevee_probes.c
@@ -98,6 +98,11 @@ void EEVEE_probes_init(EEVEE_Data *vedata)
 	DRWFboTexture tex_filter = {&txl->probe_pool, DRW_BUF_RGBA_16, DRW_TEX_FILTER | DRW_TEX_MIPMAP};
 
 	DRW_framebuffer_init(&fbl->probe_filter_fb, PROBE_SIZE, PROBE_SIZE, &tex_filter, 1);
+
+	/* Spherical Harmonic Buffer */
+	DRWFboTexture tex_sh = {&txl->probe_sh, DRW_BUF_RGBA_16, DRW_TEX_FILTER | DRW_TEX_MIPMAP};
+
+	DRW_framebuffer_init(&fbl->probe_sh_fb, 9, 1, &tex_sh, 1);
 }
 
 void EEVEE_probes_cache_init(EEVEE_Data *UNUSED(vedata))
@@ -203,7 +208,8 @@ void EEVEE_refresh_probe(EEVEE_Data *vedata)
 	DRW_framebuffer_texture_attach(fbl->probe_filter_fb, txl->probe_pool, 0, 0);
 
 	/* 4 - Compute spherical harmonics */
-	/* TODO */
-	// DRW_framebuffer_bind(fbl->probe_sh_fb);
-	// DRW_draw_pass(psl->probe_sh);
+	pinfo->shres = 64;
+	DRW_framebuffer_bind(fbl->probe_sh_fb);
+	DRW_draw_pass(psl->probe_sh_compute);
+	DRW_framebuffer_read_data(0, 0, 9, 1, 3, 0, (float *)pinfo->shcoefs);
 }
diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
index 0f47a341764..b907adc2323 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
@@ -173,6 +173,41 @@ float buffer_depth(bool is_persp, float z, float zf, float zn)
 	}
 }
 
+#define spherical_harmonics spherical_harmonics_L2
+
+/* http://seblagarde.wordpress.com/2012/01/08/pi-or-not-to-pi-in-game-lighting-equation/ */
+vec3 spherical_harmonics_L1(vec3 N, vec3 shcoefs[9])
+{
+	vec3 sh = vec3(0.0);
+
+	sh += 0.282095 * shcoefs[0];
+
+	sh += -0.488603 * N.z * shcoefs[1];
+	sh += 0.488603 * N.y * shcoefs[2];
+	sh += -0.488603 * N.x * shcoefs[3];
+
+	return sh;
+}
+
+vec3 spherical_harmonics_L2(vec3 N, vec3 shcoefs[9])
+{
+	vec3 sh = vec3(0.0);
+
+	sh += 0.282095 * shcoefs[0];
+
+	sh += -0.488603 * N.z * shcoefs[1];
+	sh += 0.488603 * N.y * shcoefs[2];
+	sh += -0.488603 * N.x * shcoefs[3];
+
+	sh += 1.092548 * N.x * N.z * shcoefs[4];
+	sh += -1.092548 * N.z * N.y * shcoefs[5];
+	sh += 0.315392 * (3.0 * N.y * N.y - 1.0) * shcoefs[6];
+	sh += -1.092548 * N.x * N.y * shcoefs[7];
+	sh += 0.546274 * (N.x * N.x - N.z * N.z) * shcoefs[8];
+
+	return sh;
+}
+
 float rectangle_solid_angle(AreaData ad)
 {
 	vec3 n0 = normalize(cross(ad.corner[0], ad.corner[1]));
diff --git a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
index 598d34941eb..189cdcf10fb 100644
--- a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
@@ -6,6 +6,7 @@ uniform mat4 ProjectionMatrix;
 
 uniform samplerCube probeFiltered;
 uniform float lodMax;
+uniform vec3 shCoefs[9];
 
 #ifndef USE_LTC
 uniform sampler2D brdfLut;
@@ -198,7 +199,7 @@ void main()
 	sd.R = reflect(-sd.V, sd.N);
 
 	/* hardcoded test vars */
-	vec3 albedo = vec3(0.0);
+	vec3 albedo = mix(vec3(0.0, 0.0, 0.0), vec3(0.8, 0.8, 0.8), saturate(worldPosition.y/2));
 	vec3 f0 = mix(vec3(0.83, 0.5, 0.1), vec3(0.03, 0.03, 0.03), saturate(worldPosition.y/2));
 	vec3 specular = mix(f0, vec3(1.0), pow(max(0.0, 1.0 - dot(sd.N, sd.V)), 5.0));
 	float roughness = saturate(worldPosition.x/lodMax);
@@ -229,5 +230,7 @@ void main()
 	vec3 Li = textureLod(probeFiltered, sd.spec_dominant_dir, roughness * lodMax).rgb;
 	radiance += Li * brdf_lut.y + f0 * Li * brdf_lut.x;
 
+	radiance += spherical_harmonics(sd.N, shCoefs) * albedo;
+
 	fragColor = vec4(radiance, 1.0);
 }
\ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/shaders/probe_sh_frag.glsl b/source/blender/draw/engines/eevee/shaders/probe_sh_frag.glsl
new file mode 100644
index 00000000000..068a5bbf8b2
--- /dev/null
+++ b/source/blend

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list