EEVEE Next: Image rendering and render passes fixes/improvements

* Fix image rendering.
* Fix AOV rendering.
* Merge all render passes and AOV textures into 2 arrays (one for colors and one for values).
* Make AOVsInfoData std140 compliant.
* Remove surface color from Diffuse Light and Specular Light passes.
* Add Environment pass support.
* Add Shadow pass support.

Pull Request: https://projects.blender.org/blender/blender/pulls/108239
This commit is contained in:
Miguel Pozo 2023-05-30 15:20:52 +02:00
parent d3d91b79e0
commit 960b53dbbb
18 changed files with 301 additions and 257 deletions

View File

@ -97,17 +97,11 @@
#define RBUFS_UTILITY_TEX_SLOT 14
/* Images. */
#define RBUFS_NORMAL_SLOT 0
#define RBUFS_LIGHT_SLOT 1
#define RBUFS_DIFF_COLOR_SLOT 2
#define RBUFS_SPEC_COLOR_SLOT 3
#define RBUFS_EMISSION_SLOT 4
#define RBUFS_AOV_COLOR_SLOT 5
#define RBUFS_AOV_VALUE_SLOT 6
#define RBUFS_CRYPTOMATTE_SLOT 7
/* G-buffer reuses render passes slots. */
#define GBUF_CLOSURE_SLOT RBUFS_LIGHT_SLOT
#define GBUF_COLOR_SLOT RBUFS_DIFF_COLOR_SLOT
#define RBUFS_COLOR_SLOT 0
#define RBUFS_VALUE_SLOT 1
#define RBUFS_CRYPTOMATTE_SLOT 2
#define GBUF_CLOSURE_SLOT 3
#define GBUF_COLOR_SLOT 4
/* Uniform Buffers. */
/* Only during pre-pass. */
@ -116,17 +110,16 @@
#define VELOCITY_CAMERA_NEXT_BUF 5
#define CAMERA_BUF_SLOT 6
#define RBUFS_BUF_SLOT 7
/* Storage Buffers. */
#define LIGHT_CULL_BUF_SLOT 0
#define LIGHT_BUF_SLOT 1
#define LIGHT_ZBIN_BUF_SLOT 2
#define LIGHT_TILE_BUF_SLOT 3
/* Only during surface shading. */
#define RBUFS_AOV_BUF_SLOT 5
/* Only during shadow rendering. */
#define SHADOW_PAGE_INFO_SLOT 5
#define SAMPLING_BUF_SLOT 6
#define SHADOW_PAGE_INFO_SLOT 4
#define SAMPLING_BUF_SLOT 5
#define CRYPTOMATTE_BUF_SLOT 7
/* Only during pre-pass. */

View File

@ -75,7 +75,7 @@ void Film::init_aovs()
for (ViewLayerAOV *aov : aovs) {
bool is_value = (aov->type == AOV_TYPE_VALUE);
uint &index = is_value ? aovs_info.value_len : aovs_info.color_len;
uint &hash = is_value ? aovs_info.hash_value[index] : aovs_info.hash_color[index];
uint &hash = is_value ? aovs_info.hash_value[index].x : aovs_info.hash_color[index].x;
hash = BLI_hash_string(aov->name);
index++;
}
@ -86,14 +86,14 @@ float *Film::read_aov(ViewLayerAOV *aov)
bool is_value = (aov->type == AOV_TYPE_VALUE);
Texture &accum_tx = is_value ? value_accum_tx_ : color_accum_tx_;
Span<uint> aovs_hash(is_value ? aovs_info.hash_value : aovs_info.hash_color,
is_value ? aovs_info.value_len : aovs_info.color_len);
Span<uint4> aovs_hash(is_value ? aovs_info.hash_value : aovs_info.hash_color,
is_value ? aovs_info.value_len : aovs_info.color_len);
/* Find AOV index. */
uint hash = BLI_hash_string(aov->name);
int aov_index = -1;
int i = 0;
for (uint candidate_hash : aovs_hash) {
if (candidate_hash == hash) {
for (uint4 candidate_hash : aovs_hash) {
if (candidate_hash.x == hash) {
aov_index = i;
break;
}
@ -105,6 +105,8 @@ float *Film::read_aov(ViewLayerAOV *aov)
int index = aov_index + (is_value ? data_.aov_value_id : data_.aov_color_id);
GPUTexture *pass_tx = accum_tx.layer_view(index);
GPU_memory_barrier(GPU_BARRIER_TEXTURE_UPDATE);
return (float *)GPU_texture_read(pass_tx, GPU_DATA_FLOAT, 0);
}
@ -431,18 +433,9 @@ void Film::sync()
accumulate_ps_.bind_ubo("camera_next", &(*velocity.camera_steps[step_next]));
accumulate_ps_.bind_texture("depth_tx", &rbuffers.depth_tx);
accumulate_ps_.bind_texture("combined_tx", &combined_final_tx_);
accumulate_ps_.bind_texture("normal_tx", &rbuffers.normal_tx);
accumulate_ps_.bind_texture("vector_tx", &rbuffers.vector_tx);
accumulate_ps_.bind_texture("light_tx", &rbuffers.light_tx);
accumulate_ps_.bind_texture("diffuse_color_tx", &rbuffers.diffuse_color_tx);
accumulate_ps_.bind_texture("specular_color_tx", &rbuffers.specular_color_tx);
accumulate_ps_.bind_texture("volume_light_tx", &rbuffers.volume_light_tx);
accumulate_ps_.bind_texture("emission_tx", &rbuffers.emission_tx);
accumulate_ps_.bind_texture("environment_tx", &rbuffers.environment_tx);
accumulate_ps_.bind_texture("shadow_tx", &rbuffers.shadow_tx);
accumulate_ps_.bind_texture("ambient_occlusion_tx", &rbuffers.ambient_occlusion_tx);
accumulate_ps_.bind_texture("aov_color_tx", &rbuffers.aov_color_tx);
accumulate_ps_.bind_texture("aov_value_tx", &rbuffers.aov_value_tx);
accumulate_ps_.bind_texture("rp_color_tx", &rbuffers.rp_color_tx);
accumulate_ps_.bind_texture("rp_value_tx", &rbuffers.rp_value_tx);
accumulate_ps_.bind_texture("cryptomatte_tx", &rbuffers.cryptomatte_tx);
/* NOTE(@fclem): 16 is the max number of sampled texture in many implementations.
* If we need more, we need to pack more of the similar passes in the same textures as arrays or
@ -455,6 +448,7 @@ void Film::sync()
accumulate_ps_.bind_image("color_accum_img", &color_accum_tx_);
accumulate_ps_.bind_image("value_accum_img", &value_accum_tx_);
accumulate_ps_.bind_image("cryptomatte_img", &cryptomatte_tx_);
accumulate_ps_.bind_ubo(RBUFS_BUF_SLOT, &inst_.render_buffers.data);
/* Sync with rendering passes. */
accumulate_ps_.barrier(GPU_BARRIER_TEXTURE_FETCH | GPU_BARRIER_SHADER_IMAGE_ACCESS);
if (use_compute) {

View File

@ -118,6 +118,7 @@ void Instance::begin_sync()
main_view.sync();
world.sync();
film.sync();
render_buffers.sync();
irradiance_cache.sync();
}
@ -211,13 +212,20 @@ void Instance::end_sync()
void Instance::render_sync()
{
/* TODO: Remove old draw manager calls. */
DRW_cache_restart();
manager->begin_sync();
begin_sync();
DRW_render_object_iter(this, render, depsgraph, object_sync_render);
end_sync();
manager->end_sync();
/* TODO: Remove old draw manager calls. */
DRW_render_instance_buffer_finish();
/* Also we weed to have a correct FBO bound for #DRW_hair_update */
// GPU_framebuffer_bind();
// DRW_hair_update();
@ -282,6 +290,29 @@ void Instance::render_read_result(RenderLayer *render_layer, const char *view_na
}
}
/* AOVs. */
LISTBASE_FOREACH (ViewLayerAOV *, aov, &view_layer->aovs) {
if ((aov->flag & AOV_CONFLICT) != 0) {
continue;
}
RenderPass *rp = RE_pass_find_by_name(render_layer, aov->name, view_name);
if (!rp) {
continue;
}
float *result = film.read_aov(aov);
if (result) {
BLI_mutex_lock(&render->update_render_passes_mutex);
/* WORKAROUND: We use texture read to avoid using a framebuffer to get the render result.
* However, on some implementation, we need a buffer with a few extra bytes for the read to
* happen correctly (see GLTexture::read()). So we need a custom memory allocation. */
/* Avoid memcpy(), replace the pointer directly. */
MEM_SAFE_FREE(rp->rect);
rp->rect = result;
BLI_mutex_unlock(&render->update_render_passes_mutex);
}
}
/* The vector pass is initialized to weird values. Set it to neutral value if not rendered. */
if ((pass_bits & EEVEE_RENDER_PASS_VECTOR) == 0) {
for (std::string vector_pass_name :

View File

@ -34,21 +34,15 @@ void WorldPipeline::sync(GPUMaterial *gpumat)
world_ps_.material_set(manager, gpumat);
world_ps_.push_constant("world_opacity_fade", inst_.film.background_opacity_get());
world_ps_.bind_texture("utility_tx", inst_.pipelines.utility_tx);
/* AOVs. */
world_ps_.bind_image("aov_color_img", &rbufs.aov_color_tx);
world_ps_.bind_image("aov_value_img", &rbufs.aov_value_tx);
world_ps_.bind_ssbo("aov_buf", &inst_.film.aovs_info);
/* RenderPasses. Cleared by background (even if bad practice). */
world_ps_.bind_image("rp_normal_img", &rbufs.normal_tx);
world_ps_.bind_image("rp_light_img", &rbufs.light_tx);
world_ps_.bind_image("rp_diffuse_color_img", &rbufs.diffuse_color_tx);
world_ps_.bind_image("rp_specular_color_img", &rbufs.specular_color_tx);
world_ps_.bind_image("rp_emission_img", &rbufs.emission_tx);
/* RenderPasses & AOVs. Cleared by background (even if bad practice). */
world_ps_.bind_image("rp_color_img", &rbufs.rp_color_tx);
world_ps_.bind_image("rp_value_img", &rbufs.rp_value_tx);
world_ps_.bind_image("rp_cryptomatte_img", &rbufs.cryptomatte_tx);
/* Required by validation layers. */
inst_.cryptomatte.bind_resources(&world_ps_);
world_ps_.bind_ubo(CAMERA_BUF_SLOT, inst_.camera.ubo_get());
world_ps_.bind_ubo(RBUFS_BUF_SLOT, &inst_.render_buffers.data);
world_ps_.draw(DRW_cache_fullscreen_quad_get(), handle);
/* To allow opaque pass rendering over it. */
@ -140,24 +134,16 @@ void ForwardPipeline::sync()
{
/* Common resources. */
/* RenderPasses. */
opaque_ps_.bind_image(RBUFS_NORMAL_SLOT, &inst_.render_buffers.normal_tx);
opaque_ps_.bind_image(RBUFS_LIGHT_SLOT, &inst_.render_buffers.light_tx);
opaque_ps_.bind_image(RBUFS_DIFF_COLOR_SLOT, &inst_.render_buffers.diffuse_color_tx);
opaque_ps_.bind_image(RBUFS_SPEC_COLOR_SLOT, &inst_.render_buffers.specular_color_tx);
opaque_ps_.bind_image(RBUFS_EMISSION_SLOT, &inst_.render_buffers.emission_tx);
/* AOVs. */
opaque_ps_.bind_image(RBUFS_AOV_COLOR_SLOT, &inst_.render_buffers.aov_color_tx);
opaque_ps_.bind_image(RBUFS_AOV_VALUE_SLOT, &inst_.render_buffers.aov_value_tx);
/* RenderPasses & AOVs. */
opaque_ps_.bind_image(RBUFS_COLOR_SLOT, &inst_.render_buffers.rp_color_tx);
opaque_ps_.bind_image(RBUFS_VALUE_SLOT, &inst_.render_buffers.rp_value_tx);
/* Cryptomatte. */
opaque_ps_.bind_image(RBUFS_CRYPTOMATTE_SLOT, &inst_.render_buffers.cryptomatte_tx);
/* Storage Buffer. */
opaque_ps_.bind_ssbo(RBUFS_AOV_BUF_SLOT, &inst_.film.aovs_info);
/* Textures. */
opaque_ps_.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
/* Uniform Buffer. */
opaque_ps_.bind_ubo(CAMERA_BUF_SLOT, inst_.camera.ubo_get());
opaque_ps_.bind_ubo(RBUFS_BUF_SLOT, &inst_.render_buffers.data);
inst_.lights.bind_resources(&opaque_ps_);
inst_.shadows.bind_resources(&opaque_ps_);
@ -327,23 +313,17 @@ void DeferredLayer::begin_sync()
/* G-buffer. */
gbuffer_ps_.bind_image(GBUF_CLOSURE_SLOT, &inst_.gbuffer.closure_tx);
gbuffer_ps_.bind_image(GBUF_COLOR_SLOT, &inst_.gbuffer.color_tx);
/* RenderPasses. */
gbuffer_ps_.bind_image(RBUFS_NORMAL_SLOT, &inst_.render_buffers.normal_tx);
/* TODO(fclem): Pack all render pass into the same texture. */
// gbuffer_ps_.bind_image(RBUFS_DIFF_COLOR_SLOT, &inst_.render_buffers.diffuse_color_tx);
gbuffer_ps_.bind_image(RBUFS_SPEC_COLOR_SLOT, &inst_.render_buffers.specular_color_tx);
gbuffer_ps_.bind_image(RBUFS_EMISSION_SLOT, &inst_.render_buffers.emission_tx);
/* AOVs. */
gbuffer_ps_.bind_image(RBUFS_AOV_COLOR_SLOT, &inst_.render_buffers.aov_color_tx);
gbuffer_ps_.bind_image(RBUFS_AOV_VALUE_SLOT, &inst_.render_buffers.aov_value_tx);
/* RenderPasses & AOVs. */
gbuffer_ps_.bind_image(RBUFS_COLOR_SLOT, &inst_.render_buffers.rp_color_tx);
gbuffer_ps_.bind_image(RBUFS_VALUE_SLOT, &inst_.render_buffers.rp_value_tx);
/* Cryptomatte. */
gbuffer_ps_.bind_image(RBUFS_CRYPTOMATTE_SLOT, &inst_.render_buffers.cryptomatte_tx);
/* Storage Buffer. */
gbuffer_ps_.bind_ssbo(RBUFS_AOV_BUF_SLOT, &inst_.film.aovs_info);
/* Textures. */
gbuffer_ps_.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
/* Uniform Buffer. */
gbuffer_ps_.bind_ubo(CAMERA_BUF_SLOT, inst_.camera.ubo_get());
gbuffer_ps_.bind_ubo(RBUFS_BUF_SLOT, &inst_.render_buffers.data);
inst_.sampling.bind_resources(&gbuffer_ps_);
inst_.cryptomatte.bind_resources(&gbuffer_ps_);
@ -380,8 +360,10 @@ void DeferredLayer::end_sync()
eval_light_ps_.bind_texture("gbuffer_closure_tx", &inst_.gbuffer.closure_tx);
eval_light_ps_.bind_texture("gbuffer_color_tx", &inst_.gbuffer.color_tx);
eval_light_ps_.push_constant("is_last_eval_pass", is_last_eval_pass);
eval_light_ps_.bind_image(RBUFS_LIGHT_SLOT, &inst_.render_buffers.light_tx);
eval_light_ps_.bind_image(RBUFS_COLOR_SLOT, &inst_.render_buffers.rp_color_tx);
eval_light_ps_.bind_image(RBUFS_VALUE_SLOT, &inst_.render_buffers.rp_value_tx);
eval_light_ps_.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
eval_light_ps_.bind_ubo(RBUFS_BUF_SLOT, &inst_.render_buffers.data);
inst_.lights.bind_resources(&eval_light_ps_);
inst_.shadows.bind_resources(&eval_light_ps_);

View File

@ -24,6 +24,36 @@
namespace blender::eevee {
void RenderBuffers::sync()
{
const eViewLayerEEVEEPassType enabled_passes = inst_.film.enabled_passes_get();
data.color_len = 0;
data.value_len = 0;
auto pass_index_get = [&](eViewLayerEEVEEPassType pass_type) {
if (enabled_passes & pass_type) {
return inst_.film.pass_storage_type(pass_type) == PASS_STORAGE_COLOR ? data.color_len++ :
data.value_len++;
}
return -1;
};
data.normal_id = pass_index_get(EEVEE_RENDER_PASS_NORMAL);
data.diffuse_light_id = pass_index_get(EEVEE_RENDER_PASS_DIFFUSE_LIGHT);
data.diffuse_color_id = pass_index_get(EEVEE_RENDER_PASS_DIFFUSE_COLOR);
data.specular_light_id = pass_index_get(EEVEE_RENDER_PASS_SPECULAR_LIGHT);
data.specular_color_id = pass_index_get(EEVEE_RENDER_PASS_SPECULAR_COLOR);
data.volume_light_id = pass_index_get(EEVEE_RENDER_PASS_VOLUME_LIGHT);
data.emission_id = pass_index_get(EEVEE_RENDER_PASS_EMIT);
data.environment_id = pass_index_get(EEVEE_RENDER_PASS_ENVIRONMENT);
data.shadow_id = pass_index_get(EEVEE_RENDER_PASS_SHADOW);
data.ambient_occlusion_id = pass_index_get(EEVEE_RENDER_PASS_AO);
data.aovs = inst_.film.aovs_info;
data.push_update();
}
void RenderBuffers::acquire(int2 extent)
{
const eViewLayerEEVEEPassType enabled_passes = inst_.film.enabled_passes_get();
@ -42,36 +72,19 @@ void RenderBuffers::acquire(int2 extent)
bool do_vector_render_pass = (enabled_passes & EEVEE_RENDER_PASS_VECTOR) ||
(inst_.motion_blur.postfx_enabled() && !inst_.is_viewport());
uint32_t max_light_color_layer = max_ii(enabled_passes & EEVEE_RENDER_PASS_DIFFUSE_LIGHT ?
int(RENDER_PASS_LAYER_DIFFUSE_LIGHT) :
-1,
enabled_passes & EEVEE_RENDER_PASS_SPECULAR_LIGHT ?
int(RENDER_PASS_LAYER_SPECULAR_LIGHT) :
-1) +
1;
/* Only RG16F when only doing only reprojection or motion blur. */
eGPUTextureFormat vector_format = do_vector_render_pass ? GPU_RGBA16F : GPU_RG16F;
/* TODO(fclem): Make vector pass allocation optional if no TAA or motion blur is needed. */
vector_tx.acquire(extent, vector_format);
normal_tx.acquire(pass_extent(EEVEE_RENDER_PASS_NORMAL), color_format);
diffuse_color_tx.acquire(pass_extent(EEVEE_RENDER_PASS_DIFFUSE_COLOR), color_format);
specular_color_tx.acquire(pass_extent(EEVEE_RENDER_PASS_SPECULAR_COLOR), color_format);
volume_light_tx.acquire(pass_extent(EEVEE_RENDER_PASS_VOLUME_LIGHT), color_format);
emission_tx.acquire(pass_extent(EEVEE_RENDER_PASS_EMIT), color_format);
environment_tx.acquire(pass_extent(EEVEE_RENDER_PASS_ENVIRONMENT), color_format);
shadow_tx.acquire(pass_extent(EEVEE_RENDER_PASS_SHADOW), float_format);
ambient_occlusion_tx.acquire(pass_extent(EEVEE_RENDER_PASS_AO), float_format);
int color_len = data.color_len + data.aovs.color_len;
int value_len = data.value_len + data.aovs.value_len;
light_tx.ensure_2d_array(color_format,
max_light_color_layer > 0 ? extent : int2(1),
max_ii(1, max_light_color_layer));
const AOVsInfoData &aovs = inst_.film.aovs_info;
aov_color_tx.ensure_2d_array(
color_format, (aovs.color_len > 0) ? extent : int2(1), max_ii(1, aovs.color_len));
aov_value_tx.ensure_2d_array(
float_format, (aovs.value_len > 0) ? extent : int2(1), max_ii(1, aovs.value_len));
rp_color_tx.ensure_2d_array(
color_format, (color_len > 0) ? extent : int2(1), math::max(1, color_len));
rp_value_tx.ensure_2d_array(
float_format, (value_len > 0) ? extent : int2(1), math::max(1, value_len));
eGPUTextureFormat cryptomatte_format = GPU_R32F;
const int cryptomatte_layer_len = inst_.film.cryptomatte_layer_max_get();
@ -93,15 +106,7 @@ void RenderBuffers::release()
depth_tx.release();
combined_tx.release();
normal_tx.release();
vector_tx.release();
diffuse_color_tx.release();
specular_color_tx.release();
volume_light_tx.release();
emission_tx.release();
environment_tx.release();
shadow_tx.release();
ambient_occlusion_tx.release();
cryptomatte_tx.release();
}

View File

@ -22,24 +22,17 @@ class Instance;
class RenderBuffers {
public:
UniformBuffer<RenderBuffersInfoData> data;
TextureFromPool depth_tx;
TextureFromPool combined_tx;
// TextureFromPool mist_tx; /* Derived from depth_tx during accumulation. */
TextureFromPool normal_tx;
TextureFromPool vector_tx;
TextureFromPool diffuse_color_tx;
TextureFromPool specular_color_tx;
TextureFromPool volume_light_tx;
TextureFromPool emission_tx;
TextureFromPool environment_tx;
TextureFromPool shadow_tx;
TextureFromPool ambient_occlusion_tx;
TextureFromPool cryptomatte_tx;
/* TODO(fclem): Use texture from pool once they support texture array. */
Texture light_tx;
Texture aov_color_tx;
Texture aov_value_tx;
Texture rp_color_tx;
Texture rp_value_tx;
private:
Instance &inst_;
@ -47,6 +40,8 @@ class RenderBuffers {
public:
RenderBuffers(Instance &inst) : inst_(inst){};
void sync();
/* Acquires (also ensures) the render buffer before rendering to them. */
void acquire(int2 extent);
void release();

View File

@ -260,7 +260,6 @@ void ShaderModule::material_create_info_ammend(GPUMaterial *gpumat, GPUCodegenOu
pipeline_type == MAT_PIPE_FORWARD)
{
/* Opaque forward do support AOVs and render pass if not using transparency. */
info.additional_info("eevee_aov_out");
info.additional_info("eevee_render_pass_out");
info.additional_info("eevee_cryptomatte_out");
}

View File

@ -307,18 +307,7 @@ static inline float film_filter_weight(float filter_radius, float sample_distanc
/** \} */
/* -------------------------------------------------------------------- */
/** \name Render passes
* \{ */
enum eRenderPassLayerIndex : uint32_t {
RENDER_PASS_LAYER_DIFFUSE_LIGHT = 0u,
RENDER_PASS_LAYER_SPECULAR_LIGHT = 1u,
};
/** \} */
/* -------------------------------------------------------------------- */
/** \name Arbitrary Output Variables
/** \name RenderBuffers
* \{ */
/* Theoretical max is 128 as we are using texture array and VRAM usage.
@ -326,10 +315,11 @@ enum eRenderPassLayerIndex : uint32_t {
* If we find a way to avoid this we could bump this number up. */
#define AOV_MAX 16
/* NOTE(@fclem): Needs to be used in #StorageBuffer because of arrays of scalar. */
struct AOVsInfoData {
uint hash_value[AOV_MAX];
uint hash_color[AOV_MAX];
/* Use uint4 to workaround std140 packing rules.
* Only the x value is used. */
uint4 hash_value[AOV_MAX];
uint4 hash_color[AOV_MAX];
/* Length of used data. */
uint color_len;
uint value_len;
@ -340,6 +330,25 @@ struct AOVsInfoData {
};
BLI_STATIC_ASSERT_ALIGN(AOVsInfoData, 16)
struct RenderBuffersInfoData {
AOVsInfoData aovs;
/* Color. */
int color_len;
int normal_id;
int diffuse_light_id;
int diffuse_color_id;
int specular_light_id;
int specular_color_id;
int volume_light_id;
int emission_id;
int environment_id;
/* Value */
int value_len;
int shadow_id;
int ambient_occlusion_id;
};
BLI_STATIC_ASSERT_ALIGN(RenderBuffersInfoData, 16)
/** \} */
/* -------------------------------------------------------------------- */

View File

@ -51,9 +51,18 @@ void main()
vec3 diffuse_light = vec3(0.0);
vec3 reflection_light = vec3(0.0);
float shadow = 1.0;
light_eval(
diffuse_data, reflection_data, P, Ng, V, vP_z, thickness, diffuse_light, reflection_light);
light_eval(diffuse_data,
reflection_data,
P,
Ng,
V,
vP_z,
thickness,
diffuse_light,
reflection_light,
shadow);
if (is_last_eval_pass) {
/* Apply color and output lighting to render-passes. */
@ -67,13 +76,21 @@ void main()
diffuse_data.color = vec3(0.0);
}
reflection_light *= reflection_data.color;
/* Light passes. */
if (rp_buf.diffuse_light_id >= 0) {
imageStore(rp_color_img, ivec3(texel, rp_buf.diffuse_light_id), vec4(diffuse_light, 1.0));
}
if (rp_buf.specular_light_id >= 0) {
imageStore(
rp_color_img, ivec3(texel, rp_buf.specular_light_id), vec4(reflection_light, 1.0));
}
if (rp_buf.shadow_id >= 0) {
imageStore(rp_value_img, ivec3(texel, rp_buf.shadow_id), vec4(shadow));
}
/* TODO: AO. */
diffuse_light *= diffuse_data.color;
/* Add radiance to light pass. */
imageStore(
rp_light_img, ivec3(texel, RENDER_PASS_LAYER_DIFFUSE_LIGHT), vec4(diffuse_light, 1.0));
imageStore(
rp_light_img, ivec3(texel, RENDER_PASS_LAYER_SPECULAR_LIGHT), vec4(reflection_light, 1.0));
reflection_light *= reflection_data.color;
/* Add radiance to combined pass. */
out_radiance = vec4(diffuse_light + reflection_light, 0.0);
out_transmittance = vec4(1.0);

View File

@ -90,42 +90,22 @@ float film_weight_accumulation(ivec2 texel_film)
return film_buf.samples_weight_total;
}
void film_sample_accum(FilmSample samp, int pass_id, sampler2D tex, inout vec4 accum)
{
if (pass_id == -1) {
return;
}
accum += texelFetch(tex, samp.texel, 0) * samp.weight;
}
void film_sample_accum(FilmSample samp, int pass_id, sampler2D tex, inout float accum)
{
if (pass_id == -1) {
return;
}
accum += texelFetch(tex, samp.texel, 0).x * samp.weight;
}
void film_sample_accum(
FilmSample samp, int pass_id, uint layer, sampler2DArray tex, inout vec4 accum)
FilmSample samp, int pass_id, int layer, sampler2DArray tex, inout vec4 accum)
{
if (pass_id == -1) {
if (pass_id < 0 || layer < 0) {
return;
}
accum += texelFetch(tex, ivec3(samp.texel, layer), 0) * samp.weight;
}
void film_sample_accum(FilmSample samp, int pass_id, sampler2DArray tex, inout vec4 accum)
void film_sample_accum(
FilmSample samp, int pass_id, int layer, sampler2DArray tex, inout float accum)
{
film_sample_accum(samp, pass_id, pass_id, tex, accum);
}
void film_sample_accum(FilmSample samp, int pass_id, sampler2DArray tex, inout float accum)
{
if (pass_id == -1) {
if (pass_id < 0 || layer < 0) {
return;
}
accum += texelFetch(tex, ivec3(samp.texel, pass_id), 0).x * samp.weight;
accum += texelFetch(tex, ivec3(samp.texel, layer), 0).x * samp.weight;
}
void film_sample_accum_mist(FilmSample samp, inout float accum)
@ -662,7 +642,7 @@ void film_process_data(ivec2 texel_film, out vec4 out_color, out float out_depth
FilmSample film_sample = film_sample_get(0, texel_film);
if (film_buf.use_reprojection || film_sample.weight < film_distance) {
vec4 normal = texelFetch(normal_tx, film_sample.texel, 0);
vec4 normal = texelFetch(rp_color_tx, ivec3(film_sample.texel, rp_buf.normal_id), 0);
float depth = texelFetch(depth_tx, film_sample.texel, 0).x;
vec4 vector = velocity_resolve(vector_tx, film_sample.texel, depth);
/* Transform to pixel space. */
@ -688,16 +668,18 @@ void film_process_data(ivec2 texel_film, out vec4 out_color, out float out_depth
FilmSample src = film_sample_get(i, texel_film);
film_sample_accum(src,
film_buf.diffuse_light_id,
RENDER_PASS_LAYER_DIFFUSE_LIGHT,
light_tx,
rp_buf.diffuse_light_id,
rp_color_tx,
diffuse_light_accum);
film_sample_accum(src,
film_buf.specular_light_id,
RENDER_PASS_LAYER_SPECULAR_LIGHT,
light_tx,
rp_buf.specular_light_id,
rp_color_tx,
specular_light_accum);
film_sample_accum(src, film_buf.volume_light_id, volume_light_tx, volume_light_accum);
film_sample_accum(src, film_buf.emission_id, emission_tx, emission_accum);
film_sample_accum(
src, film_buf.volume_light_id, rp_buf.volume_light_id, rp_color_tx, volume_light_accum);
film_sample_accum(
src, film_buf.emission_id, rp_buf.emission_id, rp_color_tx, emission_accum);
}
film_store_color(dst, film_buf.diffuse_light_id, diffuse_light_accum, out_color);
film_store_color(dst, film_buf.specular_light_id, specular_light_accum, out_color);
@ -715,11 +697,21 @@ void film_process_data(ivec2 texel_film, out vec4 out_color, out float out_depth
for (int i = 0; i < film_buf.samples_len; i++) {
FilmSample src = film_sample_get(i, texel_film);
film_sample_accum(src, film_buf.diffuse_color_id, diffuse_color_tx, diffuse_color_accum);
film_sample_accum(src, film_buf.specular_color_id, specular_color_tx, specular_color_accum);
film_sample_accum(src, film_buf.environment_id, environment_tx, environment_accum);
film_sample_accum(src, film_buf.shadow_id, shadow_tx, shadow_accum);
film_sample_accum(src, film_buf.ambient_occlusion_id, ambient_occlusion_tx, ao_accum);
film_sample_accum(src,
film_buf.diffuse_color_id,
rp_buf.diffuse_color_id,
rp_color_tx,
diffuse_color_accum);
film_sample_accum(src,
film_buf.specular_color_id,
rp_buf.specular_color_id,
rp_color_tx,
specular_color_accum);
film_sample_accum(
src, film_buf.environment_id, rp_buf.environment_id, rp_color_tx, environment_accum);
film_sample_accum(src, film_buf.shadow_id, rp_buf.shadow_id, rp_value_tx, shadow_accum);
film_sample_accum(
src, film_buf.ambient_occlusion_id, rp_buf.ambient_occlusion_id, rp_value_tx, ao_accum);
film_sample_accum_mist(src, mist_accum);
}
film_store_color(dst, film_buf.diffuse_color_id, diffuse_color_accum, out_color);
@ -735,7 +727,7 @@ void film_process_data(ivec2 texel_film, out vec4 out_color, out float out_depth
for (int i = 0; i < film_buf.samples_len; i++) {
FilmSample src = film_sample_get(i, texel_film);
film_sample_accum(src, aov, aov_color_tx, aov_accum);
film_sample_accum(src, 0, rp_buf.color_len + aov, rp_color_tx, aov_accum);
}
film_store_color(dst, film_buf.aov_color_id + aov, aov_accum, out_color);
}
@ -745,7 +737,7 @@ void film_process_data(ivec2 texel_film, out vec4 out_color, out float out_depth
for (int i = 0; i < film_buf.samples_len; i++) {
FilmSample src = film_sample_get(i, texel_film);
film_sample_accum(src, aov, aov_value_tx, aov_accum);
film_sample_accum(src, 0, rp_buf.value_len + aov, rp_value_tx, aov_accum);
}
film_store_value(dst, film_buf.aov_value_id + aov, aov_accum, out_color);
}

View File

@ -27,7 +27,8 @@ void light_eval_ex(ClosureDiffuse diffuse,
vec4 ltc_mat,
uint l_idx,
inout vec3 out_diffuse,
inout vec3 out_specular)
inout vec3 out_specular,
inout float out_shadow)
{
LightData light = light_buf[l_idx];
vec3 L;
@ -61,6 +62,7 @@ void light_eval_ex(ClosureDiffuse diffuse,
}
#endif
visibility *= float(samp.occluder_delta + samp.bias >= 0.0);
out_shadow *= float(samp.occluder_delta + samp.bias >= 0.0);
}
if (visibility < 1e-6) {
@ -89,7 +91,8 @@ void light_eval(ClosureDiffuse diffuse,
float vP_z,
float thickness,
inout vec3 out_diffuse,
inout vec3 out_specular)
inout vec3 out_specular,
inout float out_shadow)
{
vec2 uv = vec2(reflection.roughness, safe_sqrt(1.0 - dot(reflection.N, V)));
uv = uv * UTIL_TEX_UV_SCALE + UTIL_TEX_UV_BIAS;
@ -107,7 +110,8 @@ void light_eval(ClosureDiffuse diffuse,
ltc_mat,
l_idx,
out_diffuse,
out_specular);
out_specular,
out_shadow);
}
LIGHT_FOREACH_END
@ -124,7 +128,8 @@ void light_eval(ClosureDiffuse diffuse,
ltc_mat,
l_idx,
out_diffuse,
out_specular);
out_specular,
out_shadow);
}
LIGHT_FOREACH_END
}

View File

@ -237,18 +237,51 @@ float F_eta(float a, float b)
{
return a;
}
void output_renderpass_color(int id, vec4 color)
{
#if defined(MAT_RENDER_PASS_SUPPORT) && defined(GPU_FRAGMENT_SHADER)
if (id >= 0) {
ivec2 texel = ivec2(gl_FragCoord.xy);
imageStore(rp_color_img, ivec3(texel, id), color);
}
#endif
};
void output_renderpass_value(int id, float value)
{
#if defined(MAT_RENDER_PASS_SUPPORT) && defined(GPU_FRAGMENT_SHADER)
if (id >= 0) {
ivec2 texel = ivec2(gl_FragCoord.xy);
imageStore(rp_value_img, ivec3(texel, id), vec4(value));
}
#endif
};
void clear_aovs()
{
#if defined(MAT_RENDER_PASS_SUPPORT) && defined(GPU_FRAGMENT_SHADER)
for (int i = 0; i < AOV_MAX && i < rp_buf.aovs.color_len; i++) {
output_renderpass_color(rp_buf.color_len + i, vec4(0));
}
for (int i = 0; i < AOV_MAX && i < rp_buf.aovs.value_len; i++) {
output_renderpass_value(rp_buf.value_len + i, 0.0);
}
#endif
}
void output_aov(vec4 color, float value, uint hash)
{
#if defined(MAT_AOV_SUPPORT) && defined(GPU_FRAGMENT_SHADER)
for (uint i = 0; i < AOV_MAX && i < aov_buf.color_len; i++) {
if (aov_buf.hash_color[i] == hash) {
imageStore(aov_color_img, ivec3(ivec2(gl_FragCoord.xy), i), color);
#if defined(MAT_RENDER_PASS_SUPPORT) && defined(GPU_FRAGMENT_SHADER)
for (uint i = 0; i < AOV_MAX && i < rp_buf.aovs.color_len; i++) {
if (rp_buf.aovs.hash_color[i].x == hash) {
imageStore(rp_color_img, ivec3(ivec2(gl_FragCoord.xy), rp_buf.color_len + i), color);
return;
}
}
for (uint i = 0; i < AOV_MAX && i < aov_buf.value_len; i++) {
if (aov_buf.hash_value[i] == hash) {
imageStore(aov_value_img, ivec3(ivec2(gl_FragCoord.xy), i), vec4(value));
for (uint i = 0; i < AOV_MAX && i < rp_buf.aovs.value_len; i++) {
if (rp_buf.aovs.hash_value[i].x == hash) {
imageStore(rp_value_img, ivec3(ivec2(gl_FragCoord.xy), rp_buf.value_len + i), vec4(value));
return;
}
}

View File

@ -28,6 +28,9 @@ vec4 closure_to_rgba(Closure cl)
void main()
{
/* Clear AOVs first. In case the material renders to them. */
clear_aovs();
init_globals();
float noise = utility_tx_fetch(utility_tx, gl_FragCoord.xy, UTIL_BLUE_NOISE_LAYER).r;
@ -66,12 +69,10 @@ void main()
/* Some render pass can be written during the gbuffer pass. Light passes are written later. */
vec4 cryptomatte_output = vec4(cryptomatte_object_buf[resource_id], node_tree.crypto_hash, 0.0);
imageStore(rp_cryptomatte_img, out_texel, cryptomatte_output);
imageStore(rp_normal_img, out_texel, vec4(out_normal, 1.0));
/* TODO(fclem): For now, just don't do anything. In the future all render passes should be in an
* array texture and have a UBO with indirection to the correct layer. */
// imageStore(rp_diffuse_color_img, out_texel, vec4(g_diffuse_data.color, 1.0));
imageStore(rp_specular_color_img, out_texel, vec4(specular_color, 1.0));
imageStore(rp_emission_img, out_texel, vec4(g_emission, 1.0));
output_renderpass_color(rp_buf.normal_id, vec4(out_normal, 1.0));
output_renderpass_color(rp_buf.diffuse_color_id, vec4(g_diffuse_data.color, 1.0));
output_renderpass_color(rp_buf.specular_color_id, vec4(specular_color, 1.0));
output_renderpass_color(rp_buf.emission_id, vec4(g_emission, 1.0));
#endif
/* ----- GBuffer output ----- */

View File

@ -18,6 +18,7 @@ vec4 closure_to_rgba(Closure cl)
vec3 diffuse_light = vec3(0.0);
vec3 reflection_light = vec3(0.0);
vec3 refraction_light = vec3(0.0);
float shadow = 1.0;
float vP_z = dot(cameraForward, g_data.P) - dot(cameraForward, cameraPos);
@ -29,7 +30,8 @@ vec4 closure_to_rgba(Closure cl)
vP_z,
0.01 /* TODO(fclem) thickness. */,
diffuse_light,
reflection_light);
reflection_light,
shadow);
vec4 out_color;
out_color.rgb = g_emission;
@ -47,6 +49,9 @@ vec4 closure_to_rgba(Closure cl)
void main()
{
/* Clear AOVs first. In case the material renders to them. */
clear_aovs();
init_globals();
float noise = utility_tx_fetch(utility_tx, gl_FragCoord.xy, UTIL_BLUE_NOISE_LAYER).r;
@ -61,6 +66,7 @@ void main()
vec3 diffuse_light = vec3(0.0);
vec3 reflection_light = vec3(0.0);
vec3 refraction_light = vec3(0.0);
float shadow = 1.0;
float vP_z = dot(cameraForward, g_data.P) - dot(cameraForward, cameraPos);
@ -72,7 +78,8 @@ void main()
vP_z,
0.01 /* TODO(fclem) thickness. */,
diffuse_light,
reflection_light);
reflection_light,
shadow);
g_diffuse_data.color *= g_diffuse_data.weight;
g_reflection_data.color *= g_reflection_data.weight;
@ -101,17 +108,16 @@ void main()
#ifdef MAT_RENDER_PASS_SUPPORT
ivec2 out_texel = ivec2(gl_FragCoord.xy);
imageStore(rp_normal_img, out_texel, vec4(out_normal, 1.0));
imageStore(
rp_light_img, ivec3(out_texel, RENDER_PASS_LAYER_DIFFUSE_LIGHT), vec4(diffuse_light, 1.0));
imageStore(
rp_light_img, ivec3(out_texel, RENDER_PASS_LAYER_SPECULAR_LIGHT), vec4(specular_light, 1.0));
imageStore(rp_diffuse_color_img, out_texel, vec4(g_diffuse_data.color, 1.0));
imageStore(rp_specular_color_img, out_texel, vec4(specular_color, 1.0));
imageStore(rp_emission_img, out_texel, vec4(g_emission, 1.0));
imageStore(rp_cryptomatte_img,
out_texel,
vec4(cryptomatte_object_buf[resource_id], node_tree.crypto_hash, 0.0));
vec4 cryptomatte_output = vec4(cryptomatte_object_buf[resource_id], node_tree.crypto_hash, 0.0);
imageStore(rp_cryptomatte_img, out_texel, cryptomatte_output);
output_renderpass_color(rp_buf.normal_id, vec4(out_normal, 1.0));
output_renderpass_color(rp_buf.diffuse_color_id, vec4(g_diffuse_data.color, 1.0));
output_renderpass_color(rp_buf.diffuse_light_id, vec4(diffuse_light, 1.0));
output_renderpass_color(rp_buf.specular_color_id, vec4(specular_color, 1.0));
output_renderpass_color(rp_buf.specular_light_id, vec4(specular_light, 1.0));
output_renderpass_color(rp_buf.emission_id, vec4(g_emission, 1.0));
output_renderpass_value(rp_buf.shadow_id, shadow);
/* TODO: AO. */
#endif
out_radiance.rgb *= 1.0 - g_holdout;

View File

@ -13,6 +13,9 @@
void main()
{
/* Clear AOVs first. In case the material renders to them. */
clear_aovs();
init_globals();
/* View position is passed to keep accuracy. */
g_data.N = normal_view_to_world(viewCameraVec(interp.P));
@ -24,20 +27,28 @@ void main()
g_holdout = saturate(g_holdout);
ivec2 out_texel = ivec2(gl_FragCoord.xy);
imageStore(rp_normal_img, out_texel, vec4(0.0, 0.0, 0.0, 1.0));
imageStore(
rp_light_img, ivec3(out_texel, RENDER_PASS_LAYER_DIFFUSE_LIGHT), vec4(0.0, 0.0, 0.0, 1.0));
imageStore(
rp_light_img, ivec3(out_texel, RENDER_PASS_LAYER_SPECULAR_LIGHT), vec4(0.0, 0.0, 0.0, 1.0));
imageStore(rp_diffuse_color_img, out_texel, vec4(0.0, 0.0, 0.0, 1.0));
imageStore(rp_specular_color_img, out_texel, vec4(0.0, 0.0, 0.0, 1.0));
imageStore(rp_emission_img, out_texel, vec4(0.0, 0.0, 0.0, 1.0));
imageStore(rp_cryptomatte_img, out_texel, vec4(0.0));
out_background.rgb = safe_color(g_emission) * (1.0 - g_holdout);
out_background.a = saturate(avg(g_transmittance)) * g_holdout;
/* World opacity. */
out_background = mix(vec4(0.0, 0.0, 0.0, 1.0), out_background, world_opacity_fade);
/* Clear Render Buffers. */
ivec2 texel = ivec2(gl_FragCoord.xy);
vec4 environment = out_background;
environment.a = 1.0 - environment.a;
environment.rgb *= environment.a;
output_renderpass_color(rp_buf.environment_id, environment);
vec4 clear_color = vec4(0.0, 0.0, 0.0, 1.0);
output_renderpass_color(rp_buf.normal_id, clear_color);
output_renderpass_color(rp_buf.diffuse_light_id, clear_color);
output_renderpass_color(rp_buf.specular_light_id, clear_color);
output_renderpass_color(rp_buf.diffuse_color_id, clear_color);
output_renderpass_color(rp_buf.specular_color_id, clear_color);
output_renderpass_color(rp_buf.emission_id, clear_color);
output_renderpass_value(rp_buf.shadow_id, 1.0);
output_renderpass_value(rp_buf.ambient_occlusion_id, 0.0);
imageStore(rp_cryptomatte_img, texel, vec4(0.0));
}

View File

@ -24,11 +24,9 @@ GPU_SHADER_CREATE_INFO(eevee_deferred_base)
/* Combined pass output. */
.fragment_out(0, Type::VEC4, "out_radiance", DualBlend::SRC_0)
.fragment_out(0, Type::VEC4, "out_transmittance", DualBlend::SRC_1)
/* Light pass output. */
.image_array_out(RBUFS_LIGHT_SLOT, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_light_img")
/* Chaining to next pass. */
.image_out(2, Qualifier::READ_WRITE, GPU_RGBA16F, "out_diffuse_light_img")
.image_out(3, Qualifier::READ_WRITE, GPU_RGBA16F, "out_specular_light_img");
.image_out(2, Qualifier::WRITE, GPU_RGBA16F, "out_diffuse_light_img")
.image_out(3, Qualifier::WRITE, GPU_RGBA16F, "out_specular_light_img");
GPU_SHADER_CREATE_INFO(eevee_deferred_light)
.fragment_source("eevee_deferred_light_frag.glsl")
@ -40,6 +38,7 @@ GPU_SHADER_CREATE_INFO(eevee_deferred_light)
"eevee_shadow_data",
"eevee_deferred_base",
"eevee_hiz_data",
"eevee_render_pass_out",
"draw_view",
"draw_fullscreen")
.do_static_compilation(true);

View File

@ -7,21 +7,12 @@ GPU_SHADER_CREATE_INFO(eevee_film)
.uniform_buf(6, "FilmData", "film_buf")
.sampler(0, ImageType::DEPTH_2D, "depth_tx")
.sampler(1, ImageType::FLOAT_2D, "combined_tx")
.sampler(2, ImageType::FLOAT_2D, "normal_tx")
.sampler(3, ImageType::FLOAT_2D, "vector_tx")
.sampler(4, ImageType::FLOAT_2D_ARRAY, "light_tx")
.sampler(5, ImageType::FLOAT_2D, "diffuse_color_tx")
.sampler(6, ImageType::FLOAT_2D, "specular_color_tx")
.sampler(7, ImageType::FLOAT_2D, "volume_light_tx")
.sampler(8, ImageType::FLOAT_2D, "emission_tx")
.sampler(9, ImageType::FLOAT_2D, "environment_tx")
.sampler(10, ImageType::FLOAT_2D, "shadow_tx")
.sampler(11, ImageType::FLOAT_2D, "ambient_occlusion_tx")
.sampler(12, ImageType::FLOAT_2D_ARRAY, "aov_color_tx")
.sampler(13, ImageType::FLOAT_2D_ARRAY, "aov_value_tx")
.sampler(2, ImageType::FLOAT_2D, "vector_tx")
.sampler(3, ImageType::FLOAT_2D_ARRAY, "rp_color_tx")
.sampler(4, ImageType::FLOAT_2D_ARRAY, "rp_value_tx")
/* Color History for TAA needs to be sampler to leverage bilinear sampling. */
.sampler(14, ImageType::FLOAT_2D, "in_combined_tx")
.sampler(15, ImageType::FLOAT_2D, "cryptomatte_tx")
.sampler(5, ImageType::FLOAT_2D, "in_combined_tx")
.sampler(6, ImageType::FLOAT_2D, "cryptomatte_tx")
.image(0, GPU_R32F, Qualifier::READ, ImageType::FLOAT_2D_ARRAY, "in_weight_img")
.image(1, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D_ARRAY, "out_weight_img")
/* Color History for TAA needs to be sampler to leverage bilinear sampling. */
@ -31,6 +22,7 @@ GPU_SHADER_CREATE_INFO(eevee_film)
.image(5, GPU_RGBA16F, Qualifier::READ_WRITE, ImageType::FLOAT_2D_ARRAY, "color_accum_img")
.image(6, GPU_R16F, Qualifier::READ_WRITE, ImageType::FLOAT_2D_ARRAY, "value_accum_img")
.image(7, GPU_RGBA32F, Qualifier::READ_WRITE, ImageType::FLOAT_2D_ARRAY, "cryptomatte_img")
.uniform_buf(RBUFS_BUF_SLOT, "RenderBuffersInfoData", "rp_buf")
.additional_info("eevee_shared")
.additional_info("eevee_velocity_camera")
.additional_info("draw_view");

View File

@ -80,19 +80,11 @@ GPU_SHADER_INTERFACE_INFO(eevee_surf_iface, "interp")
#define image_array_out(slot, qualifier, format, name) \
image(slot, format, qualifier, ImageType::FLOAT_2D_ARRAY, name, Frequency::PASS)
GPU_SHADER_CREATE_INFO(eevee_aov_out)
.define("MAT_AOV_SUPPORT")
.image_array_out(RBUFS_AOV_COLOR_SLOT, Qualifier::WRITE, GPU_RGBA16F, "aov_color_img")
.image_array_out(RBUFS_AOV_VALUE_SLOT, Qualifier::WRITE, GPU_R16F, "aov_value_img")
.storage_buf(RBUFS_AOV_BUF_SLOT, Qualifier::READ, "AOVsInfoData", "aov_buf");
GPU_SHADER_CREATE_INFO(eevee_render_pass_out)
.define("MAT_RENDER_PASS_SUPPORT")
.image_out(RBUFS_NORMAL_SLOT, Qualifier::WRITE, GPU_RGBA16F, "rp_normal_img")
.image_array_out(RBUFS_LIGHT_SLOT, Qualifier::WRITE, GPU_RGBA16F, "rp_light_img")
.image_out(RBUFS_DIFF_COLOR_SLOT, Qualifier::WRITE, GPU_RGBA16F, "rp_diffuse_color_img")
.image_out(RBUFS_SPEC_COLOR_SLOT, Qualifier::WRITE, GPU_RGBA16F, "rp_specular_color_img")
.image_out(RBUFS_EMISSION_SLOT, Qualifier::WRITE, GPU_RGBA16F, "rp_emission_img");
.image_array_out(RBUFS_COLOR_SLOT, Qualifier::WRITE, GPU_RGBA16F, "rp_color_img")
.image_array_out(RBUFS_VALUE_SLOT, Qualifier::WRITE, GPU_R16F, "rp_value_img")
.uniform_buf(RBUFS_BUF_SLOT, "RenderBuffersInfoData", "rp_buf");
GPU_SHADER_CREATE_INFO(eevee_cryptomatte_out)
.storage_buf(CRYPTOMATTE_BUF_SLOT, Qualifier::READ, "vec2", "cryptomatte_object_buf[]")
@ -109,22 +101,12 @@ GPU_SHADER_CREATE_INFO(eevee_surf_deferred)
* limitation of the number of images we can bind on a single shader. */
.image_array_out(GBUF_CLOSURE_SLOT, Qualifier::WRITE, GPU_RGBA16, "out_gbuff_closure_img")
.image_array_out(GBUF_COLOR_SLOT, Qualifier::WRITE, GPU_RGB10_A2, "out_gbuff_color_img")
/* Render-passes need to be declared manually to avoid overlap with the G-buffer which reuse
* some of binding points. */
.image_out(RBUFS_NORMAL_SLOT, Qualifier::WRITE, GPU_RGBA16F, "rp_normal_img")
// .image_array_out(RBUFS_LIGHT_SLOT, Qualifier::WRITE, GPU_RGBA16F, "rp_light_img")
/* TODO(fclem): Merge all render-pass into the same texture array. */
// .image_out(RBUFS_DIFF_COLOR_SLOT, Qualifier::WRITE, GPU_RGBA16F, "rp_diffuse_color_img")
.image_out(RBUFS_SPEC_COLOR_SLOT, Qualifier::WRITE, GPU_RGBA16F, "rp_specular_color_img")
.image_out(RBUFS_EMISSION_SLOT, Qualifier::WRITE, GPU_RGBA16F, "rp_emission_img")
.fragment_source("eevee_surf_deferred_frag.glsl")
.additional_info("eevee_camera",
"eevee_utility_texture",
"eevee_sampling_data",
/* Added manually to avoid overlap. */
// "eevee_render_pass_out",
"eevee_cryptomatte_out",
"eevee_aov_out");
"eevee_render_pass_out",
"eevee_cryptomatte_out");
GPU_SHADER_CREATE_INFO(eevee_surf_forward)
.vertex_out(eevee_surf_iface)
@ -140,11 +122,10 @@ GPU_SHADER_CREATE_INFO(eevee_surf_forward)
"eevee_sampling_data",
"eevee_shadow_data"
/* Optionally added depending on the material. */
// "eevee_render_pass_out",
// "eevee_cryptomatte_out",
// "eevee_raytrace_data",
// "eevee_transmittance_data",
// "eevee_aov_out",
// "eevee_render_pass_out",
);
GPU_SHADER_CREATE_INFO(eevee_surf_depth)
@ -157,9 +138,8 @@ GPU_SHADER_CREATE_INFO(eevee_surf_world)
.push_constant(Type::FLOAT, "world_opacity_fade")
.fragment_out(0, Type::VEC4, "out_background")
.fragment_source("eevee_surf_world_frag.glsl")
.additional_info("eevee_aov_out",
.additional_info("eevee_render_pass_out",
"eevee_cryptomatte_out",
"eevee_render_pass_out",
"eevee_camera",
"eevee_utility_texture");