Compositor: add passes for non-viewport realtime compositor #108808

Merged
Brecht Van Lommel merged 1 commits from brecht/blender:realtime-render-comp-passes into main 2023-06-09 16:21:47 +02:00
2 changed files with 37 additions and 49 deletions

View File

@ -10,7 +10,19 @@ GPU_SHADER_CREATE_INFO(compositor_read_pass_shared)
.sampler(0, ImageType::FLOAT_2D, "input_tx")
.compute_source("compositor_read_pass.glsl");
GPU_SHADER_CREATE_INFO(compositor_read_pass)
GPU_SHADER_CREATE_INFO(compositor_read_pass_float)
.additional_info("compositor_read_pass_shared")
.image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
.define("READ_EXPRESSION(pass_color)", "vec4(pass_color.r, vec3(0.0))")
.do_static_compilation(true);
GPU_SHADER_CREATE_INFO(compositor_read_pass_vector)
.additional_info("compositor_read_pass_shared")
.image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
.define("READ_EXPRESSION(pass_color)", "pass_color")
.do_static_compilation(true);
GPU_SHADER_CREATE_INFO(compositor_read_pass_color)
.additional_info("compositor_read_pass_shared")
.image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
.define("READ_EXPRESSION(pass_color)", "pass_color")

View File

@ -825,36 +825,47 @@ class RenderLayerOperation : public NodeOperation {
void execute() override
{
const int view_layer = bnode().custom1;
GPUTexture *pass_texture = context().get_input_texture(view_layer, RE_PASSNAME_COMBINED);
GPUTexture *combined_texture = context().get_input_texture(view_layer, RE_PASSNAME_COMBINED);
execute_image(pass_texture);
execute_alpha(pass_texture);
execute_pass("Image", combined_texture, "compositor_read_pass_color");
execute_pass("Alpha", combined_texture, "compositor_read_pass_alpha");
/* Other output passes are not supported for now, so allocate them as invalid. */
for (const bNodeSocket *output : this->node()->output_sockets()) {
if (!STR_ELEM(output->identifier, "Image", "Alpha")) {
Result &unsupported_result = get_result(output->identifier);
if (unsupported_result.should_compute()) {
unsupported_result.allocate_invalid();
context().set_info_message("Viewport compositor setup not fully supported");
}
if (STR_ELEM(output->identifier, "Image", "Alpha")) {
continue;
}
GPUTexture *pass_texture = context().get_input_texture(view_layer, output->identifier);
if (output->type == SOCK_FLOAT) {
execute_pass(output->identifier, pass_texture, "compositor_read_pass_float");
}
else if (output->type == SOCK_VECTOR) {
execute_pass(output->identifier, pass_texture, "compositor_read_pass_vector");
}
else if (output->type == SOCK_RGBA) {
execute_pass(output->identifier, pass_texture, "compositor_read_pass_color");
}
else {
BLI_assert_unreachable();
}
}
}
void execute_image(GPUTexture *pass_texture)
void execute_pass(const char *pass_name, GPUTexture *pass_texture, const char *shader_name)
{
Result &image_result = get_result("Image");
Result &image_result = get_result(pass_name);
if (!image_result.should_compute()) {
return;
}
if (pass_texture == nullptr) {
/* Pass not rendered (yet). */
/* Pass not rendered yet, or not supported by viewport. */
image_result.allocate_invalid();
context().set_info_message("Viewport compositor setup not fully supported");
return;
}
GPUShader *shader = shader_manager().get("compositor_read_pass");
GPUShader *shader = shader_manager().get(shader_name);
GPU_shader_bind(shader);
/* The compositing space might be limited to a subset of the pass texture, so only read that
@ -876,41 +887,6 @@ class RenderLayerOperation : public NodeOperation {
GPU_texture_unbind(pass_texture);
image_result.unbind_as_image();
}
void execute_alpha(GPUTexture *pass_texture)
{
Result &alpha_result = get_result("Alpha");
if (!alpha_result.should_compute()) {
return;
}
if (pass_texture == nullptr) {
/* Pass not rendered (yet). */
alpha_result.allocate_invalid();
return;
}
GPUShader *shader = shader_manager().get("compositor_read_pass_alpha");
GPU_shader_bind(shader);
/* The compositing space might be limited to a subset of the pass texture, so only read that
* compositing region into an appropriately sized texture. */
const rcti compositing_region = context().get_compositing_region();
const int2 lower_bound = int2(compositing_region.xmin, compositing_region.ymin);
GPU_shader_uniform_2iv(shader, "compositing_region_lower_bound", lower_bound);
const int input_unit = GPU_shader_get_sampler_binding(shader, "input_tx");
GPU_texture_bind(pass_texture, input_unit);
const int2 compositing_region_size = context().get_compositing_region_size();
alpha_result.allocate_texture(Domain(compositing_region_size));
alpha_result.bind_as_image(shader, "output_img");
compute_dispatch_threads_at_least(shader, compositing_region_size);
GPU_shader_unbind();
GPU_texture_unbind(pass_texture);
alpha_result.unbind_as_image();
}
};
static NodeOperation *get_compositor_operation(Context &context, DNode node)