Blender  V3.3
gpencil_render.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2017 Blender Foundation. */
3 
7 #include "BLI_rect.h"
8 
9 #include "DRW_render.h"
10 
11 #include "BKE_object.h"
12 
13 #include "DNA_gpencil_types.h"
14 
15 #include "DEG_depsgraph_query.h"
16 
17 #include "RE_pipeline.h"
18 
19 #include "gpencil_engine.h"
20 
22  RenderEngine *engine,
23  struct RenderLayer *render_layer,
24  const Depsgraph *depsgraph,
25  const rcti *rect)
26 {
27  GPENCIL_FramebufferList *fbl = vedata->fbl;
28  GPENCIL_TextureList *txl = vedata->txl;
29 
31  const float *viewport_size = DRW_viewport_size_get();
32  const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
33 
34  /* Set the perspective & view matrix. */
35  float winmat[4][4], viewmat[4][4], viewinv[4][4];
36 
38  RE_GetCameraWindow(engine->re, camera, winmat);
39  RE_GetCameraModelMatrix(engine->re, camera, viewinv);
40 
41  invert_m4_m4(viewmat, viewinv);
42 
43  DRWView *view = DRW_view_create(viewmat, winmat, NULL, NULL, NULL);
46 
47  /* Create depth texture & color texture from render result. */
48  const char *viewname = RE_GetActiveRenderView(engine->re);
49  RenderPass *rpass_z_src = RE_pass_find_by_name(render_layer, RE_PASSNAME_Z, viewname);
50  RenderPass *rpass_col_src = RE_pass_find_by_name(render_layer, RE_PASSNAME_COMBINED, viewname);
51 
52  float *pix_z = (rpass_z_src) ? rpass_z_src->rect : NULL;
53  float *pix_col = (rpass_col_src) ? rpass_col_src->rect : NULL;
54 
55  if (!pix_z || !pix_col) {
57  "Warning: To render grease pencil, enable Combined and Z passes.");
58  }
59 
60  if (pix_z) {
61  /* Depth need to be remapped to [0..1] range. */
62  pix_z = MEM_dupallocN(pix_z);
63 
64  int pix_num = rpass_z_src->rectx * rpass_z_src->recty;
65 
67  for (int i = 0; i < pix_num; i++) {
68  pix_z[i] = (-winmat[3][2] / -pix_z[i]) - winmat[2][2];
69  pix_z[i] = clamp_f(pix_z[i] * 0.5f + 0.5f, 0.0f, 1.0f);
70  }
71  }
72  else {
73  /* Keep in mind, near and far distance are negatives. */
74  float near = DRW_view_near_distance_get(view);
75  float far = DRW_view_far_distance_get(view);
76  float range_inv = 1.0f / fabsf(far - near);
77  for (int i = 0; i < pix_num; i++) {
78  pix_z[i] = (pix_z[i] + near) * range_inv;
79  pix_z[i] = clamp_f(pix_z[i], 0.0f, 1.0f);
80  }
81  }
82  }
83 
84  const bool do_region = (scene->r.mode & R_BORDER) != 0;
85  const bool do_clear_z = !pix_z || do_region;
86  const bool do_clear_col = !pix_col || do_region;
87 
88  /* FIXME(fclem): we have a precision loss in the depth buffer because of this re-upload.
89  * Find where it comes from! */
90  /* In multi view render the textures can be reused. */
91  if (txl->render_depth_tx && !do_clear_z) {
93  }
94  else {
96  size[0], size[1], GPU_DEPTH_COMPONENT24, 0, do_region ? NULL : pix_z);
97  }
98  if (txl->render_color_tx && !do_clear_col) {
100  }
101  else {
103  size[0], size[1], GPU_RGBA16F, 0, do_region ? NULL : pix_col);
104  }
105 
106  GPU_framebuffer_ensure_config(&fbl->render_fb,
107  {
108  GPU_ATTACHMENT_TEXTURE(txl->render_depth_tx),
109  GPU_ATTACHMENT_TEXTURE(txl->render_color_tx),
110  });
111 
112  if (do_clear_z || do_clear_col) {
113  /* To avoid unpredictable result, clear buffers that have not be initialized. */
115  if (do_clear_col) {
116  const float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
117  GPU_framebuffer_clear_color(fbl->render_fb, clear_col);
118  }
119  if (do_clear_z) {
120  GPU_framebuffer_clear_depth(fbl->render_fb, 1.0f);
121  }
122  }
123 
124  if (do_region) {
125  int x = rect->xmin;
126  int y = rect->ymin;
127  int w = BLI_rcti_size_x(rect);
128  int h = BLI_rcti_size_y(rect);
129  if (pix_col) {
130  GPU_texture_update_sub(txl->render_color_tx, GPU_DATA_FLOAT, pix_col, x, y, 0, w, h, 0);
131  }
132  if (pix_z) {
133  GPU_texture_update_sub(txl->render_depth_tx, GPU_DATA_FLOAT, pix_z, x, y, 0, w, h, 0);
134  }
135  }
136 
137  MEM_SAFE_FREE(pix_z);
138 }
139 
140 /* render all objects and select only grease pencil */
141 static void GPENCIL_render_cache(void *vedata,
142  struct Object *ob,
143  struct RenderEngine *UNUSED(engine),
145 {
146  if (ob && ELEM(ob->type, OB_GPENCIL, OB_LAMP)) {
148  GPENCIL_cache_populate(vedata, ob);
149  }
150  }
151 }
152 
153 static void GPENCIL_render_result_z(struct RenderLayer *rl,
154  const char *viewname,
155  GPENCIL_Data *vedata,
156  const rcti *rect)
157 {
158  const DRWContextState *draw_ctx = DRW_context_state_get();
159  ViewLayer *view_layer = draw_ctx->view_layer;
160 
161  if ((view_layer->passflag & SCE_PASS_Z) != 0) {
162  RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_Z, viewname);
163 
165  rect->xmin,
166  rect->ymin,
167  BLI_rcti_size_x(rect),
168  BLI_rcti_size_y(rect),
170  rp->rect);
171 
172  float winmat[4][4];
173  DRW_view_winmat_get(NULL, winmat, false);
174 
175  int pix_num = BLI_rcti_size_x(rect) * BLI_rcti_size_y(rect);
176 
177  /* Convert GPU depth [0..1] to view Z [near..far] */
179  for (int i = 0; i < pix_num; i++) {
180  if (rp->rect[i] == 1.0f) {
181  rp->rect[i] = 1e10f; /* Background */
182  }
183  else {
184  rp->rect[i] = rp->rect[i] * 2.0f - 1.0f;
185  rp->rect[i] = winmat[3][2] / (rp->rect[i] + winmat[2][2]);
186  }
187  }
188  }
189  else {
190  /* Keep in mind, near and far distance are negatives. */
191  float near = DRW_view_near_distance_get(NULL);
192  float far = DRW_view_far_distance_get(NULL);
193  float range = fabsf(far - near);
194 
195  for (int i = 0; i < pix_num; i++) {
196  if (rp->rect[i] == 1.0f) {
197  rp->rect[i] = 1e10f; /* Background */
198  }
199  else {
200  rp->rect[i] = rp->rect[i] * range - near;
201  }
202  }
203  }
204  }
205 }
206 
208  const char *viewname,
209  GPENCIL_Data *vedata,
210  const rcti *rect)
211 {
213  GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
214 
217  rect->xmin,
218  rect->ymin,
219  BLI_rcti_size_x(rect),
220  BLI_rcti_size_y(rect),
221  4,
222  0,
224  rp->rect);
225 }
226 
227 void GPENCIL_render_to_image(void *ved,
228  RenderEngine *engine,
229  struct RenderLayer *render_layer,
230  const rcti *rect)
231 {
232  GPENCIL_Data *vedata = (GPENCIL_Data *)ved;
233  const char *viewname = RE_GetActiveRenderView(engine->re);
234  const DRWContextState *draw_ctx = DRW_context_state_get();
235  Depsgraph *depsgraph = draw_ctx->depsgraph;
236 
237  GPENCIL_render_init(vedata, engine, render_layer, depsgraph, rect);
238  GPENCIL_engine_init(vedata);
239 
241 
242  /* Loop over all objects and create draw structure. */
243  GPENCIL_cache_init(vedata);
245  GPENCIL_cache_finish(vedata);
246 
248 
249  /* Render the gpencil object and merge the result to the underlying render. */
250  GPENCIL_draw_scene(vedata);
251 
252  GPENCIL_render_result_combined(render_layer, viewname, vedata, rect);
253  GPENCIL_render_result_z(render_layer, viewname, vedata, rect);
254 }
General operations, lookup, etc. for blender objects.
@ OB_VISIBLE_SELF
Definition: BKE_object.h:150
MINLINE float clamp_f(float value, float min, float max)
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 UNUSED(x)
#define ELEM(...)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
struct Object * DEG_get_evaluated_object(const struct Depsgraph *depsgraph, struct Object *object)
struct Scene * DEG_get_evaluated_scene(const struct Depsgraph *graph)
@ OB_LAMP
@ OB_GPENCIL
#define RE_PASSNAME_COMBINED
#define R_BORDER
#define RE_PASSNAME_Z
@ SCE_PASS_Z
static AppView * view
void GPU_framebuffer_bind(GPUFrameBuffer *fb)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
void GPU_texture_update_sub(GPUTexture *tex, eGPUDataFormat data_format, const void *pixels, int offset_x, int offset_y, int offset_z, int width, int height, int depth)
Definition: gpu_texture.cc:417
@ GPU_DATA_FLOAT
Definition: GPU_texture.h:171
void GPU_texture_update(GPUTexture *tex, eGPUDataFormat data_format, const void *data)
Definition: gpu_texture.cc:444
@ GPU_DEPTH_COMPONENT24
Definition: GPU_texture.h:166
#define MEM_SAFE_FREE(v)
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between camera
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
Scene scene
const Depsgraph * depsgraph
void DRW_render_instance_buffer_finish(void)
int DRW_object_visibility_in_active_context(const Object *ob)
Definition: draw_manager.c:209
const DRWContextState * DRW_context_state_get(void)
const float * DRW_viewport_size_get(void)
Definition: draw_manager.c:288
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)
GPUTexture * DRW_texture_create_2d(int w, int h, eGPUTextureFormat format, DRWTextureFlag flags, const float *fpixels)
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_set_error_message(RenderEngine *engine, const char *msg)
Definition: engine.c:560
void GPENCIL_cache_populate(void *ved, Object *ob)
void GPENCIL_draw_scene(void *ved)
void GPENCIL_cache_init(void *ved)
void GPENCIL_cache_finish(void *ved)
void GPENCIL_engine_init(void *ved)
static void GPENCIL_render_result_combined(struct RenderLayer *rl, const char *viewname, GPENCIL_Data *vedata, const rcti *rect)
static void GPENCIL_render_result_z(struct RenderLayer *rl, const char *viewname, GPENCIL_Data *vedata, const rcti *rect)
void GPENCIL_render_init(GPENCIL_Data *vedata, RenderEngine *engine, struct RenderLayer *render_layer, const Depsgraph *depsgraph, const rcti *rect)
static void GPENCIL_render_cache(void *vedata, struct Object *ob, struct RenderEngine *UNUSED(engine), Depsgraph *UNUSED(depsgraph))
void GPENCIL_render_to_image(void *ved, RenderEngine *engine, struct RenderLayer *render_layer, const rcti *rect)
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
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:28
#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 GPENCIL_TextureList * txl
struct GPENCIL_StorageList * stl
struct GPENCIL_FramebufferList * fbl
struct GPUFrameBuffer * render_fb
struct GPENCIL_PrivateData * pd
struct GPUTexture * render_depth_tx
struct GPUTexture * render_color_tx
struct Render * re
Definition: RE_engine.h:135
float * rect
Definition: RE_pipeline.h:67
struct RenderData r
int ymin
Definition: DNA_vec_types.h:64
int xmin
Definition: DNA_vec_types.h:63