Fix #122456: EEVEE: Reset history on volume updates
Pull Request: https://projects.blender.org/blender/blender/pulls/123916
This commit is contained in:
@@ -124,6 +124,7 @@ void SyncModule::sync_mesh(Object *ob,
|
||||
|
||||
bool is_alpha_blend = false;
|
||||
bool has_transparent_shadows = false;
|
||||
bool has_volume = false;
|
||||
float inflate_bounds = 0.0f;
|
||||
for (auto i : material_array.gpu_materials.index_range()) {
|
||||
gpu::Batch *geom = mat_geom[i];
|
||||
@@ -137,6 +138,7 @@ void SyncModule::sync_mesh(Object *ob,
|
||||
if (material.has_volume) {
|
||||
volume_call(material.volume_occupancy, inst_.scene, ob, geom, res_handle);
|
||||
volume_call(material.volume_material, inst_.scene, ob, geom, res_handle);
|
||||
has_volume = true;
|
||||
/* Do not render surface if we are rendering a volume object
|
||||
* and do not have a surface closure. */
|
||||
if (!material.has_surface) {
|
||||
@@ -166,6 +168,10 @@ void SyncModule::sync_mesh(Object *ob,
|
||||
}
|
||||
}
|
||||
|
||||
if (has_volume) {
|
||||
inst_.volume.object_sync(ob_handle);
|
||||
}
|
||||
|
||||
if (inflate_bounds != 0.0f) {
|
||||
inst_.manager->update_handle_bounds(res_handle, ob_ref, inflate_bounds);
|
||||
}
|
||||
@@ -203,6 +209,7 @@ bool SyncModule::sync_sculpt(Object *ob,
|
||||
|
||||
bool is_alpha_blend = false;
|
||||
bool has_transparent_shadows = false;
|
||||
bool has_volume = false;
|
||||
float inflate_bounds = 0.0f;
|
||||
for (SculptBatch &batch :
|
||||
sculpt_batches_per_material_get(ob_ref.object, material_array.gpu_materials))
|
||||
@@ -217,6 +224,7 @@ bool SyncModule::sync_sculpt(Object *ob,
|
||||
if (material.has_volume) {
|
||||
volume_call(material.volume_occupancy, inst_.scene, ob, geom, res_handle);
|
||||
volume_call(material.volume_material, inst_.scene, ob, geom, res_handle);
|
||||
has_volume = true;
|
||||
/* Do not render surface if we are rendering a volume object
|
||||
* and do not have a surface closure. */
|
||||
if (material.has_surface == false) {
|
||||
@@ -247,6 +255,10 @@ bool SyncModule::sync_sculpt(Object *ob,
|
||||
}
|
||||
}
|
||||
|
||||
if (has_volume) {
|
||||
inst_.volume.object_sync(ob_handle);
|
||||
}
|
||||
|
||||
/* Use a valid bounding box. The PBVH module already does its own culling, but a valid */
|
||||
/* bounding box is still needed for directional shadow tile-map bounds computation. */
|
||||
const Bounds<float3> bounds = bke::pbvh::bounds_get(*ob_ref.object->sculpt->pbvh);
|
||||
@@ -294,6 +306,7 @@ void SyncModule::sync_point_cloud(Object *ob,
|
||||
/* Only support single volume material for now. */
|
||||
drawcall_add(material.volume_occupancy);
|
||||
drawcall_add(material.volume_material);
|
||||
inst_.volume.object_sync(ob_handle);
|
||||
|
||||
/* Do not render surface if we are rendering a volume object
|
||||
* and do not have a surface closure. */
|
||||
@@ -338,7 +351,7 @@ void SyncModule::sync_point_cloud(Object *ob,
|
||||
* \{ */
|
||||
|
||||
void SyncModule::sync_volume(Object *ob,
|
||||
ObjectHandle & /*ob_handle*/,
|
||||
ObjectHandle &ob_handle,
|
||||
ResourceHandle res_handle,
|
||||
const ObjectRef &ob_ref)
|
||||
{
|
||||
@@ -372,6 +385,8 @@ void SyncModule::sync_volume(Object *ob,
|
||||
|
||||
drawcall_add(material.volume_occupancy, geom, res_handle);
|
||||
drawcall_add(material.volume_material, geom, res_handle);
|
||||
|
||||
inst_.volume.object_sync(ob_handle);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -566,6 +581,7 @@ void SyncModule::sync_curves(Object *ob,
|
||||
/* Only support single volume material for now. */
|
||||
drawcall_add(material.volume_occupancy);
|
||||
drawcall_add(material.volume_material);
|
||||
inst_.volume.object_sync(ob_handle);
|
||||
/* Do not render surface if we are rendering a volume object
|
||||
* and do not have a surface closure. */
|
||||
if (material.has_surface == false) {
|
||||
|
||||
@@ -58,7 +58,34 @@ void VolumeModule::init()
|
||||
use_reprojection_ = (scene_eval->eevee.flag & SCE_EEVEE_TAA_REPROJECTION) != 0;
|
||||
}
|
||||
|
||||
void VolumeModule::begin_sync() {}
|
||||
void VolumeModule::begin_sync()
|
||||
{
|
||||
previous_objects_ = current_objects_;
|
||||
current_objects_.clear();
|
||||
}
|
||||
|
||||
void VolumeModule::world_sync(const WorldHandle &world_handle)
|
||||
{
|
||||
if (!use_reprojection_) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (world_handle.recalc && !inst_.is_playback()) {
|
||||
valid_history_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
void VolumeModule::object_sync(const ObjectHandle &ob_handle)
|
||||
{
|
||||
if (!use_reprojection_) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ob_handle.recalc && !inst_.is_playback()) {
|
||||
valid_history_ = false;
|
||||
}
|
||||
current_objects_.add(ob_handle.object_key);
|
||||
}
|
||||
|
||||
void VolumeModule::end_sync()
|
||||
{
|
||||
@@ -94,6 +121,13 @@ void VolumeModule::end_sync()
|
||||
valid_history_ = false;
|
||||
}
|
||||
|
||||
if (valid_history_) {
|
||||
/* Avoid the (potentially expensive) check if valid_history_ is already false. */
|
||||
if (current_objects_ != previous_objects_) {
|
||||
valid_history_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (inst_.camera.is_perspective()) {
|
||||
float sample_distribution = scene_eval->eevee.volumetric_sample_distribution;
|
||||
sample_distribution = 4.0f * math::max(1.0f - sample_distribution, 1e-2f);
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BLI_set.hh"
|
||||
#include "eevee_shader_shared.hh"
|
||||
|
||||
namespace blender::eevee {
|
||||
@@ -54,6 +55,10 @@ class VolumeModule {
|
||||
bool use_reprojection_;
|
||||
bool use_lights_;
|
||||
|
||||
/* Track added/removed volume objects to reset the accumulation history. */
|
||||
Set<ObjectKey> previous_objects_;
|
||||
Set<ObjectKey> current_objects_;
|
||||
|
||||
VolumesInfoData &data_;
|
||||
|
||||
/**
|
||||
@@ -134,6 +139,10 @@ class VolumeModule {
|
||||
|
||||
void begin_sync();
|
||||
|
||||
void world_sync(const WorldHandle &world_handle);
|
||||
|
||||
void object_sync(const ObjectHandle &ob_handle);
|
||||
|
||||
void end_sync();
|
||||
|
||||
/* Render material properties. */
|
||||
|
||||
@@ -101,14 +101,15 @@ void World::sync()
|
||||
{
|
||||
bool has_update = false;
|
||||
|
||||
WorldHandle wo_handle = {0};
|
||||
if (inst_.scene->world != nullptr) {
|
||||
/* Detect world update before overriding it. */
|
||||
WorldHandle wo_handle = inst_.sync.sync_world();
|
||||
wo_handle = inst_.sync.sync_world();
|
||||
has_update = wo_handle.recalc != 0;
|
||||
}
|
||||
|
||||
/* Sync volume first since its result can override the surface world. */
|
||||
sync_volume();
|
||||
sync_volume(wo_handle);
|
||||
|
||||
::World *bl_world;
|
||||
if (inst_.use_studio_light()) {
|
||||
@@ -156,7 +157,7 @@ void World::sync()
|
||||
inst_.pipelines.world.sync(gpumat);
|
||||
}
|
||||
|
||||
void World::sync_volume()
|
||||
void World::sync_volume(const WorldHandle &world_handle)
|
||||
{
|
||||
/* Studio lights have no volume shader. */
|
||||
::World *world = inst_.use_studio_light() ? nullptr : inst_.scene->world;
|
||||
@@ -168,6 +169,8 @@ void World::sync_volume()
|
||||
gpumat = inst_.shaders.world_shader_get(world, world->nodetree, MAT_PIPE_VOLUME_MATERIAL);
|
||||
}
|
||||
|
||||
bool had_volume = has_volume_;
|
||||
|
||||
if (gpumat && (GPU_material_status(gpumat) == GPU_MAT_SUCCESS)) {
|
||||
has_volume_ = GPU_material_has_volume_output(gpumat);
|
||||
has_volume_scatter_ = GPU_material_flag_get(gpumat, GPU_MATFLAG_VOLUME_SCATTER);
|
||||
@@ -179,6 +182,10 @@ void World::sync_volume()
|
||||
|
||||
/* World volume needs to be always synced for correct clearing of parameter buffers. */
|
||||
inst_.pipelines.world_volume.sync(gpumat);
|
||||
|
||||
if (has_volume_ || had_volume) {
|
||||
inst_.volume.world_sync(world_handle);
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
@@ -127,7 +127,7 @@ class World {
|
||||
}
|
||||
|
||||
private:
|
||||
void sync_volume();
|
||||
void sync_volume(const WorldHandle &world_handle);
|
||||
|
||||
/* Returns a dummy black world for when a valid world isn't present or when we want to suppress
|
||||
* any light coming from the world. */
|
||||
|
||||
Reference in New Issue
Block a user