diff options
-rw-r--r-- | source/blender/blenlib/BLI_math_vector.h | 1 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_vector_inline.c | 8 | ||||
-rw-r--r-- | source/blender/draw/engines/eevee/eevee_engine.c | 8 | ||||
-rw-r--r-- | source/blender/draw/engines/eevee/shaders/lit_surface_vert.glsl | 2 | ||||
-rw-r--r-- | source/blender/draw/intern/DRW_render.h | 1 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_mesh.c | 51 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager.c | 57 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_codegen.c | 12 |
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); |