Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenlib/BLI_math_vector.h1
-rw-r--r--source/blender/blenlib/intern/math_vector_inline.c8
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c8
-rw-r--r--source/blender/draw/engines/eevee/shaders/lit_surface_vert.glsl2
-rw-r--r--source/blender/draw/intern/DRW_render.h1
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.c51
-rw-r--r--source/blender/draw/intern/draw_manager.c57
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c12
8 files changed, 86 insertions, 54 deletions
diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h
index 3a34a199ba8..c1e5c1177cc 100644
--- a/source/blender/blenlib/BLI_math_vector.h
+++ b/source/blender/blenlib/BLI_math_vector.h
@@ -151,6 +151,7 @@ MINLINE void negate_v3_short(short r[3]);
MINLINE void negate_v3_db(double r[3]);
MINLINE void invert_v2(float r[2]);
+MINLINE void invert_v3(float r[3]);
MINLINE void abs_v2(float r[2]);
MINLINE void abs_v2_v2(float r[2], const float a[2]);
diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c
index 75bbfda3f5b..4f658ef015f 100644
--- a/source/blender/blenlib/intern/math_vector_inline.c
+++ b/source/blender/blenlib/intern/math_vector_inline.c
@@ -658,6 +658,14 @@ MINLINE void invert_v2(float r[2])
r[1] = 1.0f / r[1];
}
+MINLINE void invert_v3(float r[3])
+{
+ BLI_assert(!ELEM(0.0f, r[0], r[1], r[2]));
+ r[0] = 1.0f / r[0];
+ r[1] = 1.0f / r[1];
+ r[2] = 1.0f / r[2];
+}
+
MINLINE void abs_v2(float r[2])
{
r[0] = fabsf(r[0]);
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index 8ab07685c9d..14dc4a0dbc0 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -564,7 +564,7 @@ static void EEVEE_cache_populate(void *vedata, Object *ob)
DRW_shgroup_call_sculpt_add((do_cull) ? stl->g_data->depth_shgrp_cull : stl->g_data->depth_shgrp, ob, ob->obmat);
}
else {
- DRW_shgroup_call_add((do_cull) ? stl->g_data->depth_shgrp_cull : stl->g_data->depth_shgrp, geom, ob->obmat);
+ DRW_shgroup_call_object_add((do_cull) ? stl->g_data->depth_shgrp_cull : stl->g_data->depth_shgrp, geom, ob);
}
/* Get per-material split surface */
@@ -605,7 +605,7 @@ static void EEVEE_cache_populate(void *vedata, Object *ob)
DRW_shgroup_call_sculpt_add(shgrp, ob, ob->obmat);
}
else {
- DRW_shgroup_call_add(shgrp, mat_geom[i], ob->obmat);
+ DRW_shgroup_call_object_add(shgrp, mat_geom[i], ob);
}
}
else {
@@ -625,7 +625,7 @@ static void EEVEE_cache_populate(void *vedata, Object *ob)
DRW_shgroup_call_sculpt_add(shgrp, ob, ob->obmat);
}
else {
- DRW_shgroup_call_add(shgrp, mat_geom[i], ob->obmat);
+ DRW_shgroup_call_object_add(shgrp, mat_geom[i], ob);
}
}
}
@@ -642,7 +642,7 @@ static void EEVEE_cache_populate(void *vedata, Object *ob)
DRW_shgroup_call_sculpt_add(shgrp, ob, ob->obmat);
}
else {
- DRW_shgroup_call_add(shgrp, mat_geom[i], ob->obmat);
+ DRW_shgroup_call_object_add(shgrp, mat_geom[i], ob);
}
}
}
diff --git a/source/blender/draw/engines/eevee/shaders/lit_surface_vert.glsl b/source/blender/draw/engines/eevee/shaders/lit_surface_vert.glsl
index 4dd6bb1e287..7f1c32c8edf 100644
--- a/source/blender/draw/engines/eevee/shaders/lit_surface_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lit_surface_vert.glsl
@@ -23,6 +23,6 @@ void main() {
worldNormal = normalize(WorldNormalMatrix * nor);
#ifdef ATTRIB
- pass_attrib();
+ pass_attrib(pos);
#endif
} \ No newline at end of file
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index 652d79980e7..9096eda5f70 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -271,6 +271,7 @@ typedef void (DRWCallGenerateFn)(
void DRW_shgroup_free(struct DRWShadingGroup *shgroup);
void DRW_shgroup_call_add(DRWShadingGroup *shgroup, struct Batch *geom, float (*obmat)[4]);
+void DRW_shgroup_call_object_add(DRWShadingGroup *shgroup, struct Batch *geom, struct Object *ob);
void DRW_shgroup_call_sculpt_add(DRWShadingGroup *shgroup, struct Object *ob, float (*obmat)[4]);
void DRW_shgroup_call_generate_add(
DRWShadingGroup *shgroup, DRWCallGenerateFn *geometry_fn, void *user_data, float (*obmat)[4]);
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index 37ecf89bf26..cf8f11f6ed2 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -1167,25 +1167,6 @@ static void mesh_render_data_looptri_tans_get(
}
}
-static void mesh_render_data_looptri_orcos_get(
- MeshRenderData *rdata, const int tri_idx,
- float *(*r_vert_orcos)[3])
-{
- BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_SHADING));
- if (rdata->edit_bmesh) {
- const BMLoop **bm_looptri = (const BMLoop **)rdata->edit_bmesh->looptris[tri_idx];
- (*r_vert_orcos)[0] = rdata->orco[BM_elem_index_get(bm_looptri[0]->v)];
- (*r_vert_orcos)[1] = rdata->orco[BM_elem_index_get(bm_looptri[1]->v)];
- (*r_vert_orcos)[2] = rdata->orco[BM_elem_index_get(bm_looptri[2]->v)];
- }
- else {
- const MLoopTri *mlt = &rdata->mlooptri[tri_idx];
- (*r_vert_orcos)[0] = rdata->orco[rdata->mloop[mlt->tri[0]].v];
- (*r_vert_orcos)[1] = rdata->orco[rdata->mloop[mlt->tri[1]].v];
- (*r_vert_orcos)[2] = rdata->orco[rdata->mloop[mlt->tri[2]].v];
- }
-}
-
static bool mesh_render_data_looptri_cos_nors_smooth_get(
MeshRenderData *rdata, const int tri_idx,
float *(*r_vert_cos)[3], short **r_tri_nor, short *(*r_vert_nors)[3], bool *r_is_smooth)
@@ -1926,16 +1907,15 @@ static VertexBuffer *mesh_batch_cache_get_tri_shading_data(MeshRenderData *rdata
unsigned int vidx = 0;
const char *attrib_name;
+ if (rdata->uv_len + rdata->vcol_len == 0) {
+ return NULL;
+ }
+
VertexFormat *format = &cache->shaded_triangles_format;
VertexFormat_clear(format);
/* initialize vertex format */
-#ifdef USE_COMP_MESH_DATA
- unsigned int orco_id = VertexFormat_add_attrib(format, "orco", COMP_I16, 3, NORMALIZE_INT_TO_FLOAT);
-#else
- unsigned int orco_id = VertexFormat_add_attrib(format, "orco", COMP_F32, 3, KEEP_FLOAT);
-#endif
unsigned int *uv_id = MEM_mallocN(sizeof(*uv_id) * rdata->uv_len, "UV attrib format");
unsigned int *vcol_id = MEM_mallocN(sizeof(*vcol_id) * rdata->vcol_len, "Vcol attrib format");
unsigned int *tangent_id = MEM_mallocN(sizeof(*tangent_id) * rdata->uv_len, "Tangent attrib format");
@@ -1999,7 +1979,7 @@ static VertexBuffer *mesh_batch_cache_get_tri_shading_data(MeshRenderData *rdata
/* TODO deduplicate all verts and make use of ElementList in mesh_batch_cache_get_shaded_triangles_in_order. */
for (int i = 0; i < tri_len; i++) {
- float *tri_uvs[3], *tri_tans[3], *tri_orcos[3];
+ float *tri_uvs[3], *tri_tans[3];
unsigned char *tri_cols[3];
if (rdata->edit_bmesh == NULL ||
@@ -2052,19 +2032,7 @@ static VertexBuffer *mesh_batch_cache_get_tri_shading_data(MeshRenderData *rdata
VertexBuffer_set_attrib(vbo, vcol_id[j], vidx + 2, tri_cols[2]);
}
- /* ORCO */
- mesh_render_data_looptri_orcos_get(rdata, i, &tri_orcos);
-#ifdef USE_COMP_MESH_DATA
- short s_orco[3][3];
- normal_float_to_short_v3(s_orco[0], tri_orcos[0]);
- normal_float_to_short_v3(s_orco[1], tri_orcos[1]);
- normal_float_to_short_v3(s_orco[2], tri_orcos[2]);
-#else
- float **s_orco = tri_orcos;
-#endif
- VertexBuffer_set_attrib(vbo, orco_id, vidx++, s_orco[0]);
- VertexBuffer_set_attrib(vbo, orco_id, vidx++, s_orco[1]);
- VertexBuffer_set_attrib(vbo, orco_id, vidx++, s_orco[2]);
+ vidx += 3;
}
}
vbo_len_used = vidx;
@@ -3298,8 +3266,11 @@ Batch **DRW_mesh_batch_cache_get_surface_shaded(Mesh *me)
VertexBuffer *vbo = mesh_batch_cache_get_tri_pos_and_normals(rdata, cache);
for (int i = 0; i < mat_len; ++i) {
cache->shaded_triangles[i] = Batch_create(
- PRIM_TRIANGLES, mesh_batch_cache_get_tri_shading_data(rdata, cache), el[i]);
- Batch_add_VertexBuffer(cache->shaded_triangles[i], vbo);
+ PRIM_TRIANGLES, vbo, el[i]);
+ VertexBuffer *vbo_shading = mesh_batch_cache_get_tri_shading_data(rdata, cache);
+ if (vbo_shading) {
+ Batch_add_VertexBuffer(cache->shaded_triangles[i], vbo_shading);
+ }
}
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index a6f6b14a1d7..7d37869e0c8 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -34,6 +34,7 @@
#include "BKE_depsgraph.h"
#include "BKE_global.h"
+#include "BKE_object.h"
#include "BKE_pbvh.h"
#include "BKE_paint.h"
@@ -166,6 +167,7 @@ struct DRWInterface {
int normal;
int worldnormal;
int camtexfac;
+ int orcotexfac;
int eye;
/* Textures */
int tex_bind; /* next texture binding point */
@@ -197,6 +199,8 @@ typedef struct DRWCall {
int type;
float (*obmat)[4];
Batch *geometry;
+
+ Object *ob; /* Optionnal */
} DRWCall;
typedef struct DRWCallGenerate {
@@ -559,6 +563,7 @@ static DRWInterface *DRW_interface_create(GPUShader *shader)
interface->normal = GPU_shader_get_uniform(shader, "NormalMatrix");
interface->worldnormal = GPU_shader_get_uniform(shader, "WorldNormalMatrix");
interface->camtexfac = GPU_shader_get_uniform(shader, "CameraTexCoFactors");
+ interface->orcotexfac = GPU_shader_get_uniform(shader, "OrcoTexCoFactors[0]");
interface->eye = GPU_shader_get_uniform(shader, "eye");
interface->instance_count = 0;
interface->attribs_count = 0;
@@ -821,6 +826,24 @@ void DRW_shgroup_call_add(DRWShadingGroup *shgroup, Batch *geom, float (*obmat)[
BLI_addtail(&shgroup->calls, call);
}
+void DRW_shgroup_call_object_add(DRWShadingGroup *shgroup, Batch *geom, Object *ob)
+{
+ BLI_assert(geom != NULL);
+
+ DRWCall *call = MEM_callocN(sizeof(DRWCall), "DRWCall");
+
+ call->type = DRW_CALL_SINGLE;
+ call->obmat = ob->obmat;
+ call->geometry = geom;
+ call->ob = ob;
+
+#ifdef USE_GPU_SELECT
+ call->select_id = g_DRW_select_id;
+#endif
+
+ BLI_addtail(&shgroup->calls, call);
+}
+
void DRW_shgroup_call_generate_add(
DRWShadingGroup *shgroup,
DRWCallGenerateFn *geometry_fn, void *user_data,
@@ -1418,12 +1441,14 @@ typedef struct DRWBoundTexture {
GPUTexture *tex;
} DRWBoundTexture;
-static void draw_geometry_prepare(DRWShadingGroup *shgroup, const float (*obmat)[4])
+static void draw_geometry_prepare(
+ DRWShadingGroup *shgroup, const float (*obmat)[4], const float *texcoloc, const float *texcosize)
{
RegionView3D *rv3d = DST.draw_ctx.rv3d;
DRWInterface *interface = shgroup->interface;
float mvp[4][4], mv[4][4], mi[4][4], mvi[4][4], pi[4][4], n[3][3], wn[3][3];
+ float orcofacs[2][3] = {{0.0f, 0.0f, 0.0f}, {1.0f, 1.0f, 1.0f}};
float eye[3] = { 0.0f, 0.0f, 1.0f }; /* looking into the screen */
bool do_pi = (interface->projectioninverse != -1);
@@ -1434,6 +1459,7 @@ static void draw_geometry_prepare(DRWShadingGroup *shgroup, const float (*obmat)
bool do_n = (interface->normal != -1);
bool do_wn = (interface->worldnormal != -1);
bool do_eye = (interface->eye != -1);
+ bool do_orco = (interface->orcotexfac != -1) && (texcoloc != NULL) && (texcosize != NULL);
if (do_pi) {
invert_m4_m4(pi, rv3d->winmat);
@@ -1467,6 +1493,13 @@ static void draw_geometry_prepare(DRWShadingGroup *shgroup, const float (*obmat)
/* set eye vector, transformed to object coords */
mul_m3_v3(tmp, eye);
}
+ if (do_orco) {
+ mul_v3_v3fl(orcofacs[1], texcosize, 2.0f);
+ invert_v3(orcofacs[1]);
+ sub_v3_v3v3(orcofacs[0], texcoloc, texcosize);
+ negate_v3(orcofacs[0]);
+ mul_v3_v3(orcofacs[0], orcofacs[1]); /* result in a nice MADD in the shader */
+ }
/* Should be really simple */
/* step 1 : bind object dependent matrices */
@@ -1512,6 +1545,9 @@ static void draw_geometry_prepare(DRWShadingGroup *shgroup, const float (*obmat)
if (interface->camtexfac != -1) {
GPU_shader_uniform_vector(shgroup->shader, interface->camtexfac, 4, 1, (float *)rv3d->viewcamtexcofac);
}
+ if (interface->orcotexfac != -1) {
+ GPU_shader_uniform_vector(shgroup->shader, interface->orcotexfac, 3, 2, (float *)orcofacs);
+ }
if (interface->eye != -1) {
GPU_shader_uniform_vector(shgroup->shader, interface->eye, 3, 1, (float *)eye);
}
@@ -1531,9 +1567,16 @@ static void draw_geometry_execute(DRWShadingGroup *shgroup, Batch *geom)
}
}
-static void draw_geometry(DRWShadingGroup *shgroup, Batch *geom, const float (*obmat)[4])
+static void draw_geometry(DRWShadingGroup *shgroup, Batch *geom, const float (*obmat)[4], Object *ob)
{
- draw_geometry_prepare(shgroup, obmat);
+ float *texcoloc = NULL;
+ float *texcosize = NULL;
+
+ if (ob != NULL) {
+ BKE_object_obdata_texspace_get(ob, NULL, &texcoloc, &texcosize, NULL);
+ }
+
+ draw_geometry_prepare(shgroup, obmat, texcoloc, texcosize);
draw_geometry_execute(shgroup, geom);
}
@@ -1637,13 +1680,13 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
if (shgroup->type == DRW_SHG_INSTANCE && interface->instance_count > 0) {
GPU_SELECT_LOAD_IF_PICKSEL_LIST(&shgroup->calls);
- draw_geometry(shgroup, shgroup->instance_geom, obmat);
+ draw_geometry(shgroup, shgroup->instance_geom, obmat, NULL);
}
else {
/* Some dynamic batch can have no geom (no call to aggregate) */
if (shgroup->batch_geom) {
GPU_SELECT_LOAD_IF_PICKSEL_LIST(&shgroup->calls);
- draw_geometry(shgroup, shgroup->batch_geom, obmat);
+ draw_geometry(shgroup, shgroup->batch_geom, obmat, NULL);
}
}
}
@@ -1659,11 +1702,11 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
GPU_SELECT_LOAD_IF_PICKSEL(call);
if (call->type == DRW_CALL_SINGLE) {
- draw_geometry(shgroup, call->geometry, call->obmat);
+ draw_geometry(shgroup, call->geometry, call->obmat, call->ob);
}
else {
DRWCallGenerate *callgen = ((DRWCallGenerate *)call);
- draw_geometry_prepare(shgroup, callgen->obmat);
+ draw_geometry_prepare(shgroup, callgen->obmat, NULL, NULL);
callgen->geometry_fn(shgroup, draw_geometry_execute, callgen->user_data);
}
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index 8e97b208877..33655396d88 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -787,7 +787,11 @@ static char *code_generate_vertex_new(ListBase *nodes, const char *vert_code)
if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
/* XXX FIXME : see notes in mesh_render_data_create() */
/* NOTE : Replicate changes to mesh_render_data_create() in draw_cache_impl_mesh.c */
- if (input->attribname[0] == '\0') {
+ if (input->attribtype == CD_ORCO) {
+ /* orco is computed from local positions, see bellow */
+ BLI_dynstr_appendf(ds, "uniform vec3 OrcoTexCoFactors[2];\n");
+ }
+ else if (input->attribname[0] == '\0') {
BLI_dynstr_appendf(ds, "in %s %s;\n", GPU_DATATYPE_STR[input->type], attrib_prefix_get(input->attribtype));
BLI_dynstr_appendf(ds, "#define att%d %s\n", input->attribid, attrib_prefix_get(input->attribtype));
}
@@ -808,7 +812,7 @@ static char *code_generate_vertex_new(ListBase *nodes, const char *vert_code)
BLI_dynstr_append(ds, "#define ATTRIB\n");
BLI_dynstr_append(ds, "uniform mat3 NormalMatrix;\n");
- BLI_dynstr_append(ds, "void pass_attrib(void) {\n");
+ BLI_dynstr_append(ds, "void pass_attrib(in vec3 position) {\n");
for (node = nodes->first; node; node = node->next) {
for (input = node->inputs.first; input; input = input->next) {
@@ -821,6 +825,10 @@ static char *code_generate_vertex_new(ListBase *nodes, const char *vert_code)
ds, "\tvar%d.w = att%d.w;\n",
input->attribid, input->attribid);
}
+ else if (input->attribtype == CD_ORCO) {
+ BLI_dynstr_appendf(ds, "\tvar%d = OrcoTexCoFactors[0] + position * OrcoTexCoFactors[1];\n",
+ input->attribid);
+ }
else {
BLI_dynstr_appendf(ds, "\tvar%d = att%d;\n",
input->attribid, input->attribid);