Blender  V3.3
workbench_render.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2016 Blender Foundation. */
3 
10 #include "BLI_rect.h"
11 
12 #include "DNA_node_types.h"
13 
14 #include "BKE_report.h"
15 
16 #include "DRW_render.h"
17 
18 #include "ED_view3d.h"
19 
20 #include "GPU_context.h"
21 #include "GPU_shader.h"
22 
23 #include "DEG_depsgraph.h"
24 #include "DEG_depsgraph_query.h"
25 
26 #include "RE_pipeline.h"
27 
28 #include "workbench_private.h"
29 
30 static void workbench_render_cache(void *vedata,
31  struct Object *ob,
32  struct RenderEngine *UNUSED(engine),
33  struct Depsgraph *UNUSED(depsgraph))
34 {
35  workbench_cache_populate(vedata, ob);
36 }
37 
39 {
40  /* TODO(sergey): Shall render hold pointer to an evaluated camera instead? */
41  struct Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, RE_GetCamera(engine->re));
42 
43  /* Set the perspective, view and window matrix. */
44  float winmat[4][4], viewmat[4][4], viewinv[4][4];
45 
46  RE_GetCameraWindow(engine->re, ob_camera_eval, winmat);
47  RE_GetCameraModelMatrix(engine->re, ob_camera_eval, viewinv);
48 
49  invert_m4_m4(viewmat, viewinv);
50 
51  DRWView *view = DRW_view_create(viewmat, winmat, NULL, NULL, NULL);
54 }
55 
57 {
58  /* For image render, allocate own buffers because we don't have a viewport. */
59  const float *viewport_size = DRW_viewport_size_get();
60  const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
61 
63 
64  /* When doing a multi view rendering the first view will allocate the buffers
65  * the other views will reuse these buffers */
66  if (dtxl->color == NULL) {
67  BLI_assert(dtxl->depth == NULL);
68  dtxl->color = GPU_texture_create_2d("txl.color", UNPACK2(size), 1, GPU_RGBA16F, NULL);
70  }
71 
72  if (!(dtxl->depth && dtxl->color)) {
73  return false;
74  }
75 
77 
78  GPU_framebuffer_ensure_config(
79  &dfbl->default_fb,
80  {GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_TEXTURE(dtxl->color)});
81 
82  GPU_framebuffer_ensure_config(&dfbl->depth_only_fb,
83  {GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_NONE});
84 
85  GPU_framebuffer_ensure_config(&dfbl->color_only_fb,
86  {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(dtxl->color)});
87 
88  bool ok = true;
89  ok = ok && GPU_framebuffer_check_valid(dfbl->default_fb, NULL);
92 
93  return ok;
94 }
95 
96 static void workbench_render_result_z(struct RenderLayer *rl,
97  const char *viewname,
98  const rcti *rect)
99 {
101  const DRWContextState *draw_ctx = DRW_context_state_get();
102  ViewLayer *view_layer = draw_ctx->view_layer;
103 
104  if ((view_layer->passflag & SCE_PASS_Z) != 0) {
105  RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_Z, viewname);
106 
109  rect->xmin,
110  rect->ymin,
111  BLI_rcti_size_x(rect),
112  BLI_rcti_size_y(rect),
114  rp->rect);
115 
116  float winmat[4][4];
117  DRW_view_winmat_get(NULL, winmat, false);
118 
119  int pix_num = BLI_rcti_size_x(rect) * BLI_rcti_size_y(rect);
120 
121  /* Convert ogl depth [0..1] to view Z [near..far] */
123  for (int i = 0; i < pix_num; i++) {
124  if (rp->rect[i] == 1.0f) {
125  rp->rect[i] = 1e10f; /* Background */
126  }
127  else {
128  rp->rect[i] = rp->rect[i] * 2.0f - 1.0f;
129  rp->rect[i] = winmat[3][2] / (rp->rect[i] + winmat[2][2]);
130  }
131  }
132  }
133  else {
134  /* Keep in mind, near and far distance are negatives. */
135  float near = DRW_view_near_distance_get(NULL);
136  float far = DRW_view_far_distance_get(NULL);
137  float range = fabsf(far - near);
138 
139  for (int i = 0; i < pix_num; i++) {
140  if (rp->rect[i] == 1.0f) {
141  rp->rect[i] = 1e10f; /* Background */
142  }
143  else {
144  rp->rect[i] = rp->rect[i] * range - near;
145  }
146  }
147  }
148  }
149 }
150 
151 void workbench_render(void *ved, RenderEngine *engine, RenderLayer *render_layer, const rcti *rect)
152 {
153  WORKBENCH_Data *data = ved;
155  const DRWContextState *draw_ctx = DRW_context_state_get();
156  Depsgraph *depsgraph = draw_ctx->depsgraph;
158 
160  RE_engine_report(engine, RPT_ERROR, "Failed to allocate OpenGL buffers");
161  return;
162  }
163 
165  data->stl->wpd->cam_original_ob = DEG_get_evaluated_object(depsgraph, RE_GetCamera(engine->re));
167 
171 
173 
174  /* Also we weed to have a correct FBO bound for #DRW_curves_update */
177 
179  GPU_framebuffer_clear_depth(dfbl->default_fb, 1.0f);
180 
181  WORKBENCH_PrivateData *wpd = data->stl->wpd;
182  while (wpd->taa_sample < max_ii(1, wpd->taa_sample_len)) {
183  if (RE_engine_test_break(engine)) {
184  break;
185  }
188  }
189 
191 
192  /* Perform render step between samples to allow
193  * flushing of freed GPUBackend resources. */
194  GPU_render_step();
195 
196  /* Write render output. */
197  const char *viewname = RE_GetActiveRenderView(engine->re);
198  RenderPass *rp = RE_pass_find_by_name(render_layer, RE_PASSNAME_COMBINED, viewname);
199 
202  rect->xmin,
203  rect->ymin,
204  BLI_rcti_size_x(rect),
205  BLI_rcti_size_y(rect),
206  4,
207  0,
209  rp->rect);
210 
211  workbench_render_result_z(render_layer, viewname, rect);
212 }
213 
215 {
216  RE_engine_register_pass(engine, scene, view_layer, RE_PASSNAME_COMBINED, 4, "RGBA", SOCK_RGBA);
217 }
#define BLI_assert(a)
Definition: BLI_assert.h:46
MINLINE int max_ii(int a, int b)
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1287
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition: BLI_rect.h:190
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition: BLI_rect.h:186
#define UNPACK2(a)
#define UNUSED(x)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
struct Object * DEG_get_evaluated_object(const struct Depsgraph *depsgraph, struct Object *object)
@ SOCK_RGBA
#define RE_PASSNAME_COMBINED
#define RE_PASSNAME_Z
@ SCE_PASS_Z
static AppView * view
void GPU_render_step(void)
Definition: gpu_context.cc:202
bool GPU_framebuffer_check_valid(GPUFrameBuffer *fb, char err_out[256])
void GPU_framebuffer_bind(GPUFrameBuffer *fb)
@ GPU_DATA_FLOAT
Definition: GPU_texture.h:171
GPUTexture * GPU_texture_create_2d(const char *name, int w, int h, int mip_len, eGPUTextureFormat format, const float *data)
Definition: gpu_texture.cc:291
@ GPU_DEPTH24_STENCIL8
Definition: GPU_texture.h:120
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
Scene scene
const Depsgraph * depsgraph
void DRW_curves_update(void)
Definition: draw_curves.cc:414
DefaultFramebufferList * DRW_viewport_framebuffer_list_get(void)
Definition: draw_manager.c:633
void DRW_render_instance_buffer_finish(void)
const DRWContextState * DRW_context_state_get(void)
const float * DRW_viewport_size_get(void)
Definition: draw_manager.c:288
DefaultTextureList * DRW_viewport_texture_list_get(void)
Definition: draw_manager.c:638
void DRW_render_object_iter(void *vedata, RenderEngine *engine, struct Depsgraph *depsgraph, void(*callback)(void *vedata, Object *ob, RenderEngine *engine, struct Depsgraph *depsgraph))
float DRW_view_near_distance_get(const DRWView *view)
bool DRW_view_is_persp_get(const DRWView *view)
void DRW_view_winmat_get(const DRWView *view, float mat[4][4], bool inverse)
DRWView * DRW_view_create(const float viewmat[4][4], const float winmat[4][4], const float(*culling_viewmat)[4], const float(*culling_winmat)[4], DRWCallVisibilityFn *visibility_fn)
float DRW_view_far_distance_get(const DRWView *view)
void DRW_view_default_set(const DRWView *view)
void DRW_view_set_active(const DRWView *view)
depth_tx normal_tx diffuse_light_tx specular_light_tx volume_light_tx environment_tx ambient_occlusion_tx aov_value_tx in_weight_img GPU_RGBA16F
void RE_engine_report(RenderEngine *engine, int type, const char *msg)
Definition: engine.c:548
bool RE_engine_test_break(RenderEngine *engine)
Definition: engine.c:488
void RE_engine_register_pass(struct RenderEngine *engine, struct Scene *scene, struct ViewLayer *view_layer, const char *name, int channels, const char *chanid, eNodeSocketDatatype type)
Definition: engine.c:1171
void GPU_framebuffer_read_color(GPUFrameBuffer *gpu_fb, int x, int y, int w, int h, int channels, int slot, eGPUDataFormat format, void *data)
void GPU_framebuffer_read_depth(GPUFrameBuffer *gpu_fb, int x, int y, int w, int h, eGPUDataFormat format, void *data)
void RE_GetCameraModelMatrix(const Render *re, const struct Object *camera, float r_modelmat[4][4])
Definition: initrender.c:205
struct Object * RE_GetCamera(Render *re)
Definition: initrender.c:150
void RE_GetCameraWindow(struct Render *re, const struct Object *camera, float r_winmat[4][4])
Definition: initrender.c:181
#define fabsf(x)
Definition: metal/compat.h:219
RenderPass * RE_pass_find_by_name(RenderLayer *rl, const char *name, const char *viewname)
Definition: pipeline.c:2591
const char * RE_GetActiveRenderView(Render *re)
Definition: pipeline.c:1671
struct Depsgraph * depsgraph
Definition: DRW_render.h:987
struct ViewLayer * view_layer
Definition: DRW_render.h:980
struct GPUFrameBuffer * depth_only_fb
struct GPUFrameBuffer * default_fb
struct GPUFrameBuffer * color_only_fb
struct GPUTexture * depth
struct GPUTexture * color
struct Render * re
Definition: RE_engine.h:135
float * rect
Definition: RE_pipeline.h:67
int ymin
Definition: DNA_vec_types.h:64
int xmin
Definition: DNA_vec_types.h:63
void workbench_private_data_alloc(WORKBENCH_StorageList *stl)
void workbench_update_world_ubo(WORKBENCH_PrivateData *wpd)
void workbench_draw_finish(void *UNUSED(ved))
void workbench_cache_populate(void *ved, Object *ob)
void workbench_cache_init(void *ved)
void workbench_engine_init(void *ved)
void workbench_cache_finish(void *ved)
void workbench_draw_sample(void *ved)
static bool workbench_render_framebuffers_init(void)
void workbench_render(void *ved, RenderEngine *engine, RenderLayer *render_layer, const rcti *rect)
static void workbench_render_cache(void *vedata, struct Object *ob, struct RenderEngine *UNUSED(engine), struct Depsgraph *UNUSED(depsgraph))
static void workbench_render_result_z(struct RenderLayer *rl, const char *viewname, const rcti *rect)
static void workbench_render_matrices_init(RenderEngine *engine, Depsgraph *depsgraph)
void workbench_render_update_passes(RenderEngine *engine, Scene *scene, ViewLayer *view_layer)