EEVEE Next: Point Clouds #109832
@ -495,6 +495,7 @@ set(GLSL_SRC
|
||||
engines/eevee_next/shaders/eevee_geom_curves_vert.glsl
|
||||
engines/eevee_next/shaders/eevee_geom_gpencil_vert.glsl
|
||||
engines/eevee_next/shaders/eevee_geom_mesh_vert.glsl
|
||||
engines/eevee_next/shaders/eevee_geom_point_cloud_vert.glsl
|
||||
engines/eevee_next/shaders/eevee_geom_world_vert.glsl
|
||||
engines/eevee_next/shaders/eevee_hiz_debug_frag.glsl
|
||||
engines/eevee_next/shaders/eevee_hiz_update_comp.glsl
|
||||
|
@ -175,7 +175,7 @@ void Instance::scene_sync()
|
||||
void Instance::object_sync(Object *ob)
|
||||
{
|
||||
const bool is_renderable_type = ELEM(
|
||||
ob->type, OB_CURVES, OB_GPENCIL_LEGACY, OB_MESH, OB_LAMP, OB_LIGHTPROBE);
|
||||
ob->type, OB_CURVES, OB_GPENCIL_LEGACY, OB_MESH, OB_POINTCLOUD, OB_LAMP, OB_LIGHTPROBE);
|
||||
const int ob_visibility = DRW_object_visibility_in_active_context(ob);
|
||||
const bool partsys_is_visible = (ob_visibility & OB_VISIBLE_PARTICLES) != 0 &&
|
||||
(ob->type == OB_MESH);
|
||||
@ -208,6 +208,8 @@ void Instance::object_sync(Object *ob)
|
||||
case OB_MESH:
|
||||
sync.sync_mesh(ob, ob_handle, res_handle, ob_ref);
|
||||
break;
|
||||
case OB_POINTCLOUD:
|
||||
sync.sync_point_cloud(ob, ob_handle, res_handle, ob_ref);
|
||||
case OB_VOLUME:
|
||||
break;
|
||||
case OB_CURVES:
|
||||
|
@ -39,6 +39,7 @@ enum eMaterialPipeline {
|
||||
|
||||
enum eMaterialGeometry {
|
||||
MAT_GEOM_MESH = 0,
|
||||
MAT_GEOM_POINT_CLOUD,
|
||||
MAT_GEOM_CURVES,
|
||||
MAT_GEOM_GPENCIL,
|
||||
MAT_GEOM_VOLUME,
|
||||
@ -102,6 +103,8 @@ static inline eMaterialGeometry to_material_geometry(const Object *ob)
|
||||
return MAT_GEOM_VOLUME;
|
||||
case OB_GPENCIL_LEGACY:
|
||||
return MAT_GEOM_GPENCIL;
|
||||
case OB_POINTCLOUD:
|
||||
return MAT_GEOM_POINT_CLOUD;
|
||||
default:
|
||||
return MAT_GEOM_MESH;
|
||||
}
|
||||
|
@ -314,6 +314,7 @@ void ShaderModule::material_create_info_ammend(GPUMaterial *gpumat, GPUCodegenOu
|
||||
case MAT_GEOM_MESH:
|
||||
/** Noop. */
|
||||
break;
|
||||
case MAT_GEOM_POINT_CLOUD:
|
||||
case MAT_GEOM_CURVES:
|
||||
/** Hair attributes come from sampler buffer. Transfer attributes to sampler. */
|
||||
for (auto &input : info.vertex_inputs_) {
|
||||
@ -382,8 +383,7 @@ void ShaderModule::material_create_info_ammend(GPUMaterial *gpumat, GPUCodegenOu
|
||||
}
|
||||
|
||||
pragma37 marked this conversation as resolved
Outdated
|
||||
{
|
||||
/* Only mesh and curves support vertex displacement for now. */
|
||||
if (ELEM(geometry_type, MAT_GEOM_MESH, MAT_GEOM_CURVES, MAT_GEOM_GPENCIL)) {
|
||||
if (!ELEM(geometry_type, MAT_GEOM_WORLD, MAT_GEOM_VOLUME)) {
|
||||
vert_gen << "vec3 nodetree_displacement()\n";
|
||||
vert_gen << "{\n";
|
||||
vert_gen << ((codegen.displacement) ? codegen.displacement : "return vec3(0);\n");
|
||||
@ -444,6 +444,9 @@ void ShaderModule::material_create_info_ammend(GPUMaterial *gpumat, GPUCodegenOu
|
||||
case MAT_GEOM_MESH:
|
||||
info.additional_info("eevee_geom_mesh");
|
||||
break;
|
||||
case MAT_GEOM_POINT_CLOUD:
|
||||
info.additional_info("eevee_geom_point_cloud");
|
||||
break;
|
||||
}
|
||||
|
||||
/* Pipeline Info. */
|
||||
|
@ -18,6 +18,8 @@
|
||||
#include "DNA_modifier_types.h"
|
||||
#include "DNA_particle_types.h"
|
||||
|
||||
#include "draw_common.hh"
|
||||
|
||||
#include "eevee_instance.hh"
|
||||
|
||||
namespace blender::eevee {
|
||||
@ -154,6 +156,49 @@ void SyncModule::sync_mesh(Object *ob,
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Point Cloud
|
||||
* \{ */
|
||||
|
||||
void SyncModule::sync_point_cloud(Object *ob,
|
||||
ObjectHandle &ob_handle,
|
||||
ResourceHandle res_handle,
|
||||
const ObjectRef &ob_ref)
|
||||
{
|
||||
int material_slot = 1;
|
||||
|
||||
bool has_motion = inst_.velocity.step_object_sync(
|
||||
ob, ob_handle.object_key, res_handle, ob_handle.recalc);
|
||||
|
||||
Material &material = inst_.materials.material_get(
|
||||
ob, has_motion, material_slot - 1, MAT_GEOM_POINT_CLOUD);
|
||||
|
||||
auto drawcall_add = [&](MaterialPass &matpass) {
|
||||
if (matpass.sub_pass == nullptr) {
|
||||
return;
|
||||
}
|
||||
PassMain::Sub &object_pass = matpass.sub_pass->sub("Point Cloud Sub Pass");
|
||||
GPUBatch *geometry = point_cloud_sub_pass_setup(object_pass, ob, matpass.gpumat);
|
||||
object_pass.draw(geometry, res_handle);
|
||||
};
|
||||
|
||||
drawcall_add(material.shading);
|
||||
drawcall_add(material.prepass);
|
||||
drawcall_add(material.shadow);
|
||||
|
||||
inst_.cryptomatte.sync_object(ob, res_handle);
|
||||
GPUMaterial *gpu_material =
|
||||
inst_.materials.material_array_get(ob, has_motion).gpu_materials[material_slot - 1];
|
||||
::Material *mat = GPU_material_get_material(gpu_material);
|
||||
inst_.cryptomatte.sync_material(mat);
|
||||
|
||||
bool is_caster = material.shadow.sub_pass != nullptr;
|
||||
bool is_alpha_blend = material.is_alpha_blend_transparent;
|
||||
inst_.shadows.sync_object(ob_handle, res_handle, is_caster, is_alpha_blend);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name GPencil
|
||||
* \{ */
|
||||
|
@ -164,6 +164,10 @@ class SyncModule {
|
||||
ObjectHandle &ob_handle,
|
||||
ResourceHandle res_handle,
|
||||
const ObjectRef &ob_ref);
|
||||
void sync_point_cloud(Object *ob,
|
||||
ObjectHandle &ob_handle,
|
||||
ResourceHandle res_handle,
|
||||
const ObjectRef &ob_ref);
|
||||
void sync_gpencil(Object *ob, ObjectHandle &ob_handle, ResourceHandle res_handle);
|
||||
void sync_curves(Object *ob,
|
||||
ObjectHandle &ob_handle,
|
||||
|
@ -17,6 +17,8 @@
|
||||
#include "DEG_depsgraph_query.h"
|
||||
#include "DNA_rigidbody_types.h"
|
||||
|
||||
#include "draw_cache_impl.h"
|
||||
|
||||
#include "eevee_instance.hh"
|
||||
// #include "eevee_renderpasses.hh"
|
||||
#include "eevee_shader.hh"
|
||||
@ -129,6 +131,9 @@ bool VelocityModule::step_object_sync(Object *ob,
|
||||
case OB_CURVES:
|
||||
data.pos_buf = DRW_curves_pos_buffer_get(ob);
|
||||
break;
|
||||
case OB_POINTCLOUD:
|
||||
data.pos_buf = DRW_pointcloud_position_and_radius_buffer_get(ob);
|
||||
break;
|
||||
default:
|
||||
data.pos_buf = DRW_cache_object_pos_vertbuf_get(ob);
|
||||
break;
|
||||
|
@ -60,6 +60,56 @@ vec3 attr_load_uv(vec3 attr)
|
||||
|
||||
/** \} */
|
||||
|
||||
#elif defined(MAT_GEOM_POINT_CLOUD)
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Point Cloud
|
||||
*
|
||||
* Point Cloud objects loads attributes from buffers through sampler buffers.
|
||||
* \{ */
|
||||
|
||||
# pragma BLENDER_REQUIRE(common_pointcloud_lib.glsl)
|
||||
|
||||
# ifdef OBINFO_LIB
|
||||
vec3 attr_load_orco(vec4 orco)
|
||||
{
|
||||
vec3 P = pointcloud_get_pos();
|
||||
vec3 lP = transform_point(ModelMatrixInverse, P);
|
||||
return OrcoTexCoFactors[0].xyz + lP * OrcoTexCoFactors[1].xyz;
|
||||
}
|
||||
# endif
|
||||
|
||||
vec4 attr_load_tangent(samplerBuffer cd_buf)
|
||||
{
|
||||
return pointcloud_get_customdata_vec4(cd_buf);
|
||||
}
|
||||
vec3 attr_load_uv(samplerBuffer cd_buf)
|
||||
{
|
||||
return pointcloud_get_customdata_vec3(cd_buf);
|
||||
}
|
||||
vec4 attr_load_color(samplerBuffer cd_buf)
|
||||
{
|
||||
return pointcloud_get_customdata_vec4(cd_buf);
|
||||
}
|
||||
vec4 attr_load_vec4(samplerBuffer cd_buf)
|
||||
{
|
||||
return pointcloud_get_customdata_vec4(cd_buf);
|
||||
}
|
||||
vec3 attr_load_vec3(samplerBuffer cd_buf)
|
||||
{
|
||||
return pointcloud_get_customdata_vec3(cd_buf);
|
||||
}
|
||||
vec2 attr_load_vec2(samplerBuffer cd_buf)
|
||||
{
|
||||
return pointcloud_get_customdata_vec2(cd_buf);
|
||||
}
|
||||
float attr_load_float(samplerBuffer cd_buf)
|
||||
{
|
||||
return pointcloud_get_customdata_float(cd_buf);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
#elif defined(MAT_GEOM_GPENCIL)
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
@ -0,0 +1,48 @@
|
||||
|
||||
#pragma BLENDER_REQUIRE(gpu_shader_math_rotation_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(common_pointcloud_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(eevee_attributes_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(eevee_nodetree_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(eevee_surf_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(eevee_velocity_lib.glsl)
|
||||
|
||||
void main()
|
||||
{
|
||||
DRW_VIEW_FROM_RESOURCE_ID;
|
||||
#ifdef MAT_SHADOW
|
||||
shadow_interp.view_id = drw_view_id;
|
||||
#endif
|
||||
|
||||
init_interface();
|
||||
|
||||
point_cloud_interp.id = pointcloud_get_point_id();
|
||||
pointcloud_get_pos_and_radius(point_cloud_interp.position, point_cloud_interp.radius);
|
||||
pointcloud_get_pos_and_nor(interp.P, interp.N);
|
||||
#ifdef MAT_SHADOW
|
||||
/* Since point clouds always face the view, camera and shadow orientation don't match.
|
||||
* Apply a bias to avoid self-shadow issues. */
|
||||
pragma37 marked this conversation as resolved
Outdated
Clément Foucault
commented
I guess the issue you had is that shadow map geometry was not matching the camera one producing self shadowing. This should remove the need for all this logic. I guess the issue you had is that shadow map geometry was not matching the camera one producing self shadowing.
Instead of making the shadow camera dependent (that does not work with shadow map caching), I suggest to add a bias in the shadow map shader for point cloud. From my calculation, a bias equal to the point radius should be enough to remove any self shadowing.
This should remove the need for all this logic.
|
||||
/* TODO(fclem): remove multiplication here. Here only for keeping the size correct for now. */
|
||||
float actual_radius = point_cloud_interp.radius * 0.01;
|
||||
interp.P -= cameraVec(interp.P) * actual_radius;
|
||||
#endif
|
||||
|
||||
#ifdef MAT_VELOCITY
|
||||
vec3 lP = point_world_to_object(point_cloud_interp.position);
|
||||
vec3 prv, nxt;
|
||||
velocity_local_pos_get(lP, point_cloud_interp.id, prv, nxt);
|
||||
/* FIXME(fclem): Evaluating before displacement avoid displacement being treated as motion but
|
||||
* ignores motion from animated displacement. Supporting animated displacement motion vectors
|
||||
* would require evaluating the nodetree multiple time with different nodetree UBOs evaluated at
|
||||
* different times, but also with different attributes (maybe we could assume static attribute at
|
||||
* least). */
|
||||
velocity_vertex(prv, lP, nxt, motion.prev, motion.next);
|
||||
#endif
|
||||
|
||||
init_globals();
|
||||
attrib_load();
|
||||
|
||||
interp.P += nodetree_displacement();
|
||||
|
||||
gl_Position = point_world_to_ndc(interp.P);
|
||||
}
|
@ -38,6 +38,25 @@ GPU_SHADER_CREATE_INFO(eevee_geom_mesh)
|
||||
.vertex_source("eevee_geom_mesh_vert.glsl")
|
||||
.additional_info("draw_modelmat_new", "draw_resource_id_varying", "draw_view");
|
||||
|
||||
GPU_SHADER_INTERFACE_INFO(eevee_surf_point_cloud_iface, "point_cloud_interp")
|
||||
.smooth(Type::FLOAT, "radius")
|
||||
.smooth(Type::VEC3, "position")
|
||||
.flat(Type::INT, "id");
|
||||
pragma37 marked this conversation as resolved
Outdated
Clément Foucault
commented
no uppercase. no uppercase.
|
||||
|
||||
GPU_SHADER_CREATE_INFO(eevee_geom_point_cloud)
|
||||
.additional_info("eevee_shared")
|
||||
.define("MAT_GEOM_POINT_CLOUD")
|
||||
.vertex_source("eevee_geom_point_cloud_vert.glsl")
|
||||
.vertex_out(eevee_surf_point_cloud_iface)
|
||||
/* TODO(Miguel Pozo): Remove once we get rid of old EEVEE. */
|
||||
pragma37 marked this conversation as resolved
Outdated
Clément Foucault
commented
Add todo to remove after old EEVEE is removed. Add todo to remove after old EEVEE is removed.
|
||||
.define("pointRadius", "point_cloud_interp.radius")
|
||||
.define("pointPosition", "point_cloud_interp.position")
|
||||
.define("pointID", "point_cloud_interp.id")
|
||||
.additional_info("draw_pointcloud_new",
|
||||
"draw_modelmat_new",
|
||||
"draw_resource_id_varying",
|
||||
"draw_view");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(eevee_geom_gpencil)
|
||||
.additional_info("eevee_shared")
|
||||
.define("MAT_GEOM_GPENCIL")
|
||||
@ -223,7 +242,8 @@ GPU_SHADER_CREATE_INFO(eevee_material_stub)
|
||||
EEVEE_MAT_FINAL_VARIATION(prefix##_world, "eevee_geom_world", __VA_ARGS__) \
|
||||
EEVEE_MAT_FINAL_VARIATION(prefix##_gpencil, "eevee_geom_gpencil", __VA_ARGS__) \
|
||||
EEVEE_MAT_FINAL_VARIATION(prefix##_curves, "eevee_geom_curves", __VA_ARGS__) \
|
||||
EEVEE_MAT_FINAL_VARIATION(prefix##_mesh, "eevee_geom_mesh", __VA_ARGS__)
|
||||
EEVEE_MAT_FINAL_VARIATION(prefix##_mesh, "eevee_geom_mesh", __VA_ARGS__) \
|
||||
EEVEE_MAT_FINAL_VARIATION(prefix##_point_cloud, "eevee_geom_point_cloud", __VA_ARGS__)
|
||||
|
||||
# define EEVEE_MAT_PIPE_VARIATIONS(name, ...) \
|
||||
EEVEE_MAT_GEOM_VARIATIONS(name##_world, "eevee_surf_world", __VA_ARGS__) \
|
||||
|
@ -152,6 +152,8 @@ void DRW_curves_batch_cache_create_requested(struct Object *ob);
|
||||
|
||||
int DRW_pointcloud_material_count_get(struct PointCloud *pointcloud);
|
||||
|
||||
struct GPUVertBuf *DRW_pointcloud_position_and_radius_buffer_get(struct Object *ob);
|
||||
|
||||
struct GPUVertBuf **DRW_pointcloud_evaluated_attribute(struct PointCloud *pointcloud,
|
||||
const char *name);
|
||||
struct GPUBatch *DRW_pointcloud_batch_cache_get_dots(struct Object *ob);
|
||||
|
@ -387,6 +387,12 @@ GPUBatch *DRW_pointcloud_batch_cache_get_dots(Object *ob)
|
||||
return DRW_batch_request(&cache->eval_cache.dots);
|
||||
}
|
||||
|
||||
GPUVertBuf *DRW_pointcloud_position_and_radius_buffer_get(Object *ob)
|
||||
{
|
||||
PointCloud &pointcloud = *static_cast<PointCloud *>(ob->data);
|
||||
return pointcloud_position_and_radius_get(&pointcloud);
|
||||
}
|
||||
|
||||
GPUVertBuf **DRW_pointcloud_evaluated_attribute(PointCloud *pointcloud, const char *name)
|
||||
{
|
||||
PointCloudBatchCache &cache = *pointcloud_batch_cache_get(*pointcloud);
|
||||
|
@ -98,6 +98,8 @@ void DRW_pointcloud_free()
|
||||
}
|
||||
|
||||
#include "draw_common.hh"
|
||||
/* For drw_curves_get_attribute_sampler_name. */
|
||||
#include "draw_curves_private.hh"
|
||||
namespace blender::draw {
|
||||
|
||||
template<typename PassT>
|
||||
@ -119,14 +121,20 @@ GPUBatch *point_cloud_sub_pass_setup_implementation(PassT &sub_ps,
|
||||
sub_ps.bind_texture("ptcloud_pos_rad_tx", pos_rad_buf);
|
||||
|
||||
if (gpu_material != nullptr) {
|
||||
/* Only single material supported for now. */
|
||||
GPUBatch **geom = pointcloud_surface_shaded_get(&pointcloud, &gpu_material, 1);
|
||||
return geom[0];
|
||||
}
|
||||
else {
|
||||
GPUBatch *geom = pointcloud_surface_get(&pointcloud);
|
||||
return geom;
|
||||
ListBase gpu_attrs = GPU_material_attributes(gpu_material);
|
||||
LISTBASE_FOREACH (GPUMaterialAttribute *, gpu_attr, &gpu_attrs) {
|
||||
GPUVertBuf **attribute_buf = DRW_pointcloud_evaluated_attribute(&pointcloud, gpu_attr->name);
|
||||
if (attribute_buf) {
|
||||
char sampler_name[32];
|
||||
/** NOTE: Reusing curve attribute function. */
|
||||
drw_curves_get_attribute_sampler_name(gpu_attr->name, sampler_name);
|
||||
sub_ps.bind_texture(sampler_name, attribute_buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GPUBatch *geom = pointcloud_surface_get(&pointcloud);
|
||||
return geom;
|
||||
}
|
||||
|
||||
GPUBatch *point_cloud_sub_pass_setup(PassMain::Sub &sub_ps,
|
||||
|
@ -10,7 +10,10 @@
|
||||
|
||||
int pointcloud_get_point_id()
|
||||
{
|
||||
# ifdef GPU_VERTEX_SHADER
|
||||
return gl_VertexID / 32;
|
||||
# endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
mat3 pointcloud_get_facing_matrix(vec3 p)
|
||||
@ -40,8 +43,12 @@ void pointcloud_get_pos_nor_radius(out vec3 outpos, out vec3 outnor, out float o
|
||||
|
||||
mat3 facing_mat = pointcloud_get_facing_matrix(p);
|
||||
|
||||
int vert_id = 0;
|
||||
# ifdef GPU_VERTEX_SHADER
|
||||
/* NOTE: Avoid modulo by non-power-of-two in shader. See Index buffer setup. */
|
||||
int vert_id = gl_VertexID % 32;
|
||||
vert_id = gl_VertexID % 32;
|
||||
# endif
|
||||
|
||||
vec3 pos_inst = vec3(0.0);
|
||||
|
||||
switch (vert_id) {
|
||||
|
Loading…
Reference in New Issue
Block a user
At this point, just test for MAT_GEOM_VOLUME and MAT_GEOM_WORLD.