Blender  V2.93
workbench_render.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * Copyright 2016, Blender Foundation.
17  */
18 
25 #include "BLI_rect.h"
26 
27 #include "DNA_node_types.h"
28 
29 #include "BKE_report.h"
30 
31 #include "DRW_render.h"
32 
33 #include "ED_view3d.h"
34 
35 #include "GPU_shader.h"
36 
37 #include "DEG_depsgraph.h"
38 #include "DEG_depsgraph_query.h"
39 
40 #include "RE_pipeline.h"
41 
42 #include "workbench_private.h"
43 
44 static void workbench_render_cache(void *vedata,
45  struct Object *ob,
46  struct RenderEngine *UNUSED(engine),
47  struct Depsgraph *UNUSED(depsgraph))
48 {
49  workbench_cache_populate(vedata, ob);
50 }
51 
53 {
54  /* TODO(sergey): Shall render hold pointer to an evaluated camera instead? */
55  struct Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, RE_GetCamera(engine->re));
56 
57  /* Set the perspective, view and window matrix. */
58  float winmat[4][4], viewmat[4][4], viewinv[4][4];
59 
60  RE_GetCameraWindow(engine->re, ob_camera_eval, winmat);
61  RE_GetCameraModelMatrix(engine->re, ob_camera_eval, viewinv);
62 
63  invert_m4_m4(viewmat, viewinv);
64 
65  DRWView *view = DRW_view_create(viewmat, winmat, NULL, NULL, NULL);
68 }
69 
71 {
72  /* For image render, allocate own buffers because we don't have a viewport. */
73  const float *viewport_size = DRW_viewport_size_get();
74  const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
75 
77 
78  /* When doing a multi view rendering the first view will allocate the buffers
79  * the other views will reuse these buffers */
80  if (dtxl->color == NULL) {
81  BLI_assert(dtxl->depth == NULL);
82  dtxl->color = GPU_texture_create_2d("txl.color", UNPACK2(size), 1, GPU_RGBA16F, NULL);
84  }
85 
86  if (!(dtxl->depth && dtxl->color)) {
87  return false;
88  }
89 
91 
92  GPU_framebuffer_ensure_config(
93  &dfbl->default_fb,
94  {GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_TEXTURE(dtxl->color)});
95 
96  GPU_framebuffer_ensure_config(&dfbl->depth_only_fb,
97  {GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_NONE});
98 
99  GPU_framebuffer_ensure_config(&dfbl->color_only_fb,
100  {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(dtxl->color)});
101 
102  bool ok = true;
103  ok = ok && GPU_framebuffer_check_valid(dfbl->default_fb, NULL);
106 
107  return ok;
108 }
109 
110 static void workbench_render_result_z(struct RenderLayer *rl,
111  const char *viewname,
112  const rcti *rect)
113 {
115  const DRWContextState *draw_ctx = DRW_context_state_get();
116  ViewLayer *view_layer = draw_ctx->view_layer;
117 
118  if ((view_layer->passflag & SCE_PASS_Z) != 0) {
119  RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_Z, viewname);
120 
123  rect->xmin,
124  rect->ymin,
125  BLI_rcti_size_x(rect),
126  BLI_rcti_size_y(rect),
128  rp->rect);
129 
130  float winmat[4][4];
131  DRW_view_winmat_get(NULL, winmat, false);
132 
133  int pix_ct = BLI_rcti_size_x(rect) * BLI_rcti_size_y(rect);
134 
135  /* Convert ogl depth [0..1] to view Z [near..far] */
137  for (int i = 0; i < pix_ct; i++) {
138  if (rp->rect[i] == 1.0f) {
139  rp->rect[i] = 1e10f; /* Background */
140  }
141  else {
142  rp->rect[i] = rp->rect[i] * 2.0f - 1.0f;
143  rp->rect[i] = winmat[3][2] / (rp->rect[i] + winmat[2][2]);
144  }
145  }
146  }
147  else {
148  /* Keep in mind, near and far distance are negatives. */
149  float near = DRW_view_near_distance_get(NULL);
150  float far = DRW_view_far_distance_get(NULL);
151  float range = fabsf(far - near);
152 
153  for (int i = 0; i < pix_ct; i++) {
154  if (rp->rect[i] == 1.0f) {
155  rp->rect[i] = 1e10f; /* Background */
156  }
157  else {
158  rp->rect[i] = rp->rect[i] * range - near;
159  }
160  }
161  }
162  }
163 }
164 
165 void workbench_render(void *ved, RenderEngine *engine, RenderLayer *render_layer, const rcti *rect)
166 {
167  WORKBENCH_Data *data = ved;
169  const DRWContextState *draw_ctx = DRW_context_state_get();
170  Depsgraph *depsgraph = draw_ctx->depsgraph;
172 
174  RE_engine_report(engine, RPT_ERROR, "Failed to allocate OpenGL buffers");
175  return;
176  }
177 
179  data->stl->wpd->cam_original_ob = DEG_get_evaluated_object(depsgraph, RE_GetCamera(engine->re));
181 
185 
187 
188  /* Also we weed to have a correct fbo bound for DRW_hair_update */
190  DRW_hair_update();
191 
193  GPU_framebuffer_clear_depth(dfbl->default_fb, 1.0f);
194 
195  WORKBENCH_PrivateData *wpd = data->stl->wpd;
196  while (wpd->taa_sample < max_ii(1, wpd->taa_sample_len)) {
197  if (RE_engine_test_break(engine)) {
198  break;
199  }
202  }
203 
205 
206  /* Write render output. */
207  const char *viewname = RE_GetActiveRenderView(engine->re);
208  RenderPass *rp = RE_pass_find_by_name(render_layer, RE_PASSNAME_COMBINED, viewname);
209 
212  rect->xmin,
213  rect->ymin,
214  BLI_rcti_size_x(rect),
215  BLI_rcti_size_y(rect),
216  4,
217  0,
219  rp->rect);
220 
221  workbench_render_result_z(render_layer, viewname, rect);
222 }
223 
225 {
226  RE_engine_register_pass(engine, scene, view_layer, RE_PASSNAME_COMBINED, 4, "RGBA", SOCK_RGBA);
227 }
#define BLI_assert(a)
Definition: BLI_assert.h:58
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:1278
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition: BLI_rect.h:157
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition: BLI_rect.h:153
#define UNPACK2(a)
#define UNUSED(x)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
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
bool GPU_framebuffer_check_valid(GPUFrameBuffer *fb, char err_out[256])
void GPU_framebuffer_bind(GPUFrameBuffer *fb)
@ GPU_DATA_FLOAT
Definition: GPU_texture.h:172
GPUTexture * GPU_texture_create_2d(const char *name, int w, int h, int mip_len, eGPUTextureFormat format, const float *data)
Definition: gpu_texture.cc:250
@ GPU_DEPTH24_STENCIL8
Definition: GPU_texture.h:121
@ GPU_RGBA16F
Definition: GPU_texture.h:94
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
Scene scene
const Depsgraph * depsgraph
void DRW_hair_update(void)
Definition: draw_hair.c:300
DefaultFramebufferList * DRW_viewport_framebuffer_list_get(void)
Definition: draw_manager.c:697
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:439
DefaultTextureList * DRW_viewport_texture_list_get(void)
Definition: draw_manager.c:702
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(DRWView *view)
void DRW_view_set_active(DRWView *view)
void RE_engine_report(RenderEngine *engine, int type, const char *msg)
Definition: engine.c:495
bool RE_engine_test_break(RenderEngine *engine)
Definition: engine.c:435
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:1092
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_GetCameraWindow(struct Render *re, struct Object *camera, float r_winmat[4][4])
Definition: initrender.c:205
void RE_GetCameraModelMatrix(Render *re, struct Object *camera, float r_modelmat[4][4])
Definition: initrender.c:230
struct Object * RE_GetCamera(Render *re)
Definition: initrender.c:169
#define fabsf(x)
RenderPass * RE_pass_find_by_name(volatile RenderLayer *rl, const char *name, const char *viewname)
Definition: pipeline.c:2764
const char * RE_GetActiveRenderView(Render *re)
Definition: pipeline.c:1746
struct Depsgraph * depsgraph
Definition: DRW_render.h:753
struct ViewLayer * view_layer
Definition: DRW_render.h:746
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:136
float * rect
Definition: RE_pipeline.h:82
int ymin
Definition: DNA_vec_types.h:80
int xmin
Definition: DNA_vec_types.h:79
void workbench_private_data_alloc(WORKBENCH_StorageList *stl)
void workbench_update_world_ubo(WORKBENCH_PrivateData *wpd)
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)
void workbench_draw_finish(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)