[Bf-blender-cvs] [7a693626d63] blender2.8: Smoke: Port display to Workbench + object mode

Clément Foucault noreply at git.blender.org
Mon Jul 16 20:08:15 CEST 2018


Commit: 7a693626d63a52acd12e80209b634711154a2f9d
Author: Clément Foucault
Date:   Mon Jul 16 15:01:44 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB7a693626d63a52acd12e80209b634711154a2f9d

Smoke: Port display to Workbench + object mode

This does not fix the smokesim. It only port the drawing method.

The Object mode engine is in charge of rendering the velocity debugging.

Things left to do:
- Flame rendering.
- Color Ramp coloring of volume data.
- View facing slicing (for now it's only doing sampling starting from the
  volume bounds which gives a squarish look)
- Add option to enable dithering (currently on by default.

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

M	source/blender/blenloader/intern/readfile.c
M	source/blender/draw/CMakeLists.txt
A	source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
A	source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl
M	source/blender/draw/engines/workbench/workbench_data.c
M	source/blender/draw/engines/workbench/workbench_deferred.c
M	source/blender/draw/engines/workbench/workbench_forward.c
M	source/blender/draw/engines/workbench/workbench_private.h
A	source/blender/draw/engines/workbench/workbench_volume.c
M	source/blender/draw/intern/draw_cache.c
M	source/blender/draw/intern/draw_cache.h
M	source/blender/draw/intern/draw_common.c
M	source/blender/draw/intern/draw_common.h
M	source/blender/draw/modes/object_mode.c
A	source/blender/draw/modes/shaders/volume_velocity_vert.glsl
M	source/blender/gpu/GPU_draw.h
M	source/blender/gpu/intern/gpu_draw.c
M	source/blender/makesdna/DNA_smoke_types.h

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

diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 6b356ac2e96..f7d585e6fd7 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -5100,6 +5100,9 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
 				smd->domain->tex = NULL;
 				smd->domain->tex_shadow = NULL;
 				smd->domain->tex_flame = NULL;
+				smd->domain->tex_velocity_x = NULL;
+				smd->domain->tex_velocity_y = NULL;
+				smd->domain->tex_velocity_z = NULL;
 				smd->domain->tex_wt = NULL;
 				smd->domain->coba = newdataadr(fd, smd->domain->coba);
 
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 2183bc26755..e4c6a372d34 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -118,6 +118,7 @@ set(SRC
 	engines/workbench/workbench_forward.c
 	engines/workbench/workbench_materials.c
 	engines/workbench/workbench_studiolight.c
+	engines/workbench/workbench_volume.c
 	engines/workbench/solid_mode.c
 	engines/workbench/transparent_mode.c
 	engines/external/external_engine.c
@@ -225,6 +226,8 @@ data_to_c_simple(engines/workbench/shaders/workbench_shadow_vert.glsl SRC)
 data_to_c_simple(engines/workbench/shaders/workbench_shadow_geom.glsl SRC)
 data_to_c_simple(engines/workbench/shaders/workbench_shadow_caps_geom.glsl SRC)
 data_to_c_simple(engines/workbench/shaders/workbench_shadow_debug_frag.glsl SRC)
+data_to_c_simple(engines/workbench/shaders/workbench_volume_vert.glsl SRC)
+data_to_c_simple(engines/workbench/shaders/workbench_volume_frag.glsl SRC)
 data_to_c_simple(engines/workbench/shaders/workbench_world_light_lib.glsl SRC)
 
 data_to_c_simple(modes/shaders/common_globals_lib.glsl SRC)
@@ -297,6 +300,7 @@ data_to_c_simple(modes/shaders/paint_wire_vert.glsl SRC)
 data_to_c_simple(modes/shaders/paint_vert_frag.glsl SRC)
 data_to_c_simple(modes/shaders/particle_strand_frag.glsl SRC)
 data_to_c_simple(modes/shaders/particle_strand_vert.glsl SRC)
+data_to_c_simple(modes/shaders/volume_velocity_vert.glsl SRC)
 
 list(APPEND INC
 )
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
new file mode 100644
index 00000000000..ba5b78f4ecf
--- /dev/null
+++ b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
@@ -0,0 +1,181 @@
+
+uniform mat4 ProjectionMatrix;
+uniform mat4 ModelMatrixInverse;
+uniform mat4 ModelViewMatrixInverse;
+uniform mat4 ModelMatrix;
+
+uniform sampler2D depthBuffer;
+uniform sampler3D densityTexture;
+
+uniform int samplesLen = 256;
+uniform float stepLength; /* Step length in local space. */
+uniform float densityScale; /* Simple Opacity multiplicator. */
+uniform vec4 viewvecs[3];
+
+uniform float slicePosition;
+uniform int sliceAxis; /* -1 is no slice, 0 is X, 1 is Y, 2 is Z. */
+
+#ifdef VOLUME_SLICE
+in vec3 localPos;
+#endif
+
+out vec4 fragColor;
+
+#define M_PI  3.1415926535897932        /* pi */
+
+float phase_function_isotropic()
+{
+	return 1.0 / (4.0 * M_PI);
+}
+
+float get_view_z_from_depth(float depth)
+{
+	if (ProjectionMatrix[3][3] == 0.0) {
+		float d = 2.0 * depth - 1.0;
+		return -ProjectionMatrix[3][2] / (d + ProjectionMatrix[2][2]);
+	}
+	else {
+		return viewvecs[0].z + depth * viewvecs[1].z;
+	}
+}
+
+vec3 get_view_space_from_depth(vec2 uvcoords, float depth)
+{
+	if (ProjectionMatrix[3][3] == 0.0) {
+		return vec3(viewvecs[0].xy + uvcoords * viewvecs[1].xy, 1.0) * get_view_z_from_depth(depth);
+	}
+	else {
+		return viewvecs[0].xyz + vec3(uvcoords, depth) * viewvecs[1].xyz;
+	}
+}
+
+float max_v3(vec3 v) { return max(v.x, max(v.y, v.z)); }
+
+float line_unit_box_intersect_dist(vec3 lineorigin, vec3 linedirection)
+{
+	/* https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/ */
+	vec3 firstplane  = (vec3( 1.0) - lineorigin) / linedirection;
+	vec3 secondplane = (vec3(-1.0) - lineorigin) / linedirection;
+	vec3 furthestplane = min(firstplane, secondplane);
+	return max_v3(furthestplane);
+}
+
+void volume_properties(vec3 ls_pos, out vec3 scattering, out float extinction)
+{
+	scattering = vec3(0.0);
+	extinction = 1e-8;
+
+	vec4 density = texture(densityTexture, ls_pos * 0.5 + 0.5);
+	density.rgb /= density.a;
+	density *= densityScale;
+
+	scattering = density.rgb;
+	extinction = max(1e-8, density.a);
+}
+
+#define P(x) ((x + 0.5) * (1.0 / 16.0))
+const vec4 dither_mat[4] = vec4[4](
+	vec4( P(0.0),  P(8.0),  P(2.0), P(10.0)),
+	vec4(P(12.0),  P(4.0), P(14.0),  P(6.0)),
+	vec4( P(3.0), P(11.0),  P(1.0),  P(9.0)),
+	vec4(P(15.0),  P(7.0), P(13.0),  P(5.0))
+);
+
+vec4 volume_integration(
+        vec3 ray_ori, vec3 ray_dir, float ray_inc, float ray_max, float step_len)
+{
+	/* Start with full transmittance and no scattered light. */
+	vec3 final_scattering = vec3(0.0);
+	float final_transmittance = 1.0;
+
+	ivec2 tx = ivec2(gl_FragCoord.xy) % 4;
+	float noise = dither_mat[tx.x][tx.y];
+
+	float ray_len = noise * ray_inc;
+	for (int i = 0; i < samplesLen && ray_len < ray_max; ++i, ray_len += ray_inc) {
+		vec3 ls_pos = ray_ori + ray_dir * ray_len;
+
+		vec3 Lscat;
+		float s_extinction;
+		volume_properties(ls_pos, Lscat, s_extinction);
+		/* Evaluate Scattering */
+		float Tr = exp(-s_extinction * step_len);
+		/* integrate along the current step segment */
+		Lscat = (Lscat - Lscat * Tr) / s_extinction;
+		/* accumulate and also take into account the transmittance from previous steps */
+		final_scattering += final_transmittance * Lscat;
+		final_transmittance *= Tr;
+	}
+
+	return vec4(final_scattering, 1.0 - final_transmittance);
+}
+
+void main()
+{
+#ifdef VOLUME_SLICE
+	/* Manual depth test. TODO remove. */
+	float depth = texelFetch(depthBuffer, ivec2(gl_FragCoord.xy), 0).r;
+	if (gl_FragCoord.z >= depth) {
+		discard;
+	}
+
+	ivec3 volume_size = textureSize(densityTexture, 0);
+	float step_len;
+	if (sliceAxis == 0) {
+		step_len = float(volume_size.x);
+	}
+	else if (sliceAxis == 1) {
+		step_len = float(volume_size.y);
+	}
+	else {
+		step_len = float(volume_size.z);
+	}
+	/* FIXME Should be in world space but is in local space. */
+	step_len = 1.0 / step_len;
+
+	vec3 Lscat;
+	float s_extinction;
+	volume_properties(localPos, Lscat, s_extinction);
+	/* Evaluate Scattering */
+	float Tr = exp(-s_extinction * step_len);
+	/* integrate along the current step segment */
+	Lscat = (Lscat - Lscat * Tr) / s_extinction;
+
+	fragColor = vec4(Lscat, 1.0 - Tr);
+
+#else
+	vec2 screen_uv = gl_FragCoord.xy / vec2(textureSize(depthBuffer, 0).xy);
+	bool is_persp = ProjectionMatrix[3][3] == 0.0;
+
+	vec3 volume_center = ModelMatrix[3].xyz;
+
+	float depth = texelFetch(depthBuffer, ivec2(gl_FragCoord.xy), 0).r;
+	float depth_end = min(depth, gl_FragCoord.z);
+	vec3 vs_ray_end = get_view_space_from_depth(screen_uv, depth_end);
+	vec3 vs_ray_ori = get_view_space_from_depth(screen_uv, 0.0);
+	vec3 vs_ray_dir = (is_persp) ? (vs_ray_end - vs_ray_ori) : vec3(0.0, 0.0, -1.0);
+	vs_ray_dir /= abs(vs_ray_dir.z);
+
+	vec3 ls_ray_dir = mat3(ModelViewMatrixInverse) * vs_ray_dir;
+	vec3 ls_ray_ori = (ModelViewMatrixInverse * vec4(vs_ray_ori, 1.0)).xyz;
+	vec3 ls_ray_end = (ModelViewMatrixInverse * vec4(vs_ray_end, 1.0)).xyz;
+
+	/* TODO: Align rays to volume center so that it mimics old behaviour of slicing the volume. */
+
+	float dist = line_unit_box_intersect_dist(ls_ray_ori, ls_ray_dir);
+	if (dist > 0.0) {
+		ls_ray_ori = ls_ray_dir * dist + ls_ray_ori;
+	}
+
+	vec3 ls_vol_isect = ls_ray_end - ls_ray_ori;
+	if (dot(ls_ray_dir, ls_vol_isect) < 0.0) {
+		/* Start is further away than the end.
+		 * That means no volume is intersected. */
+		discard;
+	}
+
+	fragColor = volume_integration(ls_ray_ori, ls_ray_dir, stepLength,
+	                               length(ls_vol_isect) / length(ls_ray_dir),
+	                               length(vs_ray_dir) * stepLength);
+#endif
+}
\ No newline at end of file
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl b/source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl
new file mode 100644
index 00000000000..90a22d9d02f
--- /dev/null
+++ b/source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl
@@ -0,0 +1,31 @@
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform float slicePosition;
+uniform int sliceAxis; /* -1 is no slice, 0 is X, 1 is Y, 2 is Z. */
+
+in vec3 pos;
+
+#ifdef VOLUME_SLICE
+in vec3 uvs;
+
+out vec3 localPos;
+#endif
+
+void main()
+{
+#ifdef VOLUME_SLICE
+	if (sliceAxis == 0) {
+		localPos = vec3(slicePosition * 2.0 - 1.0, pos.xy);
+	}
+	else if (sliceAxis == 1) {
+		localPos = vec3(pos.x, slicePosition * 2.0 - 1.0, pos.y);
+	}
+	else {
+		localPos = vec3(pos.xy, slicePosition * 2.0 - 1.0);
+	}
+
+	gl_Position = ModelViewProjectionMatrix * vec4(localPos, 1.0);
+#else
+	gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+#endif
+}
diff --git a/source/blender/draw/engines/workbench/workbench_data.c b/source/blender/draw/engines/workbench/workbench_data.c
index 1f5a1e17277..ede1bd7fcb5 100644
--- a/source/blender/draw/engines/workbench/workbench_data.c
+++ b/source/blender/draw/engines/workbench/workbench_data.c
@@ -119,6 +119,9 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd)
 			wpd->viewvecs[1][2] = vec_far[2] - wpd->viewvecs[0][2];
 		}
 	}
+
+	wpd->volumes_do = false;
+	BLI_listbase_clear(&wpd->smoke_domains);
 }
 
 void workbench_private_data_get_light_direction(WORKBENCH_PrivateData *wpd, float r_light_direction[3])
diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c
index 784ed861014..d17c48b0360 100644
--- a/source/blender/draw/engines/workbench/workbench_deferred.c
+++ b/source/blender/draw/engines/workbench/workbench_deferred.c
@@ -33,6 +33,7 @@
 #include "BLI_rand.h"
 
 #include "BKE_node.h"
+#include "BKE_modifier.h"
 #include "BKE_particle.h"
 
 #include "DNA_image_types.h"
@@ -327,12 +328,11 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata)
 		char *cavity_frag = workbench_build_cavity_frag();
 		e_data.cavity_sh = DRW_shader_cr

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list