Blender V4.3
gpencil_render.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2017 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8#include "BLI_rect.h"
9
10#include "DRW_render.hh"
11
12#include "BKE_object.hh"
13
15
17
18#include "RE_pipeline.h"
19
20#include "IMB_imbuf_types.hh"
21
22#include "gpencil_engine.h"
23
25 RenderEngine *engine,
26 RenderLayer *render_layer,
27 const Depsgraph *depsgraph,
28 const rcti *rect)
29{
30 GPENCIL_FramebufferList *fbl = vedata->fbl;
31 GPENCIL_TextureList *txl = vedata->txl;
32
34 const float *viewport_size = DRW_viewport_size_get();
35 const int size[2] = {int(viewport_size[0]), int(viewport_size[1])};
36
37 /* Set the perspective & view matrix. */
38 float winmat[4][4], viewmat[4][4], viewinv[4][4];
39
41 RE_GetCameraWindow(engine->re, camera, winmat);
42 RE_GetCameraModelMatrix(engine->re, camera, viewinv);
43
44 invert_m4_m4(viewmat, viewinv);
45
46 DRWView *view = DRW_view_create(viewmat, winmat, nullptr, nullptr, nullptr);
49
50 /* Create depth texture & color texture from render result. */
51 const char *viewname = RE_GetActiveRenderView(engine->re);
52 RenderPass *rpass_z_src = RE_pass_find_by_name(render_layer, RE_PASSNAME_Z, viewname);
53 RenderPass *rpass_col_src = RE_pass_find_by_name(render_layer, RE_PASSNAME_COMBINED, viewname);
54
55 float *pix_z = (rpass_z_src) ? rpass_z_src->ibuf->float_buffer.data : nullptr;
56 float *pix_col = (rpass_col_src) ? rpass_col_src->ibuf->float_buffer.data : nullptr;
57
58 if (!pix_z || !pix_col) {
60 "Warning: To render grease pencil, enable Combined and Z passes.");
61 }
62
63 if (pix_z) {
64 /* Depth need to be remapped to [0..1] range. */
65 pix_z = static_cast<float *>(MEM_dupallocN(pix_z));
66
67 int pix_num = rpass_z_src->rectx * rpass_z_src->recty;
68
70 for (int i = 0; i < pix_num; i++) {
71 pix_z[i] = (-winmat[3][2] / -pix_z[i]) - winmat[2][2];
72 pix_z[i] = clamp_f(pix_z[i] * 0.5f + 0.5f, 0.0f, 1.0f);
73 }
74 }
75 else {
76 /* Keep in mind, near and far distance are negatives. */
77 float near = DRW_view_near_distance_get(view);
79 float range_inv = 1.0f / fabsf(far - near);
80 for (int i = 0; i < pix_num; i++) {
81 pix_z[i] = (pix_z[i] + near) * range_inv;
82 pix_z[i] = clamp_f(pix_z[i], 0.0f, 1.0f);
83 }
84 }
85 }
86
87 const bool do_region = (scene->r.mode & R_BORDER) != 0;
88 const bool do_clear_z = !pix_z || do_region;
89 const bool do_clear_col = !pix_col || do_region;
90
91 /* FIXME(fclem): we have a precision loss in the depth buffer because of this re-upload.
92 * Find where it comes from! */
93 /* In multi view render the textures can be reused. */
94 if (txl->render_depth_tx && !do_clear_z) {
96 }
97 else {
99 size[0], size[1], GPU_DEPTH_COMPONENT24, DRWTextureFlag(0), do_region ? nullptr : pix_z);
100 }
101 if (txl->render_color_tx && !do_clear_col) {
103 }
104 else {
106 size[0], size[1], GPU_RGBA16F, DRWTextureFlag(0), do_region ? nullptr : pix_col);
107 }
108
110 {
111 GPU_ATTACHMENT_TEXTURE(txl->render_depth_tx),
112 GPU_ATTACHMENT_TEXTURE(txl->render_color_tx),
113 });
114
115 if (do_clear_z || do_clear_col) {
116 /* To avoid unpredictable result, clear buffers that have not be initialized. */
118 if (do_clear_col) {
119 const float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
120 GPU_framebuffer_clear_color(fbl->render_fb, clear_col);
121 }
122 if (do_clear_z) {
124 }
125 }
126
127 if (do_region) {
128 int x = rect->xmin;
129 int y = rect->ymin;
130 int w = BLI_rcti_size_x(rect);
131 int h = BLI_rcti_size_y(rect);
132 if (pix_col) {
133 GPU_texture_update_sub(txl->render_color_tx, GPU_DATA_FLOAT, pix_col, x, y, 0, w, h, 0);
134 }
135 if (pix_z) {
136 GPU_texture_update_sub(txl->render_depth_tx, GPU_DATA_FLOAT, pix_z, x, y, 0, w, h, 0);
137 }
138 }
139
140 MEM_SAFE_FREE(pix_z);
141}
142
143/* render all objects and select only grease pencil */
144static void GPENCIL_render_cache(void *vedata,
145 Object *ob,
146 RenderEngine * /*engine*/,
147 Depsgraph * /*depsgraph*/)
148{
151 GPENCIL_cache_populate(vedata, ob);
152 }
153 }
154}
155
157 const char *viewname,
158 GPENCIL_Data *vedata,
159 const rcti *rect)
160{
161 const DRWContextState *draw_ctx = DRW_context_state_get();
162 ViewLayer *view_layer = draw_ctx->view_layer;
163 if ((view_layer->passflag & SCE_PASS_Z) == 0) {
164 return;
165 }
166 RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_Z, viewname);
167 if (rp == nullptr) {
168 return;
169 }
170
171 float *ro_buffer_data = rp->ibuf->float_buffer.data;
172
174 rect->xmin,
175 rect->ymin,
176 BLI_rcti_size_x(rect),
177 BLI_rcti_size_y(rect),
179 ro_buffer_data);
180
181 float winmat[4][4];
182 DRW_view_winmat_get(nullptr, winmat, false);
183
184 int pix_num = BLI_rcti_size_x(rect) * BLI_rcti_size_y(rect);
185
186 /* Convert GPU depth [0..1] to view Z [near..far] */
187 if (DRW_view_is_persp_get(nullptr)) {
188 for (int i = 0; i < pix_num; i++) {
189 if (ro_buffer_data[i] == 1.0f) {
190 ro_buffer_data[i] = 1e10f; /* Background */
191 }
192 else {
193 ro_buffer_data[i] = ro_buffer_data[i] * 2.0f - 1.0f;
194 ro_buffer_data[i] = winmat[3][2] / (ro_buffer_data[i] + winmat[2][2]);
195 }
196 }
197 }
198 else {
199 /* Keep in mind, near and far distance are negatives. */
200 float near = DRW_view_near_distance_get(nullptr);
201 float far = DRW_view_far_distance_get(nullptr);
202 float range = fabsf(far - near);
203
204 for (int i = 0; i < pix_num; i++) {
205 if (ro_buffer_data[i] == 1.0f) {
206 ro_buffer_data[i] = 1e10f; /* Background */
207 }
208 else {
209 ro_buffer_data[i] = ro_buffer_data[i] * range - near;
210 }
211 }
212 }
213}
214
216 const char *viewname,
217 GPENCIL_Data *vedata,
218 const rcti *rect)
219{
221 GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
222
225 rect->xmin,
226 rect->ymin,
227 BLI_rcti_size_x(rect),
228 BLI_rcti_size_y(rect),
229 4,
230 0,
232 rp->ibuf->float_buffer.data);
233}
234
236 RenderEngine *engine,
237 RenderLayer *render_layer,
238 const rcti *rect)
239{
240 GPENCIL_Data *vedata = (GPENCIL_Data *)ved;
241 const char *viewname = RE_GetActiveRenderView(engine->re);
242 const DRWContextState *draw_ctx = DRW_context_state_get();
243 Depsgraph *depsgraph = draw_ctx->depsgraph;
244
245 GPENCIL_render_init(vedata, engine, render_layer, depsgraph, rect);
246 GPENCIL_engine_init(vedata);
247
249
250 /* Loop over all objects and create draw structure. */
251 GPENCIL_cache_init(vedata);
253 GPENCIL_cache_finish(vedata);
254
256
257 /* Render the gpencil object and merge the result to the underlying render. */
258 GPENCIL_draw_scene(vedata);
259
260 GPENCIL_render_result_combined(render_layer, viewname, vedata, rect);
261 GPENCIL_render_result_z(render_layer, viewname, vedata, rect);
262}
General operations, lookup, etc. for blender objects.
@ OB_VISIBLE_SELF
MINLINE float clamp_f(float value, float min, float max)
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition BLI_rect.h:193
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition BLI_rect.h:189
#define ELEM(...)
Scene * DEG_get_evaluated_scene(const Depsgraph *graph)
Object * DEG_get_evaluated_object(const Depsgraph *depsgraph, Object *object)
@ OB_GREASE_PENCIL
@ OB_LAMP
@ OB_GPENCIL_LEGACY
#define RE_PASSNAME_COMBINED
@ R_BORDER
#define RE_PASSNAME_Z
@ SCE_PASS_Z
DRWTextureFlag
static AppView * view
void GPU_framebuffer_read_depth(GPUFrameBuffer *framebuffer, int x, int y, int width, int height, eGPUDataFormat data_format, void *r_data)
void GPU_framebuffer_bind(GPUFrameBuffer *framebuffer)
void GPU_framebuffer_read_color(GPUFrameBuffer *framebuffer, int x, int y, int width, int height, int channels, int slot, eGPUDataFormat data_format, void *r_data)
void GPU_framebuffer_clear_color(GPUFrameBuffer *fb, const float clear_col[4])
#define GPU_framebuffer_ensure_config(_fb,...)
void GPU_framebuffer_clear_depth(GPUFrameBuffer *fb, float clear_depth)
@ GPU_DATA_FLOAT
void GPU_texture_update_sub(GPUTexture *texture, eGPUDataFormat data_format, const void *pixels, int offset_x, int offset_y, int offset_z, int width, int height, int depth)
@ GPU_DEPTH_COMPONENT24
void GPU_texture_update(GPUTexture *texture, eGPUDataFormat data_format, const void *data)
Contains defines and structs used throughout the imbuf module.
#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 Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture 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
BPy_StructRNA * depsgraph
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
#define fabsf(x)
const float * DRW_viewport_size_get()
void DRW_render_instance_buffer_finish()
int DRW_object_visibility_in_active_context(const Object *ob)
const DRWContextState * DRW_context_state_get()
void DRW_render_object_iter(void *vedata, RenderEngine *engine, Depsgraph *depsgraph, void(*callback)(void *vedata, Object *ob, RenderEngine *engine, 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)
float DRW_view_far_distance_get(const DRWView *view)
void DRW_view_default_set(const DRWView *view)
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)
void DRW_view_set_active(const DRWView *view)
GPUTexture * DRW_texture_create_2d(int w, int h, eGPUTextureFormat format, DRWTextureFlag flags, const float *fpixels)
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
void GPENCIL_engine_init(void *vedata)
void GPENCIL_cache_init(void *vedata)
void GPENCIL_cache_finish(void *vedata)
void GPENCIL_cache_populate(void *vedata, struct Object *ob)
void GPENCIL_draw_scene(void *vedata)
void GPENCIL_render_to_image(void *ved, RenderEngine *engine, RenderLayer *render_layer, const rcti *rect)
static void GPENCIL_render_cache(void *vedata, Object *ob, RenderEngine *, Depsgraph *)
static void GPENCIL_render_result_combined(RenderLayer *rl, const char *viewname, GPENCIL_Data *vedata, const rcti *rect)
void GPENCIL_render_init(GPENCIL_Data *vedata, RenderEngine *engine, RenderLayer *render_layer, const Depsgraph *depsgraph, const rcti *rect)
static void GPENCIL_render_result_z(RenderLayer *rl, const char *viewname, GPENCIL_Data *vedata, const rcti *rect)
void RE_GetCameraModelMatrix(const Render *re, const Object *camera, float r_modelmat[4][4])
void RE_GetCameraWindow(Render *re, const Object *camera, float r_winmat[4][4])
Object * RE_GetCamera(Render *re)
void RE_engine_set_error_message(RenderEngine *engine, const char *msg)
void *(* MEM_dupallocN)(const void *vmemh)
Definition mallocn.cc:39
RenderPass * RE_pass_find_by_name(RenderLayer *rl, const char *name, const char *viewname)
const char * RE_GetActiveRenderView(Render *re)
ViewLayer * view_layer
Depsgraph * depsgraph
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
ImBufFloatBuffer float_buffer
struct Render * re
Definition RE_engine.h:141
struct ImBuf * ibuf
Definition RE_pipeline.h:68
struct RenderData r
int ymin
int xmin