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
69 if (DRW_view_is_persp_get(view)) {
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);
78 float far = DRW_view_far_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
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)
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
const Depsgraph * depsgraph
#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
int ymin
int xmin