[Bf-blender-cvs] [4f7665c8441] blender2.8: Eevee: Volumetrics: Add Volume object support.

Clément Foucault noreply at git.blender.org
Fri Oct 27 23:28:41 CEST 2017


Commit: 4f7665c84410e9e25360b0d80ce073c54242e5d4
Author: Clément Foucault
Date:   Fri Oct 27 16:20:33 2017 +0200
Branches: blender2.8
https://developer.blender.org/rB4f7665c84410e9e25360b0d80ce073c54242e5d4

Eevee: Volumetrics: Add Volume object support.

This is quite basic as it only support boundbing boxes.
But the material can refine the volume shape in anyway the user like.

To overcome this limitation, a voxelisation should be done on the mesh (generating a SDF maybe?) and tested against every volumetric cell.

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

M	source/blender/draw/engines/eevee/eevee_effects.c
M	source/blender/draw/engines/eevee/eevee_materials.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/volumetric_frag.glsl
M	source/blender/draw/engines/eevee/shaders/volumetric_geom.glsl
M	source/blender/gpu/shaders/gpu_shader_material.glsl
M	source/blender/nodes/shader/nodes/node_shader_tex_coord.c

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

diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c
index c6dcf78d401..d3c22ed29f4 100644
--- a/source/blender/draw/engines/eevee/eevee_effects.c
+++ b/source/blender/draw/engines/eevee/eevee_effects.c
@@ -36,6 +36,7 @@
 
 #include "BKE_global.h" /* for G.debug_value */
 #include "BKE_camera.h"
+#include "BKE_mesh.h"
 #include "BKE_object.h"
 #include "BKE_animsys.h"
 #include "BKE_screen.h"
@@ -93,6 +94,7 @@ static struct {
 	struct GPUShader *dof_resolve_sh;
 
 	/* Volumetric */
+	struct GPUShader *volumetric_clear_sh;
 	struct GPUShader *volumetric_scatter_sh;
 	struct GPUShader *volumetric_integration_sh;
 	struct GPUShader *volumetric_resolve_sh;
@@ -300,6 +302,12 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
 		e_data.volumetric_common_lamps_lib = BLI_dynstr_get_cstring(ds_frag);
 		BLI_dynstr_free(ds_frag);
 
+		e_data.volumetric_clear_sh = DRW_shader_create_with_lib(datatoc_volumetric_vert_glsl,
+		                                                        datatoc_volumetric_geom_glsl,
+		                                                        datatoc_volumetric_frag_glsl,
+		                                                        e_data.volumetric_common_lib,
+		                                                        "#define VOLUMETRICS\n"
+		                                                        "#define CLEAR\n");
 		e_data.volumetric_scatter_sh = DRW_shader_create_with_lib(datatoc_volumetric_vert_glsl,
 		                                                          datatoc_volumetric_geom_glsl,
 		                                                          datatoc_volumetric_scatter_frag_glsl,
@@ -1031,6 +1039,38 @@ static DRWShadingGroup *eevee_create_bloom_pass(const char *name, EEVEE_EffectsI
 	return grp;
 }
 
+void EEVEE_effects_cache_volume_object_add(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata, Scene *scene, Object *ob)
+{
+	float *texcoloc = NULL;
+	float *texcosize = NULL;
+	EEVEE_VolumetricsInfo *volumetrics = sldata->volumetrics;
+	Material *ma = give_current_material(ob, 1);
+
+	if (ma == NULL) {
+		return;
+	}
+
+	struct GPUMaterial *mat = EEVEE_material_mesh_volume_get(scene, ma);
+
+	DRWShadingGroup *grp = DRW_shgroup_material_empty_tri_batch_create(mat, vedata->psl->volumetric_objects_ps, volumetrics->froxel_tex_size[2]);
+
+	/* Making sure it's updated. */
+	invert_m4_m4(ob->imat, ob->obmat);
+
+	BKE_mesh_texspace_get_reference((struct Mesh *)ob->data, NULL, &texcoloc, NULL, &texcosize);
+
+	if (grp) {
+		DRW_shgroup_uniform_mat4(grp, "volumeObjectMatrix", (float *)ob->imat);
+		DRW_shgroup_uniform_vec3(grp, "volumeOrcoLoc", texcoloc, 1);
+		DRW_shgroup_uniform_vec3(grp, "volumeOrcoSize", texcosize, 1);
+		DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)vedata->stl->g_data->viewvecs, 2);
+		DRW_shgroup_uniform_ivec3(grp, "volumeTextureSize", (int *)volumetrics->froxel_tex_size, 1);
+		DRW_shgroup_uniform_vec2(grp, "volume_uv_ratio", (float *)volumetrics->volume_coord_scale, 1);
+		DRW_shgroup_uniform_vec3(grp, "volume_param", (float *)volumetrics->depth_param, 1);
+		DRW_shgroup_uniform_vec3(grp, "volume_jitter", (float *)volumetrics->jitter, 1);
+	}
+}
+
 void EEVEE_effects_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
 {
 	EEVEE_PassList *psl = vedata->psl;
@@ -1054,27 +1094,37 @@ void EEVEE_effects_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
 	if ((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) {
 		const DRWContextState *draw_ctx = DRW_context_state_get();
 		Scene *scene = draw_ctx->scene;
-		struct World *wo = scene->world; /* Already checked non NULL */
 		EEVEE_VolumetricsInfo *volumetrics = sldata->volumetrics;
 		static int zero = 0;
 		DRWShadingGroup *grp;
 
 		/* World pass is not additive as it also clear the buffer. */
-		psl->volumetric_ps = DRW_pass_create("Volumetric Properties", DRW_STATE_WRITE_COLOR);
+		psl->volumetric_world_ps = DRW_pass_create("Volumetric World", DRW_STATE_WRITE_COLOR);
 
 		/* World Volumetric */
-		struct GPUMaterial *mat = EEVEE_material_world_volume_get(scene, wo);
-
-		grp = DRW_shgroup_material_empty_tri_batch_create(mat, psl->volumetric_ps, volumetrics->froxel_tex_size[2]);
+		struct World *wo = scene->world;
+		if (wo != NULL && wo->use_nodes && wo->nodetree) {
+			struct GPUMaterial *mat = EEVEE_material_world_volume_get(scene, wo);
+
+			grp = DRW_shgroup_material_empty_tri_batch_create(mat, psl->volumetric_world_ps, volumetrics->froxel_tex_size[2]);
+
+			if (grp) {
+				DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)stl->g_data->viewvecs, 2);
+				DRW_shgroup_uniform_ivec3(grp, "volumeTextureSize", (int *)volumetrics->froxel_tex_size, 1);
+				DRW_shgroup_uniform_vec2(grp, "volume_uv_ratio", (float *)volumetrics->volume_coord_scale, 1);
+				DRW_shgroup_uniform_vec3(grp, "volume_param", (float *)volumetrics->depth_param, 1);
+				DRW_shgroup_uniform_vec3(grp, "volume_jitter", (float *)volumetrics->jitter, 1);
+			}
+		}
+		else {
+			grp = DRW_shgroup_empty_tri_batch_create(e_data.volumetric_clear_sh, psl->volumetric_world_ps, volumetrics->froxel_tex_size[2]);
 
-		if (grp) {
-			DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)stl->g_data->viewvecs, 2);
 			DRW_shgroup_uniform_ivec3(grp, "volumeTextureSize", (int *)volumetrics->froxel_tex_size, 1);
-			DRW_shgroup_uniform_vec2(grp, "volume_uv_ratio", (float *)volumetrics->volume_coord_scale, 1);
-			DRW_shgroup_uniform_vec3(grp, "volume_param", (float *)volumetrics->depth_param, 1);
-			DRW_shgroup_uniform_vec3(grp, "volume_jitter", (float *)volumetrics->jitter, 1);
 		}
 
+		/* Volumetric Objects */
+		psl->volumetric_objects_ps = DRW_pass_create("Volumetric Properties", DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE);
+
 		psl->volumetric_scatter_ps = DRW_pass_create("Volumetric Scattering", DRW_STATE_WRITE_COLOR);
 		grp = DRW_shgroup_empty_tri_batch_create(e_data.volumetric_scatter_sh, psl->volumetric_scatter_ps, volumetrics->froxel_tex_size[2]);
 		DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)stl->g_data->viewvecs, 2);
@@ -1490,7 +1540,8 @@ void EEVEE_effects_do_volumetrics(EEVEE_SceneLayerData *UNUSED(sldata), EEVEE_Da
 
 		/* Step 1: Participating Media Properties */
 		DRW_framebuffer_bind(fbl->volumetric_fb);
-		DRW_draw_pass(psl->volumetric_ps);
+		DRW_draw_pass(psl->volumetric_world_ps);
+		DRW_draw_pass(psl->volumetric_objects_ps);
 
 		/* Step 2: Scatter Light */
 		DRW_framebuffer_bind(fbl->volumetric_scat_fb);
@@ -1852,6 +1903,7 @@ void EEVEE_effects_free(void)
 	DRW_SHADER_FREE_SAFE(e_data.gtao_sh);
 	DRW_SHADER_FREE_SAFE(e_data.gtao_debug_sh);
 
+	DRW_SHADER_FREE_SAFE(e_data.volumetric_clear_sh);
 	DRW_SHADER_FREE_SAFE(e_data.volumetric_scatter_sh);
 	DRW_SHADER_FREE_SAFE(e_data.volumetric_integration_sh);
 	DRW_SHADER_FREE_SAFE(e_data.volumetric_resolve_sh);
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index f5d3898d1bc..1d551796a60 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -318,7 +318,7 @@ static char *eevee_get_defines(int options)
 	return str;
 }
 
-static char *eevee_get_volume_defines(int UNUSED(options))
+static char *eevee_get_volume_defines(int options)
 {
 	char *str = NULL;
 
@@ -326,6 +326,10 @@ static char *eevee_get_volume_defines(int UNUSED(options))
 	BLI_dynstr_appendf(ds, SHADER_DEFINES);
 	BLI_dynstr_appendf(ds, "#define VOLUMETRICS\n");
 
+	if ((options & VAR_MAT_VOLUME) != 0) {
+		BLI_dynstr_appendf(ds, "#define MESH_SHADER\n");
+	}
+
 	str = BLI_dynstr_get_cstring(ds);
 	BLI_dynstr_free(ds);
 
@@ -656,6 +660,28 @@ struct GPUMaterial *EEVEE_material_mesh_get(
 	return mat;
 }
 
+struct GPUMaterial *EEVEE_material_mesh_volume_get(struct Scene *scene, Material *ma)
+{
+	const void *engine = &DRW_engine_viewport_eevee_type;
+	int options = VAR_MAT_VOLUME;
+
+	GPUMaterial *mat = GPU_material_from_nodetree_find(&ma->gpumaterial, engine, options);
+	if (mat != NULL) {
+		return mat;
+	}
+
+	char *defines = eevee_get_volume_defines(options);
+
+	mat = GPU_material_from_nodetree(
+	        scene, ma->nodetree, &ma->gpumaterial, engine, options,
+	        datatoc_volumetric_vert_glsl, datatoc_volumetric_geom_glsl, e_data.volume_shader_lib,
+	        defines);
+
+	MEM_freeN(defines);
+
+	return mat;
+}
+
 struct GPUMaterial *EEVEE_material_mesh_depth_get(
         struct Scene *scene, Material *ma,
         bool use_hashed_alpha, bool is_shadow)
@@ -1200,6 +1226,12 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl
 			DRW_cache_mesh_sculpt_coords_ensure(ob);
 		}
 
+		/* Only support single volume material for now. */
+		/* XXX We rely on the previously compiled surface shader
+		 * to know if the material has a "volume nodetree".
+		 */
+		bool use_volume_material = (gpumat_array[0] && GPU_material_use_domain_volume(gpumat_array[0]));
+
 		/* Get per-material split surface */
 		struct Gwn_Batch **mat_geom = DRW_cache_object_surface_material_get(ob, gpumat_array, materials_len);
 		if (mat_geom) {
@@ -1209,6 +1241,14 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl
 				if (ma == NULL)
 					ma = &defmaterial;
 
+				/* Do not render surface if we are rendering a volume object
+				 * and do not have a surface closure. */
+				if (use_volume_material &&
+					(gpumat_array[i] && !GPU_material_use_domain_surface(gpumat_array[i])))
+				{
+					continue;
+				}
+
 				/* Shading pass */
 				ADD_SHGROUP_CALL(shgrp_array[i], ob, mat_geom[i]);
 
@@ -1241,6 +1281,11 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl
 				}
 			}
 		}
+
+		/* Volumetrics */
+		if (vedata->stl->effects->use_volumetrics && use_volume_material) {
+			EEVEE_effects_cache_volume_object_add(sldata, vedata, scene, ob);
+		}
 	}
 
 	if (ob->type == OB_MESH) {
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index ced44fad0c9..20353fdc512 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list