Eevee-Next: World Reflective Light #108149

Merged
Jeroen Bakker merged 33 commits from Jeroen-Bakker/blender:eevee-next-world-shader into main 2023-06-29 15:25:04 +02:00
7 changed files with 61 additions and 85 deletions
Showing only changes of commit 00fda3ecda - Show all commits

View File

@ -291,7 +291,8 @@ void Instance::render_sample()
}
sampling.step();
capture_view.render();
main_view.render();
motion_blur.step();

View File

@ -67,6 +67,7 @@ class Instance {
Film film;
RenderBuffers render_buffers;
MainView main_view;
CaptureView capture_view;
World world;
LightProbeModule light_probes;
IrradianceCache irradiance_cache;
@ -118,6 +119,7 @@ class Instance {
film(*this),
render_buffers(*this),
main_view(*this),
capture_view(*this),
world(*this),
light_probes(*this),
irradiance_cache(*this){};

View File

@ -60,19 +60,8 @@ void BackgroundPipeline::render(View &view)
/** \name World Probe Pipeline
* \{ */
void WorldPipeline::sync()
void WorldPipeline::sync(GPUMaterial *gpumat)
{
for (int face : IndexRange(6)) {
CubemapSide &side = sides_[face];
/* View */
float4x4 view_m4 = cubeface_mat(face);
float4x4 win_m4;
cubeface_winmat_get(win_m4, 1.0f, 10.0f);
side.view.sync(view_m4, win_m4);
side.cubemap_face_ps.init();
side.cubemap_face_ps.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_ALWAYS);
}
const int2 extent(1);
constexpr eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_WRITE;
dummy_cryptomatte_tx_.ensure_2d(GPU_RGBA32F, extent, usage);
@ -80,31 +69,12 @@ void WorldPipeline::sync()
dummy_aov_color_tx_.ensure_2d_array(GPU_RGBA16F, extent, 1, usage);
dummy_aov_value_tx_.ensure_2d_array(GPU_R16F, extent, 1, usage);
has_draw_commands_ = false;
}
PassSimple &pass = cubemap_face_ps_;
pass.init();
pass.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_ALWAYS);
void WorldPipeline::sync(GPUMaterial *gpumat)
{
for (int face : IndexRange(6)) {
sync(gpumat, face);
}
has_draw_commands_ = true;
}
void WorldPipeline::sync(GPUMaterial *gpumat, int face)
{
Manager &manager = *inst_.manager;
CubemapSide &side = sides_[face];
/* Framebuffer. */
Texture &cubemap = inst_.reflection_probes.cubemaps_tx_;
side.cubemap_face_fb.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE_CUBEFACE(cubemap, face));
ResourceHandle handle = manager.resource_handle(float4x4::identity());
PassSimple &pass = side.cubemap_face_ps;
pass.framebuffer_set(&side.cubemap_face_fb);
pass.material_set(manager, gpumat);
pass.push_constant("world_opacity_fade", 1.0f);
@ -127,32 +97,11 @@ void WorldPipeline::sync(GPUMaterial *gpumat, int face)
pass.bind_ssbo("aov_buf", &inst_.film.aovs_info);
pass.draw(DRW_cache_fullscreen_quad_get(), handle);
pass.barrier(GPU_BARRIER_SHADER_IMAGE_ACCESS);
}
void WorldPipeline::render()
void WorldPipeline::render(View &view)
{
if (!has_draw_commands_) {
return;
}
GPUFrameBuffer *previous_framebuffer = GPU_framebuffer_active_get();
GPU_debug_group_begin("World.Probe");
for (int face : IndexRange(6)) {
sides_[face].render(inst_);
}
GPU_debug_group_end();
GPU_texture_update_mipmap_chain(inst_.reflection_probes.cubemaps_tx_);
if (previous_framebuffer) {
GPU_framebuffer_bind(previous_framebuffer);
}
}
void WorldPipeline::CubemapSide::render(Instance &instance)
{
instance.manager->submit(cubemap_face_ps, view);
inst_.manager->submit(cubemap_face_ps_, view);
}
/** \} */

View File

@ -59,37 +59,14 @@ class WorldPipeline {
Texture dummy_aov_color_tx_;
Texture dummy_aov_value_tx_;
struct CubemapSide {
PassSimple cubemap_face_ps;
View view;
Framebuffer cubemap_face_fb;
void render(Instance &instance);
};
/**
* Keep track if the world probe needs to be updated. This should only be the case when the
* world is updated. This flag is used to skip updating mipmaps when the world isn't changed.
*/
bool has_draw_commands_ = false;
CubemapSide sides_[6] = {
{{"PosX"}, {"PosX"}},
{{"NegX"}, {"NegX"}},
{{"PosY"}, {"PosY"}},
{{"NegY"}, {"NegY"}},
{{"PosZ"}, {"PosZ"}},
{{"NegZ"}, {"NegZ"}},
};
PassSimple cubemap_face_ps_ = {"World.Probe"};
public:
WorldPipeline(Instance &inst) : inst_(inst){};
void sync();
void sync(GPUMaterial *gpumat);
void render();
void render(View &view);
private:
void sync(GPUMaterial *gpumat, int face);
}; // namespace blender::eevee
/** \} */
@ -361,7 +338,6 @@ class PipelineModule {
deferred.begin_sync();
forward.sync();
shadow.sync();
world.sync();
capture.sync();
}

View File

@ -29,6 +29,7 @@ namespace blender::eevee {
class Instance;
class WorldPipeline;
class CaptureView;
/* -------------------------------------------------------------------- */
/** \name Reflection Probes
@ -85,6 +86,8 @@ class ReflectionProbeModule {
void sync(const ReflectionProbe &cubemap);
friend class WorldPipeline;
/* Capture View requires access to the cubemaps texture for framebuffer configuration. */
friend class CaptureView;
};
} // namespace blender::eevee

View File

@ -118,7 +118,6 @@ void ShadingView::render()
GPU_framebuffer_bind(combined_fb_);
GPU_framebuffer_clear_color_depth(combined_fb_, clear_color, 1.0f);
inst_.pipelines.world.render();
inst_.pipelines.background.render(render_view_new_);
/* TODO(fclem): Move it after the first prepass (and hiz update) once pipeline is stabilized. */
@ -190,4 +189,31 @@ void ShadingView::update_view()
/** \} */
/* -------------------------------------------------------------------- */
/** \name Capture View
* \{ */
void CaptureView::render()
{
// TODO: only do this when world needs to be captured.
View view = {"World.Capture.View"};
for (int face : IndexRange(6)) {
capture_fb_.ensure(
GPU_ATTACHMENT_NONE,
GPU_ATTACHMENT_TEXTURE_CUBEFACE(inst_.reflection_probes.cubemaps_tx_, face));
GPU_framebuffer_bind(capture_fb_);
float4x4 view_m4 = cubeface_mat(face);
float4x4 win_m4;
cubeface_winmat_get(win_m4, 1.0f, 10.0f);
view.sync(view_m4, win_m4);
inst_.pipelines.world.render(view);
}
GPU_texture_update_mipmap_chain(inst_.reflection_probes.cubemaps_tx_);
}
/** \} */
} // namespace blender::eevee

View File

@ -142,4 +142,23 @@ class MainView {
/** \} */
/* -------------------------------------------------------------------- */
/** \name Capture View
*
* View for capturing cubemap renders outside a ShadingView.
* \{ */
class CaptureView {
private:
Instance &inst_;
Framebuffer capture_fb_ = {"World.Capture"};
public:
CaptureView(Instance &inst) : inst_(inst) {}
void render();
};
/** \} */
} // namespace blender::eevee