Eevee-Next: World Reflective Light #108149
|
@ -148,6 +148,7 @@ set(SRC
|
||||||
engines/eevee_next/eevee_material.cc
|
engines/eevee_next/eevee_material.cc
|
||||||
engines/eevee_next/eevee_motion_blur.cc
|
engines/eevee_next/eevee_motion_blur.cc
|
||||||
engines/eevee_next/eevee_pipeline.cc
|
engines/eevee_next/eevee_pipeline.cc
|
||||||
|
engines/eevee_next/eevee_reflection_probes.cc
|
||||||
engines/eevee_next/eevee_renderbuffers.cc
|
engines/eevee_next/eevee_renderbuffers.cc
|
||||||
engines/eevee_next/eevee_sampling.cc
|
engines/eevee_next/eevee_sampling.cc
|
||||||
engines/eevee_next/eevee_shader.cc
|
engines/eevee_next/eevee_shader.cc
|
||||||
|
@ -286,6 +287,7 @@ set(SRC
|
||||||
engines/eevee_next/eevee_material.hh
|
engines/eevee_next/eevee_material.hh
|
||||||
engines/eevee_next/eevee_motion_blur.hh
|
engines/eevee_next/eevee_motion_blur.hh
|
||||||
engines/eevee_next/eevee_pipeline.hh
|
engines/eevee_next/eevee_pipeline.hh
|
||||||
|
engines/eevee_next/eevee_reflection_probes.hh
|
||||||
engines/eevee_next/eevee_renderbuffers.hh
|
engines/eevee_next/eevee_renderbuffers.hh
|
||||||
engines/eevee_next/eevee_sampling.hh
|
engines/eevee_next/eevee_sampling.hh
|
||||||
engines/eevee_next/eevee_shader.hh
|
engines/eevee_next/eevee_shader.hh
|
||||||
|
@ -478,6 +480,7 @@ set(GLSL_SRC
|
||||||
engines/eevee_next/shaders/eevee_motion_blur_gather_comp.glsl
|
engines/eevee_next/shaders/eevee_motion_blur_gather_comp.glsl
|
||||||
engines/eevee_next/shaders/eevee_motion_blur_lib.glsl
|
engines/eevee_next/shaders/eevee_motion_blur_lib.glsl
|
||||||
engines/eevee_next/shaders/eevee_nodetree_lib.glsl
|
engines/eevee_next/shaders/eevee_nodetree_lib.glsl
|
||||||
|
engines/eevee_next/shaders/eevee_reflection_probe_lib.glsl
|
||||||
engines/eevee_next/shaders/eevee_sampling_lib.glsl
|
engines/eevee_next/shaders/eevee_sampling_lib.glsl
|
||||||
engines/eevee_next/shaders/eevee_shadow_debug_frag.glsl
|
engines/eevee_next/shaders/eevee_shadow_debug_frag.glsl
|
||||||
engines/eevee_next/shaders/eevee_shadow_lib.glsl
|
engines/eevee_next/shaders/eevee_shadow_lib.glsl
|
||||||
|
|
|
@ -95,6 +95,7 @@
|
||||||
/* Only during shadow rendering. */
|
/* Only during shadow rendering. */
|
||||||
#define SHADOW_RENDER_MAP_SLOT 13
|
#define SHADOW_RENDER_MAP_SLOT 13
|
||||||
#define RBUFS_UTILITY_TEX_SLOT 14
|
#define RBUFS_UTILITY_TEX_SLOT 14
|
||||||
|
#define REFLECTION_PROBE_TEX_SLOT 16
|
||||||
|
|
||||||
/* Images. */
|
/* Images. */
|
||||||
#define RBUFS_NORMAL_SLOT 0
|
#define RBUFS_NORMAL_SLOT 0
|
||||||
|
|
|
@ -71,6 +71,7 @@ void Instance::init(const int2 &output_res,
|
||||||
motion_blur.init();
|
motion_blur.init();
|
||||||
main_view.init();
|
main_view.init();
|
||||||
irradiance_cache.init();
|
irradiance_cache.init();
|
||||||
|
reflection_probes.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Instance::set_time(float time)
|
void Instance::set_time(float time)
|
||||||
|
@ -117,6 +118,7 @@ void Instance::begin_sync()
|
||||||
hiz_buffer.sync();
|
hiz_buffer.sync();
|
||||||
main_view.sync();
|
main_view.sync();
|
||||||
world.sync();
|
world.sync();
|
||||||
|
reflection_probes.sync();
|
||||||
film.sync();
|
film.sync();
|
||||||
irradiance_cache.sync();
|
irradiance_cache.sync();
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "eevee_material.hh"
|
#include "eevee_material.hh"
|
||||||
#include "eevee_motion_blur.hh"
|
#include "eevee_motion_blur.hh"
|
||||||
#include "eevee_pipeline.hh"
|
#include "eevee_pipeline.hh"
|
||||||
|
#include "eevee_reflection_probes.hh"
|
||||||
#include "eevee_renderbuffers.hh"
|
#include "eevee_renderbuffers.hh"
|
||||||
#include "eevee_sampling.hh"
|
#include "eevee_sampling.hh"
|
||||||
#include "eevee_shader.hh"
|
#include "eevee_shader.hh"
|
||||||
|
@ -51,6 +52,7 @@ class Instance {
|
||||||
PipelineModule pipelines;
|
PipelineModule pipelines;
|
||||||
ShadowModule shadows;
|
ShadowModule shadows;
|
||||||
LightModule lights;
|
LightModule lights;
|
||||||
|
ReflectionProbeModule reflection_probes;
|
||||||
VelocityModule velocity;
|
VelocityModule velocity;
|
||||||
MotionBlurModule motion_blur;
|
MotionBlurModule motion_blur;
|
||||||
DepthOfField depth_of_field;
|
DepthOfField depth_of_field;
|
||||||
|
@ -97,6 +99,7 @@ class Instance {
|
||||||
pipelines(*this),
|
pipelines(*this),
|
||||||
shadows(*this),
|
shadows(*this),
|
||||||
lights(*this),
|
lights(*this),
|
||||||
|
reflection_probes(*this),
|
||||||
velocity(*this),
|
velocity(*this),
|
||||||
motion_blur(*this),
|
motion_blur(*this),
|
||||||
depth_of_field(*this),
|
depth_of_field(*this),
|
||||||
|
|
|
@ -62,6 +62,75 @@ void WorldPipeline::render(View &view)
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------- */
|
||||||
|
/** \name World Probe Pipeline
|
||||||
|
* \{ */
|
||||||
|
|
||||||
|
void WorldProbePipeline::sync()
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldProbePipeline::sync(GPUMaterial *gpumat)
|
||||||
|
{
|
||||||
|
for (int face : IndexRange(6)) {
|
||||||
|
sync(gpumat, face);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldProbePipeline::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());
|
||||||
|
|
||||||
|
side.cubemap_face_ps.framebuffer_set(&side.cubemap_face_fb);
|
||||||
|
side.cubemap_face_ps.material_set(manager, gpumat);
|
||||||
|
|
||||||
|
side.cubemap_face_ps.draw(DRW_cache_fullscreen_quad_get(), handle);
|
||||||
|
/* To allow opaque pass rendering over it. */
|
||||||
|
side.cubemap_face_ps.barrier(GPU_BARRIER_SHADER_IMAGE_ACCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldProbePipeline::render()
|
||||||
|
{
|
||||||
|
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 WorldProbePipeline::CubemapSide::render(Instance &instance)
|
||||||
|
{
|
||||||
|
instance.manager->submit(cubemap_face_ps, view);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \} */
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/** \name Shadow Pipeline
|
/** \name Shadow Pipeline
|
||||||
*
|
*
|
||||||
|
@ -387,6 +456,7 @@ void DeferredLayer::end_sync()
|
||||||
inst_.shadows.bind_resources(&eval_light_ps_);
|
inst_.shadows.bind_resources(&eval_light_ps_);
|
||||||
inst_.sampling.bind_resources(&eval_light_ps_);
|
inst_.sampling.bind_resources(&eval_light_ps_);
|
||||||
inst_.hiz_buffer.bind_resources(&eval_light_ps_);
|
inst_.hiz_buffer.bind_resources(&eval_light_ps_);
|
||||||
|
inst_.reflection_probes.bind_resources(&eval_light_ps_);
|
||||||
|
|
||||||
eval_light_ps_.barrier(GPU_BARRIER_TEXTURE_FETCH | GPU_BARRIER_SHADER_IMAGE_ACCESS);
|
eval_light_ps_.barrier(GPU_BARRIER_TEXTURE_FETCH | GPU_BARRIER_SHADER_IMAGE_ACCESS);
|
||||||
eval_light_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3);
|
eval_light_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3);
|
||||||
|
|
|
@ -43,6 +43,45 @@ class WorldPipeline {
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------- */
|
||||||
|
/** \name World Probe Pipeline
|
||||||
|
*
|
||||||
|
* Render reflection probe of the world background.
|
||||||
|
* \{ */
|
||||||
|
|
||||||
|
class WorldProbePipeline {
|
||||||
|
private:
|
||||||
|
Instance &inst_;
|
||||||
|
|
||||||
|
struct CubemapSide {
|
||||||
|
PassSimple cubemap_face_ps;
|
||||||
|
View view;
|
||||||
|
Framebuffer cubemap_face_fb;
|
||||||
|
void render(Instance &instance);
|
||||||
|
};
|
||||||
|
|
||||||
|
CubemapSide sides_[6] = {
|
||||||
|
{{"PosX"}, {"PosX"}},
|
||||||
|
{{"NegX"}, {"NegX"}},
|
||||||
|
{{"PosY"}, {"PosY"}},
|
||||||
|
{{"NegY"}, {"NegY"}},
|
||||||
|
{{"PosZ"}, {"PosZ"}},
|
||||||
|
{{"NegZ"}, {"NegZ"}},
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
WorldProbePipeline(Instance &inst) : inst_(inst){};
|
||||||
|
|
||||||
|
void sync();
|
||||||
|
void sync(GPUMaterial *gpumat);
|
||||||
|
void render();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void sync(GPUMaterial *gpumat, int face);
|
||||||
|
}; // namespace blender::eevee
|
||||||
|
|
||||||
|
/** \} */
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/** \name Shadow Pass
|
/** \name Shadow Pass
|
||||||
*
|
*
|
||||||
|
@ -266,6 +305,7 @@ class UtilityTexture : public Texture {
|
||||||
class PipelineModule {
|
class PipelineModule {
|
||||||
public:
|
public:
|
||||||
WorldPipeline world;
|
WorldPipeline world;
|
||||||
|
WorldProbePipeline world_probe;
|
||||||
DeferredPipeline deferred;
|
DeferredPipeline deferred;
|
||||||
ForwardPipeline forward;
|
ForwardPipeline forward;
|
||||||
ShadowPipeline shadow;
|
ShadowPipeline shadow;
|
||||||
|
@ -273,13 +313,15 @@ class PipelineModule {
|
||||||
UtilityTexture utility_tx;
|
UtilityTexture utility_tx;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PipelineModule(Instance &inst) : world(inst), deferred(inst), forward(inst), shadow(inst){};
|
PipelineModule(Instance &inst)
|
||||||
|
: world(inst), world_probe(inst), deferred(inst), forward(inst), shadow(inst){};
|
||||||
|
|
||||||
void begin_sync()
|
void begin_sync()
|
||||||
{
|
{
|
||||||
deferred.begin_sync();
|
deferred.begin_sync();
|
||||||
forward.sync();
|
forward.sync();
|
||||||
shadow.sync();
|
shadow.sync();
|
||||||
|
world_probe.sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void end_sync()
|
void end_sync()
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
* Copyright 2023 Blender Foundation. */
|
||||||
|
|
||||||
|
#include "eevee_reflection_probes.hh"
|
||||||
|
#include "eevee_instance.hh"
|
||||||
|
|
||||||
|
namespace blender::eevee {
|
||||||
|
|
||||||
|
void ReflectionProbeModule::init()
|
||||||
|
{
|
||||||
|
if (cubemaps_.is_empty()) {
|
||||||
|
cubemaps_.reserve(MAX_PROBES);
|
||||||
|
|
||||||
|
/* Initialize the world cubemap. */
|
||||||
|
ReflectionProbe world_cubemap;
|
||||||
|
world_cubemap.type = ReflectionProbe::Type::World;
|
||||||
|
world_cubemap.is_dirty = true;
|
||||||
|
cubemaps_.append(world_cubemap);
|
||||||
|
|
||||||
|
cubemaps_tx_.ensure_cube_array(GPU_RGBA16F,
|
||||||
|
MAX_RESOLUTION,
|
||||||
|
MAX_PROBES,
|
||||||
|
GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT,
|
||||||
|
NULL,
|
||||||
|
12);
|
||||||
|
GPU_texture_mipmap_mode(cubemaps_tx_, true, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReflectionProbeModule::sync()
|
||||||
|
{
|
||||||
|
for (int index : IndexRange(MAX_PROBES)) {
|
||||||
|
ReflectionProbe &cubemap = cubemaps_[index];
|
||||||
|
if (!cubemap.needs_update()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
sync(cubemap);
|
||||||
|
cubemap.is_dirty = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReflectionProbeModule::sync(const ReflectionProbe &cubemap)
|
||||||
|
{
|
||||||
|
if (cubemap.type == ReflectionProbe::Type::World) {
|
||||||
|
GPUMaterial *world_material = instance_.world.get_world_material();
|
||||||
|
instance_.pipelines.world_probe.sync(world_material);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
BLI_assert_unreachable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReflectionProbeModule::set_world_dirty()
|
||||||
|
{
|
||||||
|
cubemaps_[WORLD_SLOT].is_dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------- */
|
||||||
|
/** \name World
|
||||||
|
*
|
||||||
|
* \{ */
|
||||||
|
|
||||||
|
bool ReflectionProbe::needs_update() const
|
||||||
|
{
|
||||||
|
return type != Type::Unused && is_dirty;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \} */
|
||||||
|
|
||||||
|
} // namespace blender::eevee
|
|
@ -0,0 +1,89 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
* Copyright 2023 Blender Foundation. */
|
||||||
|
|
||||||
|
/** \file
|
||||||
|
* \ingroup eevee
|
||||||
|
*
|
||||||
|
* Cubemaps
|
||||||
|
*
|
||||||
|
* Cubemaps record light from different locations in the scene. These cubemaps are used to add
|
||||||
|
* environment and indirect lighting from light probes.
|
||||||
|
*
|
||||||
|
* - Although we have Global illumination light probes can still be used for situations that
|
||||||
|
* GI doesn't work. For example semi-transparent surfaces.
|
||||||
|
* - The first cubemap is always reserved for the world shading.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "eevee_shader_shared.hh"
|
||||||
|
|
||||||
|
#include "BKE_cryptomatte.hh"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
struct Material;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace blender::eevee {
|
||||||
|
|
||||||
|
class Instance;
|
||||||
|
class WorldProbePipeline;
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------- */
|
||||||
|
/** \name Reflection Probes
|
||||||
|
* \{ */
|
||||||
|
class ReflectionProbe {
|
||||||
|
public:
|
||||||
|
enum Type { Unused, World };
|
||||||
|
|
||||||
|
Type type;
|
||||||
|
bool is_dirty = false;
|
||||||
|
|
||||||
|
bool needs_update() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ReflectionProbeModule {
|
||||||
|
private:
|
||||||
|
/** The max number of probes to track. */
|
||||||
|
static constexpr int MAX_PROBES = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum resolution of a cubemap side.
|
||||||
|
*
|
||||||
|
* Must be a power of two; intension to be used as a cubemap atlas.
|
||||||
|
*/
|
||||||
|
static constexpr int MAX_RESOLUTION = 2048;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Index of the probe that is used for world background.
|
||||||
|
*
|
||||||
|
* NOTE: First probe always contains the world probe.
|
||||||
|
*/
|
||||||
|
static constexpr int WORLD_SLOT = 0;
|
||||||
|
|
||||||
|
Instance &instance_;
|
||||||
|
|
||||||
|
Vector<ReflectionProbe> cubemaps_;
|
||||||
|
Texture cubemaps_tx_ = {"Probes"};
|
||||||
|
|
||||||
|
public:
|
||||||
|
ReflectionProbeModule(Instance &instance) : instance_(instance) {}
|
||||||
|
|
||||||
|
void init();
|
||||||
|
void set_world_dirty();
|
||||||
|
|
||||||
|
void sync();
|
||||||
|
|
||||||
|
template<typename T> void bind_resources(draw::detail::PassBase<T> *pass)
|
||||||
|
{
|
||||||
|
pass->bind_texture(REFLECTION_PROBE_TEX_SLOT, cubemaps_tx_);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void sync(const ReflectionProbe &cubemap);
|
||||||
|
|
||||||
|
friend class WorldProbePipeline;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace blender::eevee
|
|
@ -119,14 +119,13 @@ void ShadingView::render()
|
||||||
GPU_framebuffer_clear_color_depth(combined_fb_, clear_color, 1.0f);
|
GPU_framebuffer_clear_color_depth(combined_fb_, clear_color, 1.0f);
|
||||||
|
|
||||||
inst_.pipelines.world.render(render_view_new_);
|
inst_.pipelines.world.render(render_view_new_);
|
||||||
|
inst_.pipelines.world_probe.render();
|
||||||
|
|
||||||
/* TODO(fclem): Move it after the first prepass (and hiz update) once pipeline is stabilized. */
|
/* TODO(fclem): Move it after the first prepass (and hiz update) once pipeline is stabilized. */
|
||||||
inst_.lights.set_view(render_view_new_, extent_);
|
inst_.lights.set_view(render_view_new_, extent_);
|
||||||
|
|
||||||
inst_.pipelines.deferred.render(render_view_new_, prepass_fb_, combined_fb_, extent_);
|
inst_.pipelines.deferred.render(render_view_new_, prepass_fb_, combined_fb_, extent_);
|
||||||
|
|
||||||
// inst_.lightprobes.draw_cache_display();
|
|
||||||
|
|
||||||
// inst_.lookdev.render_overlay(view_fb_);
|
// inst_.lookdev.render_overlay(view_fb_);
|
||||||
|
|
||||||
inst_.pipelines.forward.render(render_view_new_, prepass_fb_, combined_fb_, rbufs.combined_tx);
|
inst_.pipelines.forward.render(render_view_new_, prepass_fb_, combined_fb_, rbufs.combined_tx);
|
||||||
|
|
|
@ -90,7 +90,7 @@ void World::sync()
|
||||||
WorldHandle &wo_handle = inst_.sync.sync_world(bl_world);
|
WorldHandle &wo_handle = inst_.sync.sync_world(bl_world);
|
||||||
|
|
||||||
if (wo_handle.recalc != 0) {
|
if (wo_handle.recalc != 0) {
|
||||||
// inst_.lightprobes.set_world_dirty();
|
inst_.reflection_probes.set_world_dirty();
|
||||||
}
|
}
|
||||||
wo_handle.reset_recalc_flag();
|
wo_handle.reset_recalc_flag();
|
||||||
|
|
||||||
|
@ -111,6 +111,21 @@ void World::sync()
|
||||||
inst_.pipelines.world.sync(gpumat);
|
inst_.pipelines.world.sync(gpumat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GPUMaterial *World::get_world_material()
|
||||||
|
{
|
||||||
|
::World *bl_world = inst_.scene->world;
|
||||||
|
if (bl_world == nullptr) {
|
||||||
|
bl_world = default_world_get();
|
||||||
|
}
|
||||||
|
|
||||||
|
bNodeTree *ntree = (bl_world->nodetree && bl_world->use_nodes) ?
|
||||||
|
bl_world->nodetree :
|
||||||
|
default_tree.nodetree_get(bl_world);
|
||||||
|
|
||||||
|
GPUMaterial *gpumat = inst_.shaders.world_shader_get(bl_world, ntree);
|
||||||
|
return gpumat;
|
||||||
|
}
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
} // namespace blender::eevee
|
} // namespace blender::eevee
|
||||||
|
|
|
@ -62,6 +62,13 @@ class World {
|
||||||
~World();
|
~World();
|
||||||
|
|
||||||
void sync();
|
void sync();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the world material.
|
||||||
|
*
|
||||||
|
* NOTE: this function should only be called after World::sync has been executed.
|
||||||
|
*/
|
||||||
|
GPUMaterial *get_world_material();
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#pragma BLENDER_REQUIRE(eevee_gbuffer_lib.glsl)
|
#pragma BLENDER_REQUIRE(eevee_gbuffer_lib.glsl)
|
||||||
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
|
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
|
||||||
#pragma BLENDER_REQUIRE(eevee_light_eval_lib.glsl)
|
#pragma BLENDER_REQUIRE(eevee_light_eval_lib.glsl)
|
||||||
|
#pragma BLENDER_REQUIRE(eevee_reflection_probe_lib.glsl)
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
|
@ -52,6 +53,7 @@ void main()
|
||||||
vec3 diffuse_light = vec3(0.0);
|
vec3 diffuse_light = vec3(0.0);
|
||||||
vec3 reflection_light = vec3(0.0);
|
vec3 reflection_light = vec3(0.0);
|
||||||
|
|
||||||
|
light_world_eval(diffuse_data, reflection_data, P, V, diffuse_light, reflection_light);
|
||||||
light_eval(
|
light_eval(
|
||||||
diffuse_data, reflection_data, P, Ng, V, vP_z, thickness, diffuse_light, reflection_light);
|
diffuse_data, reflection_data, P, Ng, V, vP_z, thickness, diffuse_light, reflection_light);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
void light_world_eval(ClosureDiffuse diffuse,
|
||||||
|
ClosureReflection reflection,
|
||||||
|
vec3 P,
|
||||||
|
vec3 V,
|
||||||
|
inout vec3 out_diffuse,
|
||||||
|
inout vec3 out_specular)
|
||||||
|
{
|
||||||
|
float linear_roughness = fast_sqrt(reflection.roughness);
|
||||||
|
/* TODO: This should be based by actual LOD?.*/
|
||||||
|
float lod_cube_max = 12.0;
|
||||||
|
float lod = linear_roughness * lod_cube_max;
|
||||||
|
|
||||||
|
vec3 R = -reflect(V, reflection.N);
|
||||||
|
vec3 world_light = textureLod_cubemapArray(reflectionProbes, vec4(R, 0.0), lod).rgb;
|
||||||
|
out_specular += world_light;
|
||||||
|
}
|
|
@ -37,6 +37,7 @@ GPU_SHADER_CREATE_INFO(eevee_deferred_light)
|
||||||
.additional_info("eevee_shared",
|
.additional_info("eevee_shared",
|
||||||
"eevee_utility_texture",
|
"eevee_utility_texture",
|
||||||
"eevee_light_data",
|
"eevee_light_data",
|
||||||
|
"eevee_reflection_probe_data",
|
||||||
"eevee_shadow_data",
|
"eevee_shadow_data",
|
||||||
"eevee_deferred_base",
|
"eevee_deferred_base",
|
||||||
"eevee_hiz_data",
|
"eevee_hiz_data",
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
#include "eevee_defines.hh"
|
||||||
|
#include "gpu_shader_create_info.hh"
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------- */
|
||||||
|
/** \name Shared
|
||||||
|
* \{ */
|
||||||
|
|
||||||
|
GPU_SHADER_CREATE_INFO(eevee_reflection_probe_data)
|
||||||
|
.sampler(REFLECTION_PROBE_TEX_SLOT, ImageType::FLOAT_CUBE_ARRAY, "reflectionProbes");
|
||||||
|
|
||||||
|
/** \} */
|
|
@ -674,7 +674,7 @@ class Texture : NonCopyable {
|
||||||
float *data = nullptr,
|
float *data = nullptr,
|
||||||
int mip_len = 1)
|
int mip_len = 1)
|
||||||
{
|
{
|
||||||
return ensure_impl(extent, extent, layers, mip_len, format, usage, data, false, true);
|
return ensure_impl(extent, extent, layers, mip_len, format, usage, data, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1033,8 +1033,7 @@ class TextureRef : public Texture {
|
||||||
* Dummy type to bind texture as image.
|
* Dummy type to bind texture as image.
|
||||||
* It is just a GPUTexture in disguise.
|
* It is just a GPUTexture in disguise.
|
||||||
*/
|
*/
|
||||||
class Image {
|
class Image {};
|
||||||
};
|
|
||||||
|
|
||||||
static inline Image *as_image(GPUTexture *tex)
|
static inline Image *as_image(GPUTexture *tex)
|
||||||
{
|
{
|
||||||
|
|
|
@ -648,6 +648,7 @@ set(SRC_SHADER_CREATE_INFOS
|
||||||
../draw/engines/eevee_next/shaders/infos/eevee_light_culling_info.hh
|
../draw/engines/eevee_next/shaders/infos/eevee_light_culling_info.hh
|
||||||
../draw/engines/eevee_next/shaders/infos/eevee_material_info.hh
|
../draw/engines/eevee_next/shaders/infos/eevee_material_info.hh
|
||||||
../draw/engines/eevee_next/shaders/infos/eevee_motion_blur_info.hh
|
../draw/engines/eevee_next/shaders/infos/eevee_motion_blur_info.hh
|
||||||
|
../draw/engines/eevee_next/shaders/infos/eevee_reflection_probe_info.hh
|
||||||
../draw/engines/eevee_next/shaders/infos/eevee_shadow_info.hh
|
../draw/engines/eevee_next/shaders/infos/eevee_shadow_info.hh
|
||||||
../draw/engines/eevee_next/shaders/infos/eevee_velocity_info.hh
|
../draw/engines/eevee_next/shaders/infos/eevee_velocity_info.hh
|
||||||
../draw/engines/gpencil/shaders/infos/gpencil_info.hh
|
../draw/engines/gpencil/shaders/infos/gpencil_info.hh
|
||||||
|
|
Loading…
Reference in New Issue