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:
parent
d3d91b79e0
commit
960b53dbbb
|
@ -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. */
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 :
|
||||
|
|
|
@ -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_);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 ----- */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
Loading…
Reference in New Issue