[Bf-blender-cvs] [8b647659852] new-object-types: Objects: initial viewport draw of hair, point cloud and volumes

Brecht Van Lommel noreply at git.blender.org
Wed Jan 29 20:54:56 CET 2020


Commit: 8b647659852c542e56c5126e38966242f3b15d7b
Author: Brecht Van Lommel
Date:   Wed Jan 29 10:37:54 2020 +0100
Branches: new-object-types
https://developer.blender.org/rB8b647659852c542e56c5126e38966242f3b15d7b

Objects: initial viewport draw of hair, point cloud and volumes

* Hair works in workbench and Eevee, by generating batch caches compatible with
  particle hair. Selection does not work, and there is no code yet for
  attributes like variable radius or UVs.

* Volumes are rendered by workbench and Eevee. But they only used the density
  grid, ignore OpenVDB transforms and the code here is generally incomplete.

* Point clouds are only drawn as part of the overlay engine, just a quick hack
  to show something and not properly integrated as part of workbench and Eevee.

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

M	source/blender/blenkernel/BKE_volume.h
M	source/blender/blenkernel/intern/volume.cc
M	source/blender/draw/CMakeLists.txt
M	source/blender/draw/engines/eevee/eevee_engine.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/eevee_render.c
M	source/blender/draw/engines/eevee/eevee_volumes.c
M	source/blender/draw/engines/overlay/overlay_engine.c
M	source/blender/draw/engines/overlay/overlay_extra.c
A	source/blender/draw/engines/overlay/overlay_pointcloud.c
M	source/blender/draw/engines/overlay/overlay_private.h
M	source/blender/draw/engines/overlay/overlay_shader.c
A	source/blender/draw/engines/overlay/shaders/pointcloud_frag.glsl
A	source/blender/draw/engines/overlay/shaders/pointcloud_vert.glsl
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_volume.c
M	source/blender/draw/intern/draw_cache.c
M	source/blender/draw/intern/draw_cache.h
M	source/blender/draw/intern/draw_cache_impl.h
A	source/blender/draw/intern/draw_cache_impl_hair.c
M	source/blender/draw/intern/draw_cache_impl_particles.c
A	source/blender/draw/intern/draw_cache_impl_pointcloud.c
A	source/blender/draw/intern/draw_cache_impl_volume.c
M	source/blender/draw/intern/draw_hair.c
M	source/blender/draw/intern/draw_hair_private.h
M	source/blender/draw/intern/draw_manager.c
M	source/blender/gpu/GPU_texture.h
M	source/blender/gpu/intern/gpu_draw_smoke.c
M	source/blender/gpu/intern/gpu_texture.c
M	source/blender/makesdna/DNA_hair_types.h
M	source/blender/makesdna/DNA_pointcloud_types.h
M	source/blender/makesdna/DNA_volume_types.h

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

diff --git a/source/blender/blenkernel/BKE_volume.h b/source/blender/blenkernel/BKE_volume.h
index 5d2610f8a7a..366dba87d2c 100644
--- a/source/blender/blenkernel/BKE_volume.h
+++ b/source/blender/blenkernel/BKE_volume.h
@@ -96,6 +96,7 @@ const char *BKE_volume_grid_name(const struct VolumeGrid *grid);
 
 const VolumeGrid *BKE_volume_grid_for_tree(struct Volume *volume, int grid_index);
 bool BKE_volume_grid_bounds(const struct VolumeGrid *grid, float min[3], float max[3]);
+float *BKE_volume_grid_to_dense_voxels(const struct VolumeGrid *volume_grid, size_t size[3]);
 
 #ifdef __cplusplus
 }
diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc
index 501641b9f42..d8305e9711d 100644
--- a/source/blender/blenkernel/intern/volume.cc
+++ b/source/blender/blenkernel/intern/volume.cc
@@ -45,6 +45,7 @@
 #ifdef WITH_OPENVDB
 #  include <mutex>
 #  include <openvdb/openvdb.h>
+#  include <openvdb/tools/Dense.h>
 
 struct VolumeGrid {
   VolumeGrid(const openvdb::GridBase::Ptr &vdb, const bool has_tree) : vdb(vdb), has_tree(has_tree)
@@ -398,3 +399,32 @@ bool BKE_volume_grid_bounds(const VolumeGrid *volume_grid, float min[3], float m
   return false;
 #endif
 }
+
+float *BKE_volume_grid_to_dense_voxels(const VolumeGrid *volume_grid, size_t size[3])
+{
+#ifdef WITH_OPENVDB
+  /* TODO: support different grid types. */
+  /* TODO: return NULL for empty grids. */
+  const openvdb::GridBase::Ptr &grid = volume_grid->vdb;
+  BLI_assert(volume_grid->has_tree);
+
+  openvdb::Coord coord = grid->evalActiveVoxelDim();
+  size[0] = coord.x();
+  size[1] = coord.y();
+  size[2] = coord.z();
+
+  float *voxels = (float *)MEM_malloc_arrayN(size[0] * size[1] * size[2], sizeof(float), __func__);
+
+  openvdb::FloatGrid::Ptr floatgrid = openvdb::gridPtrCast<openvdb::FloatGrid>(grid);
+  openvdb::tools::Dense<float, openvdb::tools::LayoutXYZ> dense(
+      floatgrid->evalActiveVoxelBoundingBox(), voxels);
+  openvdb::tools::copyToDense(*floatgrid, dense);
+
+  return voxels;
+#else
+  size[0] = 0;
+  size[1] = 0;
+  size[2] = 0;
+  return NULL;
+#endif
+}
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 6c55fa7ce30..f38936ddaf4 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -52,10 +52,13 @@ set(SRC
   intern/draw_cache_extract_mesh.c
   intern/draw_cache_impl_curve.c
   intern/draw_cache_impl_displist.c
+  intern/draw_cache_impl_hair.c
   intern/draw_cache_impl_lattice.c
   intern/draw_cache_impl_mesh.c
   intern/draw_cache_impl_metaball.c
   intern/draw_cache_impl_particles.c
+  intern/draw_cache_impl_pointcloud.c
+  intern/draw_cache_impl_volume.c
   intern/draw_common.c
   intern/draw_debug.c
   intern/draw_hair.c
@@ -135,6 +138,7 @@ set(SRC
   engines/overlay/overlay_outline.c
   engines/overlay/overlay_paint.c
   engines/overlay/overlay_particle.c
+  engines/overlay/overlay_pointcloud.c
   engines/overlay/overlay_sculpt.c
   engines/overlay/overlay_shader.c
   engines/overlay/overlay_wireframe.c
@@ -377,6 +381,8 @@ data_to_c_simple(engines/overlay/shaders/paint_weight_vert.glsl SRC)
 data_to_c_simple(engines/overlay/shaders/paint_wire_vert.glsl SRC)
 data_to_c_simple(engines/overlay/shaders/particle_vert.glsl SRC)
 data_to_c_simple(engines/overlay/shaders/particle_frag.glsl SRC)
+data_to_c_simple(engines/overlay/shaders/pointcloud_vert.glsl SRC)
+data_to_c_simple(engines/overlay/shaders/pointcloud_frag.glsl SRC)
 data_to_c_simple(engines/overlay/shaders/sculpt_mask_vert.glsl SRC)
 data_to_c_simple(engines/overlay/shaders/volume_velocity_vert.glsl SRC)
 data_to_c_simple(engines/overlay/shaders/wireframe_vert.glsl SRC)
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index a31caa14c74..67f6b385d5d 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -119,7 +119,7 @@ void EEVEE_cache_populate(void *vedata, Object *ob)
   bool cast_shadow = false;
 
   if (ob_visibility & OB_VISIBLE_PARTICLES) {
-    EEVEE_hair_cache_populate(vedata, sldata, ob, &cast_shadow);
+    EEVEE_particle_hair_cache_populate(vedata, sldata, ob, &cast_shadow);
   }
 
   if (DRW_object_is_renderable(ob) && (ob_visibility & OB_VISIBLE_SELF)) {
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index 697d22ebeff..8cc9e8fa2af 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -31,9 +31,10 @@
 #include "BKE_paint.h"
 #include "BKE_particle.h"
 
-#include "DNA_world_types.h"
+#include "DNA_hair_types.h"
 #include "DNA_modifier_types.h"
 #include "DNA_view3d_types.h"
+#include "DNA_world_types.h"
 
 #include "GPU_material.h"
 
@@ -875,7 +876,7 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_get(EEVEE_ViewLayerDa
 
   EEVEE_PassList *psl = vedata->psl;
 
-  BLI_assert(!is_hair || (ob && psys && md));
+  BLI_assert(!is_hair || (ob && ((psys && md) || ob->type == OB_HAIR)));
 
   SET_FLAG_FROM_TEST(options, is_hair, VAR_MAT_HAIR);
   SET_FLAG_FROM_TEST(options, holdout, VAR_MAT_HOLDOUT);
@@ -1440,6 +1441,100 @@ BLI_INLINE Material *eevee_object_material_get(Object *ob, int slot)
   return ma;
 }
 
+static void eevee_hair_cache_populate(EEVEE_Data *vedata,
+                                      EEVEE_ViewLayerData *sldata,
+                                      Object *ob,
+                                      ParticleSystem *psys,
+                                      ModifierData *md,
+                                      int matnr,
+                                      bool *cast_shadow)
+{
+  EEVEE_PassList *psl = vedata->psl;
+  EEVEE_StorageList *stl = vedata->stl;
+  const DRWContextState *draw_ctx = DRW_context_state_get();
+  Scene *scene = draw_ctx->scene;
+
+  DRWShadingGroup *shgrp = NULL;
+  Material *ma = eevee_object_material_get(ob, matnr - 1);
+
+  float *color_p = &ma->r;
+  float *metal_p = &ma->metallic;
+  float *spec_p = &ma->spec;
+  float *rough_p = &ma->roughness;
+
+  bool use_ssr = ((stl->effects->enabled_effects & EFFECT_SSR) != 0);
+  const bool holdout = (ob->base_flag & BASE_HOLDOUT) != 0;
+
+  shgrp = DRW_shgroup_hair_create(ob, psys, md, psl->depth_pass, e_data.default_hair_prepass_sh);
+
+  shgrp = DRW_shgroup_hair_create(
+      ob, psys, md, psl->depth_pass_clip, e_data.default_hair_prepass_clip_sh);
+
+  shgrp = NULL;
+
+  if (ma->use_nodes && ma->nodetree && !holdout) {
+    static int ssr_id;
+    ssr_id = (use_ssr) ? 1 : -1;
+    static float half = 0.5f;
+    static float error_col[3] = {1.0f, 0.0f, 1.0f};
+    static float compile_col[3] = {0.5f, 0.5f, 0.5f};
+    struct GPUMaterial *gpumat = EEVEE_material_hair_get(scene, ma);
+
+    switch (GPU_material_status(gpumat)) {
+      case GPU_MAT_SUCCESS: {
+        bool use_diffuse = GPU_material_flag_get(gpumat, GPU_MATFLAG_DIFFUSE);
+        bool use_glossy = GPU_material_flag_get(gpumat, GPU_MATFLAG_GLOSSY);
+        bool use_refract = GPU_material_flag_get(gpumat, GPU_MATFLAG_REFRACT);
+
+        shgrp = DRW_shgroup_material_hair_create(ob, psys, md, psl->material_pass, gpumat);
+
+        if (!use_diffuse && !use_glossy && !use_refract) {
+          /* FIXME: Small hack to avoid issue when utilTex is needed for
+           * world_normals_get and none of the bsdfs that need it are present.
+           * This can try to bind utilTex even if not needed. */
+          DRW_shgroup_uniform_texture(shgrp, "utilTex", e_data.util_tex);
+        }
+
+        add_standard_uniforms(shgrp,
+                              sldata,
+                              vedata,
+                              &ssr_id,
+                              NULL,
+                              use_diffuse,
+                              use_glossy,
+                              use_refract,
+                              false,
+                              false);
+        break;
+      }
+      case GPU_MAT_QUEUED: {
+        stl->g_data->queued_shaders_count++;
+        color_p = compile_col;
+        metal_p = spec_p = rough_p = ½
+        break;
+      }
+      case GPU_MAT_FAILED:
+      default:
+        color_p = error_col;
+        metal_p = spec_p = rough_p = ½
+        break;
+    }
+  }
+
+  /* Fallback to default shader */
+  if (shgrp == NULL) {
+    shgrp = EEVEE_default_shading_group_get(sldata, vedata, ob, psys, md, true, holdout, use_ssr);
+    DRW_shgroup_uniform_vec3(shgrp, "basecol", color_p, 1);
+    DRW_shgroup_uniform_float(shgrp, "metallic", metal_p, 1);
+    DRW_shgroup_uniform_float(shgrp, "specular", spec_p, 1);
+    DRW_shgroup_uniform_float(shgrp, "roughness", rough_p, 1);
+  }
+
+  /* Shadows */
+  DRW_shgroup_hair_create(ob, psys, md, psl->shadow_pass, e_data.default_hair_prepass_sh);
+  *cast_shadow = true;
+}
+
 void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
                                     EEVEE_ViewLayerData *sldata,
                                     Object *ob,
@@ -1535,7 +1630,16 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
     bool use_volume_material = (gpumat_array[0] &&
                                 GPU_material_use_domain_volume(gpumat_array[0]));
 
-    if ((ob->dt >= OB_SOLID) || DRW_state_is_image_render()) {
+    if (ob->type == OB_HAIR) {
+      /* Hair object. */
+      eevee_hair_cache_populate(vedata, sldata, ob, NULL, NULL, HAIR_MATERIAL_NR, cast_shadow);
+      use_volume_material = false;
+    }
+    else if (ob->type == OB_VOLUME) {
+      /* Volume object. */
+      /* TODO: ensure volume objects have a volume material assigned by default. */
+    }
+    else if ((ob->dt >= OB_SOLID) || DRW_state_is_image_render()) {
       /* Get per-material split surface */
       struct GPUBatch **mat_geom = NULL;
 
@@ -1612,18 +1716,12 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
   }
 }
 
-void EEVEE_hair_cache_populate(EEVEE_Data *vedata,
-                               EEVEE_ViewLayerData *sldata,
-                               Object *ob,
-                               bool *cast_shadow)
+void EEVEE_particle_hair_cache_pop

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list