EEVEE: Add correct volumetric support for point clouds
Since 4.5 the point clouds are out of experimental. The drawing of pointcloud did not allow for correct volume estimation as the shape are not rendered as closed objects (i.e. the backfaces were not rendered). This patch renders the backfaces for the volume occupancy pass by rendering the pointcloud twice and flipping the shape alignment matrix. This reverse the winding and does a backface hit as it would do for a sphere primitive. This solution even if not perfect avoids adding more geometry in the Index Buffer. The geometry approach might be preferable in the future if we find a way to render the spheres without an IBO or with a JIT generated IBO. Rel #141490 Pull Request: https://projects.blender.org/blender/blender/pulls/142095
This commit is contained in:
committed by
Clément Foucault
parent
34e176d255
commit
50e876f21d
@@ -264,18 +264,28 @@ void SyncModule::sync_pointcloud(Object *ob, ObjectHandle &ob_handle, const Obje
|
||||
Material &material = inst_.materials.material_get(
|
||||
ob, has_motion, material_slot - 1, MAT_GEOM_POINTCLOUD);
|
||||
|
||||
auto drawcall_add = [&](MaterialPass &matpass) {
|
||||
auto drawcall_add = [&](MaterialPass &matpass, bool dual_sided = false) {
|
||||
if (matpass.sub_pass == nullptr) {
|
||||
return;
|
||||
}
|
||||
PassMain::Sub &object_pass = matpass.sub_pass->sub("Point Cloud Sub Pass");
|
||||
gpu::Batch *geometry = pointcloud_sub_pass_setup(object_pass, ob, matpass.gpumat);
|
||||
object_pass.draw(geometry, res_handle);
|
||||
if (dual_sided) {
|
||||
/* WORKAROUND: Hack to generate backfaces. Should also be baked into the Index Buf too at
|
||||
* some point in the future. */
|
||||
object_pass.push_constant("ptcloud_backface", false);
|
||||
object_pass.draw(geometry, res_handle);
|
||||
object_pass.push_constant("ptcloud_backface", true);
|
||||
object_pass.draw(geometry, res_handle);
|
||||
}
|
||||
else {
|
||||
object_pass.draw(geometry, res_handle);
|
||||
}
|
||||
};
|
||||
|
||||
if (material.has_volume) {
|
||||
/* Only support single volume material for now. */
|
||||
drawcall_add(material.volume_occupancy);
|
||||
drawcall_add(material.volume_occupancy, true);
|
||||
drawcall_add(material.volume_material);
|
||||
inst_.volume.object_sync(ob_handle);
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@ GPU_SHADER_NAMED_INTERFACE_END(pointcloud_interp_flat)
|
||||
|
||||
GPU_SHADER_CREATE_INFO(eevee_geom_pointcloud)
|
||||
ADDITIONAL_INFO(eevee_shared)
|
||||
PUSH_CONSTANT(bool, ptcloud_backface)
|
||||
DEFINE("MAT_GEOM_POINTCLOUD")
|
||||
VERTEX_SOURCE("eevee_geom_pointcloud_vert.glsl")
|
||||
VERTEX_OUT(eevee_surf_iface)
|
||||
|
||||
@@ -27,6 +27,11 @@ float3x3 pointcloud_get_facing_matrix(float3 p)
|
||||
{
|
||||
float3x3 facing_mat;
|
||||
facing_mat[2] = drw_world_incident_vector(p);
|
||||
# ifdef MAT_GEOM_POINTCLOUD
|
||||
if (ptcloud_backface) {
|
||||
facing_mat[2] = -facing_mat[2];
|
||||
}
|
||||
# endif
|
||||
facing_mat[1] = normalize(cross(drw_view().viewinv[0].xyz, facing_mat[2]));
|
||||
facing_mat[0] = cross(facing_mat[1], facing_mat[2]);
|
||||
return facing_mat;
|
||||
|
||||
Reference in New Issue
Block a user