[Bf-blender-cvs] [d20b672e01c] tmp-workbench-rewrite2: wbench next: render to image
Miguel Pozo
noreply at git.blender.org
Wed Nov 30 18:08:04 CET 2022
Commit: d20b672e01c2f7b64db3a5b43d3dda1b432bd816
Author: Miguel Pozo
Date: Tue Nov 29 20:18:25 2022 +0100
Branches: tmp-workbench-rewrite2
https://developer.blender.org/rBd20b672e01c2f7b64db3a5b43d3dda1b432bd816
wbench next: render to image
===================================================================
M release/scripts/startup/bl_ui/properties_view_layer.py
M source/blender/draw/engines/workbench/workbench_engine.cc
M source/blender/draw/engines/workbench/workbench_private.hh
M source/blender/draw/engines/workbench/workbench_state.cc
===================================================================
diff --git a/release/scripts/startup/bl_ui/properties_view_layer.py b/release/scripts/startup/bl_ui/properties_view_layer.py
index b18734ea98a..c45cafa07fa 100644
--- a/release/scripts/startup/bl_ui/properties_view_layer.py
+++ b/release/scripts/startup/bl_ui/properties_view_layer.py
@@ -44,7 +44,7 @@ class VIEWLAYER_PT_layer(ViewLayerButtonsPanel, Panel):
class VIEWLAYER_PT_layer_passes(ViewLayerButtonsPanel, Panel):
bl_label = "Passes"
- COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT'}
+ COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH_NEXT'}
def draw(self, context):
pass
@@ -94,6 +94,23 @@ class VIEWLAYER_PT_eevee_next_layer_passes_data(ViewLayerButtonsPanel, Panel):
sub.active = not scene.eevee.use_motion_blur
sub.prop(view_layer, "use_pass_vector")
+class VIEWLAYER_PT_eevee_next_layer_passes_data(ViewLayerButtonsPanel, Panel):
+ bl_label = "Data"
+ bl_parent_id = "VIEWLAYER_PT_layer_passes"
+
+ COMPAT_ENGINES = {'BLENDER_WORKBENCH_NEXT'}
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
+
+ view_layer = context.view_layer
+
+ col = layout.column()
+ col.prop(view_layer, "use_pass_combined")
+ col.prop(view_layer, "use_pass_z")
+
class VIEWLAYER_PT_eevee_layer_passes_light(ViewLayerButtonsPanel, Panel):
bl_label = "Light"
diff --git a/source/blender/draw/engines/workbench/workbench_engine.cc b/source/blender/draw/engines/workbench/workbench_engine.cc
index 0a3d89f37f0..483664b3f66 100644
--- a/source/blender/draw/engines/workbench/workbench_engine.cc
+++ b/source/blender/draw/engines/workbench/workbench_engine.cc
@@ -6,6 +6,7 @@
#include "BKE_paint.h"
#include "BKE_particle.h"
#include "BKE_pbvh.h"
+#include "BKE_report.h"
#include "DEG_depsgraph_query.h"
#include "DNA_fluid_types.h"
#include "ED_paint.h"
@@ -34,9 +35,9 @@ class Instance {
DofPass dof_ps;
AntiAliasingPass anti_aliasing_ps;
- void init()
+ void init(Object *camera_ob = nullptr)
{
- scene_state.init();
+ scene_state.init(camera_ob);
resources.init(scene_state);
outline_ps.init(scene_state);
@@ -462,19 +463,201 @@ static void workbench_id_update(void *vedata, struct ID *id)
UNUSED_VARS(vedata, id);
}
+/* RENDER */
+
+static bool workbench_render_framebuffers_init(void)
+{
+ /* For image render, allocate own buffers because we don't have a viewport. */
+ const float2 viewport_size = DRW_viewport_size_get();
+ const int2 size = {int(viewport_size.x), int(viewport_size.y)};
+
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+
+ /* When doing a multi view rendering the first view will allocate the buffers
+ * the other views will reuse these buffers */
+ if (dtxl->color == nullptr) {
+ BLI_assert(dtxl->depth == nullptr);
+ dtxl->color = GPU_texture_create_2d("txl.color", size.x, size.y, 1, GPU_RGBA16F, nullptr);
+ dtxl->depth = GPU_texture_create_2d(
+ "txl.depth", size.x, size.y, 1, GPU_DEPTH24_STENCIL8, nullptr);
+ }
+
+ if (!(dtxl->depth && dtxl->color)) {
+ return false;
+ }
+
+ DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+
+ GPU_framebuffer_ensure_config(
+ &dfbl->default_fb,
+ {GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_TEXTURE(dtxl->color)});
+
+ GPU_framebuffer_ensure_config(&dfbl->depth_only_fb,
+ {GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_NONE});
+
+ GPU_framebuffer_ensure_config(&dfbl->color_only_fb,
+ {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(dtxl->color)});
+
+ return GPU_framebuffer_check_valid(dfbl->default_fb, nullptr) &&
+ GPU_framebuffer_check_valid(dfbl->color_only_fb, nullptr) &&
+ GPU_framebuffer_check_valid(dfbl->depth_only_fb, nullptr);
+}
+
+#ifdef DEBUG
+/* This is just to ease GPU debugging when the frame delimiter is set to Finish */
+# define GPU_FINISH_DELIMITER() GPU_finish()
+#else
+# define GPU_FINISH_DELIMITER()
+#endif
+
static void workbench_render_to_image(void *vedata,
struct RenderEngine *engine,
struct RenderLayer *layer,
- const struct rcti *UNUSED(rect))
+ const struct rcti *rect)
{
- UNUSED_VARS(vedata, engine, layer);
+ /* TODO(fclem): Remove once it is minimum required. */
+ if (!GPU_shader_storage_buffer_objects_support()) {
+ return;
+ }
+
+ if (!workbench_render_framebuffers_init()) {
+ RE_engine_report(engine, RPT_ERROR, "Failed to allocate GPU buffers");
+ return;
+ }
+
+ GPU_FINISH_DELIMITER();
+
+ /* Setup */
+
+ DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ Depsgraph *depsgraph = draw_ctx->depsgraph;
+
+ WORKBENCH_Data *ved = reinterpret_cast<WORKBENCH_Data *>(vedata);
+ if (ved->instance == nullptr) {
+ ved->instance = new workbench::Instance();
+ }
+
+ /* TODO(sergey): Shall render hold pointer to an evaluated camera instead? */
+ Object *camera_ob = DEG_get_evaluated_object(depsgraph, RE_GetCamera(engine->re));
+
+ /* Set the perspective, view and window matrix. */
+ float4x4 winmat, viewmat, viewinv;
+ RE_GetCameraWindow(engine->re, camera_ob, winmat.ptr());
+ RE_GetCameraModelMatrix(engine->re, camera_ob, viewinv.ptr());
+ viewmat = viewinv.inverted();
+
+ DRWView *view = DRW_view_create(viewmat.ptr(), winmat.ptr(), nullptr, nullptr, nullptr);
+ DRW_view_default_set(view);
+ DRW_view_set_active(view);
+
+ /* Render */
+ do {
+ if (RE_engine_test_break(engine)) {
+ break;
+ }
+
+ ved->instance->init(camera_ob);
+
+ DRW_manager_get()->begin_sync();
+
+ workbench_cache_init(vedata);
+ auto workbench_render_cache = [](void *vedata,
+ struct Object *ob,
+ struct RenderEngine *UNUSED(engine),
+ struct Depsgraph *UNUSED(depsgraph)) {
+ workbench_cache_populate(vedata, ob);
+ };
+ DRW_render_object_iter(vedata, engine, depsgraph, workbench_render_cache);
+ workbench_cache_finish(vedata);
+
+ DRW_manager_get()->end_sync();
+
+ /* Also we weed to have a correct FBO bound for #DRW_curves_update */
+ // GPU_framebuffer_bind(dfbl->default_fb);
+ // DRW_curves_update(); /* TODO(Miguel Pozo): Check this once curves are implemented */
+
+ workbench_draw_scene(vedata);
+
+ /* Perform render step between samples to allow
+ * flushing of freed GPUBackend resources. */
+ GPU_render_step();
+ GPU_FINISH_DELIMITER();
+ } while (ved->instance->scene_state.sample + 1 < ved->instance->scene_state.samples_len);
+
+ const char *viewname = RE_GetActiveRenderView(engine->re);
+ /* Write render output. */
+ {
+ RenderPass *rp = RE_pass_find_by_name(layer, RE_PASSNAME_COMBINED, viewname);
+ if (rp) {
+ GPU_framebuffer_bind(dfbl->default_fb);
+ GPU_framebuffer_read_color(dfbl->default_fb,
+ rect->xmin,
+ rect->ymin,
+ BLI_rcti_size_x(rect),
+ BLI_rcti_size_y(rect),
+ 4,
+ 0,
+ GPU_DATA_FLOAT,
+ rp->rect);
+ }
+ }
+ /* Write render Z output */
+ {
+ RenderPass *rp = RE_pass_find_by_name(layer, RE_PASSNAME_Z, viewname);
+ if (rp) {
+ GPU_framebuffer_bind(dfbl->default_fb);
+ GPU_framebuffer_read_depth(dfbl->default_fb,
+ rect->xmin,
+ rect->ymin,
+ BLI_rcti_size_x(rect),
+ BLI_rcti_size_y(rect),
+ GPU_DATA_FLOAT,
+ rp->rect);
+
+ int pix_num = BLI_rcti_size_x(rect) * BLI_rcti_size_y(rect);
+
+ /* Convert ogl depth [0..1] to view Z [near..far] */
+ if (DRW_view_is_persp_get(nullptr)) {
+ for (float &z : MutableSpan(rp->rect, pix_num)) {
+ if (z == 1.0f) {
+ z = 1e10f; /* Background */
+ }
+ else {
+ z = z * 2.0f - 1.0f;
+ z = winmat[3][2] / (z + winmat[2][2]);
+ }
+ }
+ }
+ else {
+ /* Keep in mind, near and far distance are negatives. */
+ float near = DRW_view_near_distance_get(nullptr);
+ float far = DRW_view_far_distance_get(nullptr);
+ float range = fabsf(far - near);
+
+ for (float &z : MutableSpan(rp->rect, pix_num)) {
+ if (z == 1.0f) {
+ z = 1e10f; /* Background */
+ }
+ else {
+ z = z * range - near;
+ }
+ }
+ }
+ }
+ }
}
static void workbench_render_update_passes(RenderEngine *engine,
Scene *scene,
ViewLayer *view_layer)
{
- RE_engine_register_pass(engine, scene, view_layer, RE_PASSNAME_COMBINED, 4, "RGBA", SOCK_RGBA);
+ if (view_layer->passflag & SCE_PASS_COMBINED) {
+ RE_engine_register_pass(engine, scene, view_layer, RE_PASSNAME_COMBINED, 4, "RGBA", SOCK_RGBA);
+ }
+ if (view_layer->passflag & SCE_PASS_Z) {
+ RE_engine_register_pass(engine, scene, view_layer, RE_PASSNAME_Z, 1, "Z", SOCK_FLOAT);
+ }
}
extern "C" {
diff --git a/source/blender/draw/engines/workbench/workbench_private.hh b/source/blender/draw/engines/workbench/workbench_private.hh
index fca61f2ec59..58451e92ab9 100644
--- a/source/blender/draw/engines/workbench/workbench_private.hh
+++ b/source/blender/draw/engines/workbench/workbench_private.hh
@@ -94,7 +94,7 @@ struct SceneState {
/* When r == -1.0 the shader uses the vertex color */
Material material_attribute_color = Material(float3(-1.0f));
- void init();
+ void init(Object *camera_ob = nullptr);
};
struct ObjectState {
diff
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list