2022-02-11 09:07:11 +11:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
|
* Copyright 2019 Blender Foundation. */
|
2019-07-14 16:49:44 +02:00
|
|
|
|
|
|
|
|
/** \file
|
|
|
|
|
* \ingroup draw
|
|
|
|
|
*/
|
|
|
|
|
|
2019-09-13 21:12:26 +10:00
|
|
|
#pragma once
|
2019-07-14 16:49:44 +02:00
|
|
|
|
2022-06-05 12:04:42 +02:00
|
|
|
#include <algorithm>
|
|
|
|
|
|
|
|
|
|
#include "BLI_utildefines.h"
|
2020-06-02 15:07:17 +02:00
|
|
|
|
2021-10-26 18:16:33 -03:00
|
|
|
#include "DNA_customdata_types.h"
|
2022-06-05 12:04:42 +02:00
|
|
|
#include "DNA_mesh_types.h"
|
|
|
|
|
#include "DNA_view3d_enums.h"
|
2021-10-26 18:16:33 -03:00
|
|
|
|
|
|
|
|
#include "BKE_attribute.h"
|
2022-01-11 15:42:07 +01:00
|
|
|
#include "BKE_object.h"
|
2021-10-26 18:16:33 -03:00
|
|
|
|
2021-06-01 09:23:37 +02:00
|
|
|
#include "GPU_batch.h"
|
|
|
|
|
#include "GPU_index_buffer.h"
|
|
|
|
|
#include "GPU_vertex_buffer.h"
|
|
|
|
|
|
EEVEE: support Curves attributes rendering
This adds support to render Curves attributes in EEVEE.
Each attribute is stored in a texture derived from a VBO. As the
shading group needs the textures to be valid upon creation, the
attributes are created and setup during its very creation, instead
of doing it lazily via create_requested which we cannot rely on
anyway as contrary to the mesh batch, we do cannot really tell if
attributes need to be updated or else via some `DRW_batch_requested`.
Since point attributes need refinement, and since attributes are all
cast to vec4/float4 to account for differences in type conversions
between Blender and OpenGL, the refinement shader for points is
used as is. The point attributes are stored for each subdivision level
in CurvesEvalFinalCache. Each subdivision level also keeps track of the
attributes already in use so they are properly updated when needed.
Some basic garbage collection was added similar to what is done
for meshes: if the attributes used over time have been different
from the currently used attributes for too long, then the buffers
are freed, ensuring that stale attributesare removed.
This adds `CurvesInfos` to the shader creation info, which stores
the scope in which the attributes are defined. Scopes are stored
as booleans, in an array indexed by attribute loading order which
is also the order in which the attributes were added to the material.
A mapping is necessary between the indices used for the scoping, and
the ones used in the Curves cache, as this may contain stale
attributes which have not been garbage collected yet.
Common utilities with the mesh code for handling requested
attributes were moved to a separate file.
Differential Revision: https://developer.blender.org/D14916
2022-05-24 05:02:57 +02:00
|
|
|
#include "draw_attributes.h"
|
|
|
|
|
|
2022-06-05 12:04:42 +02:00
|
|
|
struct DRWSubdivCache;
|
|
|
|
|
struct MeshRenderData;
|
|
|
|
|
struct TaskGraph;
|
|
|
|
|
|
2019-07-14 16:49:44 +02:00
|
|
|
/* Vertex Group Selection and display options */
|
2022-06-05 12:04:42 +02:00
|
|
|
struct DRW_MeshWeightState {
|
2019-07-14 16:49:44 +02:00
|
|
|
int defgroup_active;
|
|
|
|
|
int defgroup_len;
|
|
|
|
|
|
|
|
|
|
short flags;
|
|
|
|
|
char alert_mode;
|
|
|
|
|
|
2021-07-08 13:26:55 +10:00
|
|
|
/* Set of all selected bones for Multi-paint. */
|
2022-06-05 12:15:22 +02:00
|
|
|
bool *defgroup_sel; /* #defgroup_len */
|
2019-07-14 16:49:44 +02:00
|
|
|
int defgroup_sel_count;
|
2018-10-07 18:25:51 +03:00
|
|
|
|
|
|
|
|
/* Set of all locked and unlocked deform bones for Lock Relative mode. */
|
2022-06-05 12:15:22 +02:00
|
|
|
bool *defgroup_locked; /* #defgroup_len */
|
|
|
|
|
bool *defgroup_unlocked; /* #defgroup_len */
|
2022-06-05 12:04:42 +02:00
|
|
|
};
|
2019-07-14 16:49:44 +02:00
|
|
|
|
|
|
|
|
/* DRW_MeshWeightState.flags */
|
|
|
|
|
enum {
|
|
|
|
|
DRW_MESH_WEIGHT_STATE_MULTIPAINT = (1 << 0),
|
|
|
|
|
DRW_MESH_WEIGHT_STATE_AUTO_NORMALIZE = (1 << 1),
|
2018-10-07 18:25:51 +03:00
|
|
|
DRW_MESH_WEIGHT_STATE_LOCK_RELATIVE = (1 << 2),
|
2019-07-14 16:49:44 +02:00
|
|
|
};
|
|
|
|
|
|
2022-06-05 12:04:42 +02:00
|
|
|
enum eMRIterType {
|
2019-07-14 16:49:44 +02:00
|
|
|
MR_ITER_LOOPTRI = 1 << 0,
|
2020-07-01 00:13:39 +10:00
|
|
|
MR_ITER_POLY = 1 << 1,
|
2019-07-14 16:49:44 +02:00
|
|
|
MR_ITER_LEDGE = 1 << 2,
|
|
|
|
|
MR_ITER_LVERT = 1 << 3,
|
2022-06-05 12:04:42 +02:00
|
|
|
};
|
2021-06-01 12:12:13 +02:00
|
|
|
ENUM_OPERATORS(eMRIterType, MR_ITER_LVERT)
|
2019-07-14 16:49:44 +02:00
|
|
|
|
2022-06-05 12:04:42 +02:00
|
|
|
enum eMRDataType {
|
2021-06-07 13:27:38 +02:00
|
|
|
MR_DATA_NONE = 0,
|
2019-07-14 16:49:44 +02:00
|
|
|
MR_DATA_POLY_NOR = 1 << 1,
|
|
|
|
|
MR_DATA_LOOP_NOR = 1 << 2,
|
|
|
|
|
MR_DATA_LOOPTRI = 1 << 3,
|
2021-07-21 14:46:41 -03:00
|
|
|
MR_DATA_LOOSE_GEOM = 1 << 4,
|
2021-06-24 15:56:58 +10:00
|
|
|
/** Force loop normals calculation. */
|
2021-07-21 14:46:41 -03:00
|
|
|
MR_DATA_TAN_LOOP_NOR = 1 << 5,
|
2021-07-20 11:43:38 -03:00
|
|
|
MR_DATA_POLYS_SORTED = 1 << 6,
|
2022-06-05 12:04:42 +02:00
|
|
|
};
|
2021-07-20 11:43:38 -03:00
|
|
|
ENUM_OPERATORS(eMRDataType, MR_DATA_POLYS_SORTED)
|
2021-06-01 12:12:13 +02:00
|
|
|
|
2022-01-11 15:42:07 +01:00
|
|
|
BLI_INLINE int mesh_render_mat_len_get(const Object *object, const Mesh *me)
|
2019-07-14 16:49:44 +02:00
|
|
|
{
|
2022-01-11 15:42:07 +01:00
|
|
|
if (me->edit_mesh != NULL) {
|
|
|
|
|
const Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(object);
|
|
|
|
|
if (editmesh_eval_final != NULL) {
|
2022-06-05 12:04:42 +02:00
|
|
|
return std::max<int>(1, editmesh_eval_final->totcol);
|
2022-01-11 15:42:07 +01:00
|
|
|
}
|
2021-05-19 10:23:09 +02:00
|
|
|
}
|
2022-06-05 12:04:42 +02:00
|
|
|
return std::max<int>(1, me->totcol);
|
2019-07-14 16:49:44 +02:00
|
|
|
}
|
|
|
|
|
|
2022-06-05 12:04:42 +02:00
|
|
|
struct MeshBufferList {
|
2022-06-05 12:15:22 +02:00
|
|
|
/* Every VBO below contains at least enough data for every loop in the mesh
|
|
|
|
|
* (except fdots and skin roots). For some VBOs, it extends to (in this exact order) :
|
|
|
|
|
* loops + loose_edges * 2 + loose_verts */
|
2019-07-14 16:49:44 +02:00
|
|
|
struct {
|
|
|
|
|
GPUVertBuf *pos_nor; /* extend */
|
|
|
|
|
GPUVertBuf *lnor; /* extend */
|
|
|
|
|
GPUVertBuf *edge_fac; /* extend */
|
|
|
|
|
GPUVertBuf *weights; /* extend */
|
2019-08-14 22:43:44 +02:00
|
|
|
GPUVertBuf *uv;
|
|
|
|
|
GPUVertBuf *tan;
|
2020-09-18 19:30:02 +02:00
|
|
|
GPUVertBuf *sculpt_data;
|
2019-07-14 16:49:44 +02:00
|
|
|
GPUVertBuf *orco;
|
|
|
|
|
/* Only for edit mode. */
|
|
|
|
|
GPUVertBuf *edit_data; /* extend */
|
|
|
|
|
GPUVertBuf *edituv_data;
|
2021-02-17 15:36:18 +11:00
|
|
|
GPUVertBuf *edituv_stretch_area;
|
|
|
|
|
GPUVertBuf *edituv_stretch_angle;
|
2019-07-14 16:49:44 +02:00
|
|
|
GPUVertBuf *mesh_analysis;
|
|
|
|
|
GPUVertBuf *fdots_pos;
|
|
|
|
|
GPUVertBuf *fdots_nor;
|
|
|
|
|
GPUVertBuf *fdots_uv;
|
|
|
|
|
// GPUVertBuf *fdots_edit_data; /* inside fdots_nor for now. */
|
|
|
|
|
GPUVertBuf *fdots_edituv_data;
|
2019-10-15 01:49:53 +02:00
|
|
|
GPUVertBuf *skin_roots;
|
2019-07-14 16:49:44 +02:00
|
|
|
/* Selection */
|
|
|
|
|
GPUVertBuf *vert_idx; /* extend */
|
|
|
|
|
GPUVertBuf *edge_idx; /* extend */
|
|
|
|
|
GPUVertBuf *poly_idx;
|
|
|
|
|
GPUVertBuf *fdot_idx;
|
2021-10-26 18:16:33 -03:00
|
|
|
GPUVertBuf *attr[GPU_MAX_ATTR];
|
Geometry Nodes: viewport preview
This adds support for showing geometry passed to the Viewer in the 3d
viewport (instead of just in the spreadsheet). The "viewer geometry"
bypasses the group output. So it is not necessary to change the final
output of the node group to be able to see the intermediate geometry.
**Activation and deactivation of a viewer node**
* A viewer node is activated by clicking on it.
* Ctrl+shift+click on any node/socket connects it to the viewer and
makes it active.
* Ctrl+shift+click in empty space deactivates the active viewer.
* When the active viewer is not visible anymore (e.g. another object
is selected, or the current node group is exit), it is deactivated.
* Clicking on the icon in the header of the Viewer node toggles whether
its active or not.
**Pinning**
* The spreadsheet still allows pinning the active viewer as before.
When pinned, the spreadsheet still references the viewer node even
when it becomes inactive.
* The viewport does not support pinning at the moment. It always shows
the active viewer.
**Attribute**
* When a field is linked to the second input of the viewer node it is
displayed as an overlay in the viewport.
* When possible the correct domain for the attribute is determined
automatically. This does not work in all cases. It falls back to the
face corner domain on meshes and the point domain on curves. When
necessary, the domain can be picked manually.
* The spreadsheet now only shows the "Viewer" column for the domain
that is selected in the Viewer node.
* Instance attributes are visualized as a constant color per instance.
**Viewport Options**
* The attribute overlay opacity can be controlled with the "Viewer Node"
setting in the overlays popover.
* A viewport can be configured not to show intermediate viewer-geometry
by disabling the "Viewer Node" option in the "View" menu.
**Implementation Details**
* The "spreadsheet context path" was generalized to a "viewer path" that
is used in more places now.
* The viewer node itself determines the attribute domain, evaluates the
field and stores the result in a `.viewer` attribute.
* A new "viewer attribute' overlay displays the data from the `.viewer`
attribute.
* The ground truth for the active viewer node is stored in the workspace
now. Node editors, spreadsheets and viewports retrieve the active
viewer from there unless they are pinned.
* The depsgraph object iterator has a new "viewer path" setting. When set,
the viewed geometry of the corresponding object is part of the iterator
instead of the final evaluated geometry.
* To support the instance attribute overlay `DupliObject` was extended
to contain the information necessary for drawing the overlay.
* The ctrl+shift+click operator has been refactored so that it can make
existing links to viewers active again.
* The auto-domain-detection in the Viewer node works by checking the
"preferred domain" for every field input. If there is not exactly one
preferred domain, the fallback is used.
Known limitations:
* Loose edges of meshes don't have the attribute overlay. This could be
added separately if necessary.
* Some attributes are hard to visualize as a color directly. For example,
the values might have to be normalized or some should be drawn as arrays.
For now, we encourage users to build node groups that generate appropriate
viewer-geometry. We might include some of that functionality in future versions.
Support for displaying attribute values as text in the viewport is planned as well.
* There seems to be an issue with the attribute overlay for pointclouds on
nvidia gpus, to be investigated.
Differential Revision: https://developer.blender.org/D15954
2022-09-28 17:54:59 +02:00
|
|
|
GPUVertBuf *attr_viewer;
|
2019-07-14 16:49:44 +02:00
|
|
|
} vbo;
|
|
|
|
|
/* Index Buffers:
|
|
|
|
|
* Only need to be updated when topology changes. */
|
|
|
|
|
struct {
|
2022-06-05 12:15:22 +02:00
|
|
|
/* Indices to vloops. Ordered per material. */
|
|
|
|
|
GPUIndexBuf *tris;
|
|
|
|
|
/* Loose edges last. */
|
|
|
|
|
GPUIndexBuf *lines;
|
|
|
|
|
/* Sub buffer of `lines` only containing the loose edges. */
|
|
|
|
|
GPUIndexBuf *lines_loose;
|
2019-07-14 16:49:44 +02:00
|
|
|
GPUIndexBuf *points;
|
|
|
|
|
GPUIndexBuf *fdots;
|
|
|
|
|
/* 3D overlays. */
|
2022-06-05 12:15:22 +02:00
|
|
|
/* no loose edges. */
|
|
|
|
|
GPUIndexBuf *lines_paint_mask;
|
2019-07-14 16:49:44 +02:00
|
|
|
GPUIndexBuf *lines_adjacency;
|
|
|
|
|
/* Uv overlays. (visibility can differ from 3D view) */
|
|
|
|
|
GPUIndexBuf *edituv_tris;
|
|
|
|
|
GPUIndexBuf *edituv_lines;
|
|
|
|
|
GPUIndexBuf *edituv_points;
|
|
|
|
|
GPUIndexBuf *edituv_fdots;
|
|
|
|
|
} ibo;
|
2022-06-05 12:04:42 +02:00
|
|
|
};
|
2019-07-14 16:49:44 +02:00
|
|
|
|
2022-06-05 12:04:42 +02:00
|
|
|
struct MeshBatchList {
|
2021-08-23 12:46:14 -03:00
|
|
|
/* Surfaces / Render */
|
|
|
|
|
GPUBatch *surface;
|
|
|
|
|
GPUBatch *surface_weights;
|
|
|
|
|
/* Edit mode */
|
|
|
|
|
GPUBatch *edit_triangles;
|
|
|
|
|
GPUBatch *edit_vertices;
|
|
|
|
|
GPUBatch *edit_edges;
|
|
|
|
|
GPUBatch *edit_vnor;
|
|
|
|
|
GPUBatch *edit_lnor;
|
|
|
|
|
GPUBatch *edit_fdots;
|
|
|
|
|
GPUBatch *edit_mesh_analysis;
|
|
|
|
|
GPUBatch *edit_skin_roots;
|
|
|
|
|
/* Edit UVs */
|
|
|
|
|
GPUBatch *edituv_faces_stretch_area;
|
|
|
|
|
GPUBatch *edituv_faces_stretch_angle;
|
|
|
|
|
GPUBatch *edituv_faces;
|
|
|
|
|
GPUBatch *edituv_edges;
|
|
|
|
|
GPUBatch *edituv_verts;
|
|
|
|
|
GPUBatch *edituv_fdots;
|
|
|
|
|
/* Edit selection */
|
|
|
|
|
GPUBatch *edit_selection_verts;
|
|
|
|
|
GPUBatch *edit_selection_edges;
|
|
|
|
|
GPUBatch *edit_selection_faces;
|
|
|
|
|
GPUBatch *edit_selection_fdots;
|
|
|
|
|
/* Common display / Other */
|
|
|
|
|
GPUBatch *all_verts;
|
|
|
|
|
GPUBatch *all_edges;
|
|
|
|
|
GPUBatch *loose_edges;
|
|
|
|
|
GPUBatch *edge_detection;
|
2022-06-05 12:15:22 +02:00
|
|
|
/* Individual edges with face normals. */
|
|
|
|
|
GPUBatch *wire_edges;
|
|
|
|
|
/* Loops around faces. no edges between selected faces */
|
|
|
|
|
GPUBatch *wire_loops;
|
|
|
|
|
/* Same as wire_loops but only has uvs. */
|
|
|
|
|
GPUBatch *wire_loops_uvs;
|
2021-08-23 12:46:14 -03:00
|
|
|
GPUBatch *sculpt_overlays;
|
Geometry Nodes: viewport preview
This adds support for showing geometry passed to the Viewer in the 3d
viewport (instead of just in the spreadsheet). The "viewer geometry"
bypasses the group output. So it is not necessary to change the final
output of the node group to be able to see the intermediate geometry.
**Activation and deactivation of a viewer node**
* A viewer node is activated by clicking on it.
* Ctrl+shift+click on any node/socket connects it to the viewer and
makes it active.
* Ctrl+shift+click in empty space deactivates the active viewer.
* When the active viewer is not visible anymore (e.g. another object
is selected, or the current node group is exit), it is deactivated.
* Clicking on the icon in the header of the Viewer node toggles whether
its active or not.
**Pinning**
* The spreadsheet still allows pinning the active viewer as before.
When pinned, the spreadsheet still references the viewer node even
when it becomes inactive.
* The viewport does not support pinning at the moment. It always shows
the active viewer.
**Attribute**
* When a field is linked to the second input of the viewer node it is
displayed as an overlay in the viewport.
* When possible the correct domain for the attribute is determined
automatically. This does not work in all cases. It falls back to the
face corner domain on meshes and the point domain on curves. When
necessary, the domain can be picked manually.
* The spreadsheet now only shows the "Viewer" column for the domain
that is selected in the Viewer node.
* Instance attributes are visualized as a constant color per instance.
**Viewport Options**
* The attribute overlay opacity can be controlled with the "Viewer Node"
setting in the overlays popover.
* A viewport can be configured not to show intermediate viewer-geometry
by disabling the "Viewer Node" option in the "View" menu.
**Implementation Details**
* The "spreadsheet context path" was generalized to a "viewer path" that
is used in more places now.
* The viewer node itself determines the attribute domain, evaluates the
field and stores the result in a `.viewer` attribute.
* A new "viewer attribute' overlay displays the data from the `.viewer`
attribute.
* The ground truth for the active viewer node is stored in the workspace
now. Node editors, spreadsheets and viewports retrieve the active
viewer from there unless they are pinned.
* The depsgraph object iterator has a new "viewer path" setting. When set,
the viewed geometry of the corresponding object is part of the iterator
instead of the final evaluated geometry.
* To support the instance attribute overlay `DupliObject` was extended
to contain the information necessary for drawing the overlay.
* The ctrl+shift+click operator has been refactored so that it can make
existing links to viewers active again.
* The auto-domain-detection in the Viewer node works by checking the
"preferred domain" for every field input. If there is not exactly one
preferred domain, the fallback is used.
Known limitations:
* Loose edges of meshes don't have the attribute overlay. This could be
added separately if necessary.
* Some attributes are hard to visualize as a color directly. For example,
the values might have to be normalized or some should be drawn as arrays.
For now, we encourage users to build node groups that generate appropriate
viewer-geometry. We might include some of that functionality in future versions.
Support for displaying attribute values as text in the viewport is planned as well.
* There seems to be an issue with the attribute overlay for pointclouds on
nvidia gpus, to be investigated.
Differential Revision: https://developer.blender.org/D15954
2022-09-28 17:54:59 +02:00
|
|
|
GPUBatch *surface_viewer_attribute;
|
2022-06-05 12:04:42 +02:00
|
|
|
};
|
2021-08-23 12:46:14 -03:00
|
|
|
|
|
|
|
|
#define MBC_BATCH_LEN (sizeof(MeshBatchList) / sizeof(void *))
|
2022-06-07 10:31:28 +02:00
|
|
|
#define MBC_VBO_LEN (sizeof(MeshBufferList::vbo) / sizeof(void *))
|
|
|
|
|
#define MBC_IBO_LEN (sizeof(MeshBufferList::ibo) / sizeof(void *))
|
2021-08-23 12:46:14 -03:00
|
|
|
|
|
|
|
|
#define MBC_BATCH_INDEX(batch) (offsetof(MeshBatchList, batch) / sizeof(void *))
|
|
|
|
|
|
2022-06-05 12:04:42 +02:00
|
|
|
enum DRWBatchFlag {
|
2021-08-23 12:46:14 -03:00
|
|
|
MBC_SURFACE = (1u << MBC_BATCH_INDEX(surface)),
|
|
|
|
|
MBC_SURFACE_WEIGHTS = (1u << MBC_BATCH_INDEX(surface_weights)),
|
|
|
|
|
MBC_EDIT_TRIANGLES = (1u << MBC_BATCH_INDEX(edit_triangles)),
|
|
|
|
|
MBC_EDIT_VERTICES = (1u << MBC_BATCH_INDEX(edit_vertices)),
|
|
|
|
|
MBC_EDIT_EDGES = (1u << MBC_BATCH_INDEX(edit_edges)),
|
|
|
|
|
MBC_EDIT_VNOR = (1u << MBC_BATCH_INDEX(edit_vnor)),
|
|
|
|
|
MBC_EDIT_LNOR = (1u << MBC_BATCH_INDEX(edit_lnor)),
|
|
|
|
|
MBC_EDIT_FACEDOTS = (1u << MBC_BATCH_INDEX(edit_fdots)),
|
|
|
|
|
MBC_EDIT_MESH_ANALYSIS = (1u << MBC_BATCH_INDEX(edit_mesh_analysis)),
|
|
|
|
|
MBC_SKIN_ROOTS = (1u << MBC_BATCH_INDEX(edit_skin_roots)),
|
|
|
|
|
MBC_EDITUV_FACES_STRETCH_AREA = (1u << MBC_BATCH_INDEX(edituv_faces_stretch_area)),
|
|
|
|
|
MBC_EDITUV_FACES_STRETCH_ANGLE = (1u << MBC_BATCH_INDEX(edituv_faces_stretch_angle)),
|
|
|
|
|
MBC_EDITUV_FACES = (1u << MBC_BATCH_INDEX(edituv_faces)),
|
|
|
|
|
MBC_EDITUV_EDGES = (1u << MBC_BATCH_INDEX(edituv_edges)),
|
|
|
|
|
MBC_EDITUV_VERTS = (1u << MBC_BATCH_INDEX(edituv_verts)),
|
|
|
|
|
MBC_EDITUV_FACEDOTS = (1u << MBC_BATCH_INDEX(edituv_fdots)),
|
|
|
|
|
MBC_EDIT_SELECTION_VERTS = (1u << MBC_BATCH_INDEX(edit_selection_verts)),
|
|
|
|
|
MBC_EDIT_SELECTION_EDGES = (1u << MBC_BATCH_INDEX(edit_selection_edges)),
|
|
|
|
|
MBC_EDIT_SELECTION_FACES = (1u << MBC_BATCH_INDEX(edit_selection_faces)),
|
|
|
|
|
MBC_EDIT_SELECTION_FACEDOTS = (1u << MBC_BATCH_INDEX(edit_selection_fdots)),
|
|
|
|
|
MBC_ALL_VERTS = (1u << MBC_BATCH_INDEX(all_verts)),
|
|
|
|
|
MBC_ALL_EDGES = (1u << MBC_BATCH_INDEX(all_edges)),
|
|
|
|
|
MBC_LOOSE_EDGES = (1u << MBC_BATCH_INDEX(loose_edges)),
|
|
|
|
|
MBC_EDGE_DETECTION = (1u << MBC_BATCH_INDEX(edge_detection)),
|
|
|
|
|
MBC_WIRE_EDGES = (1u << MBC_BATCH_INDEX(wire_edges)),
|
|
|
|
|
MBC_WIRE_LOOPS = (1u << MBC_BATCH_INDEX(wire_loops)),
|
|
|
|
|
MBC_WIRE_LOOPS_UVS = (1u << MBC_BATCH_INDEX(wire_loops_uvs)),
|
|
|
|
|
MBC_SCULPT_OVERLAYS = (1u << MBC_BATCH_INDEX(sculpt_overlays)),
|
Geometry Nodes: viewport preview
This adds support for showing geometry passed to the Viewer in the 3d
viewport (instead of just in the spreadsheet). The "viewer geometry"
bypasses the group output. So it is not necessary to change the final
output of the node group to be able to see the intermediate geometry.
**Activation and deactivation of a viewer node**
* A viewer node is activated by clicking on it.
* Ctrl+shift+click on any node/socket connects it to the viewer and
makes it active.
* Ctrl+shift+click in empty space deactivates the active viewer.
* When the active viewer is not visible anymore (e.g. another object
is selected, or the current node group is exit), it is deactivated.
* Clicking on the icon in the header of the Viewer node toggles whether
its active or not.
**Pinning**
* The spreadsheet still allows pinning the active viewer as before.
When pinned, the spreadsheet still references the viewer node even
when it becomes inactive.
* The viewport does not support pinning at the moment. It always shows
the active viewer.
**Attribute**
* When a field is linked to the second input of the viewer node it is
displayed as an overlay in the viewport.
* When possible the correct domain for the attribute is determined
automatically. This does not work in all cases. It falls back to the
face corner domain on meshes and the point domain on curves. When
necessary, the domain can be picked manually.
* The spreadsheet now only shows the "Viewer" column for the domain
that is selected in the Viewer node.
* Instance attributes are visualized as a constant color per instance.
**Viewport Options**
* The attribute overlay opacity can be controlled with the "Viewer Node"
setting in the overlays popover.
* A viewport can be configured not to show intermediate viewer-geometry
by disabling the "Viewer Node" option in the "View" menu.
**Implementation Details**
* The "spreadsheet context path" was generalized to a "viewer path" that
is used in more places now.
* The viewer node itself determines the attribute domain, evaluates the
field and stores the result in a `.viewer` attribute.
* A new "viewer attribute' overlay displays the data from the `.viewer`
attribute.
* The ground truth for the active viewer node is stored in the workspace
now. Node editors, spreadsheets and viewports retrieve the active
viewer from there unless they are pinned.
* The depsgraph object iterator has a new "viewer path" setting. When set,
the viewed geometry of the corresponding object is part of the iterator
instead of the final evaluated geometry.
* To support the instance attribute overlay `DupliObject` was extended
to contain the information necessary for drawing the overlay.
* The ctrl+shift+click operator has been refactored so that it can make
existing links to viewers active again.
* The auto-domain-detection in the Viewer node works by checking the
"preferred domain" for every field input. If there is not exactly one
preferred domain, the fallback is used.
Known limitations:
* Loose edges of meshes don't have the attribute overlay. This could be
added separately if necessary.
* Some attributes are hard to visualize as a color directly. For example,
the values might have to be normalized or some should be drawn as arrays.
For now, we encourage users to build node groups that generate appropriate
viewer-geometry. We might include some of that functionality in future versions.
Support for displaying attribute values as text in the viewport is planned as well.
* There seems to be an issue with the attribute overlay for pointclouds on
nvidia gpus, to be investigated.
Differential Revision: https://developer.blender.org/D15954
2022-09-28 17:54:59 +02:00
|
|
|
MBC_VIEWER_ATTRIBUTE_OVERLAY = (1u << MBC_BATCH_INDEX(surface_viewer_attribute)),
|
2022-06-05 12:04:42 +02:00
|
|
|
MBC_SURFACE_PER_MAT = (1u << MBC_BATCH_LEN),
|
|
|
|
|
};
|
|
|
|
|
ENUM_OPERATORS(DRWBatchFlag, MBC_SURFACE_PER_MAT);
|
2021-08-23 12:46:14 -03:00
|
|
|
|
|
|
|
|
BLI_STATIC_ASSERT(MBC_BATCH_LEN < 32, "Number of batches exceeded the limit of bit fields");
|
|
|
|
|
|
2022-06-05 12:04:42 +02:00
|
|
|
struct MeshExtractLooseGeom {
|
OpenSubDiv: add support for an OpenGL evaluator
This evaluator is used in order to evaluate subdivision at render time, allowing for
faster renders of meshes with a subdivision surface modifier placed at the last
position in the modifier list.
When evaluating the subsurf modifier, we detect whether we can delegate evaluation
to the draw code. If so, the subdivision is first evaluated on the GPU using our own
custom evaluator (only the coarse data needs to be initially sent to the GPU), then,
buffers for the final `MeshBufferCache` are filled on the GPU using a set of
compute shaders. However, some buffers are still filled on the CPU side, if doing so
on the GPU is impractical (e.g. the line adjacency buffer used for x-ray, whose
logic is hardly GPU compatible).
This is done at the mesh buffer extraction level so that the result can be readily used
in the various OpenGL engines, without having to write custom geometry or tesselation
shaders.
We use our own subdivision evaluation shaders, instead of OpenSubDiv's vanilla one, in
order to control the data layout, and interpolation. For example, we store vertex colors
as compressed 16-bit integers, while OpenSubDiv's default evaluator only work for float
types.
In order to still access the modified geometry on the CPU side, for use in modifiers
or transform operators, a dedicated wrapper type is added `MESH_WRAPPER_TYPE_SUBD`.
Subdivision will be lazily evaluated via `BKE_object_get_evaluated_mesh` which will
create such a wrapper if possible. If the final subdivision surface is not needed on
the CPU side, `BKE_object_get_evaluated_mesh_no_subsurf` should be used.
Enabling or disabling GPU subdivision can be done through the user preferences (under
Viewport -> Subdivision).
See patch description for benchmarks.
Reviewed By: campbellbarton, jbakker, fclem, brecht, #eevee_viewport
Differential Revision: https://developer.blender.org/D12406
2021-12-27 16:34:47 +01:00
|
|
|
int edge_len;
|
|
|
|
|
int vert_len;
|
|
|
|
|
int *verts;
|
|
|
|
|
int *edges;
|
2022-06-05 12:04:42 +02:00
|
|
|
};
|
OpenSubDiv: add support for an OpenGL evaluator
This evaluator is used in order to evaluate subdivision at render time, allowing for
faster renders of meshes with a subdivision surface modifier placed at the last
position in the modifier list.
When evaluating the subsurf modifier, we detect whether we can delegate evaluation
to the draw code. If so, the subdivision is first evaluated on the GPU using our own
custom evaluator (only the coarse data needs to be initially sent to the GPU), then,
buffers for the final `MeshBufferCache` are filled on the GPU using a set of
compute shaders. However, some buffers are still filled on the CPU side, if doing so
on the GPU is impractical (e.g. the line adjacency buffer used for x-ray, whose
logic is hardly GPU compatible).
This is done at the mesh buffer extraction level so that the result can be readily used
in the various OpenGL engines, without having to write custom geometry or tesselation
shaders.
We use our own subdivision evaluation shaders, instead of OpenSubDiv's vanilla one, in
order to control the data layout, and interpolation. For example, we store vertex colors
as compressed 16-bit integers, while OpenSubDiv's default evaluator only work for float
types.
In order to still access the modified geometry on the CPU side, for use in modifiers
or transform operators, a dedicated wrapper type is added `MESH_WRAPPER_TYPE_SUBD`.
Subdivision will be lazily evaluated via `BKE_object_get_evaluated_mesh` which will
create such a wrapper if possible. If the final subdivision surface is not needed on
the CPU side, `BKE_object_get_evaluated_mesh_no_subsurf` should be used.
Enabling or disabling GPU subdivision can be done through the user preferences (under
Viewport -> Subdivision).
See patch description for benchmarks.
Reviewed By: campbellbarton, jbakker, fclem, brecht, #eevee_viewport
Differential Revision: https://developer.blender.org/D12406
2021-12-27 16:34:47 +01:00
|
|
|
|
2021-05-31 09:32:37 +02:00
|
|
|
/**
|
|
|
|
|
* Data that are kept around between extractions to reduce rebuilding time.
|
|
|
|
|
*
|
|
|
|
|
* - Loose geometry.
|
|
|
|
|
*/
|
2022-06-05 12:04:42 +02:00
|
|
|
struct MeshBufferCache {
|
2021-08-23 13:28:55 -03:00
|
|
|
MeshBufferList buff;
|
|
|
|
|
|
OpenSubDiv: add support for an OpenGL evaluator
This evaluator is used in order to evaluate subdivision at render time, allowing for
faster renders of meshes with a subdivision surface modifier placed at the last
position in the modifier list.
When evaluating the subsurf modifier, we detect whether we can delegate evaluation
to the draw code. If so, the subdivision is first evaluated on the GPU using our own
custom evaluator (only the coarse data needs to be initially sent to the GPU), then,
buffers for the final `MeshBufferCache` are filled on the GPU using a set of
compute shaders. However, some buffers are still filled on the CPU side, if doing so
on the GPU is impractical (e.g. the line adjacency buffer used for x-ray, whose
logic is hardly GPU compatible).
This is done at the mesh buffer extraction level so that the result can be readily used
in the various OpenGL engines, without having to write custom geometry or tesselation
shaders.
We use our own subdivision evaluation shaders, instead of OpenSubDiv's vanilla one, in
order to control the data layout, and interpolation. For example, we store vertex colors
as compressed 16-bit integers, while OpenSubDiv's default evaluator only work for float
types.
In order to still access the modified geometry on the CPU side, for use in modifiers
or transform operators, a dedicated wrapper type is added `MESH_WRAPPER_TYPE_SUBD`.
Subdivision will be lazily evaluated via `BKE_object_get_evaluated_mesh` which will
create such a wrapper if possible. If the final subdivision surface is not needed on
the CPU side, `BKE_object_get_evaluated_mesh_no_subsurf` should be used.
Enabling or disabling GPU subdivision can be done through the user preferences (under
Viewport -> Subdivision).
See patch description for benchmarks.
Reviewed By: campbellbarton, jbakker, fclem, brecht, #eevee_viewport
Differential Revision: https://developer.blender.org/D12406
2021-12-27 16:34:47 +01:00
|
|
|
MeshExtractLooseGeom loose_geom;
|
2021-06-15 15:31:17 +02:00
|
|
|
|
|
|
|
|
struct {
|
2021-07-20 11:43:38 -03:00
|
|
|
int *tri_first_index;
|
|
|
|
|
int *mat_tri_len;
|
2021-06-15 15:31:17 +02:00
|
|
|
int visible_tri_len;
|
2021-07-20 11:43:38 -03:00
|
|
|
} poly_sorted;
|
2022-06-05 12:04:42 +02:00
|
|
|
};
|
2021-05-31 09:32:37 +02:00
|
|
|
|
2021-08-23 13:28:55 -03:00
|
|
|
#define FOREACH_MESH_BUFFER_CACHE(batch_cache, mbc) \
|
|
|
|
|
for (MeshBufferCache *mbc = &batch_cache->final; \
|
|
|
|
|
mbc == &batch_cache->final || mbc == &batch_cache->cage || mbc == &batch_cache->uv_cage; \
|
|
|
|
|
mbc = (mbc == &batch_cache->final) ? \
|
|
|
|
|
&batch_cache->cage : \
|
|
|
|
|
((mbc == &batch_cache->cage) ? &batch_cache->uv_cage : NULL))
|
2019-07-14 16:49:44 +02:00
|
|
|
|
2022-06-05 12:04:42 +02:00
|
|
|
struct MeshBatchCache {
|
2021-08-23 13:28:55 -03:00
|
|
|
MeshBufferCache final, cage, uv_cage;
|
2021-05-31 09:32:37 +02:00
|
|
|
|
2021-08-23 12:46:14 -03:00
|
|
|
MeshBatchList batch;
|
2019-07-14 16:49:44 +02:00
|
|
|
|
2021-08-23 09:52:13 -03:00
|
|
|
/* Index buffer per material. These are subranges of `ibo.tris` */
|
|
|
|
|
GPUIndexBuf **tris_per_mat;
|
|
|
|
|
|
2019-07-14 16:49:44 +02:00
|
|
|
GPUBatch **surface_per_mat;
|
|
|
|
|
|
2022-06-05 12:15:22 +02:00
|
|
|
DRWSubdivCache *subdiv_cache;
|
OpenSubDiv: add support for an OpenGL evaluator
This evaluator is used in order to evaluate subdivision at render time, allowing for
faster renders of meshes with a subdivision surface modifier placed at the last
position in the modifier list.
When evaluating the subsurf modifier, we detect whether we can delegate evaluation
to the draw code. If so, the subdivision is first evaluated on the GPU using our own
custom evaluator (only the coarse data needs to be initially sent to the GPU), then,
buffers for the final `MeshBufferCache` are filled on the GPU using a set of
compute shaders. However, some buffers are still filled on the CPU side, if doing so
on the GPU is impractical (e.g. the line adjacency buffer used for x-ray, whose
logic is hardly GPU compatible).
This is done at the mesh buffer extraction level so that the result can be readily used
in the various OpenGL engines, without having to write custom geometry or tesselation
shaders.
We use our own subdivision evaluation shaders, instead of OpenSubDiv's vanilla one, in
order to control the data layout, and interpolation. For example, we store vertex colors
as compressed 16-bit integers, while OpenSubDiv's default evaluator only work for float
types.
In order to still access the modified geometry on the CPU side, for use in modifiers
or transform operators, a dedicated wrapper type is added `MESH_WRAPPER_TYPE_SUBD`.
Subdivision will be lazily evaluated via `BKE_object_get_evaluated_mesh` which will
create such a wrapper if possible. If the final subdivision surface is not needed on
the CPU side, `BKE_object_get_evaluated_mesh_no_subsurf` should be used.
Enabling or disabling GPU subdivision can be done through the user preferences (under
Viewport -> Subdivision).
See patch description for benchmarks.
Reviewed By: campbellbarton, jbakker, fclem, brecht, #eevee_viewport
Differential Revision: https://developer.blender.org/D12406
2021-12-27 16:34:47 +01:00
|
|
|
|
2022-06-05 12:15:22 +02:00
|
|
|
DRWBatchFlag batch_requested;
|
|
|
|
|
DRWBatchFlag batch_ready;
|
2019-07-14 16:49:44 +02:00
|
|
|
|
2022-06-05 12:15:22 +02:00
|
|
|
/* Settings to determine if cache is invalid. */
|
2019-07-14 16:49:44 +02:00
|
|
|
int edge_len;
|
|
|
|
|
int tri_len;
|
|
|
|
|
int poly_len;
|
|
|
|
|
int vert_len;
|
|
|
|
|
int mat_len;
|
2022-06-05 12:15:22 +02:00
|
|
|
/* Instantly invalidates cache, skipping mesh check */
|
|
|
|
|
bool is_dirty;
|
2019-07-14 16:49:44 +02:00
|
|
|
bool is_editmode;
|
|
|
|
|
bool is_uvsyncsel;
|
|
|
|
|
|
2022-06-05 12:15:22 +02:00
|
|
|
DRW_MeshWeightState weight_state;
|
2019-07-14 16:49:44 +02:00
|
|
|
|
|
|
|
|
DRW_MeshCDMask cd_used, cd_needed, cd_used_over_time;
|
|
|
|
|
|
EEVEE: support Curves attributes rendering
This adds support to render Curves attributes in EEVEE.
Each attribute is stored in a texture derived from a VBO. As the
shading group needs the textures to be valid upon creation, the
attributes are created and setup during its very creation, instead
of doing it lazily via create_requested which we cannot rely on
anyway as contrary to the mesh batch, we do cannot really tell if
attributes need to be updated or else via some `DRW_batch_requested`.
Since point attributes need refinement, and since attributes are all
cast to vec4/float4 to account for differences in type conversions
between Blender and OpenGL, the refinement shader for points is
used as is. The point attributes are stored for each subdivision level
in CurvesEvalFinalCache. Each subdivision level also keeps track of the
attributes already in use so they are properly updated when needed.
Some basic garbage collection was added similar to what is done
for meshes: if the attributes used over time have been different
from the currently used attributes for too long, then the buffers
are freed, ensuring that stale attributesare removed.
This adds `CurvesInfos` to the shader creation info, which stores
the scope in which the attributes are defined. Scopes are stored
as booleans, in an array indexed by attribute loading order which
is also the order in which the attributes were added to the material.
A mapping is necessary between the indices used for the scoping, and
the ones used in the Curves cache, as this may contain stale
attributes which have not been garbage collected yet.
Common utilities with the mesh code for handling requested
attributes were moved to a separate file.
Differential Revision: https://developer.blender.org/D14916
2022-05-24 05:02:57 +02:00
|
|
|
DRW_Attributes attr_used, attr_needed, attr_used_over_time;
|
2021-10-26 18:16:33 -03:00
|
|
|
|
2019-07-14 16:49:44 +02:00
|
|
|
int lastmatch;
|
|
|
|
|
|
|
|
|
|
/* Valid only if edge_detection is up to date. */
|
|
|
|
|
bool is_manifold;
|
|
|
|
|
|
2019-09-03 13:42:11 +02:00
|
|
|
/* Total areas for drawing UV Stretching. Contains the summed area in mesh
|
|
|
|
|
* space (`tot_area`) and the summed area in uv space (`tot_uvarea`).
|
|
|
|
|
*
|
|
|
|
|
* Only valid after `DRW_mesh_batch_cache_create_requested` has been called. */
|
|
|
|
|
float tot_area, tot_uv_area;
|
|
|
|
|
|
2019-07-14 16:49:44 +02:00
|
|
|
bool no_loose_wire;
|
2022-04-05 11:42:55 -07:00
|
|
|
|
|
|
|
|
eV3DShadingColorType color_type;
|
|
|
|
|
bool pbvh_is_drawing;
|
2022-06-05 12:04:42 +02:00
|
|
|
};
|
2019-07-14 16:49:44 +02:00
|
|
|
|
2021-06-14 08:00:42 -03:00
|
|
|
#define MBC_EDITUV \
|
|
|
|
|
(MBC_EDITUV_FACES_STRETCH_AREA | MBC_EDITUV_FACES_STRETCH_ANGLE | MBC_EDITUV_FACES | \
|
|
|
|
|
MBC_EDITUV_EDGES | MBC_EDITUV_VERTS | MBC_EDITUV_FACEDOTS | MBC_WIRE_LOOPS_UVS)
|
|
|
|
|
|
2022-06-05 12:04:42 +02:00
|
|
|
namespace blender::draw {
|
|
|
|
|
|
2022-06-05 12:15:22 +02:00
|
|
|
void mesh_buffer_cache_create_requested(TaskGraph *task_graph,
|
2021-08-26 12:36:13 +10:00
|
|
|
MeshBatchCache *cache,
|
|
|
|
|
MeshBufferCache *mbc,
|
2022-01-11 15:42:07 +01:00
|
|
|
Object *object,
|
2019-07-14 16:49:44 +02:00
|
|
|
Mesh *me,
|
2022-01-07 11:38:08 +11:00
|
|
|
bool is_editmode,
|
|
|
|
|
bool is_paint_mode,
|
|
|
|
|
bool is_mode_active,
|
2020-01-07 14:06:33 +11:00
|
|
|
const float obmat[4][4],
|
2022-01-07 11:38:08 +11:00
|
|
|
bool do_final,
|
|
|
|
|
bool do_uvedit,
|
2020-02-19 01:44:52 +01:00
|
|
|
const Scene *scene,
|
2022-06-05 12:15:22 +02:00
|
|
|
const ToolSettings *ts,
|
2022-01-07 11:38:08 +11:00
|
|
|
bool use_hide);
|
2021-06-01 12:12:13 +02:00
|
|
|
|
OpenSubDiv: add support for an OpenGL evaluator
This evaluator is used in order to evaluate subdivision at render time, allowing for
faster renders of meshes with a subdivision surface modifier placed at the last
position in the modifier list.
When evaluating the subsurf modifier, we detect whether we can delegate evaluation
to the draw code. If so, the subdivision is first evaluated on the GPU using our own
custom evaluator (only the coarse data needs to be initially sent to the GPU), then,
buffers for the final `MeshBufferCache` are filled on the GPU using a set of
compute shaders. However, some buffers are still filled on the CPU side, if doing so
on the GPU is impractical (e.g. the line adjacency buffer used for x-ray, whose
logic is hardly GPU compatible).
This is done at the mesh buffer extraction level so that the result can be readily used
in the various OpenGL engines, without having to write custom geometry or tesselation
shaders.
We use our own subdivision evaluation shaders, instead of OpenSubDiv's vanilla one, in
order to control the data layout, and interpolation. For example, we store vertex colors
as compressed 16-bit integers, while OpenSubDiv's default evaluator only work for float
types.
In order to still access the modified geometry on the CPU side, for use in modifiers
or transform operators, a dedicated wrapper type is added `MESH_WRAPPER_TYPE_SUBD`.
Subdivision will be lazily evaluated via `BKE_object_get_evaluated_mesh` which will
create such a wrapper if possible. If the final subdivision surface is not needed on
the CPU side, `BKE_object_get_evaluated_mesh_no_subsurf` should be used.
Enabling or disabling GPU subdivision can be done through the user preferences (under
Viewport -> Subdivision).
See patch description for benchmarks.
Reviewed By: campbellbarton, jbakker, fclem, brecht, #eevee_viewport
Differential Revision: https://developer.blender.org/D12406
2021-12-27 16:34:47 +01:00
|
|
|
void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache *cache,
|
|
|
|
|
MeshBufferCache *mbc,
|
2022-06-05 12:15:22 +02:00
|
|
|
DRWSubdivCache *subdiv_cache,
|
|
|
|
|
MeshRenderData *mr);
|
OpenSubDiv: add support for an OpenGL evaluator
This evaluator is used in order to evaluate subdivision at render time, allowing for
faster renders of meshes with a subdivision surface modifier placed at the last
position in the modifier list.
When evaluating the subsurf modifier, we detect whether we can delegate evaluation
to the draw code. If so, the subdivision is first evaluated on the GPU using our own
custom evaluator (only the coarse data needs to be initially sent to the GPU), then,
buffers for the final `MeshBufferCache` are filled on the GPU using a set of
compute shaders. However, some buffers are still filled on the CPU side, if doing so
on the GPU is impractical (e.g. the line adjacency buffer used for x-ray, whose
logic is hardly GPU compatible).
This is done at the mesh buffer extraction level so that the result can be readily used
in the various OpenGL engines, without having to write custom geometry or tesselation
shaders.
We use our own subdivision evaluation shaders, instead of OpenSubDiv's vanilla one, in
order to control the data layout, and interpolation. For example, we store vertex colors
as compressed 16-bit integers, while OpenSubDiv's default evaluator only work for float
types.
In order to still access the modified geometry on the CPU side, for use in modifiers
or transform operators, a dedicated wrapper type is added `MESH_WRAPPER_TYPE_SUBD`.
Subdivision will be lazily evaluated via `BKE_object_get_evaluated_mesh` which will
create such a wrapper if possible. If the final subdivision surface is not needed on
the CPU side, `BKE_object_get_evaluated_mesh_no_subsurf` should be used.
Enabling or disabling GPU subdivision can be done through the user preferences (under
Viewport -> Subdivision).
See patch description for benchmarks.
Reviewed By: campbellbarton, jbakker, fclem, brecht, #eevee_viewport
Differential Revision: https://developer.blender.org/D12406
2021-12-27 16:34:47 +01:00
|
|
|
|
2022-06-05 12:04:42 +02:00
|
|
|
} // namespace blender::draw
|