Compare commits
5 Commits
temp-defor
...
tmp-pointc
Author | SHA1 | Date | |
---|---|---|---|
e8f8c13d4b | |||
0c062a9e08 | |||
38655c43fb | |||
102f66c0a4 | |||
5e12123685 |
@@ -143,7 +143,6 @@ set(SRC
|
|||||||
engines/overlay/overlay_outline.c
|
engines/overlay/overlay_outline.c
|
||||||
engines/overlay/overlay_paint.c
|
engines/overlay/overlay_paint.c
|
||||||
engines/overlay/overlay_particle.c
|
engines/overlay/overlay_particle.c
|
||||||
engines/overlay/overlay_pointcloud.c
|
|
||||||
engines/overlay/overlay_sculpt.c
|
engines/overlay/overlay_sculpt.c
|
||||||
engines/overlay/overlay_shader.c
|
engines/overlay/overlay_shader.c
|
||||||
engines/overlay/overlay_wireframe.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_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_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_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_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_shader_interface_lib.glsl SRC)
|
||||||
data_to_c_simple(engines/workbench/shaders/workbench_shadow_caps_geom.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_colormanagement_lib.glsl SRC)
|
||||||
data_to_c_simple(intern/shaders/common_globals_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_lib.glsl SRC)
|
||||||
data_to_c_simple(intern/shaders/common_hair_refine_vert.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)
|
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_motion_path_cache_init(vedata);
|
||||||
OVERLAY_outline_cache_init(vedata);
|
OVERLAY_outline_cache_init(vedata);
|
||||||
OVERLAY_particle_cache_init(vedata);
|
OVERLAY_particle_cache_init(vedata);
|
||||||
OVERLAY_pointcloud_cache_init(vedata);
|
|
||||||
OVERLAY_wireframe_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);
|
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 ... */
|
/* Relationship, object center, bounbox ... */
|
||||||
if (!pd->hide_overlays) {
|
if (!pd->hide_overlays) {
|
||||||
OVERLAY_extra_cache_populate(vedata, ob);
|
OVERLAY_extra_cache_populate(vedata, ob);
|
||||||
@@ -482,7 +475,6 @@ static void OVERLAY_draw_scene(void *vedata)
|
|||||||
OVERLAY_armature_draw(vedata);
|
OVERLAY_armature_draw(vedata);
|
||||||
OVERLAY_particle_draw(vedata);
|
OVERLAY_particle_draw(vedata);
|
||||||
OVERLAY_metaball_draw(vedata);
|
OVERLAY_metaball_draw(vedata);
|
||||||
OVERLAY_pointcloud_draw(vedata);
|
|
||||||
OVERLAY_gpencil_draw(vedata);
|
OVERLAY_gpencil_draw(vedata);
|
||||||
OVERLAY_extra_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);
|
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);
|
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();
|
GPUShader *sh_gpencil = OVERLAY_shader_outline_prepass_gpencil();
|
||||||
|
|
||||||
pd->outlines_gpencil_grp = grp = DRW_shgroup_create(sh_gpencil, psl->outlines_prepass_ps);
|
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;
|
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) {
|
if (dupli && !init_dupli) {
|
||||||
geom = dupli->outline_geom;
|
geom = dupli->outline_geom;
|
||||||
shgroup = dupli->outline_shgrp;
|
shgroup = dupli->outline_shgrp;
|
||||||
@@ -307,12 +318,18 @@ void OVERLAY_outline_cache_populate(OVERLAY_Data *vedata,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (geom) {
|
if (geom) {
|
||||||
shgroup = pd->outlines_grp;
|
shgroup = (ob->type == OB_POINTCLOUD) ? pd->outlines_ptcloud_grp : pd->outlines_grp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shgroup && geom) {
|
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) {
|
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_lines_grp;
|
||||||
DRWShadingGroup *motion_path_points_grp;
|
DRWShadingGroup *motion_path_points_grp;
|
||||||
DRWShadingGroup *outlines_grp;
|
DRWShadingGroup *outlines_grp;
|
||||||
|
DRWShadingGroup *outlines_ptcloud_grp;
|
||||||
DRWShadingGroup *outlines_gpencil_grp;
|
DRWShadingGroup *outlines_gpencil_grp;
|
||||||
DRWShadingGroup *paint_depth_grp;
|
DRWShadingGroup *paint_depth_grp;
|
||||||
DRWShadingGroup *paint_surf_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_cache_populate(OVERLAY_Data *vedata, Object *ob);
|
||||||
void OVERLAY_particle_draw(OVERLAY_Data *vedata);
|
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_init(OVERLAY_Data *vedata);
|
||||||
void OVERLAY_sculpt_cache_populate(OVERLAY_Data *vedata, Object *ob);
|
void OVERLAY_sculpt_cache_populate(OVERLAY_Data *vedata, Object *ob);
|
||||||
void OVERLAY_sculpt_draw(OVERLAY_Data *vedata);
|
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_uniform_color(void);
|
||||||
GPUShader *OVERLAY_shader_outline_prepass(bool use_wire);
|
GPUShader *OVERLAY_shader_outline_prepass(bool use_wire);
|
||||||
GPUShader *OVERLAY_shader_outline_prepass_gpencil(void);
|
GPUShader *OVERLAY_shader_outline_prepass_gpencil(void);
|
||||||
|
GPUShader *OVERLAY_shader_outline_prepass_pointcloud(void);
|
||||||
GPUShader *OVERLAY_shader_extra_grid(void);
|
GPUShader *OVERLAY_shader_extra_grid(void);
|
||||||
GPUShader *OVERLAY_shader_outline_detect(void);
|
GPUShader *OVERLAY_shader_outline_detect(void);
|
||||||
GPUShader *OVERLAY_shader_paint_face(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_fxaa_lib_glsl[];
|
||||||
extern char datatoc_common_smaa_lib_glsl[];
|
extern char datatoc_common_smaa_lib_glsl[];
|
||||||
extern char datatoc_common_globals_lib_glsl[];
|
extern char datatoc_common_globals_lib_glsl[];
|
||||||
|
extern char datatoc_common_pointcloud_lib_glsl[];
|
||||||
extern char datatoc_common_view_lib_glsl[];
|
extern char datatoc_common_view_lib_glsl[];
|
||||||
|
|
||||||
typedef struct OVERLAY_Shaders {
|
typedef struct OVERLAY_Shaders {
|
||||||
@@ -181,6 +182,7 @@ typedef struct OVERLAY_Shaders {
|
|||||||
GPUShader *motion_path_vert;
|
GPUShader *motion_path_vert;
|
||||||
GPUShader *outline_prepass;
|
GPUShader *outline_prepass;
|
||||||
GPUShader *outline_prepass_gpencil;
|
GPUShader *outline_prepass_gpencil;
|
||||||
|
GPUShader *outline_prepass_pointcloud;
|
||||||
GPUShader *outline_prepass_wire;
|
GPUShader *outline_prepass_wire;
|
||||||
GPUShader *outline_detect;
|
GPUShader *outline_detect;
|
||||||
GPUShader *paint_face;
|
GPUShader *paint_face;
|
||||||
@@ -1135,6 +1137,33 @@ GPUShader *OVERLAY_shader_outline_prepass_gpencil(void)
|
|||||||
return sh_data->outline_prepass_gpencil;
|
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)
|
GPUShader *OVERLAY_shader_outline_detect(void)
|
||||||
{
|
{
|
||||||
OVERLAY_Shaders *sh_data = &e_data.sh_data[0];
|
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) {
|
if (use_wire && ELEM(ob->type, OB_VOLUME, OB_POINTCLOUD)) {
|
||||||
/* Volume object as points exception. */
|
bool draw_as_points = true;
|
||||||
Volume *volume = ob->data;
|
if (ob->type == OB_VOLUME) {
|
||||||
if (volume->display.wireframe_type == VOLUME_WIREFRAME_POINTS) {
|
/* 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;
|
float *color;
|
||||||
OVERLAY_ExtraCallBuffers *cb = OVERLAY_extra_call_buffer_get(vedata, ob);
|
OVERLAY_ExtraCallBuffers *cb = OVERLAY_extra_call_buffer_get(vedata, ob);
|
||||||
DRW_object_wire_theme_get(ob, draw_ctx->view_layer, &color);
|
DRW_object_wire_theme_get(ob, draw_ctx->view_layer, &color);
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
uniform bool isTransform;
|
uniform bool isTransform;
|
||||||
|
|
||||||
#ifndef USE_GPENCIL
|
#if !defined(USE_GPENCIL) && !defined(POINTCLOUD)
|
||||||
in vec3 pos;
|
in vec3 pos;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -56,7 +56,11 @@ void main()
|
|||||||
# endif
|
# endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
# ifdef POINTCLOUD
|
||||||
|
vec3 world_pos = pointcloud_get_pos();
|
||||||
|
# else
|
||||||
vec3 world_pos = point_object_to_world(pos);
|
vec3 world_pos = point_object_to_world(pos);
|
||||||
|
# endif
|
||||||
gl_Position = point_world_to_ndc(world_pos);
|
gl_Position = point_world_to_ndc(world_pos);
|
||||||
# ifdef USE_GEOM
|
# ifdef USE_GEOM
|
||||||
vPos = point_world_to_view(world_pos);
|
vPos = point_world_to_view(world_pos);
|
||||||
|
@@ -2,16 +2,15 @@
|
|||||||
uniform vec4 color;
|
uniform vec4 color;
|
||||||
|
|
||||||
/* ---- Per instance Attrs ---- */
|
/* ---- Per instance Attrs ---- */
|
||||||
in vec3 pointcloud_pos;
|
in vec4 ptcloud; /* Position and radius. */
|
||||||
in vec3 pointcloud_radius;
|
|
||||||
|
|
||||||
out vec4 finalColor;
|
out vec4 finalColor;
|
||||||
|
|
||||||
void main()
|
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;
|
float world_radius = (world_size.x + world_size.y + world_size.z) / 3.0;
|
||||||
|
|
||||||
gl_Position = point_world_to_ndc(world_pos);
|
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)
|
static void workbench_cache_texpaint_populate(WORKBENCH_PrivateData *wpd, Object *ob)
|
||||||
{
|
{
|
||||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
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);
|
SET_FLAG_FROM_TEST(state, imapaint->interp == IMAGEPAINT_INTERP_LINEAR, GPU_SAMPLER_FILTER);
|
||||||
|
|
||||||
DRWShadingGroup *grp = workbench_image_setup(wpd, ob, 0, ima, NULL, state);
|
DRWShadingGroup *grp = workbench_image_setup(wpd, ob, 0, ima, NULL, state);
|
||||||
DRW_shgroup_call(grp, geom, ob);
|
workbench_object_drawcall(grp, geom, ob);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -157,7 +168,7 @@ static void workbench_cache_texpaint_populate(WORKBENCH_PrivateData *wpd, Object
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
DRWShadingGroup *grp = workbench_image_setup(wpd, ob, i + 1, NULL, NULL, 0);
|
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) {
|
if (geom) {
|
||||||
DRWShadingGroup *grp = workbench_material_setup(wpd, ob, 0, color_type, r_transp);
|
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 {
|
else {
|
||||||
@@ -207,7 +218,7 @@ static void workbench_cache_common_populate(WORKBENCH_PrivateData *wpd,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
DRWShadingGroup *grp = workbench_material_setup(wpd, ob, i + 1, color_type, r_transp);
|
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. */
|
/* TODO don't free reuse next redraw. */
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
for (int j = 0; j < 2; j++) {
|
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) {
|
if (wpd->prepass[i][j][k].material_hash) {
|
||||||
BLI_ghash_free(wpd->prepass[i][j][k].material_hash, NULL, NULL);
|
BLI_ghash_free(wpd->prepass[i][j][k].material_hash, NULL, NULL);
|
||||||
wpd->prepass[i][j][k].material_hash = NULL;
|
wpd->prepass[i][j][k].material_hash = NULL;
|
||||||
|
@@ -162,7 +162,7 @@ DRWShadingGroup *workbench_material_setup_ex(WORKBENCH_PrivateData *wpd,
|
|||||||
Object *ob,
|
Object *ob,
|
||||||
int mat_nr,
|
int mat_nr,
|
||||||
eV3DShadingColorType color_type,
|
eV3DShadingColorType color_type,
|
||||||
bool hair,
|
eWORKBENCH_DataType datatype,
|
||||||
bool *r_transp)
|
bool *r_transp)
|
||||||
{
|
{
|
||||||
Image *ima = NULL;
|
Image *ima = NULL;
|
||||||
@@ -180,7 +180,7 @@ DRWShadingGroup *workbench_material_setup_ex(WORKBENCH_PrivateData *wpd,
|
|||||||
|
|
||||||
switch (color_type) {
|
switch (color_type) {
|
||||||
case V3D_SHADING_TEXTURE_COLOR: {
|
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: {
|
case V3D_SHADING_MATERIAL_COLOR: {
|
||||||
/* For now, we use the same ubo for material and object coloring but with different indices.
|
/* 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);
|
Material *ma = workbench_object_material_get(ob, mat_nr);
|
||||||
|
|
||||||
const bool transp = wpd->shading.xray_alpha < 1.0f || ma->a < 1.0f;
|
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) {
|
if (r_transp && transp) {
|
||||||
*r_transp = true;
|
*r_transp = true;
|
||||||
@@ -216,7 +216,7 @@ DRWShadingGroup *workbench_material_setup_ex(WORKBENCH_PrivateData *wpd,
|
|||||||
}
|
}
|
||||||
case V3D_SHADING_VERTEX_COLOR: {
|
case V3D_SHADING_VERTEX_COLOR: {
|
||||||
const bool transp = wpd->shading.xray_alpha < 1.0f;
|
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;
|
return grp;
|
||||||
}
|
}
|
||||||
default: {
|
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);
|
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;
|
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) {
|
if (resource_changed) {
|
||||||
grp = DRW_shgroup_create_sub(grp);
|
grp = DRW_shgroup_create_sub(grp);
|
||||||
DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr);
|
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,
|
Image *ima,
|
||||||
ImageUser *iuser,
|
ImageUser *iuser,
|
||||||
eGPUSamplerState sampler,
|
eGPUSamplerState sampler,
|
||||||
bool hair)
|
eWORKBENCH_DataType datatype)
|
||||||
{
|
{
|
||||||
GPUTexture *tex = NULL, *tex_tile_data = NULL;
|
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 infront = (ob->dtx & OB_DRAWXRAY) != 0;
|
||||||
const bool transp = wpd->shading.xray_alpha < 1.0f;
|
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;
|
DRWShadingGroup **grp_tex = NULL;
|
||||||
/* A hashmap stores image shgroups to pack all similar drawcalls together. */
|
/* 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_PassList *psl = vedata->psl;
|
||||||
WORKBENCH_PrivateData *wpd = data->stl->wpd;
|
WORKBENCH_PrivateData *wpd = vedata->stl->wpd;
|
||||||
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
|
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
|
||||||
struct GPUShader *sh;
|
struct GPUShader *sh;
|
||||||
DRWShadingGroup *grp;
|
DRWShadingGroup *grp;
|
||||||
@@ -84,31 +84,31 @@ void workbench_opaque_cache_init(WORKBENCH_Data *data)
|
|||||||
pass = psl->opaque_ps;
|
pass = psl->opaque_ps;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int hair = 0; hair < 2; hair++) {
|
for (eWORKBENCH_DataType data = 0; data < WORKBENCH_DATATYPE_MAX; data++) {
|
||||||
wpd->prepass[opaque][infront][hair].material_hash = BLI_ghash_ptr_new(__func__);
|
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_block(grp, "material_block", wpd->material_ubo_curr);
|
||||||
DRW_shgroup_uniform_int_copy(grp, "materialIndex", -1);
|
DRW_shgroup_uniform_int_copy(grp, "materialIndex", -1);
|
||||||
DRW_shgroup_uniform_bool_copy(grp, "useMatcap", use_matcap);
|
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_block(grp, "material_block", wpd->material_ubo_curr);
|
||||||
DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. (uses vcol) */
|
DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. (uses vcol) */
|
||||||
DRW_shgroup_uniform_bool_copy(grp, "useMatcap", use_matcap);
|
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_block(grp, "material_block", wpd->material_ubo_curr);
|
||||||
DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. */
|
DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. */
|
||||||
DRW_shgroup_uniform_bool_copy(grp, "useMatcap", use_matcap);
|
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_block(grp, "material_block", wpd->material_ubo_curr);
|
||||||
DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. */
|
DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. */
|
||||||
DRW_shgroup_uniform_bool_copy(grp, "useMatcap", use_matcap);
|
DRW_shgroup_uniform_bool_copy(grp, "useMatcap", use_matcap);
|
||||||
|
@@ -71,6 +71,14 @@ struct RenderEngine;
|
|||||||
struct RenderLayer;
|
struct RenderLayer;
|
||||||
struct rcti;
|
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 {
|
typedef struct WORKBENCH_FramebufferList {
|
||||||
struct GPUFrameBuffer *opaque_fb;
|
struct GPUFrameBuffer *opaque_fb;
|
||||||
struct GPUFrameBuffer *opaque_infront_fb;
|
struct GPUFrameBuffer *opaque_infront_fb;
|
||||||
@@ -293,8 +301,8 @@ typedef struct WORKBENCH_PrivateData {
|
|||||||
/** Object IDs buffer for curvature & outline. */
|
/** Object IDs buffer for curvature & outline. */
|
||||||
struct GPUTexture *object_id_tx;
|
struct GPUTexture *object_id_tx;
|
||||||
|
|
||||||
/** Pre-pass information for each draw types [transparent][infront][hair]. */
|
/** Pre-pass information for each draw types [transparent][infront][datatype]. */
|
||||||
WORKBENCH_Prepass prepass[2][2][2];
|
WORKBENCH_Prepass prepass[2][2][WORKBENCH_DATATYPE_MAX];
|
||||||
|
|
||||||
/* Materials */
|
/* Materials */
|
||||||
/** Copy of vldata->material_ubo for faster access. */
|
/** 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);
|
void workbench_shadow_cache_populate(WORKBENCH_Data *data, Object *ob, const bool has_transp_mat);
|
||||||
|
|
||||||
/* workbench_shader.c */
|
/* workbench_shader.c */
|
||||||
GPUShader *workbench_shader_opaque_get(WORKBENCH_PrivateData *wpd, bool hair);
|
GPUShader *workbench_shader_opaque_get(WORKBENCH_PrivateData *wpd, eWORKBENCH_DataType data);
|
||||||
GPUShader *workbench_shader_opaque_image_get(WORKBENCH_PrivateData *wpd, bool hair, bool tiled);
|
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_composite_get(WORKBENCH_PrivateData *wpd);
|
||||||
GPUShader *workbench_shader_merge_infront_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,
|
GPUShader *workbench_shader_transparent_image_get(WORKBENCH_PrivateData *wpd,
|
||||||
bool hair,
|
eWORKBENCH_DataType data,
|
||||||
bool tiled);
|
bool tiled);
|
||||||
GPUShader *workbench_shader_transparent_resolve_get(WORKBENCH_PrivateData *wpd);
|
GPUShader *workbench_shader_transparent_resolve_get(WORKBENCH_PrivateData *wpd);
|
||||||
|
|
||||||
@@ -455,7 +465,7 @@ DRWShadingGroup *workbench_material_setup_ex(WORKBENCH_PrivateData *wpd,
|
|||||||
Object *ob,
|
Object *ob,
|
||||||
int mat_nr,
|
int mat_nr,
|
||||||
eV3DShadingColorType color_type,
|
eV3DShadingColorType color_type,
|
||||||
bool hair,
|
eWORKBENCH_DataType datatype,
|
||||||
bool *r_transp);
|
bool *r_transp);
|
||||||
DRWShadingGroup *workbench_image_setup_ex(WORKBENCH_PrivateData *wpd,
|
DRWShadingGroup *workbench_image_setup_ex(WORKBENCH_PrivateData *wpd,
|
||||||
Object *ob,
|
Object *ob,
|
||||||
@@ -463,17 +473,20 @@ DRWShadingGroup *workbench_image_setup_ex(WORKBENCH_PrivateData *wpd,
|
|||||||
Image *ima,
|
Image *ima,
|
||||||
ImageUser *iuser,
|
ImageUser *iuser,
|
||||||
eGPUSamplerState sampler,
|
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) \
|
#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) \
|
#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) \
|
#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) \
|
#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 */
|
/* workbench_data.c */
|
||||||
void workbench_private_data_init(WORKBENCH_PrivateData *wpd);
|
void workbench_private_data_init(WORKBENCH_PrivateData *wpd);
|
||||||
|
@@ -29,11 +29,13 @@
|
|||||||
#include "workbench_private.h"
|
#include "workbench_private.h"
|
||||||
|
|
||||||
extern char datatoc_common_hair_lib_glsl[];
|
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_view_lib_glsl[];
|
||||||
extern char datatoc_common_smaa_lib_glsl[];
|
extern char datatoc_common_smaa_lib_glsl[];
|
||||||
|
|
||||||
extern char datatoc_workbench_prepass_vert_glsl[];
|
extern char datatoc_workbench_prepass_vert_glsl[];
|
||||||
extern char datatoc_workbench_prepass_hair_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_prepass_frag_glsl[];
|
||||||
|
|
||||||
extern char datatoc_workbench_effect_cavity_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. */
|
/* Maximum number of variations. */
|
||||||
#define MAX_LIGHTING 3
|
#define MAX_LIGHTING 3
|
||||||
#define MAX_COLOR 3
|
#define MAX_COLOR 3
|
||||||
#define MAX_GEOM 2
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
VOLUME_SH_SLICE = 0,
|
VOLUME_SH_SLICE = 0,
|
||||||
@@ -85,8 +86,9 @@ enum {
|
|||||||
#define VOLUME_SH_MAX (1 << (VOLUME_SH_CUBIC + 1))
|
#define VOLUME_SH_MAX (1 << (VOLUME_SH_CUBIC + 1))
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
struct GPUShader *opaque_prepass_sh_cache[GPU_SHADER_CFG_LEN][MAX_GEOM][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][MAX_GEOM][MAX_LIGHTING][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 *opaque_composite_sh[MAX_LIGHTING];
|
||||||
struct GPUShader *oit_resolve_sh;
|
struct GPUShader *oit_resolve_sh;
|
||||||
@@ -119,6 +121,7 @@ void workbench_shader_library_ensure(void)
|
|||||||
/* NOTE: Theses needs to be ordered by dependencies. */
|
/* 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_hair_lib);
|
||||||
DRW_SHADER_LIB_ADD(e_data.lib, common_view_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, gpu_shader_common_obinfos_lib);
|
||||||
DRW_SHADER_LIB_ADD(e_data.lib, workbench_shader_interface_lib);
|
DRW_SHADER_LIB_ADD(e_data.lib, workbench_shader_interface_lib);
|
||||||
DRW_SHADER_LIB_ADD(e_data.lib, workbench_common_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;
|
return (textured) ? (tiled ? 2 : 1) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GPUShader *workbench_shader_get_ex(
|
static GPUShader *workbench_shader_get_ex(WORKBENCH_PrivateData *wpd,
|
||||||
WORKBENCH_PrivateData *wpd, bool transp, bool hair, bool textured, bool tiled)
|
bool transp,
|
||||||
|
eWORKBENCH_DataType datatype,
|
||||||
|
bool textured,
|
||||||
|
bool tiled)
|
||||||
{
|
{
|
||||||
int color = workbench_color_index(wpd, textured, tiled);
|
int color = workbench_color_index(wpd, textured, tiled);
|
||||||
int light = wpd->shading.light;
|
int light = wpd->shading.light;
|
||||||
BLI_assert(light < MAX_LIGHTING);
|
BLI_assert(light < MAX_LIGHTING);
|
||||||
struct GPUShader **shader =
|
struct GPUShader **shader =
|
||||||
(transp) ? &e_data.transp_prepass_sh_cache[wpd->sh_cfg][hair][light][color] :
|
(transp) ? &e_data.transp_prepass_sh_cache[wpd->sh_cfg][datatype][light][color] :
|
||||||
&e_data.opaque_prepass_sh_cache[wpd->sh_cfg][hair][color];
|
&e_data.opaque_prepass_sh_cache[wpd->sh_cfg][datatype][color];
|
||||||
|
|
||||||
if (*shader == NULL) {
|
if (*shader == NULL) {
|
||||||
char *defines = workbench_build_defines(wpd, textured, tiled, false, false);
|
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;
|
datatoc_workbench_prepass_frag_glsl;
|
||||||
char *frag_src = DRW_shader_library_create_shader_string(e_data.lib, frag_file);
|
char *frag_src = DRW_shader_library_create_shader_string(e_data.lib, frag_file);
|
||||||
|
|
||||||
char *vert_file = hair ? datatoc_workbench_prepass_hair_vert_glsl :
|
char *vert_file = (datatype == WORKBENCH_DATATYPE_HAIR) ?
|
||||||
datatoc_workbench_prepass_vert_glsl;
|
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);
|
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];
|
const GPUShaderConfigData *sh_cfg_data = &GPU_shader_cfg_data[wpd->sh_cfg];
|
||||||
@@ -207,6 +216,10 @@ static GPUShader *workbench_shader_get_ex(
|
|||||||
defines,
|
defines,
|
||||||
transp ? "#define TRANSPARENT_MATERIAL\n" :
|
transp ? "#define TRANSPARENT_MATERIAL\n" :
|
||||||
"#define OPAQUE_MATERIAL\n",
|
"#define OPAQUE_MATERIAL\n",
|
||||||
|
(datatype == WORKBENCH_DATATYPE_POINTCLOUD) ?
|
||||||
|
"#define UNIFORM_RESOURCE_ID\n"
|
||||||
|
"#define INSTANCED_ATTR\n" :
|
||||||
|
NULL,
|
||||||
NULL},
|
NULL},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -217,26 +230,29 @@ static GPUShader *workbench_shader_get_ex(
|
|||||||
return *shader;
|
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,
|
GPUShader *workbench_shader_transparent_image_get(WORKBENCH_PrivateData *wpd,
|
||||||
bool hair,
|
eWORKBENCH_DataType datatype,
|
||||||
bool tiled)
|
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)
|
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_PassList *psl = vedata->psl;
|
||||||
WORKBENCH_PrivateData *wpd = data->stl->wpd;
|
WORKBENCH_PrivateData *wpd = vedata->stl->wpd;
|
||||||
struct GPUShader *sh;
|
struct GPUShader *sh;
|
||||||
DRWShadingGroup *grp;
|
DRWShadingGroup *grp;
|
||||||
|
|
||||||
@@ -105,30 +105,30 @@ void workbench_transparent_cache_init(WORKBENCH_Data *data)
|
|||||||
pass = psl->transp_accum_ps;
|
pass = psl->transp_accum_ps;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int hair = 0; hair < 2; hair++) {
|
for (eWORKBENCH_DataType data = 0; data < WORKBENCH_DATATYPE_MAX; data++) {
|
||||||
wpd->prepass[transp][infront][hair].material_hash = BLI_ghash_ptr_new(__func__);
|
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_block(grp, "material_block", wpd->material_ubo_curr);
|
||||||
DRW_shgroup_uniform_int_copy(grp, "materialIndex", -1);
|
DRW_shgroup_uniform_int_copy(grp, "materialIndex", -1);
|
||||||
workbench_transparent_lighting_uniforms(wpd, grp);
|
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_block(grp, "material_block", wpd->material_ubo_curr);
|
||||||
DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. (uses vcol) */
|
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_block(grp, "material_block", wpd->material_ubo_curr);
|
||||||
DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. */
|
DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. */
|
||||||
workbench_transparent_lighting_uniforms(wpd, grp);
|
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_block(grp, "material_block", wpd->material_ubo_curr);
|
||||||
DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. */
|
DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. */
|
||||||
workbench_transparent_lighting_uniforms(wpd, grp);
|
workbench_transparent_lighting_uniforms(wpd, grp);
|
||||||
|
@@ -829,7 +829,7 @@ GPUBatch *DRW_cache_object_face_wireframe_get(Object *ob)
|
|||||||
case OB_HAIR:
|
case OB_HAIR:
|
||||||
return NULL;
|
return NULL;
|
||||||
case OB_POINTCLOUD:
|
case OB_POINTCLOUD:
|
||||||
return NULL;
|
return DRW_pointcloud_batch_cache_get_dots(ob);
|
||||||
case OB_VOLUME:
|
case OB_VOLUME:
|
||||||
return DRW_cache_volume_face_wireframe_get(ob);
|
return DRW_cache_volume_face_wireframe_get(ob);
|
||||||
case OB_GPENCIL: {
|
case OB_GPENCIL: {
|
||||||
@@ -880,7 +880,7 @@ GPUBatch *DRW_cache_object_surface_get(Object *ob)
|
|||||||
case OB_HAIR:
|
case OB_HAIR:
|
||||||
return NULL;
|
return NULL;
|
||||||
case OB_POINTCLOUD:
|
case OB_POINTCLOUD:
|
||||||
return NULL;
|
return DRW_cache_pointcloud_surface_get(ob);
|
||||||
case OB_VOLUME:
|
case OB_VOLUME:
|
||||||
return NULL;
|
return NULL;
|
||||||
default:
|
default:
|
||||||
@@ -958,7 +958,7 @@ GPUBatch **DRW_cache_object_surface_material_get(struct Object *ob,
|
|||||||
case OB_HAIR:
|
case OB_HAIR:
|
||||||
return NULL;
|
return NULL;
|
||||||
case OB_POINTCLOUD:
|
case OB_POINTCLOUD:
|
||||||
return NULL;
|
return DRW_cache_pointcloud_surface_shaded_get(ob, gpumat_array, gpumat_array_len);
|
||||||
case OB_VOLUME:
|
case OB_VOLUME:
|
||||||
return NULL;
|
return NULL;
|
||||||
default:
|
default:
|
||||||
@@ -3289,9 +3289,16 @@ GPUBatch *DRW_cache_lattice_vert_overlay_get(Object *ob)
|
|||||||
|
|
||||||
GPUBatch *DRW_cache_pointcloud_get_dots(Object *object)
|
GPUBatch *DRW_cache_pointcloud_get_dots(Object *object)
|
||||||
{
|
{
|
||||||
|
BLI_assert(object->type == OB_POINTCLOUD);
|
||||||
return DRW_pointcloud_batch_cache_get_dots(object);
|
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
|
/** \name Volume
|
||||||
* \{ */
|
* \{ */
|
||||||
|
@@ -215,6 +215,7 @@ struct GPUBatch *DRW_cache_hair_edge_detection_get(struct Object *ob, bool *r_is
|
|||||||
|
|
||||||
/* PointCloud */
|
/* PointCloud */
|
||||||
struct GPUBatch *DRW_cache_pointcloud_get_dots(struct Object *obj);
|
struct GPUBatch *DRW_cache_pointcloud_get_dots(struct Object *obj);
|
||||||
|
struct GPUBatch *DRW_cache_pointcloud_surface_get(struct Object *obj);
|
||||||
|
|
||||||
/* Volume */
|
/* Volume */
|
||||||
typedef struct DRWVolumeGrid {
|
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);
|
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_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 */
|
/* Volume */
|
||||||
int DRW_volume_material_count_get(struct Volume *volume);
|
int DRW_volume_material_count_get(struct Volume *volume);
|
||||||
|
@@ -28,6 +28,7 @@
|
|||||||
#include "MEM_guardedalloc.h"
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
#include "BLI_math_base.h"
|
#include "BLI_math_base.h"
|
||||||
|
#include "BLI_math_vector.h"
|
||||||
#include "BLI_utildefines.h"
|
#include "BLI_utildefines.h"
|
||||||
|
|
||||||
#include "DNA_object_types.h"
|
#include "DNA_object_types.h"
|
||||||
@@ -45,11 +46,18 @@ static void pointcloud_batch_cache_clear(PointCloud *pointcloud);
|
|||||||
/* PointCloud GPUBatch Cache */
|
/* PointCloud GPUBatch Cache */
|
||||||
|
|
||||||
typedef struct PointCloudBatchCache {
|
typedef struct PointCloudBatchCache {
|
||||||
GPUVertBuf *pos;
|
GPUVertBuf *pos; /* Position and radius. */
|
||||||
GPUBatch *batch;
|
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 */
|
/* settings to determine if cache is invalid */
|
||||||
bool is_dirty;
|
bool is_dirty;
|
||||||
|
|
||||||
|
int mat_len;
|
||||||
} PointCloudBatchCache;
|
} PointCloudBatchCache;
|
||||||
|
|
||||||
/* GPUBatch cache management. */
|
/* GPUBatch cache management. */
|
||||||
@@ -57,7 +65,14 @@ typedef struct PointCloudBatchCache {
|
|||||||
static bool pointcloud_batch_cache_valid(PointCloud *pointcloud)
|
static bool pointcloud_batch_cache_valid(PointCloud *pointcloud)
|
||||||
{
|
{
|
||||||
PointCloudBatchCache *cache = pointcloud->batch_cache;
|
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)
|
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));
|
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;
|
cache->is_dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,8 +128,18 @@ static void pointcloud_batch_cache_clear(PointCloud *pointcloud)
|
|||||||
return;
|
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->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)
|
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;
|
PointCloud *pointcloud = ob->data;
|
||||||
|
const bool has_radius = pointcloud->radius != NULL;
|
||||||
|
|
||||||
static GPUVertFormat format = {0};
|
static GPUVertFormat format = {0};
|
||||||
static uint pos_id;
|
static uint pos;
|
||||||
static uint radius_id;
|
|
||||||
if (format.attr_len == 0) {
|
if (format.attr_len == 0) {
|
||||||
/* initialize vertex format */
|
/* initialize vertex format */
|
||||||
pos_id = GPU_vertformat_attr_add(&format, "pointcloud_pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
/* From the opengl wiki:
|
||||||
radius_id = GPU_vertformat_attr_add(
|
* Note that size does not have to exactly match the size used by the vertex shader. If the
|
||||||
&format, "pointcloud_radius", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
|
* 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);
|
cache->pos = GPU_vertbuf_create_with_format(&format);
|
||||||
GPU_vertbuf_data_alloc(cache->pos, pointcloud->totpoint);
|
GPU_vertbuf_data_alloc(cache->pos, pointcloud->totpoint);
|
||||||
GPU_vertbuf_attr_fill(cache->pos, pos_id, pointcloud->co);
|
|
||||||
|
|
||||||
if (pointcloud->radius) {
|
if (has_radius) {
|
||||||
GPU_vertbuf_attr_fill(cache->pos, radius_id, pointcloud->radius);
|
float(*vbo_data)[4] = (float(*)[4])cache->pos->data;
|
||||||
}
|
|
||||||
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__);
|
|
||||||
for (int i = 0; i < pointcloud->totpoint; i++) {
|
for (int i = 0; i < pointcloud->totpoint; i++) {
|
||||||
/* TODO: add default radius to PointCloud data structure. */
|
copy_v3_v3(vbo_data[i], pointcloud->co[i]);
|
||||||
radius[i] = 0.01f;
|
/* 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)
|
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;
|
PointCloud *pointcloud = ob->data;
|
||||||
PointCloudBatchCache *cache = pointcloud_batch_cache_get(pointcloud);
|
PointCloudBatchCache *cache = pointcloud_batch_cache_get(pointcloud);
|
||||||
|
|
||||||
if (cache->batch == NULL) {
|
if (cache->dots == NULL) {
|
||||||
pointcloud_batch_cache_ensure_pos(ob, cache);
|
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)
|
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);
|
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(
|
void DRW_shgroup_call_instance_range(
|
||||||
DRWShadingGroup *shgroup, Object *ob, struct GPUBatch *geom, uint i_sta, uint i_ct)
|
DRWShadingGroup *shgroup, Object *ob, struct GPUBatch *geom, uint i_sta, uint i_ct)
|
||||||
{
|
{
|
||||||
BLI_assert(i_ct > 0);
|
|
||||||
BLI_assert(geom != NULL);
|
BLI_assert(geom != NULL);
|
||||||
if (G.f & G_FLAG_PICKSEL) {
|
if (G.f & G_FLAG_PICKSEL) {
|
||||||
drw_command_set_select_id(shgroup, NULL, DST.select_id);
|
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_object_to_world(n) (transpose(mat3(ModelMatrixInverse)) * n)
|
||||||
#define normal_world_to_object(n) (transpose(mat3(ModelMatrix)) * n)
|
#define normal_world_to_object(n) (transpose(mat3(ModelMatrix)) * n)
|
||||||
#define normal_world_to_view(n) (mat3(ViewMatrix) * 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_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)
|
#define point_object_to_view(p) ((ViewMatrix * vec4((ModelMatrix * vec4(p, 1.0)).xyz, 1.0)).xyz)
|
||||||
|
Reference in New Issue
Block a user