[Bf-blender-cvs] [84ad9b102e7] blender2.8: Workbench: Add cubic filtering for smoke simulation

Clément Foucault noreply at git.blender.org
Wed Nov 7 13:25:34 CET 2018


Commit: 84ad9b102e708da54188752bde34daba8b6611b2
Author: Clément Foucault
Date:   Wed Nov 7 13:22:22 2018 +0100
Branches: blender2.8
https://developer.blender.org/rB84ad9b102e708da54188752bde34daba8b6611b2

Workbench: Add cubic filtering for smoke simulation

The option is per domain and only affects the solid / xray / wireframe view.

Eevee is not yet supported.

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

M	release/scripts/startup/bl_ui/properties_physics_smoke.py
M	source/blender/blenkernel/intern/smoke.c
M	source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
M	source/blender/draw/engines/workbench/workbench_volume.c
M	source/blender/makesdna/DNA_smoke_types.h
M	source/blender/makesrna/intern/rna_smoke.c

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

diff --git a/release/scripts/startup/bl_ui/properties_physics_smoke.py b/release/scripts/startup/bl_ui/properties_physics_smoke.py
index 9896d3afc52..2e698ffb58d 100644
--- a/release/scripts/startup/bl_ui/properties_physics_smoke.py
+++ b/release/scripts/startup/bl_ui/properties_physics_smoke.py
@@ -596,9 +596,11 @@ class PHYSICS_PT_smoke_viewport_display(PhysicButtonsPanel, Panel):
         sub.prop(domain, "slice_axis")
         sub.prop(domain, "slice_depth")
 
-        col = col.row()
-        col.enabled = do_full_slicing or not do_axis_slicing
-        col.prop(domain, "slice_per_voxel")
+        row = col.row()
+        row.enabled = do_full_slicing or not do_axis_slicing
+        row.prop(domain, "slice_per_voxel")
+
+        col.prop(domain, "display_interpolation")
 
 
 class PHYSICS_PT_smoke_viewport_display_color(PhysicButtonsPanel, Panel):
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index be3a025a96f..ced6cf0fe74 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -670,6 +670,7 @@ void smokeModifier_copy(const struct SmokeModifierData *smd, struct SmokeModifie
 		tsds->slice_per_voxel = sds->slice_per_voxel;
 		tsds->slice_depth = sds->slice_depth;
 		tsds->slice_axis = sds->slice_axis;
+		tsds->interp_method = sds->interp_method;
 		tsds->draw_velocity = sds->draw_velocity;
 		tsds->vector_draw_type = sds->vector_draw_type;
 		tsds->vector_scale = sds->vector_scale;
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
index 023ebb8e111..f14078a71eb 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
@@ -67,20 +67,73 @@ float line_unit_box_intersect_dist(vec3 lineorigin, vec3 linedirection)
 	return max_v3(furthestplane);
 }
 
+#define sample_trilinear(ima, co) texture(ima, co)
+
+vec4 sample_tricubic(sampler3D ima, vec3 co)
+{
+	vec3 tex_size = vec3(textureSize(ima, 0).xyz);
+
+	co *= tex_size;
+	/* texel center */
+	vec3 tc = floor(co - 0.5) + 0.5;
+	vec3 f = co - tc;
+	vec3 f2 = f * f;
+	vec3 f3 = f2 * f;
+	/* Bspline coefs (optimized) */
+	vec3 w3 =  f3 / 6.0;
+	vec3 w0 = -w3       + f2 * 0.5 - f * 0.5 + 1.0 / 6.0;
+	vec3 w1 =  f3 * 0.5 - f2                 + 2.0 / 3.0;
+	vec3 w2 = 1.0 - w0 - w1 - w3;
+
+	vec3 s0 = w0 + w1;
+	vec3 s1 = w2 + w3;
+
+	vec3 f0 = w1 / (w0 + w1);
+	vec3 f1 = w3 / (w2 + w3);
+
+	vec2 final_z;
+	vec4 final_co;
+	final_co.xy = tc.xy - 1.0 + f0.xy;
+	final_co.zw = tc.xy + 1.0 + f1.xy;
+	final_z     = tc.zz + vec2(-1.0, 1.0) + vec2(f0.z, f1.z);
+
+	final_co /= tex_size.xyxy;
+	final_z  /= tex_size.zz;
+
+	vec4 color;
+	color  = texture(ima, vec3(final_co.xy, final_z.x)) * s0.x * s0.y * s0.z;
+	color += texture(ima, vec3(final_co.zy, final_z.x)) * s1.x * s0.y * s0.z;
+	color += texture(ima, vec3(final_co.xw, final_z.x)) * s0.x * s1.y * s0.z;
+	color += texture(ima, vec3(final_co.zw, final_z.x)) * s1.x * s1.y * s0.z;
+
+	color += texture(ima, vec3(final_co.xy, final_z.y)) * s0.x * s0.y * s1.z;
+	color += texture(ima, vec3(final_co.zy, final_z.y)) * s1.x * s0.y * s1.z;
+	color += texture(ima, vec3(final_co.xw, final_z.y)) * s0.x * s1.y * s1.z;
+	color += texture(ima, vec3(final_co.zw, final_z.y)) * s1.x * s1.y * s1.z;
+
+	return color;
+}
+
+#ifdef USE_TRICUBIC
+#  define sample_volume_texture sample_tricubic
+#else
+#  define sample_volume_texture sample_trilinear
+#endif
+
 void volume_properties(vec3 ls_pos, out vec3 scattering, out float extinction)
 {
 	vec3 co = ls_pos * 0.5 + 0.5;
 #ifdef USE_COBA
-	float val = texture(densityTexture, co).r;
+	float val = sample_volume_texture(densityTexture, co).r;
 	vec4 tval = texture(transferTexture, val) * densityScale;
 	tval.rgb = pow(tval.rgb, vec3(2.2));
 	scattering = tval.rgb * 1500.0;
 	extinction = max(1e-4, tval.a * 50.0);
 #else
-	float flame = texture(flameTexture, co).r;
+	float flame = sample_volume_texture(flameTexture, co).r;
 	vec4 emission = texture(flameColorTexture, flame);
-	float shadows = texture(shadowTexture, co).r;
-	vec4 density = texture(densityTexture, co); /* rgb: color, a: density */
+	float shadows = sample_volume_texture(shadowTexture, co).r;
+	vec4 density = sample_volume_texture(densityTexture, co); /* rgb: color, a: density */
 
 	scattering = density.rgb * density.a * densityScale;
 	extinction = max(1e-4, dot(scattering, vec3(0.33333)));
diff --git a/source/blender/draw/engines/workbench/workbench_volume.c b/source/blender/draw/engines/workbench/workbench_volume.c
index 0f6b3e5954a..e720bb6aa64 100644
--- a/source/blender/draw/engines/workbench/workbench_volume.c
+++ b/source/blender/draw/engines/workbench/workbench_volume.c
@@ -28,6 +28,7 @@
 #include "BKE_modifier.h"
 
 #include "BLI_rand.h"
+#include "BLI_dynstr.h"
 
 #include "DNA_modifier_types.h"
 #include "DNA_object_force_types.h"
@@ -35,8 +36,16 @@
 
 #include "GPU_draw.h"
 
+enum {
+	VOLUME_SH_SLICE = 0,
+	VOLUME_SH_COBA,
+	VOLUME_SH_CUBIC,
+};
+
+#define VOLUME_SH_MAX (1 << (VOLUME_SH_CUBIC + 1))
+
 static struct {
-	struct GPUShader *volume_sh;
+	struct GPUShader *volume_sh[VOLUME_SH_MAX];
 	struct GPUShader *volume_coba_sh;
 	struct GPUShader *volume_slice_sh;
 	struct GPUShader *volume_slice_coba_sh;
@@ -47,26 +56,43 @@ static struct {
 extern char datatoc_workbench_volume_vert_glsl[];
 extern char datatoc_workbench_volume_frag_glsl[];
 
-void workbench_volume_engine_init(void)
+static GPUShader *volume_shader_get(bool slice, bool coba, bool cubic)
 {
-	if (!e_data.volume_sh) {
-		e_data.volume_sh = DRW_shader_create(
-		        datatoc_workbench_volume_vert_glsl, NULL,
-		        datatoc_workbench_volume_frag_glsl, NULL);
-		e_data.volume_coba_sh = DRW_shader_create(
-		        datatoc_workbench_volume_vert_glsl, NULL,
-		        datatoc_workbench_volume_frag_glsl,
-		        "#define USE_COBA\n");
-		e_data.volume_slice_sh = DRW_shader_create(
-		        datatoc_workbench_volume_vert_glsl, NULL,
-		        datatoc_workbench_volume_frag_glsl,
-		        "#define VOLUME_SLICE\n");
-		e_data.volume_slice_coba_sh = DRW_shader_create(
+	int id = 0;
+	id += (slice) ? (1 << VOLUME_SH_SLICE) : 0;
+	id += (coba) ? (1 << VOLUME_SH_COBA) : 0;
+	id += (cubic) ? (1 << VOLUME_SH_CUBIC) : 0;
+
+	if (!e_data.volume_sh[id]) {
+		DynStr *ds = BLI_dynstr_new();
+
+		if (slice) {
+			BLI_dynstr_append(ds, "#define VOLUME_SLICE\n");
+		}
+		if (coba) {
+			BLI_dynstr_append(ds, "#define USE_COBA\n");
+		}
+		if (cubic) {
+			BLI_dynstr_append(ds, "#define USE_TRICUBIC\n");
+		}
+
+		char *defines = BLI_dynstr_get_cstring(ds);
+		BLI_dynstr_free(ds);
+
+		e_data.volume_sh[id] = DRW_shader_create(
 		        datatoc_workbench_volume_vert_glsl, NULL,
 		        datatoc_workbench_volume_frag_glsl,
-		        "#define VOLUME_SLICE\n"
-		        "#define USE_COBA\n");
+		        defines);
 
+		MEM_freeN(defines);
+	}
+
+	return e_data.volume_sh[id];
+}
+
+void workbench_volume_engine_init(void)
+{
+	if (!e_data.dummy_tex) {
 		float pixel[4] = {0.0f, 0.0f, 0.0f, 0.0f};
 		e_data.dummy_tex = GPU_texture_create_3D(1, 1, 1, GPU_RGBA8, pixel, NULL);
 		e_data.dummy_coba_tex = GPU_texture_create_1D(1, GPU_RGBA8, pixel, NULL);
@@ -75,10 +101,9 @@ void workbench_volume_engine_init(void)
 
 void workbench_volume_engine_free(void)
 {
-	DRW_SHADER_FREE_SAFE(e_data.volume_sh);
-	DRW_SHADER_FREE_SAFE(e_data.volume_coba_sh);
-	DRW_SHADER_FREE_SAFE(e_data.volume_slice_sh);
-	DRW_SHADER_FREE_SAFE(e_data.volume_slice_coba_sh);
+	for (int i = 0; i < VOLUME_SH_MAX; ++i) {
+		DRW_SHADER_FREE_SAFE(e_data.volume_sh[i]);
+	}
 	DRW_TEXTURE_FREE_SAFE(e_data.dummy_tex);
 	DRW_TEXTURE_FREE_SAFE(e_data.dummy_coba_tex);
 }
@@ -121,6 +146,8 @@ void workbench_volume_cache_populate(WORKBENCH_Data *vedata, Scene *scene, Objec
 
 	const bool use_slice = (sds->slice_method == MOD_SMOKE_SLICE_AXIS_ALIGNED &&
 	                        sds->axis_slice_method == AXIS_SLICE_SINGLE);
+	const bool cubic_interp = (sds->interp_method == VOLUME_INTERP_CUBIC);
+	GPUShader *sh = volume_shader_get(use_slice, sds->use_coba, cubic_interp);
 
 	if (use_slice) {
 		float invviewmat[4][4];
@@ -130,7 +157,6 @@ void workbench_volume_cache_populate(WORKBENCH_Data *vedata, Scene *scene, Objec
 		                  ? axis_dominant_v3_single(invviewmat[2])
 		                  : sds->slice_axis - 1;
 
-		GPUShader *sh = (sds->use_coba) ? e_data.volume_slice_coba_sh : e_data.volume_slice_sh;
 		grp = DRW_shgroup_create(sh, vedata->psl->volume_pass);
 		DRW_shgroup_uniform_float_copy(grp, "slicePosition", sds->slice_depth);
 		DRW_shgroup_uniform_int_copy(grp, "sliceAxis", axis);
@@ -140,7 +166,6 @@ void workbench_volume_cache_populate(WORKBENCH_Data *vedata, Scene *scene, Objec
 		BLI_halton_1D(3, 0.0, effect_info->jitter_index, &noise_ofs);
 		int max_slices = max_iii(sds->res[0], sds->res[1], sds->res[2]) * sds->slice_per_voxel;
 
-		GPUShader *sh = (sds->use_coba) ? e_data.volume_coba_sh : e_data.volume_sh;
 		grp = DRW_shgroup_create(sh, vedata->psl->volume_pass);
 		DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)wpd->viewvecs, 3);
 		DRW_shgroup_uniform_int_copy(grp, "samplesLen", max_slices);
diff --git a/source/blender/makesdna/DNA_smoke_types.h b/source/blender/makesdna/DNA_smoke_types.h
index b8ac0de0090..97913e29ad4 100644
--- a/source/blender/makesdna/DNA_smoke_types.h
+++ b/source/blender/makesdna/DNA_smoke_types.h
@@ -72,6 +72,12 @@ enum {
 	SLICE_AXIS_Z    = 3,
 };
 
+/* axis aligned method */
+enum {
+	VOLUME_INTERP_LINEAR   = 0,
+	VOLUME_INTERP_CUBIC    = 1,
+};
+
 enum {
 	VECTOR_DRAW_NEEDLE     = 0,
 	VECTOR_DRAW_STREAMLINE = 1,
@@ -222,7 +228,7 @@ typedef struct SmokeDomainSettings {
 	char vector_draw_type;
 	char use_coba;
 	char coba_field;  /* simulation field used for the color mapping */
-	char pad2;
+	char interp_method;
 
 	float clipping;
 	float pad3;
diff --git a/source/blender/makesrna/intern/rna_smoke.c b/source/blender/makesrna/intern/rna_smoke.c
index 5eb25985fa4..591798d508a 100644
--- a/source/blender/makesrna/intern/rna_smoke.c
+++ b/source/blender/makesrna/intern/rna_smoke.c
@@ -514

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list