Compare commits
5 Commits
temp-paral
...
tmp-pointc
Author | SHA1 | Date | |
---|---|---|---|
e8f8c13d4b | |||
0c062a9e08 | |||
38655c43fb | |||
102f66c0a4 | |||
5e12123685 |
@@ -143,7 +143,6 @@ set(SRC
|
||||
engines/overlay/overlay_outline.c
|
||||
engines/overlay/overlay_paint.c
|
||||
engines/overlay/overlay_particle.c
|
||||
engines/overlay/overlay_pointcloud.c
|
||||
engines/overlay/overlay_sculpt.c
|
||||
engines/overlay/overlay_shader.c
|
||||
engines/overlay/overlay_wireframe.c
|
||||
@@ -271,6 +270,7 @@ data_to_c_simple(engines/workbench/shaders/workbench_material_lib.glsl SRC)
|
||||
data_to_c_simple(engines/workbench/shaders/workbench_merge_infront_frag.glsl SRC)
|
||||
data_to_c_simple(engines/workbench/shaders/workbench_prepass_frag.glsl SRC)
|
||||
data_to_c_simple(engines/workbench/shaders/workbench_prepass_hair_vert.glsl SRC)
|
||||
data_to_c_simple(engines/workbench/shaders/workbench_prepass_pointcloud_vert.glsl SRC)
|
||||
data_to_c_simple(engines/workbench/shaders/workbench_prepass_vert.glsl SRC)
|
||||
data_to_c_simple(engines/workbench/shaders/workbench_shader_interface_lib.glsl SRC)
|
||||
data_to_c_simple(engines/workbench/shaders/workbench_shadow_caps_geom.glsl SRC)
|
||||
@@ -285,6 +285,7 @@ data_to_c_simple(engines/workbench/shaders/workbench_world_light_lib.glsl SRC)
|
||||
|
||||
data_to_c_simple(intern/shaders/common_colormanagement_lib.glsl SRC)
|
||||
data_to_c_simple(intern/shaders/common_globals_lib.glsl SRC)
|
||||
data_to_c_simple(intern/shaders/common_pointcloud_lib.glsl SRC)
|
||||
data_to_c_simple(intern/shaders/common_hair_lib.glsl SRC)
|
||||
data_to_c_simple(intern/shaders/common_hair_refine_vert.glsl SRC)
|
||||
data_to_c_simple(intern/shaders/common_view_lib.glsl SRC)
|
||||
|
@@ -182,7 +182,6 @@ static void OVERLAY_cache_init(void *vedata)
|
||||
OVERLAY_motion_path_cache_init(vedata);
|
||||
OVERLAY_outline_cache_init(vedata);
|
||||
OVERLAY_particle_cache_init(vedata);
|
||||
OVERLAY_pointcloud_cache_init(vedata);
|
||||
OVERLAY_wireframe_cache_init(vedata);
|
||||
}
|
||||
|
||||
@@ -403,12 +402,6 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob)
|
||||
OVERLAY_particle_cache_populate(vedata, ob);
|
||||
}
|
||||
|
||||
/* TODO: these should not be overlays, just here for testing since it's
|
||||
* easier to implement than integrating it into eevee/workbench. */
|
||||
if (ob->type == OB_POINTCLOUD) {
|
||||
OVERLAY_pointcloud_cache_populate(vedata, ob);
|
||||
}
|
||||
|
||||
/* Relationship, object center, bounbox ... */
|
||||
if (!pd->hide_overlays) {
|
||||
OVERLAY_extra_cache_populate(vedata, ob);
|
||||
@@ -482,7 +475,6 @@ static void OVERLAY_draw_scene(void *vedata)
|
||||
OVERLAY_armature_draw(vedata);
|
||||
OVERLAY_particle_draw(vedata);
|
||||
OVERLAY_metaball_draw(vedata);
|
||||
OVERLAY_pointcloud_draw(vedata);
|
||||
OVERLAY_gpencil_draw(vedata);
|
||||
OVERLAY_extra_draw(vedata);
|
||||
|
||||
|
@@ -138,6 +138,11 @@ void OVERLAY_outline_cache_init(OVERLAY_Data *vedata)
|
||||
pd->outlines_grp = grp = DRW_shgroup_create(sh_geom, psl->outlines_prepass_ps);
|
||||
DRW_shgroup_uniform_bool_copy(grp, "isTransform", (G.moving & G_TRANSFORM_OBJ) != 0);
|
||||
|
||||
GPUShader *sh_geom_ptcloud = OVERLAY_shader_outline_prepass_pointcloud();
|
||||
|
||||
pd->outlines_ptcloud_grp = grp = DRW_shgroup_create(sh_geom_ptcloud, psl->outlines_prepass_ps);
|
||||
DRW_shgroup_uniform_bool_copy(grp, "isTransform", (G.moving & G_TRANSFORM_OBJ) != 0);
|
||||
|
||||
GPUShader *sh_gpencil = OVERLAY_shader_outline_prepass_gpencil();
|
||||
|
||||
pd->outlines_gpencil_grp = grp = DRW_shgroup_create(sh_gpencil, psl->outlines_prepass_ps);
|
||||
@@ -288,6 +293,12 @@ void OVERLAY_outline_cache_populate(OVERLAY_Data *vedata,
|
||||
return;
|
||||
}
|
||||
|
||||
if (ob->type == OB_POINTCLOUD && pd->wireframe_mode) {
|
||||
/* Looks bad in this case. Could be relaxed if we draw a
|
||||
* wireframe of some sort in the future. */
|
||||
return;
|
||||
}
|
||||
|
||||
if (dupli && !init_dupli) {
|
||||
geom = dupli->outline_geom;
|
||||
shgroup = dupli->outline_shgrp;
|
||||
@@ -307,12 +318,18 @@ void OVERLAY_outline_cache_populate(OVERLAY_Data *vedata,
|
||||
}
|
||||
|
||||
if (geom) {
|
||||
shgroup = pd->outlines_grp;
|
||||
shgroup = (ob->type == OB_POINTCLOUD) ? pd->outlines_ptcloud_grp : pd->outlines_grp;
|
||||
}
|
||||
}
|
||||
|
||||
if (shgroup && geom) {
|
||||
DRW_shgroup_call(shgroup, geom, ob);
|
||||
if (ob->type == OB_POINTCLOUD) {
|
||||
/* Draw range to avoid drawcall batching messing up the instance attrib. */
|
||||
DRW_shgroup_call_instance_range(shgroup, ob, geom, 0, 0);
|
||||
}
|
||||
else {
|
||||
DRW_shgroup_call(shgroup, geom, ob);
|
||||
}
|
||||
}
|
||||
|
||||
if (init_dupli) {
|
||||
|
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Copyright 2020, Blender Foundation.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup draw_engine
|
||||
*/
|
||||
|
||||
#include "DRW_render.h"
|
||||
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "DNA_pointcloud_types.h"
|
||||
|
||||
#include "BKE_pointcache.h"
|
||||
|
||||
#include "overlay_private.h"
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name PointCloud
|
||||
* \{ */
|
||||
|
||||
void OVERLAY_pointcloud_cache_init(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
GPUShader *sh;
|
||||
DRWShadingGroup *grp;
|
||||
|
||||
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
|
||||
DRW_PASS_CREATE(psl->pointcloud_ps, state | pd->clipping_state);
|
||||
|
||||
sh = OVERLAY_shader_pointcloud_dot();
|
||||
pd->pointcloud_dots_grp = grp = DRW_shgroup_create(sh, psl->pointcloud_ps);
|
||||
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
|
||||
}
|
||||
|
||||
void OVERLAY_pointcloud_cache_populate(OVERLAY_Data *vedata, Object *ob)
|
||||
{
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
|
||||
struct GPUBatch *geom = DRW_cache_pointcloud_get_dots(ob);
|
||||
|
||||
const float color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
|
||||
DRWShadingGroup *grp = DRW_shgroup_create_sub(pd->pointcloud_dots_grp);
|
||||
DRW_shgroup_uniform_vec4_copy(grp, "color", color);
|
||||
DRW_shgroup_call(grp, geom, ob);
|
||||
}
|
||||
|
||||
void OVERLAY_pointcloud_draw(OVERLAY_Data *vedata)
|
||||
{
|
||||
OVERLAY_PassList *psl = vedata->psl;
|
||||
|
||||
DRW_draw_pass(psl->pointcloud_ps);
|
||||
}
|
||||
|
||||
/** \} */
|
@@ -243,6 +243,7 @@ typedef struct OVERLAY_PrivateData {
|
||||
DRWShadingGroup *motion_path_lines_grp;
|
||||
DRWShadingGroup *motion_path_points_grp;
|
||||
DRWShadingGroup *outlines_grp;
|
||||
DRWShadingGroup *outlines_ptcloud_grp;
|
||||
DRWShadingGroup *outlines_gpencil_grp;
|
||||
DRWShadingGroup *paint_depth_grp;
|
||||
DRWShadingGroup *paint_surf_grp;
|
||||
@@ -550,10 +551,6 @@ void OVERLAY_particle_cache_init(OVERLAY_Data *vedata);
|
||||
void OVERLAY_particle_cache_populate(OVERLAY_Data *vedata, Object *ob);
|
||||
void OVERLAY_particle_draw(OVERLAY_Data *vedata);
|
||||
|
||||
void OVERLAY_pointcloud_cache_init(OVERLAY_Data *vedata);
|
||||
void OVERLAY_pointcloud_cache_populate(OVERLAY_Data *vedata, Object *ob);
|
||||
void OVERLAY_pointcloud_draw(OVERLAY_Data *vedata);
|
||||
|
||||
void OVERLAY_sculpt_cache_init(OVERLAY_Data *vedata);
|
||||
void OVERLAY_sculpt_cache_populate(OVERLAY_Data *vedata, Object *ob);
|
||||
void OVERLAY_sculpt_draw(OVERLAY_Data *vedata);
|
||||
@@ -610,6 +607,7 @@ GPUShader *OVERLAY_shader_motion_path_vert(void);
|
||||
GPUShader *OVERLAY_shader_uniform_color(void);
|
||||
GPUShader *OVERLAY_shader_outline_prepass(bool use_wire);
|
||||
GPUShader *OVERLAY_shader_outline_prepass_gpencil(void);
|
||||
GPUShader *OVERLAY_shader_outline_prepass_pointcloud(void);
|
||||
GPUShader *OVERLAY_shader_extra_grid(void);
|
||||
GPUShader *OVERLAY_shader_outline_detect(void);
|
||||
GPUShader *OVERLAY_shader_paint_face(void);
|
||||
|
@@ -127,6 +127,7 @@ extern char datatoc_common_fullscreen_vert_glsl[];
|
||||
extern char datatoc_common_fxaa_lib_glsl[];
|
||||
extern char datatoc_common_smaa_lib_glsl[];
|
||||
extern char datatoc_common_globals_lib_glsl[];
|
||||
extern char datatoc_common_pointcloud_lib_glsl[];
|
||||
extern char datatoc_common_view_lib_glsl[];
|
||||
|
||||
typedef struct OVERLAY_Shaders {
|
||||
@@ -181,6 +182,7 @@ typedef struct OVERLAY_Shaders {
|
||||
GPUShader *motion_path_vert;
|
||||
GPUShader *outline_prepass;
|
||||
GPUShader *outline_prepass_gpencil;
|
||||
GPUShader *outline_prepass_pointcloud;
|
||||
GPUShader *outline_prepass_wire;
|
||||
GPUShader *outline_detect;
|
||||
GPUShader *paint_face;
|
||||
@@ -1135,6 +1137,33 @@ GPUShader *OVERLAY_shader_outline_prepass_gpencil(void)
|
||||
return sh_data->outline_prepass_gpencil;
|
||||
}
|
||||
|
||||
GPUShader *OVERLAY_shader_outline_prepass_pointcloud(void)
|
||||
{
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
const GPUShaderConfigData *sh_cfg = &GPU_shader_cfg_data[draw_ctx->sh_cfg];
|
||||
OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
|
||||
if (!sh_data->outline_prepass_pointcloud) {
|
||||
sh_data->outline_prepass_pointcloud = GPU_shader_create_from_arrays({
|
||||
.vert = (const char *[]){sh_cfg->lib,
|
||||
datatoc_common_view_lib_glsl,
|
||||
datatoc_common_pointcloud_lib_glsl,
|
||||
datatoc_gpu_shader_common_obinfos_lib_glsl,
|
||||
datatoc_outline_prepass_vert_glsl,
|
||||
NULL},
|
||||
.frag = (const char *[]){datatoc_common_view_lib_glsl,
|
||||
datatoc_gpencil_common_lib_glsl,
|
||||
datatoc_outline_prepass_frag_glsl,
|
||||
NULL},
|
||||
.defs = (const char *[]){sh_cfg->def,
|
||||
"#define POINTCLOUD\n",
|
||||
"#define INSTANCED_ATTR\n",
|
||||
"#define UNIFORM_RESOURCE_ID\n",
|
||||
NULL},
|
||||
});
|
||||
}
|
||||
return sh_data->outline_prepass_pointcloud;
|
||||
}
|
||||
|
||||
GPUShader *OVERLAY_shader_outline_detect(void)
|
||||
{
|
||||
OVERLAY_Shaders *sh_data = &e_data.sh_data[0];
|
||||
|
@@ -235,10 +235,15 @@ void OVERLAY_wireframe_cache_populate(OVERLAY_Data *vedata,
|
||||
}
|
||||
}
|
||||
|
||||
if (use_wire && ob->type == OB_VOLUME) {
|
||||
/* Volume object as points exception. */
|
||||
Volume *volume = ob->data;
|
||||
if (volume->display.wireframe_type == VOLUME_WIREFRAME_POINTS) {
|
||||
if (use_wire && ELEM(ob->type, OB_VOLUME, OB_POINTCLOUD)) {
|
||||
bool draw_as_points = true;
|
||||
if (ob->type == OB_VOLUME) {
|
||||
/* Volume object as points exception. */
|
||||
Volume *volume = ob->data;
|
||||
draw_as_points = volume->display.wireframe_type == VOLUME_WIREFRAME_POINTS;
|
||||
}
|
||||
|
||||
if (draw_as_points) {
|
||||
float *color;
|
||||
OVERLAY_ExtraCallBuffers *cb = OVERLAY_extra_call_buffer_get(vedata, ob);
|
||||
DRW_object_wire_theme_get(ob, draw_ctx->view_layer, &color);
|
||||
|
@@ -1,7 +1,7 @@
|
||||
|
||||
uniform bool isTransform;
|
||||
|
||||
#ifndef USE_GPENCIL
|
||||
#if !defined(USE_GPENCIL) && !defined(POINTCLOUD)
|
||||
in vec3 pos;
|
||||
#endif
|
||||
|
||||
@@ -56,7 +56,11 @@ void main()
|
||||
# endif
|
||||
|
||||
#else
|
||||
# ifdef POINTCLOUD
|
||||
vec3 world_pos = pointcloud_get_pos();
|
||||
# else
|
||||
vec3 world_pos = point_object_to_world(pos);
|
||||
# endif
|
||||
gl_Position = point_world_to_ndc(world_pos);
|
||||
# ifdef USE_GEOM
|
||||
vPos = point_world_to_view(world_pos);
|
||||
|
@@ -2,16 +2,15 @@
|
||||
uniform vec4 color;
|
||||
|
||||
/* ---- Per instance Attrs ---- */
|
||||
in vec3 pointcloud_pos;
|
||||
in vec3 pointcloud_radius;
|
||||
in vec4 ptcloud; /* Position and radius. */
|
||||
|
||||
out vec4 finalColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 world_pos = point_object_to_world(pointcloud_pos);
|
||||
vec3 world_pos = point_object_to_world(ptcloud.xyz);
|
||||
|
||||
vec3 world_size = abs(mat3(ModelMatrix) * vec3(pointcloud_radius));
|
||||
vec3 world_size = abs(mat3(ModelMatrix) * vec3(ptcloud.w));
|
||||
float world_radius = (world_size.x + world_size.y + world_size.z) / 3.0;
|
||||
|
||||
gl_Position = point_world_to_ndc(world_pos);
|
||||
|
@@ -0,0 +1,38 @@
|
||||
|
||||
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(common_pointcloud_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(workbench_shader_interface_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(workbench_common_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(workbench_material_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(workbench_image_lib.glsl)
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 world_pos;
|
||||
pointcloud_get_pos_and_nor(world_pos, normal_interp);
|
||||
|
||||
normal_interp = normalize(normal_world_to_view(normal_interp));
|
||||
|
||||
gl_Position = point_world_to_ndc(world_pos);
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_calc_clip_distance(world_pos);
|
||||
#endif
|
||||
|
||||
uv_interp = vec2(0.0);
|
||||
|
||||
#ifdef OPAQUE_MATERIAL
|
||||
float metallic, roughness;
|
||||
#endif
|
||||
workbench_material_data_get(resource_handle, color_interp, alpha_interp, roughness, metallic);
|
||||
|
||||
if (materialIndex == 0) {
|
||||
color_interp = vec3(1.0);
|
||||
}
|
||||
|
||||
#ifdef OPAQUE_MATERIAL
|
||||
packed_rough_metal = workbench_float_pair_encode(roughness, metallic);
|
||||
#endif
|
||||
|
||||
object_id = int((uint(resource_id) + 1u) & 0xFFu);
|
||||
}
|
@@ -130,6 +130,17 @@ static void workbench_cache_sculpt_populate(WORKBENCH_PrivateData *wpd,
|
||||
}
|
||||
}
|
||||
|
||||
BLI_INLINE void workbench_object_drawcall(DRWShadingGroup *grp, struct GPUBatch *geom, Object *ob)
|
||||
{
|
||||
if (ob->type == OB_POINTCLOUD) {
|
||||
/* Draw range to avoid drawcall batching messing up the instance attrib. */
|
||||
DRW_shgroup_call_instance_range(grp, ob, geom, 0, 0);
|
||||
}
|
||||
else {
|
||||
DRW_shgroup_call(grp, geom, ob);
|
||||
}
|
||||
}
|
||||
|
||||
static void workbench_cache_texpaint_populate(WORKBENCH_PrivateData *wpd, Object *ob)
|
||||
{
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
@@ -145,7 +156,7 @@ static void workbench_cache_texpaint_populate(WORKBENCH_PrivateData *wpd, Object
|
||||
SET_FLAG_FROM_TEST(state, imapaint->interp == IMAGEPAINT_INTERP_LINEAR, GPU_SAMPLER_FILTER);
|
||||
|
||||
DRWShadingGroup *grp = workbench_image_setup(wpd, ob, 0, ima, NULL, state);
|
||||
DRW_shgroup_call(grp, geom, ob);
|
||||
workbench_object_drawcall(grp, geom, ob);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -157,7 +168,7 @@ static void workbench_cache_texpaint_populate(WORKBENCH_PrivateData *wpd, Object
|
||||
continue;
|
||||
}
|
||||
DRWShadingGroup *grp = workbench_image_setup(wpd, ob, i + 1, NULL, NULL, 0);
|
||||
DRW_shgroup_call(grp, geoms[i], ob);
|
||||
workbench_object_drawcall(grp, geoms[i], ob);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -194,7 +205,7 @@ static void workbench_cache_common_populate(WORKBENCH_PrivateData *wpd,
|
||||
|
||||
if (geom) {
|
||||
DRWShadingGroup *grp = workbench_material_setup(wpd, ob, 0, color_type, r_transp);
|
||||
DRW_shgroup_call(grp, geom, ob);
|
||||
workbench_object_drawcall(grp, geom, ob);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -207,7 +218,7 @@ static void workbench_cache_common_populate(WORKBENCH_PrivateData *wpd,
|
||||
continue;
|
||||
}
|
||||
DRWShadingGroup *grp = workbench_material_setup(wpd, ob, i + 1, color_type, r_transp);
|
||||
DRW_shgroup_call(grp, geoms[i], ob);
|
||||
workbench_object_drawcall(grp, geoms[i], ob);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -450,7 +461,7 @@ void workbench_cache_finish(void *ved)
|
||||
/* TODO don't free reuse next redraw. */
|
||||
for (int i = 0; i < 2; i++) {
|
||||
for (int j = 0; j < 2; j++) {
|
||||
for (int k = 0; k < 2; k++) {
|
||||
for (int k = 0; k < WORKBENCH_DATATYPE_MAX; k++) {
|
||||
if (wpd->prepass[i][j][k].material_hash) {
|
||||
BLI_ghash_free(wpd->prepass[i][j][k].material_hash, NULL, NULL);
|
||||
wpd->prepass[i][j][k].material_hash = NULL;
|
||||
|
@@ -162,7 +162,7 @@ DRWShadingGroup *workbench_material_setup_ex(WORKBENCH_PrivateData *wpd,
|
||||
Object *ob,
|
||||
int mat_nr,
|
||||
eV3DShadingColorType color_type,
|
||||
bool hair,
|
||||
eWORKBENCH_DataType datatype,
|
||||
bool *r_transp)
|
||||
{
|
||||
Image *ima = NULL;
|
||||
@@ -180,7 +180,7 @@ DRWShadingGroup *workbench_material_setup_ex(WORKBENCH_PrivateData *wpd,
|
||||
|
||||
switch (color_type) {
|
||||
case V3D_SHADING_TEXTURE_COLOR: {
|
||||
return workbench_image_setup_ex(wpd, ob, mat_nr, ima, iuser, sampler, hair);
|
||||
return workbench_image_setup_ex(wpd, ob, mat_nr, ima, iuser, sampler, datatype);
|
||||
}
|
||||
case V3D_SHADING_MATERIAL_COLOR: {
|
||||
/* For now, we use the same ubo for material and object coloring but with different indices.
|
||||
@@ -191,7 +191,7 @@ DRWShadingGroup *workbench_material_setup_ex(WORKBENCH_PrivateData *wpd,
|
||||
Material *ma = workbench_object_material_get(ob, mat_nr);
|
||||
|
||||
const bool transp = wpd->shading.xray_alpha < 1.0f || ma->a < 1.0f;
|
||||
WORKBENCH_Prepass *prepass = &wpd->prepass[transp][infront][hair];
|
||||
WORKBENCH_Prepass *prepass = &wpd->prepass[transp][infront][datatype];
|
||||
|
||||
if (r_transp && transp) {
|
||||
*r_transp = true;
|
||||
@@ -216,7 +216,7 @@ DRWShadingGroup *workbench_material_setup_ex(WORKBENCH_PrivateData *wpd,
|
||||
}
|
||||
case V3D_SHADING_VERTEX_COLOR: {
|
||||
const bool transp = wpd->shading.xray_alpha < 1.0f;
|
||||
DRWShadingGroup *grp = wpd->prepass[transp][infront][hair].vcol_shgrp;
|
||||
DRWShadingGroup *grp = wpd->prepass[transp][infront][datatype].vcol_shgrp;
|
||||
return grp;
|
||||
}
|
||||
default: {
|
||||
@@ -231,7 +231,7 @@ DRWShadingGroup *workbench_material_setup_ex(WORKBENCH_PrivateData *wpd,
|
||||
workbench_material_ubo_data(wpd, ob, NULL, &wpd->material_ubo_data_curr[mat_id], color_type);
|
||||
|
||||
const bool transp = wpd->shading.xray_alpha < 1.0f || ob->color[3] < 1.0f;
|
||||
DRWShadingGroup *grp = wpd->prepass[transp][infront][hair].common_shgrp;
|
||||
DRWShadingGroup *grp = wpd->prepass[transp][infront][datatype].common_shgrp;
|
||||
if (resource_changed) {
|
||||
grp = DRW_shgroup_create_sub(grp);
|
||||
DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr);
|
||||
@@ -251,7 +251,7 @@ DRWShadingGroup *workbench_image_setup_ex(WORKBENCH_PrivateData *wpd,
|
||||
Image *ima,
|
||||
ImageUser *iuser,
|
||||
eGPUSamplerState sampler,
|
||||
bool hair)
|
||||
eWORKBENCH_DataType datatype)
|
||||
{
|
||||
GPUTexture *tex = NULL, *tex_tile_data = NULL;
|
||||
|
||||
@@ -275,7 +275,7 @@ DRWShadingGroup *workbench_image_setup_ex(WORKBENCH_PrivateData *wpd,
|
||||
|
||||
const bool infront = (ob->dtx & OB_DRAWXRAY) != 0;
|
||||
const bool transp = wpd->shading.xray_alpha < 1.0f;
|
||||
WORKBENCH_Prepass *prepass = &wpd->prepass[transp][infront][hair];
|
||||
WORKBENCH_Prepass *prepass = &wpd->prepass[transp][infront][datatype];
|
||||
|
||||
DRWShadingGroup **grp_tex = NULL;
|
||||
/* A hashmap stores image shgroups to pack all similar drawcalls together. */
|
||||
|
@@ -59,10 +59,10 @@ void workbench_opaque_engine_init(WORKBENCH_Data *data)
|
||||
});
|
||||
}
|
||||
|
||||
void workbench_opaque_cache_init(WORKBENCH_Data *data)
|
||||
void workbench_opaque_cache_init(WORKBENCH_Data *vedata)
|
||||
{
|
||||
WORKBENCH_PassList *psl = data->psl;
|
||||
WORKBENCH_PrivateData *wpd = data->stl->wpd;
|
||||
WORKBENCH_PassList *psl = vedata->psl;
|
||||
WORKBENCH_PrivateData *wpd = vedata->stl->wpd;
|
||||
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
|
||||
struct GPUShader *sh;
|
||||
DRWShadingGroup *grp;
|
||||
@@ -84,31 +84,31 @@ void workbench_opaque_cache_init(WORKBENCH_Data *data)
|
||||
pass = psl->opaque_ps;
|
||||
}
|
||||
|
||||
for (int hair = 0; hair < 2; hair++) {
|
||||
wpd->prepass[opaque][infront][hair].material_hash = BLI_ghash_ptr_new(__func__);
|
||||
for (eWORKBENCH_DataType data = 0; data < WORKBENCH_DATATYPE_MAX; data++) {
|
||||
wpd->prepass[opaque][infront][data].material_hash = BLI_ghash_ptr_new(__func__);
|
||||
|
||||
sh = workbench_shader_opaque_get(wpd, hair);
|
||||
sh = workbench_shader_opaque_get(wpd, data);
|
||||
|
||||
wpd->prepass[opaque][infront][hair].common_shgrp = grp = DRW_shgroup_create(sh, pass);
|
||||
wpd->prepass[opaque][infront][data].common_shgrp = grp = DRW_shgroup_create(sh, pass);
|
||||
DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr);
|
||||
DRW_shgroup_uniform_int_copy(grp, "materialIndex", -1);
|
||||
DRW_shgroup_uniform_bool_copy(grp, "useMatcap", use_matcap);
|
||||
|
||||
wpd->prepass[opaque][infront][hair].vcol_shgrp = grp = DRW_shgroup_create(sh, pass);
|
||||
wpd->prepass[opaque][infront][data].vcol_shgrp = grp = DRW_shgroup_create(sh, pass);
|
||||
DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr);
|
||||
DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. (uses vcol) */
|
||||
DRW_shgroup_uniform_bool_copy(grp, "useMatcap", use_matcap);
|
||||
|
||||
sh = workbench_shader_opaque_image_get(wpd, hair, false);
|
||||
sh = workbench_shader_opaque_image_get(wpd, data, false);
|
||||
|
||||
wpd->prepass[opaque][infront][hair].image_shgrp = grp = DRW_shgroup_create(sh, pass);
|
||||
wpd->prepass[opaque][infront][data].image_shgrp = grp = DRW_shgroup_create(sh, pass);
|
||||
DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr);
|
||||
DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. */
|
||||
DRW_shgroup_uniform_bool_copy(grp, "useMatcap", use_matcap);
|
||||
|
||||
sh = workbench_shader_opaque_image_get(wpd, hair, true);
|
||||
sh = workbench_shader_opaque_image_get(wpd, data, true);
|
||||
|
||||
wpd->prepass[opaque][infront][hair].image_tiled_shgrp = grp = DRW_shgroup_create(sh, pass);
|
||||
wpd->prepass[opaque][infront][data].image_tiled_shgrp = grp = DRW_shgroup_create(sh, pass);
|
||||
DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr);
|
||||
DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. */
|
||||
DRW_shgroup_uniform_bool_copy(grp, "useMatcap", use_matcap);
|
||||
|
@@ -71,6 +71,14 @@ struct RenderEngine;
|
||||
struct RenderLayer;
|
||||
struct rcti;
|
||||
|
||||
typedef enum eWORKBENCH_DataType {
|
||||
WORKBENCH_DATATYPE_MESH = 0,
|
||||
WORKBENCH_DATATYPE_HAIR,
|
||||
WORKBENCH_DATATYPE_POINTCLOUD,
|
||||
|
||||
WORKBENCH_DATATYPE_MAX,
|
||||
} eWORKBENCH_DataType;
|
||||
|
||||
typedef struct WORKBENCH_FramebufferList {
|
||||
struct GPUFrameBuffer *opaque_fb;
|
||||
struct GPUFrameBuffer *opaque_infront_fb;
|
||||
@@ -293,8 +301,8 @@ typedef struct WORKBENCH_PrivateData {
|
||||
/** Object IDs buffer for curvature & outline. */
|
||||
struct GPUTexture *object_id_tx;
|
||||
|
||||
/** Pre-pass information for each draw types [transparent][infront][hair]. */
|
||||
WORKBENCH_Prepass prepass[2][2][2];
|
||||
/** Pre-pass information for each draw types [transparent][infront][datatype]. */
|
||||
WORKBENCH_Prepass prepass[2][2][WORKBENCH_DATATYPE_MAX];
|
||||
|
||||
/* Materials */
|
||||
/** Copy of vldata->material_ubo for faster access. */
|
||||
@@ -393,14 +401,16 @@ void workbench_shadow_cache_init(WORKBENCH_Data *data);
|
||||
void workbench_shadow_cache_populate(WORKBENCH_Data *data, Object *ob, const bool has_transp_mat);
|
||||
|
||||
/* workbench_shader.c */
|
||||
GPUShader *workbench_shader_opaque_get(WORKBENCH_PrivateData *wpd, bool hair);
|
||||
GPUShader *workbench_shader_opaque_image_get(WORKBENCH_PrivateData *wpd, bool hair, bool tiled);
|
||||
GPUShader *workbench_shader_opaque_get(WORKBENCH_PrivateData *wpd, eWORKBENCH_DataType data);
|
||||
GPUShader *workbench_shader_opaque_image_get(WORKBENCH_PrivateData *wpd,
|
||||
eWORKBENCH_DataType data,
|
||||
bool tiled);
|
||||
GPUShader *workbench_shader_composite_get(WORKBENCH_PrivateData *wpd);
|
||||
GPUShader *workbench_shader_merge_infront_get(WORKBENCH_PrivateData *wpd);
|
||||
|
||||
GPUShader *workbench_shader_transparent_get(WORKBENCH_PrivateData *wpd, bool hair);
|
||||
GPUShader *workbench_shader_transparent_get(WORKBENCH_PrivateData *wpd, eWORKBENCH_DataType data);
|
||||
GPUShader *workbench_shader_transparent_image_get(WORKBENCH_PrivateData *wpd,
|
||||
bool hair,
|
||||
eWORKBENCH_DataType data,
|
||||
bool tiled);
|
||||
GPUShader *workbench_shader_transparent_resolve_get(WORKBENCH_PrivateData *wpd);
|
||||
|
||||
@@ -455,7 +465,7 @@ DRWShadingGroup *workbench_material_setup_ex(WORKBENCH_PrivateData *wpd,
|
||||
Object *ob,
|
||||
int mat_nr,
|
||||
eV3DShadingColorType color_type,
|
||||
bool hair,
|
||||
eWORKBENCH_DataType datatype,
|
||||
bool *r_transp);
|
||||
DRWShadingGroup *workbench_image_setup_ex(WORKBENCH_PrivateData *wpd,
|
||||
Object *ob,
|
||||
@@ -463,17 +473,20 @@ DRWShadingGroup *workbench_image_setup_ex(WORKBENCH_PrivateData *wpd,
|
||||
Image *ima,
|
||||
ImageUser *iuser,
|
||||
eGPUSamplerState sampler,
|
||||
bool hair);
|
||||
eWORKBENCH_DataType datatype);
|
||||
|
||||
#define WORKBENCH_OBJECT_DATATYPE(ob) \
|
||||
((ob->type == OB_POINTCLOUD) ? WORKBENCH_DATATYPE_POINTCLOUD : WORKBENCH_DATATYPE_MESH)
|
||||
|
||||
#define workbench_material_setup(wpd, ob, mat_nr, color_type, r_transp) \
|
||||
workbench_material_setup_ex(wpd, ob, mat_nr, color_type, false, r_transp)
|
||||
workbench_material_setup_ex(wpd, ob, mat_nr, color_type, WORKBENCH_OBJECT_DATATYPE(ob), r_transp)
|
||||
#define workbench_image_setup(wpd, ob, mat_nr, ima, iuser, interp) \
|
||||
workbench_image_setup_ex(wpd, ob, mat_nr, ima, iuser, interp, false)
|
||||
workbench_image_setup_ex(wpd, ob, mat_nr, ima, iuser, interp, WORKBENCH_OBJECT_DATATYPE(ob))
|
||||
|
||||
#define workbench_material_hair_setup(wpd, ob, mat_nr, color_type) \
|
||||
workbench_material_setup_ex(wpd, ob, mat_nr, color_type, true, 0)
|
||||
workbench_material_setup_ex(wpd, ob, mat_nr, color_type, WORKBENCH_DATATYPE_HAIR, 0)
|
||||
#define workbench_image_hair_setup(wpd, ob, mat_nr, ima, iuser, interp) \
|
||||
workbench_image_setup_ex(wpd, ob, mat_nr, ima, iuser, interp, true)
|
||||
workbench_image_setup_ex(wpd, ob, mat_nr, ima, iuser, interp, WORKBENCH_DATATYPE_HAIR)
|
||||
|
||||
/* workbench_data.c */
|
||||
void workbench_private_data_init(WORKBENCH_PrivateData *wpd);
|
||||
|
@@ -29,11 +29,13 @@
|
||||
#include "workbench_private.h"
|
||||
|
||||
extern char datatoc_common_hair_lib_glsl[];
|
||||
extern char datatoc_common_pointcloud_lib_glsl[];
|
||||
extern char datatoc_common_view_lib_glsl[];
|
||||
extern char datatoc_common_smaa_lib_glsl[];
|
||||
|
||||
extern char datatoc_workbench_prepass_vert_glsl[];
|
||||
extern char datatoc_workbench_prepass_hair_vert_glsl[];
|
||||
extern char datatoc_workbench_prepass_pointcloud_vert_glsl[];
|
||||
extern char datatoc_workbench_prepass_frag_glsl[];
|
||||
|
||||
extern char datatoc_workbench_effect_cavity_frag_glsl[];
|
||||
@@ -74,7 +76,6 @@ extern char datatoc_gpu_shader_common_obinfos_lib_glsl[];
|
||||
/* Maximum number of variations. */
|
||||
#define MAX_LIGHTING 3
|
||||
#define MAX_COLOR 3
|
||||
#define MAX_GEOM 2
|
||||
|
||||
enum {
|
||||
VOLUME_SH_SLICE = 0,
|
||||
@@ -85,8 +86,9 @@ enum {
|
||||
#define VOLUME_SH_MAX (1 << (VOLUME_SH_CUBIC + 1))
|
||||
|
||||
static struct {
|
||||
struct GPUShader *opaque_prepass_sh_cache[GPU_SHADER_CFG_LEN][MAX_GEOM][MAX_COLOR];
|
||||
struct GPUShader *transp_prepass_sh_cache[GPU_SHADER_CFG_LEN][MAX_GEOM][MAX_LIGHTING][MAX_COLOR];
|
||||
struct GPUShader *opaque_prepass_sh_cache[GPU_SHADER_CFG_LEN][WORKBENCH_DATATYPE_MAX][MAX_COLOR];
|
||||
struct GPUShader *transp_prepass_sh_cache[GPU_SHADER_CFG_LEN][WORKBENCH_DATATYPE_MAX]
|
||||
[MAX_LIGHTING][MAX_COLOR];
|
||||
|
||||
struct GPUShader *opaque_composite_sh[MAX_LIGHTING];
|
||||
struct GPUShader *oit_resolve_sh;
|
||||
@@ -119,6 +121,7 @@ void workbench_shader_library_ensure(void)
|
||||
/* NOTE: Theses needs to be ordered by dependencies. */
|
||||
DRW_SHADER_LIB_ADD(e_data.lib, common_hair_lib);
|
||||
DRW_SHADER_LIB_ADD(e_data.lib, common_view_lib);
|
||||
DRW_SHADER_LIB_ADD(e_data.lib, common_pointcloud_lib);
|
||||
DRW_SHADER_LIB_ADD(e_data.lib, gpu_shader_common_obinfos_lib);
|
||||
DRW_SHADER_LIB_ADD(e_data.lib, workbench_shader_interface_lib);
|
||||
DRW_SHADER_LIB_ADD(e_data.lib, workbench_common_lib);
|
||||
@@ -177,15 +180,18 @@ static int workbench_color_index(WORKBENCH_PrivateData *UNUSED(wpd), bool textur
|
||||
return (textured) ? (tiled ? 2 : 1) : 0;
|
||||
}
|
||||
|
||||
static GPUShader *workbench_shader_get_ex(
|
||||
WORKBENCH_PrivateData *wpd, bool transp, bool hair, bool textured, bool tiled)
|
||||
static GPUShader *workbench_shader_get_ex(WORKBENCH_PrivateData *wpd,
|
||||
bool transp,
|
||||
eWORKBENCH_DataType datatype,
|
||||
bool textured,
|
||||
bool tiled)
|
||||
{
|
||||
int color = workbench_color_index(wpd, textured, tiled);
|
||||
int light = wpd->shading.light;
|
||||
BLI_assert(light < MAX_LIGHTING);
|
||||
struct GPUShader **shader =
|
||||
(transp) ? &e_data.transp_prepass_sh_cache[wpd->sh_cfg][hair][light][color] :
|
||||
&e_data.opaque_prepass_sh_cache[wpd->sh_cfg][hair][color];
|
||||
(transp) ? &e_data.transp_prepass_sh_cache[wpd->sh_cfg][datatype][light][color] :
|
||||
&e_data.opaque_prepass_sh_cache[wpd->sh_cfg][datatype][color];
|
||||
|
||||
if (*shader == NULL) {
|
||||
char *defines = workbench_build_defines(wpd, textured, tiled, false, false);
|
||||
@@ -194,8 +200,11 @@ static GPUShader *workbench_shader_get_ex(
|
||||
datatoc_workbench_prepass_frag_glsl;
|
||||
char *frag_src = DRW_shader_library_create_shader_string(e_data.lib, frag_file);
|
||||
|
||||
char *vert_file = hair ? datatoc_workbench_prepass_hair_vert_glsl :
|
||||
datatoc_workbench_prepass_vert_glsl;
|
||||
char *vert_file = (datatype == WORKBENCH_DATATYPE_HAIR) ?
|
||||
datatoc_workbench_prepass_hair_vert_glsl :
|
||||
((datatype == WORKBENCH_DATATYPE_POINTCLOUD) ?
|
||||
datatoc_workbench_prepass_pointcloud_vert_glsl :
|
||||
datatoc_workbench_prepass_vert_glsl);
|
||||
char *vert_src = DRW_shader_library_create_shader_string(e_data.lib, vert_file);
|
||||
|
||||
const GPUShaderConfigData *sh_cfg_data = &GPU_shader_cfg_data[wpd->sh_cfg];
|
||||
@@ -207,6 +216,10 @@ static GPUShader *workbench_shader_get_ex(
|
||||
defines,
|
||||
transp ? "#define TRANSPARENT_MATERIAL\n" :
|
||||
"#define OPAQUE_MATERIAL\n",
|
||||
(datatype == WORKBENCH_DATATYPE_POINTCLOUD) ?
|
||||
"#define UNIFORM_RESOURCE_ID\n"
|
||||
"#define INSTANCED_ATTR\n" :
|
||||
NULL,
|
||||
NULL},
|
||||
});
|
||||
|
||||
@@ -217,26 +230,29 @@ static GPUShader *workbench_shader_get_ex(
|
||||
return *shader;
|
||||
}
|
||||
|
||||
GPUShader *workbench_shader_opaque_get(WORKBENCH_PrivateData *wpd, bool hair)
|
||||
GPUShader *workbench_shader_opaque_get(WORKBENCH_PrivateData *wpd, eWORKBENCH_DataType datatype)
|
||||
{
|
||||
return workbench_shader_get_ex(wpd, false, hair, false, false);
|
||||
return workbench_shader_get_ex(wpd, false, datatype, false, false);
|
||||
}
|
||||
|
||||
GPUShader *workbench_shader_opaque_image_get(WORKBENCH_PrivateData *wpd, bool hair, bool tiled)
|
||||
GPUShader *workbench_shader_opaque_image_get(WORKBENCH_PrivateData *wpd,
|
||||
eWORKBENCH_DataType datatype,
|
||||
bool tiled)
|
||||
{
|
||||
return workbench_shader_get_ex(wpd, false, hair, true, tiled);
|
||||
return workbench_shader_get_ex(wpd, false, datatype, true, tiled);
|
||||
}
|
||||
|
||||
GPUShader *workbench_shader_transparent_get(WORKBENCH_PrivateData *wpd, bool hair)
|
||||
GPUShader *workbench_shader_transparent_get(WORKBENCH_PrivateData *wpd,
|
||||
eWORKBENCH_DataType datatype)
|
||||
{
|
||||
return workbench_shader_get_ex(wpd, true, hair, false, false);
|
||||
return workbench_shader_get_ex(wpd, true, datatype, false, false);
|
||||
}
|
||||
|
||||
GPUShader *workbench_shader_transparent_image_get(WORKBENCH_PrivateData *wpd,
|
||||
bool hair,
|
||||
eWORKBENCH_DataType datatype,
|
||||
bool tiled)
|
||||
{
|
||||
return workbench_shader_get_ex(wpd, true, hair, true, tiled);
|
||||
return workbench_shader_get_ex(wpd, true, datatype, true, tiled);
|
||||
}
|
||||
|
||||
GPUShader *workbench_shader_composite_get(WORKBENCH_PrivateData *wpd)
|
||||
|
@@ -83,10 +83,10 @@ static void workbench_transparent_lighting_uniforms(WORKBENCH_PrivateData *wpd,
|
||||
}
|
||||
}
|
||||
|
||||
void workbench_transparent_cache_init(WORKBENCH_Data *data)
|
||||
void workbench_transparent_cache_init(WORKBENCH_Data *vedata)
|
||||
{
|
||||
WORKBENCH_PassList *psl = data->psl;
|
||||
WORKBENCH_PrivateData *wpd = data->stl->wpd;
|
||||
WORKBENCH_PassList *psl = vedata->psl;
|
||||
WORKBENCH_PrivateData *wpd = vedata->stl->wpd;
|
||||
struct GPUShader *sh;
|
||||
DRWShadingGroup *grp;
|
||||
|
||||
@@ -105,30 +105,30 @@ void workbench_transparent_cache_init(WORKBENCH_Data *data)
|
||||
pass = psl->transp_accum_ps;
|
||||
}
|
||||
|
||||
for (int hair = 0; hair < 2; hair++) {
|
||||
wpd->prepass[transp][infront][hair].material_hash = BLI_ghash_ptr_new(__func__);
|
||||
for (eWORKBENCH_DataType data = 0; data < WORKBENCH_DATATYPE_MAX; data++) {
|
||||
wpd->prepass[transp][infront][data].material_hash = BLI_ghash_ptr_new(__func__);
|
||||
|
||||
sh = workbench_shader_transparent_get(wpd, hair);
|
||||
sh = workbench_shader_transparent_get(wpd, data);
|
||||
|
||||
wpd->prepass[transp][infront][hair].common_shgrp = grp = DRW_shgroup_create(sh, pass);
|
||||
wpd->prepass[transp][infront][data].common_shgrp = grp = DRW_shgroup_create(sh, pass);
|
||||
DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr);
|
||||
DRW_shgroup_uniform_int_copy(grp, "materialIndex", -1);
|
||||
workbench_transparent_lighting_uniforms(wpd, grp);
|
||||
|
||||
wpd->prepass[transp][infront][hair].vcol_shgrp = grp = DRW_shgroup_create(sh, pass);
|
||||
wpd->prepass[transp][infront][data].vcol_shgrp = grp = DRW_shgroup_create(sh, pass);
|
||||
DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr);
|
||||
DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. (uses vcol) */
|
||||
|
||||
sh = workbench_shader_transparent_image_get(wpd, hair, false);
|
||||
sh = workbench_shader_transparent_image_get(wpd, data, false);
|
||||
|
||||
wpd->prepass[transp][infront][hair].image_shgrp = grp = DRW_shgroup_create(sh, pass);
|
||||
wpd->prepass[transp][infront][data].image_shgrp = grp = DRW_shgroup_create(sh, pass);
|
||||
DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr);
|
||||
DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. */
|
||||
workbench_transparent_lighting_uniforms(wpd, grp);
|
||||
|
||||
sh = workbench_shader_transparent_image_get(wpd, hair, true);
|
||||
sh = workbench_shader_transparent_image_get(wpd, data, true);
|
||||
|
||||
wpd->prepass[transp][infront][hair].image_tiled_shgrp = grp = DRW_shgroup_create(sh, pass);
|
||||
wpd->prepass[transp][infront][data].image_tiled_shgrp = grp = DRW_shgroup_create(sh, pass);
|
||||
DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr);
|
||||
DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. */
|
||||
workbench_transparent_lighting_uniforms(wpd, grp);
|
||||
|
@@ -829,7 +829,7 @@ GPUBatch *DRW_cache_object_face_wireframe_get(Object *ob)
|
||||
case OB_HAIR:
|
||||
return NULL;
|
||||
case OB_POINTCLOUD:
|
||||
return NULL;
|
||||
return DRW_pointcloud_batch_cache_get_dots(ob);
|
||||
case OB_VOLUME:
|
||||
return DRW_cache_volume_face_wireframe_get(ob);
|
||||
case OB_GPENCIL: {
|
||||
@@ -880,7 +880,7 @@ GPUBatch *DRW_cache_object_surface_get(Object *ob)
|
||||
case OB_HAIR:
|
||||
return NULL;
|
||||
case OB_POINTCLOUD:
|
||||
return NULL;
|
||||
return DRW_cache_pointcloud_surface_get(ob);
|
||||
case OB_VOLUME:
|
||||
return NULL;
|
||||
default:
|
||||
@@ -958,7 +958,7 @@ GPUBatch **DRW_cache_object_surface_material_get(struct Object *ob,
|
||||
case OB_HAIR:
|
||||
return NULL;
|
||||
case OB_POINTCLOUD:
|
||||
return NULL;
|
||||
return DRW_cache_pointcloud_surface_shaded_get(ob, gpumat_array, gpumat_array_len);
|
||||
case OB_VOLUME:
|
||||
return NULL;
|
||||
default:
|
||||
@@ -3289,9 +3289,16 @@ GPUBatch *DRW_cache_lattice_vert_overlay_get(Object *ob)
|
||||
|
||||
GPUBatch *DRW_cache_pointcloud_get_dots(Object *object)
|
||||
{
|
||||
BLI_assert(object->type == OB_POINTCLOUD);
|
||||
return DRW_pointcloud_batch_cache_get_dots(object);
|
||||
}
|
||||
|
||||
GPUBatch *DRW_cache_pointcloud_surface_get(Object *object)
|
||||
{
|
||||
BLI_assert(object->type == OB_POINTCLOUD);
|
||||
return DRW_pointcloud_batch_cache_get_surface(object);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Volume
|
||||
* \{ */
|
||||
|
@@ -215,6 +215,7 @@ struct GPUBatch *DRW_cache_hair_edge_detection_get(struct Object *ob, bool *r_is
|
||||
|
||||
/* PointCloud */
|
||||
struct GPUBatch *DRW_cache_pointcloud_get_dots(struct Object *obj);
|
||||
struct GPUBatch *DRW_cache_pointcloud_surface_get(struct Object *obj);
|
||||
|
||||
/* Volume */
|
||||
typedef struct DRWVolumeGrid {
|
||||
|
@@ -144,6 +144,10 @@ int DRW_hair_material_count_get(struct Hair *hair);
|
||||
int DRW_pointcloud_material_count_get(struct PointCloud *pointcloud);
|
||||
|
||||
struct GPUBatch *DRW_pointcloud_batch_cache_get_dots(struct Object *ob);
|
||||
struct GPUBatch *DRW_pointcloud_batch_cache_get_surface(struct Object *ob);
|
||||
struct GPUBatch **DRW_cache_pointcloud_surface_shaded_get(struct Object *ob,
|
||||
struct GPUMaterial **gpumat_array,
|
||||
uint gpumat_array_len);
|
||||
|
||||
/* Volume */
|
||||
int DRW_volume_material_count_get(struct Volume *volume);
|
||||
|
@@ -28,6 +28,7 @@
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_math_base.h"
|
||||
#include "BLI_math_vector.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "DNA_object_types.h"
|
||||
@@ -45,11 +46,18 @@ static void pointcloud_batch_cache_clear(PointCloud *pointcloud);
|
||||
/* PointCloud GPUBatch Cache */
|
||||
|
||||
typedef struct PointCloudBatchCache {
|
||||
GPUVertBuf *pos;
|
||||
GPUBatch *batch;
|
||||
GPUVertBuf *pos; /* Position and radius. */
|
||||
GPUVertBuf *geom; /* Instanced geometry for each point in the cloud (small sphere). */
|
||||
GPUIndexBuf *geom_indices;
|
||||
|
||||
GPUBatch *dots;
|
||||
GPUBatch *surface;
|
||||
GPUBatch **surface_per_mat;
|
||||
|
||||
/* settings to determine if cache is invalid */
|
||||
bool is_dirty;
|
||||
|
||||
int mat_len;
|
||||
} PointCloudBatchCache;
|
||||
|
||||
/* GPUBatch cache management. */
|
||||
@@ -57,7 +65,14 @@ typedef struct PointCloudBatchCache {
|
||||
static bool pointcloud_batch_cache_valid(PointCloud *pointcloud)
|
||||
{
|
||||
PointCloudBatchCache *cache = pointcloud->batch_cache;
|
||||
return (cache && cache->is_dirty == false);
|
||||
|
||||
if (cache == NULL) {
|
||||
return false;
|
||||
}
|
||||
if (cache->mat_len != DRW_pointcloud_material_count_get(pointcloud)) {
|
||||
return false;
|
||||
}
|
||||
return cache->is_dirty == false;
|
||||
}
|
||||
|
||||
static void pointcloud_batch_cache_init(PointCloud *pointcloud)
|
||||
@@ -71,6 +86,10 @@ static void pointcloud_batch_cache_init(PointCloud *pointcloud)
|
||||
memset(cache, 0, sizeof(*cache));
|
||||
}
|
||||
|
||||
cache->mat_len = DRW_pointcloud_material_count_get(pointcloud);
|
||||
cache->surface_per_mat = MEM_callocN(sizeof(GPUBatch *) * cache->mat_len,
|
||||
"pointcloud suface_per_mat");
|
||||
|
||||
cache->is_dirty = false;
|
||||
}
|
||||
|
||||
@@ -109,8 +128,18 @@ static void pointcloud_batch_cache_clear(PointCloud *pointcloud)
|
||||
return;
|
||||
}
|
||||
|
||||
GPU_BATCH_DISCARD_SAFE(cache->batch);
|
||||
GPU_BATCH_DISCARD_SAFE(cache->dots);
|
||||
GPU_BATCH_DISCARD_SAFE(cache->surface);
|
||||
GPU_VERTBUF_DISCARD_SAFE(cache->pos);
|
||||
GPU_VERTBUF_DISCARD_SAFE(cache->geom);
|
||||
GPU_INDEXBUF_DISCARD_SAFE(cache->geom_indices);
|
||||
|
||||
if (cache->surface_per_mat) {
|
||||
for (int i = 0; i < cache->mat_len; i++) {
|
||||
GPU_BATCH_DISCARD_SAFE(cache->surface_per_mat[i]);
|
||||
}
|
||||
}
|
||||
MEM_SAFE_FREE(cache->surface_per_mat);
|
||||
}
|
||||
|
||||
void DRW_pointcloud_batch_cache_free(PointCloud *pointcloud)
|
||||
@@ -126,35 +155,83 @@ static void pointcloud_batch_cache_ensure_pos(Object *ob, PointCloudBatchCache *
|
||||
}
|
||||
|
||||
PointCloud *pointcloud = ob->data;
|
||||
const bool has_radius = pointcloud->radius != NULL;
|
||||
|
||||
static GPUVertFormat format = {0};
|
||||
static uint pos_id;
|
||||
static uint radius_id;
|
||||
static uint pos;
|
||||
if (format.attr_len == 0) {
|
||||
/* initialize vertex format */
|
||||
pos_id = GPU_vertformat_attr_add(&format, "pointcloud_pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
||||
radius_id = GPU_vertformat_attr_add(
|
||||
&format, "pointcloud_radius", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
|
||||
/* From the opengl wiki:
|
||||
* Note that size does not have to exactly match the size used by the vertex shader. If the
|
||||
* vertex shader has fewer components than the attribute provides, then the extras are ignored.
|
||||
* If the vertex shader has more components than the array provides, the extras are given
|
||||
* values from the vector (0, 0, 0, 1) for the missing XYZW components.
|
||||
*/
|
||||
int comp_len = has_radius ? 4 : 3;
|
||||
pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, comp_len, GPU_FETCH_FLOAT);
|
||||
}
|
||||
|
||||
GPU_VERTBUF_DISCARD_SAFE(cache->pos);
|
||||
cache->pos = GPU_vertbuf_create_with_format(&format);
|
||||
GPU_vertbuf_data_alloc(cache->pos, pointcloud->totpoint);
|
||||
GPU_vertbuf_attr_fill(cache->pos, pos_id, pointcloud->co);
|
||||
|
||||
if (pointcloud->radius) {
|
||||
GPU_vertbuf_attr_fill(cache->pos, radius_id, pointcloud->radius);
|
||||
}
|
||||
else if (pointcloud->totpoint) {
|
||||
/* TODO: optimize for constant radius by not including in vertex buffer at all? */
|
||||
float *radius = MEM_malloc_arrayN(pointcloud->totpoint, sizeof(float), __func__);
|
||||
if (has_radius) {
|
||||
float(*vbo_data)[4] = (float(*)[4])cache->pos->data;
|
||||
for (int i = 0; i < pointcloud->totpoint; i++) {
|
||||
/* TODO: add default radius to PointCloud data structure. */
|
||||
radius[i] = 0.01f;
|
||||
copy_v3_v3(vbo_data[i], pointcloud->co[i]);
|
||||
/* TODO(fclem) remove multiplication here. Here only for keeping the size correct for now. */
|
||||
vbo_data[i][3] = pointcloud->radius[i] * 100.0f;
|
||||
}
|
||||
GPU_vertbuf_attr_fill(cache->pos, radius_id, radius);
|
||||
MEM_freeN(radius);
|
||||
}
|
||||
else {
|
||||
GPU_vertbuf_attr_fill(cache->pos, pos, pointcloud->co);
|
||||
}
|
||||
}
|
||||
|
||||
static const float half_octahedron_normals[5][3] = {
|
||||
{0.0f, 0.0f, 1.0f},
|
||||
{1.0f, 0.0f, 0.0f},
|
||||
{0.0f, 1.0f, 0.0f},
|
||||
{-1.0f, 0.0f, 0.0f},
|
||||
{0.0f, -1.0f, 0.0f},
|
||||
};
|
||||
|
||||
static const uint half_octahedron_tris[4][3] = {
|
||||
{0, 1, 2},
|
||||
{0, 2, 3},
|
||||
{0, 3, 4},
|
||||
{0, 4, 1},
|
||||
};
|
||||
|
||||
static void pointcloud_batch_cache_ensure_geom(Object *UNUSED(ob), PointCloudBatchCache *cache)
|
||||
{
|
||||
if (cache->geom != NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
static GPUVertFormat format = {0};
|
||||
static uint pos;
|
||||
if (format.attr_len == 0) {
|
||||
/* initialize vertex format */
|
||||
pos = GPU_vertformat_attr_add(&format, "pos_inst", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
||||
GPU_vertformat_alias_add(&format, "nor");
|
||||
}
|
||||
|
||||
cache->geom = GPU_vertbuf_create_with_format(&format);
|
||||
GPU_vertbuf_data_alloc(cache->geom, ARRAY_SIZE(half_octahedron_normals));
|
||||
|
||||
GPU_vertbuf_attr_fill(cache->geom, pos, half_octahedron_normals);
|
||||
|
||||
GPUIndexBufBuilder builder;
|
||||
GPU_indexbuf_init(&builder,
|
||||
GPU_PRIM_TRIS,
|
||||
ARRAY_SIZE(half_octahedron_tris),
|
||||
ARRAY_SIZE(half_octahedron_normals));
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(half_octahedron_tris); i++) {
|
||||
GPU_indexbuf_add_tri_verts(&builder, UNPACK3(half_octahedron_tris[i]));
|
||||
}
|
||||
|
||||
cache->geom_indices = GPU_indexbuf_build(&builder);
|
||||
}
|
||||
|
||||
GPUBatch *DRW_pointcloud_batch_cache_get_dots(Object *ob)
|
||||
@@ -162,12 +239,47 @@ GPUBatch *DRW_pointcloud_batch_cache_get_dots(Object *ob)
|
||||
PointCloud *pointcloud = ob->data;
|
||||
PointCloudBatchCache *cache = pointcloud_batch_cache_get(pointcloud);
|
||||
|
||||
if (cache->batch == NULL) {
|
||||
if (cache->dots == NULL) {
|
||||
pointcloud_batch_cache_ensure_pos(ob, cache);
|
||||
cache->batch = GPU_batch_create(GPU_PRIM_POINTS, cache->pos, NULL);
|
||||
cache->dots = GPU_batch_create(GPU_PRIM_POINTS, cache->pos, NULL);
|
||||
}
|
||||
|
||||
return cache->batch;
|
||||
return cache->dots;
|
||||
}
|
||||
|
||||
GPUBatch *DRW_pointcloud_batch_cache_get_surface(Object *ob)
|
||||
{
|
||||
PointCloud *pointcloud = ob->data;
|
||||
PointCloudBatchCache *cache = pointcloud_batch_cache_get(pointcloud);
|
||||
|
||||
if (cache->surface == NULL) {
|
||||
pointcloud_batch_cache_ensure_pos(ob, cache);
|
||||
pointcloud_batch_cache_ensure_geom(ob, cache);
|
||||
|
||||
cache->surface = GPU_batch_create(GPU_PRIM_TRIS, cache->geom, cache->geom_indices);
|
||||
GPU_batch_instbuf_add_ex(cache->surface, cache->pos, false);
|
||||
}
|
||||
|
||||
return cache->surface;
|
||||
}
|
||||
|
||||
GPUBatch **DRW_cache_pointcloud_surface_shaded_get(Object *ob,
|
||||
struct GPUMaterial **UNUSED(gpumat_array),
|
||||
uint gpumat_array_len)
|
||||
{
|
||||
PointCloud *pointcloud = ob->data;
|
||||
PointCloudBatchCache *cache = pointcloud_batch_cache_get(pointcloud);
|
||||
BLI_assert(cache->mat_len == gpumat_array_len);
|
||||
|
||||
if (cache->surface_per_mat[0] == NULL) {
|
||||
pointcloud_batch_cache_ensure_pos(ob, cache);
|
||||
pointcloud_batch_cache_ensure_geom(ob, cache);
|
||||
|
||||
cache->surface_per_mat[0] = GPU_batch_create(GPU_PRIM_TRIS, cache->geom, cache->geom_indices);
|
||||
GPU_batch_instbuf_add_ex(cache->surface, cache->pos, false);
|
||||
}
|
||||
|
||||
return cache->surface_per_mat;
|
||||
}
|
||||
|
||||
int DRW_pointcloud_material_count_get(PointCloud *pointcloud)
|
||||
|
@@ -793,10 +793,10 @@ void DRW_shgroup_call_range(
|
||||
drw_command_draw_range(shgroup, geom, handle, v_sta, v_ct);
|
||||
}
|
||||
|
||||
/* A count of 0 instance will use the default number of instance in the batch. */
|
||||
void DRW_shgroup_call_instance_range(
|
||||
DRWShadingGroup *shgroup, Object *ob, struct GPUBatch *geom, uint i_sta, uint i_ct)
|
||||
{
|
||||
BLI_assert(i_ct > 0);
|
||||
BLI_assert(geom != NULL);
|
||||
if (G.f & G_FLAG_PICKSEL) {
|
||||
drw_command_set_select_id(shgroup, NULL, DST.select_id);
|
||||
|
@@ -0,0 +1,39 @@
|
||||
|
||||
/* NOTE: To be used with UNIFORM_RESOURCE_ID and INSTANCED_ATTR as define. */
|
||||
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
|
||||
|
||||
in vec4 pos; /* Position and radius. */
|
||||
|
||||
/* ---- Instanced attribs ---- */
|
||||
|
||||
in vec3 pos_inst;
|
||||
in vec3 nor;
|
||||
|
||||
mat3 pointcloud_get_facing_matrix(vec3 p)
|
||||
{
|
||||
mat3 facing_mat;
|
||||
facing_mat[2] = normalize(ViewMatrixInverse[3].xyz - p);
|
||||
facing_mat[1] = normalize(cross(ViewMatrixInverse[0].xyz, facing_mat[2]));
|
||||
facing_mat[0] = cross(facing_mat[1], facing_mat[2]);
|
||||
return facing_mat;
|
||||
}
|
||||
|
||||
/* Return world position and normal. */
|
||||
void pointcloud_get_pos_and_nor(out vec3 outpos, out vec3 outnor)
|
||||
{
|
||||
vec3 p = point_object_to_world(pos.xyz);
|
||||
mat3 facing_mat = pointcloud_get_facing_matrix(p);
|
||||
|
||||
float radius = dot(abs(mat3(ModelMatrix) * pos.www), vec3(1.0 / 3.0));
|
||||
/* TODO(fclem) remove multiplication here. Here only for keeping the size correct for now. */
|
||||
radius *= 0.01;
|
||||
outpos = p + (facing_mat * pos_inst) * radius;
|
||||
outnor = facing_mat * nor;
|
||||
}
|
||||
|
||||
vec3 pointcloud_get_pos(void)
|
||||
{
|
||||
vec3 outpos, outnor;
|
||||
pointcloud_get_pos_and_nor(outpos, outnor);
|
||||
return outpos;
|
||||
}
|
@@ -171,6 +171,7 @@ uniform mat4 ModelMatrixInverse;
|
||||
#define normal_object_to_world(n) (transpose(mat3(ModelMatrixInverse)) * n)
|
||||
#define normal_world_to_object(n) (transpose(mat3(ModelMatrix)) * n)
|
||||
#define normal_world_to_view(n) (mat3(ViewMatrix) * n)
|
||||
#define normal_view_to_world(n) (mat3(ViewMatrixInverse) * n)
|
||||
|
||||
#define point_object_to_ndc(p) (ViewProjectionMatrix * vec4((ModelMatrix * vec4(p, 1.0)).xyz, 1.0))
|
||||
#define point_object_to_view(p) ((ViewMatrix * vec4((ModelMatrix * vec4(p, 1.0)).xyz, 1.0)).xyz)
|
||||
|
Reference in New Issue
Block a user