[Bf-blender-cvs] [26df09fe1ee] new-object-types: Volumes: better integration into workbench drawing

Brecht Van Lommel noreply at git.blender.org
Sat Feb 15 22:27:30 CET 2020


Commit: 26df09fe1ee9b87df03c76777bf91e035c0ed182
Author: Brecht Van Lommel
Date:   Thu Feb 13 16:30:11 2020 +0100
Branches: new-object-types
https://developer.blender.org/rB26df09fe1ee9b87df03c76777bf91e035c0ed182

Volumes: better integration into workbench drawing

* Respect workbench object/material/single/random color
* Add viewport display panel, with density scale setting
* Memory usage: half float and only needed channels for OpenGL textures
* Various bugfixes

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

M	release/scripts/startup/bl_ui/properties_data_volume.py
M	source/blender/blenkernel/intern/volume.cc
M	source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
M	source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl
M	source/blender/draw/engines/workbench/workbench_volume.c
M	source/blender/draw/intern/draw_cache_impl_volume.c
M	source/blender/gpu/GPU_texture.h
M	source/blender/gpu/intern/gpu_texture.c
M	source/blender/gpu/shaders/material/gpu_shader_material_volume_info.glsl
M	source/blender/makesdna/DNA_volume_types.h
M	source/blender/makesrna/intern/rna_volume.c

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

diff --git a/release/scripts/startup/bl_ui/properties_data_volume.py b/release/scripts/startup/bl_ui/properties_data_volume.py
index f0f394b6e2f..30124681123 100644
--- a/release/scripts/startup/bl_ui/properties_data_volume.py
+++ b/release/scripts/startup/bl_ui/properties_data_volume.py
@@ -108,6 +108,21 @@ class DATA_PT_volume_grids(DataButtonsPanel, Panel):
         layout.template_list("VOLUME_UL_grids", "grids", volume, "grids", volume.grids, "active_index", rows=3)
 
 
+class DATA_PT_volume_viewport_display(DataButtonsPanel, Panel):
+    bl_label = "Viewport Display"
+    bl_options = {'DEFAULT_CLOSED'}
+    COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
+
+    def draw(self, context):
+        layout = self.layout
+        layout.use_property_split = True
+        layout.use_property_decorate = False
+
+        volume = context.volume
+        display = volume.display
+        layout.prop(display, "density_scale")
+
+
 class DATA_PT_custom_props_volume(DataButtonsPanel, PropertyPanel, Panel):
     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
     _context_path = "object.data"
@@ -118,6 +133,7 @@ classes = (
     DATA_PT_context_volume,
     DATA_PT_volume_grids,
     DATA_PT_volume_file,
+    DATA_PT_volume_viewport_display,
     DATA_PT_custom_props_volume,
     VOLUME_UL_grids,
 )
diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc
index 96a0f486205..aeb329cdc96 100644
--- a/source/blender/blenkernel/intern/volume.cc
+++ b/source/blender/blenkernel/intern/volume.cc
@@ -434,6 +434,8 @@ void BKE_volume_init(Volume *volume)
   volume->frame_start = 1;
   volume->frame_offset = 0;
   volume->frame_duration = 0;
+  /* TODO: why is this needed for common volume files? */
+  volume->display.density_scale = 10.0f;
   BKE_volume_init_grids(volume);
 }
 
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 c38d8fe06bc..09593d3543b 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
@@ -3,9 +3,11 @@ uniform sampler2D depthBuffer;
 
 uniform sampler3D densityTexture;
 uniform sampler3D shadowTexture;
+#ifdef VOLUME_SMOKE
 uniform sampler3D flameTexture;
 uniform sampler1D flameColorTexture;
 uniform sampler1D transferTexture;
+#endif
 
 uniform int samplesLen = 256;
 uniform float noiseOfs = 0.0f;
@@ -14,10 +16,10 @@ uniform float densityScale; /* Simple Opacity multiplicator. */
 uniform vec4 viewvecs[3];
 uniform vec3 activeColor;
 
+#ifdef VOLUME_SLICE
 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
 
@@ -129,6 +131,8 @@ void volume_properties(vec3 ls_pos, out vec3 scattering, out float extinction)
   scattering = tval.rgb * 1500.0;
   extinction = max(1e-4, tval.a * 50.0);
 #else
+#  ifdef VOLUME_SMOKE
+  /* Fluid modifier. */
   float flame = sample_volume_texture(flameTexture, co).r;
   vec4 emission = texture(flameColorTexture, flame);
   float shadows = sample_volume_texture(shadowTexture, co).r;
@@ -142,6 +146,18 @@ void volume_properties(vec3 ls_pos, out vec3 scattering, out float extinction)
 
   /* 800 is arbitrary and here to mimic old viewport. TODO make it a parameter */
   scattering += pow(emission.rgb, vec3(2.2)) * emission.a * 800.0;
+#  else
+  /* Volume object. */
+  vec3 density = sample_volume_texture(densityTexture, co).rgb;
+  float shadows = sample_volume_texture(shadowTexture, co).r;
+
+  scattering = density * densityScale;
+  extinction = max(1e-4, dot(scattering, vec3(0.33333)));
+  scattering *= activeColor;
+
+  /* Scale shadows in log space and clamp them to avoid completely black shadows. */
+  scattering *= exp(clamp(log(shadows) * densityScale * 0.1, -2.5, 0.0)) * M_PI;
+#  endif
 #endif
 }
 
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl b/source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl
index 3542a1a91fc..ed37ccfea54 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl
@@ -1,6 +1,8 @@
 
+#ifdef VOLUME_SLICE
 uniform float slicePosition;
 uniform int sliceAxis; /* -1 is no slice, 0 is X, 1 is Y, 2 is Z. */
+#endif
 
 in vec3 pos;
 
diff --git a/source/blender/draw/engines/workbench/workbench_volume.c b/source/blender/draw/engines/workbench/workbench_volume.c
index 9a5fe7db5bd..f55e0085076 100644
--- a/source/blender/draw/engines/workbench/workbench_volume.c
+++ b/source/blender/draw/engines/workbench/workbench_volume.c
@@ -31,8 +31,9 @@
 #include "BLI_dynstr.h"
 #include "BLI_string_utils.h"
 
-#include "BKE_object.h"
 #include "BKE_fluid.h"
+#include "BKE_global.h"
+#include "BKE_object.h"
 #include "BKE_volume.h"
 
 #include "GPU_draw.h"
@@ -41,9 +42,10 @@ enum {
   VOLUME_SH_SLICE = 0,
   VOLUME_SH_COBA,
   VOLUME_SH_CUBIC,
+  VOLUME_SH_SMOKE,
 };
 
-#define VOLUME_SH_MAX (1 << (VOLUME_SH_CUBIC + 1))
+#define VOLUME_SH_MAX (1 << (VOLUME_SH_SMOKE + 1))
 
 static struct {
   struct GPUShader *volume_sh[VOLUME_SH_MAX];
@@ -58,12 +60,13 @@ extern char datatoc_workbench_volume_frag_glsl[];
 extern char datatoc_common_view_lib_glsl[];
 extern char datatoc_gpu_shader_common_obinfos_lib_glsl[];
 
-static GPUShader *volume_shader_get(bool slice, bool coba, bool cubic)
+static GPUShader *volume_shader_get(bool slice, bool coba, bool cubic, bool smoke)
 {
   int id = 0;
   id += (slice) ? (1 << VOLUME_SH_SLICE) : 0;
   id += (coba) ? (1 << VOLUME_SH_COBA) : 0;
   id += (cubic) ? (1 << VOLUME_SH_CUBIC) : 0;
+  id += (smoke) ? (1 << VOLUME_SH_SMOKE) : 0;
 
   if (!e_data.volume_sh[id]) {
     DynStr *ds = BLI_dynstr_new();
@@ -77,6 +80,9 @@ static GPUShader *volume_shader_get(bool slice, bool coba, bool cubic)
     if (cubic) {
       BLI_dynstr_append(ds, "#define USE_TRICUBIC\n");
     }
+    if (smoke) {
+      BLI_dynstr_append(ds, "#define VOLUME_SMOKE\n");
+    }
 
     char *defines = BLI_dynstr_get_cstring(ds);
     BLI_dynstr_free(ds);
@@ -158,7 +164,7 @@ static void workbench_volume_modifier_cache_populate(WORKBENCH_Data *vedata,
   const bool use_slice = (mds->slice_method == FLUID_DOMAIN_SLICE_AXIS_ALIGNED &&
                           mds->axis_slice_method == AXIS_SLICE_SINGLE);
   const bool cubic_interp = (mds->interp_method == VOLUME_INTERP_CUBIC);
-  GPUShader *sh = volume_shader_get(use_slice, mds->use_coba, cubic_interp);
+  GPUShader *sh = volume_shader_get(use_slice, mds->use_coba, cubic_interp, true);
 
   if (use_slice) {
     float invviewmat[4][4];
@@ -228,10 +234,20 @@ static void workbench_volume_modifier_cache_populate(WORKBENCH_Data *vedata,
   BLI_addtail(&wpd->smoke_domains, BLI_genericNodeN(mmd));
 }
 
+static void work_volume_material_color(WORKBENCH_PrivateData *wpd, Object *ob, float color[3])
+{
+  WORKBENCH_MaterialData material_template;
+  Material *ma = BKE_object_material_get(ob, 1);
+  int color_type = workbench_material_determine_color_type(wpd, NULL, ob, false);
+  workbench_material_update_data(wpd, ob, ma, &material_template, color_type);
+  copy_v3_v3(color, material_template.base_color);
+}
+
 static void workbench_volume_object_cache_populate(WORKBENCH_Data *vedata, Object *ob)
 {
   /* Create 3D textures. */
   Volume *volume = ob->data;
+  BKE_volume_load(volume, G.main);
   VolumeGrid *volume_grid = BKE_volume_grid_active_get(volume);
   if (volume_grid == NULL) {
     return;
@@ -241,24 +257,18 @@ static void workbench_volume_object_cache_populate(WORKBENCH_Data *vedata, Objec
     return;
   }
 
-  // TODO: shaders assumes all textures to have the same bounding box.
-  // to solve this each texture would need its own loc + size transform.
-  // DRWVolumeGrid *temperature = DRW_volume_batch_cache_get_temperature(volume, "temperature");
-
   WORKBENCH_PrivateData *wpd = vedata->stl->g_data;
   WORKBENCH_EffectInfo *effect_info = vedata->stl->effects;
   DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
 
   wpd->volumes_do = true;
 
-  // TODO: add user settings
-  const bool use_slice = false;
-  const bool cubic_interp = false;
-  const float slice_per_voxel = 5.0f;
-  const float display_thickness = 1000.0f;
-
   /* Create shader. */
-  GPUShader *sh = volume_shader_get(use_slice, false, cubic_interp);
+  GPUShader *sh = volume_shader_get(false, false, false, false);
+
+  /* Compute color. */
+  float color[3];
+  work_volume_material_color(wpd, ob, color);
 
   /* Combined texture to object, and object to world transform. */
   float texture_to_world[4][4];
@@ -269,17 +279,18 @@ static void workbench_volume_object_cache_populate(WORKBENCH_Data *vedata, Objec
   mat4_to_size(world_size, texture_to_world);
   abs_v3(world_size);
 
-  /* Compute slice parameters. */
+  /* Compute step parameters. */
   double noise_ofs;
   BLI_halton_1d(3, 0.0, effect_info->jitter_index, &noise_ofs);
   float step_length, max_slice;
   float slice_ct[3] = {grid->resolution[0], grid->resolution[1], grid->resolution[2]};
-  mul_v3_fl(slice_ct, max_ff(0.001f, slice_per_voxel));
+  mul_v3_fl(slice_ct, max_ff(0.001f, 5.0f));
   max_slice = max_fff(slice_ct[0], slice_ct[1], slice_ct[2]);
   invert_v3(slice_ct);
   mul_v3_v3(slice_ct, world_size);
   step_length = len_v3(slice_ct);
 
+  /* Set uniforms. */
   DRWShadingGroup *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_slice);
@@ -287,20 +298,16 @@ static void workbench_volume_object_cache_populate(WORKBENCH_Data *vedata, Objec
   DRW_shgroup_uniform_float_copy(grp, "noiseOfs", noise_ofs);
   DRW_shgroup_state_enable(grp, DRW_STATE_CULL_FRONT);
 
-  static float white[3] = {1.0f, 1.0f, 1.0f};
-  // TODO: density is rgb color + a density, it's getting squared currently?
   DRW_shgroup_uniform_texture(grp, "densityTexture", grid->texture);
-  // TODO: implement shadow texture, like manta_smoke_ca

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list