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:
Diffstat (limited to 'source/blender/render/intern/source')
-rw-r--r--source/blender/render/intern/source/bake_api.c2
-rw-r--r--source/blender/render/intern/source/convertblender.c60
-rw-r--r--source/blender/render/intern/source/multires_bake.c2
-rw-r--r--source/blender/render/intern/source/renderdatabase.c41
-rw-r--r--source/blender/render/intern/source/shadeinput.c37
5 files changed, 92 insertions, 50 deletions
diff --git a/source/blender/render/intern/source/bake_api.c b/source/blender/render/intern/source/bake_api.c
index eff021c9b14..1a0ef4e64d4 100644
--- a/source/blender/render/intern/source/bake_api.c
+++ b/source/blender/render/intern/source/bake_api.c
@@ -425,7 +425,7 @@ static TriTessFace *mesh_calc_tri_tessface(
if (tangent) {
DM_ensure_normals(dm);
- DM_calc_loop_tangents(dm);
+ DM_calc_loop_tangents(dm, true, NULL, 0);
tspace = dm->getLoopDataArray(dm, CD_TANGENT);
BLI_assert(tspace);
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index a02c262d58d..69ae7433fff 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -302,7 +302,7 @@ static void calc_tangent_vector(ObjectRen *obr, VlakRen *vlr, int do_tangent)
typedef struct {
ObjectRen *obr;
-
+ int mtface_index;
} SRenderMeshToTangent;
/* interface */
@@ -335,7 +335,7 @@ static void GetTextureCoordinate(const SMikkTSpaceContext *pContext, float r_uv[
//assert(vert_index>=0 && vert_index<4);
SRenderMeshToTangent *pMesh = (SRenderMeshToTangent *) pContext->m_pUserData;
VlakRen *vlr= RE_findOrAddVlak(pMesh->obr, face_num);
- MTFace *tface= RE_vlakren_get_tface(pMesh->obr, vlr, pMesh->obr->actmtface, NULL, 0);
+ MTFace *tface= RE_vlakren_get_tface(pMesh->obr, vlr, pMesh->mtface_index, NULL, 0);
const float *coord;
if (tface != NULL) {
@@ -369,7 +369,7 @@ static void SetTSpace(const SMikkTSpaceContext *pContext, const float fvTangent[
//assert(vert_index>=0 && vert_index<4);
SRenderMeshToTangent *pMesh = (SRenderMeshToTangent *) pContext->m_pUserData;
VlakRen *vlr = RE_findOrAddVlak(pMesh->obr, face_num);
- float *ftang = RE_vlakren_get_nmap_tangent(pMesh->obr, vlr, 1);
+ float *ftang = RE_vlakren_get_nmap_tangent(pMesh->obr, vlr, pMesh->mtface_index, true);
if (ftang!=NULL) {
copy_v3_v3(&ftang[iVert*4+0], fvTangent);
ftang[iVert*4+3]=fSign;
@@ -455,7 +455,12 @@ static void calc_vertexnormals(Render *UNUSED(re), ObjectRen *obr, bool do_verte
sInterface.m_getNormal = GetNormal;
sInterface.m_setTSpaceBasic = SetTSpace;
- genTangSpaceDefault(&sContext);
+ for (a = 0; a < MAX_MTFACE; a++) {
+ if (obr->tangent_mask & 1 << a) {
+ mesh2tangent.mtface_index = a;
+ genTangSpaceDefault(&sContext);
+ }
+ }
}
}
@@ -1969,7 +1974,8 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
float xn, yn, zn, imat[3][3], mat[4][4]; //nor[3],
float *orco = NULL;
short (*loop_nors)[4][3] = NULL;
- bool need_orco = false, need_stress = false, need_nmap_tangent = false, need_tangent = false, need_origindex = false;
+ bool need_orco = false, need_stress = false, need_tangent = false, need_origindex = false;
+ bool need_nmap_tangent_concrete = false;
int a, a1, ok, vertofs;
int end, totvert = 0;
bool do_autosmooth = false, do_displace = false;
@@ -2004,9 +2010,11 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
if (ma->mode_l & MA_NORMAP_TANG) {
if (me->mtpoly==NULL) {
need_orco= 1;
- need_tangent= 1;
}
- need_nmap_tangent= 1;
+ need_tangent= 1;
+ }
+ if (ma->mode2_l & MA_TANGENT_CONCRETE) {
+ need_nmap_tangent_concrete = true;
}
}
}
@@ -2017,7 +2025,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
need_orco= 1;
need_tangent= 1;
}
- need_nmap_tangent= 1;
+ need_nmap_tangent_concrete = true;
}
/* check autosmooth and displacement, we then have to skip only-verts optimize
@@ -2130,14 +2138,13 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
/* store customdata names, because DerivedMesh is freed */
RE_set_customdata_names(obr, &dm->faceData);
- /* add tangent layer if we need one */
- if (need_nmap_tangent!=0 && CustomData_get_layer_index(&dm->faceData, CD_TANGENT) == -1) {
- bool generate_data = false;
- if (CustomData_get_layer_index(&dm->loopData, CD_TANGENT) == -1) {
- dm->calcLoopTangents(dm);
- generate_data = true;
- }
- DM_generate_tangent_tessface_data(dm, generate_data);
+ /* add tangent layers if we need */
+ if ((ma->nmap_tangent_names_count && need_nmap_tangent_concrete) || need_tangent) {
+ dm->calcLoopTangents(
+ dm, need_tangent,
+ (const char (*)[MAX_NAME])ma->nmap_tangent_names, ma->nmap_tangent_names_count);
+ obr->tangent_mask = dm->tangent_mask;
+ DM_generate_tangent_tessface_data(dm, need_nmap_tangent_concrete || need_tangent);
}
/* still to do for keys: the correct local texture coordinate */
@@ -2257,7 +2264,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
CustomDataLayer *layer;
MTFace *mtface, *mtf;
MCol *mcol, *mc;
- int index, mtfn= 0, mcn= 0, mtng=0, mln = 0, vindex;
+ int index, mtfn= 0, mcn= 0, mln = 0, vindex;
char *name;
int nr_verts = v4!=0 ? 4 : 3;
@@ -2280,17 +2287,24 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
for (vindex=0; vindex<nr_verts; vindex++)
mc[vindex]=mcol[a*4+rev_tab[vindex]];
}
- else if (layer->type == CD_TANGENT && mtng < 1) {
- if (need_nmap_tangent != 0) {
- const float * tangent = (const float *) layer->data;
- float * ftang = RE_vlakren_get_nmap_tangent(obr, vlr, 1);
+ else if (layer->type == CD_TANGENT) {
+ if (need_nmap_tangent_concrete || need_tangent) {
+ int uv_start = CustomData_get_layer_index(&dm->faceData, CD_MTFACE);
+ int uv_index = CustomData_get_named_layer_index(&dm->faceData, CD_MTFACE, layer->name);
+ BLI_assert(uv_start >= 0 && uv_index >= 0);
+ if ((uv_start < 0 || uv_index < 0))
+ continue;
+ int n = uv_index - uv_start;
+
+ const float *tangent = (const float *) layer->data;
+ float *ftang = RE_vlakren_get_nmap_tangent(obr, vlr, n, true);
+
for (vindex=0; vindex<nr_verts; vindex++) {
copy_v4_v4(ftang+vindex*4, tangent+a*16+rev_tab[vindex]*4);
mul_mat3_m4_v3(mat, ftang+vindex*4);
normalize_v3(ftang+vindex*4);
}
}
- mtng++;
}
else if (layer->type == CD_TESSLOOPNORMAL && mln < 1) {
if (loop_nors) {
@@ -2398,7 +2412,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
}
if (recalc_normals!=0 || need_tangent!=0)
- calc_vertexnormals(re, obr, recalc_normals, need_tangent, need_nmap_tangent);
+ calc_vertexnormals(re, obr, recalc_normals, need_tangent, need_nmap_tangent_concrete);
}
MEM_SAFE_FREE(loop_nors);
diff --git a/source/blender/render/intern/source/multires_bake.c b/source/blender/render/intern/source/multires_bake.c
index 8eb6e7000ab..8c6d9c5f951 100644
--- a/source/blender/render/intern/source/multires_bake.c
+++ b/source/blender/render/intern/source/multires_bake.c
@@ -456,7 +456,7 @@ static void do_multires_bake(MultiresBakeRender *bkr, Image *ima, bool require_t
if (require_tangent) {
if (CustomData_get_layer_index(&dm->loopData, CD_TANGENT) == -1)
- DM_calc_loop_tangents(dm);
+ DM_calc_loop_tangents(dm, true, NULL, 0);
pvtangent = DM_get_loop_data_layer(dm, CD_TANGENT);
}
diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c
index 39e4e7b048a..de08ea8d11c 100644
--- a/source/blender/render/intern/source/renderdatabase.c
+++ b/source/blender/render/intern/source/renderdatabase.c
@@ -70,6 +70,7 @@
#include "DNA_material_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_texture_types.h"
+#include "DNA_listBase.h"
#include "BKE_customdata.h"
#include "BKE_DerivedMesh.h"
@@ -379,19 +380,28 @@ float *RE_vlakren_get_surfnor(ObjectRen *obr, VlakRen *vlak, int verify)
return surfnor + (vlak->index & 255)*RE_SURFNOR_ELEMS;
}
-float *RE_vlakren_get_nmap_tangent(ObjectRen *obr, VlakRen *vlak, int verify)
+float *RE_vlakren_get_nmap_tangent(ObjectRen *obr, VlakRen *vlak, int index, bool verify)
{
- float *tangent;
+ float **tangents;
int nr= vlak->index>>8;
- tangent= obr->vlaknodes[nr].tangent;
- if (tangent==NULL) {
- if (verify)
- tangent= obr->vlaknodes[nr].tangent= MEM_callocN(256*RE_NMAP_TANGENT_ELEMS*sizeof(float), "tangent table");
+ tangents = obr->vlaknodes[nr].tangent_arrays;
+
+ if (index + 1 > 8) {
+ return NULL;
+ }
+
+ index = index < 0 ? 0: index;
+
+ if (tangents[index] == NULL) {
+ if (verify) {
+ tangents[index] = MEM_callocN(256*RE_NMAP_TANGENT_ELEMS*sizeof(float), "tangent table");
+ }
else
return NULL;
}
- return tangent + (vlak->index & 255)*RE_NMAP_TANGENT_ELEMS;
+
+ return tangents[index] + (vlak->index & 255)*RE_NMAP_TANGENT_ELEMS;
}
RadFace **RE_vlakren_get_radface(ObjectRen *obr, VlakRen *vlak, int verify)
@@ -414,7 +424,8 @@ VlakRen *RE_vlakren_copy(ObjectRen *obr, VlakRen *vlr)
VlakRen *vlr1 = RE_findOrAddVlak(obr, obr->totvlak++);
MTFace *mtface, *mtface1;
MCol *mcol, *mcol1;
- float *surfnor, *surfnor1, *tangent, *tangent1;
+ float *surfnor, *surfnor1;
+ float *tangent, *tangent1;
int *origindex, *origindex1;
RadFace **radface, **radface1;
int i, index = vlr1->index;
@@ -446,9 +457,11 @@ VlakRen *RE_vlakren_copy(ObjectRen *obr, VlakRen *vlr)
copy_v3_v3(surfnor1, surfnor);
}
- tangent= RE_vlakren_get_nmap_tangent(obr, vlr, 0);
- if (tangent) {
- tangent1= RE_vlakren_get_nmap_tangent(obr, vlr1, 1);
+ for (i=0; i < MAX_MTFACE; i++) {
+ tangent = RE_vlakren_get_nmap_tangent(obr, vlr, i, false);
+ if (!tangent)
+ continue;
+ tangent1 = RE_vlakren_get_nmap_tangent(obr, vlr1, i, true);
memcpy(tangent1, tangent, sizeof(float)*RE_NMAP_TANGENT_ELEMS);
}
@@ -789,8 +802,10 @@ void free_renderdata_vlaknodes(VlakTableNode *vlaknodes)
MEM_freeN(vlaknodes[a].origindex);
if (vlaknodes[a].surfnor)
MEM_freeN(vlaknodes[a].surfnor);
- if (vlaknodes[a].tangent)
- MEM_freeN(vlaknodes[a].tangent);
+ for (int b = 0; b < MAX_MTFACE; b++) {
+ if (vlaknodes[a].tangent_arrays[b])
+ MEM_freeN(vlaknodes[a].tangent_arrays[b]);
+ }
if (vlaknodes[a].radface)
MEM_freeN(vlaknodes[a].radface);
}
diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c
index d5fdcb2423a..bfdeed1e354 100644
--- a/source/blender/render/intern/source/shadeinput.c
+++ b/source/blender/render/intern/source/shadeinput.c
@@ -883,7 +883,10 @@ void shade_input_set_shade_texco(ShadeInput *shi)
float u = shi->u, v = shi->v;
float l = 1.0f + u + v, dl;
int mode = shi->mode; /* or-ed result for all nodes */
+ int mode2 = shi->mode2;
short texco = shi->mat->texco;
+ const bool need_mikk_tangent = (mode & MA_NORMAP_TANG || R.flag & R_NEED_TANGENT);
+ const bool need_mikk_tangent_concrete = (mode2 & MA_TANGENT_CONCRETE) != 0;
/* calculate dxno */
if (shi->vlr->flag & R_SMOOTH) {
@@ -904,8 +907,8 @@ void shade_input_set_shade_texco(ShadeInput *shi)
}
/* calc tangents */
- if (mode & (MA_TANGENT_V | MA_NORMAP_TANG) || R.flag & R_NEED_TANGENT) {
- const float *tangent, *s1, *s2, *s3;
+ if (mode & (MA_TANGENT_V | MA_NORMAP_TANG) || mode2 & MA_TANGENT_CONCRETE || R.flag & R_NEED_TANGENT) {
+ const float *s1, *s2, *s3;
float tl, tu, tv;
if (shi->vlr->flag & R_SMOOTH) {
@@ -942,14 +945,18 @@ void shade_input_set_shade_texco(ShadeInput *shi)
}
}
- if (mode & MA_NORMAP_TANG || R.flag & R_NEED_TANGENT) {
- tangent = RE_vlakren_get_nmap_tangent(obr, shi->vlr, 0);
+ if (need_mikk_tangent || need_mikk_tangent_concrete) {
+ int j1 = shi->i1, j2 = shi->i2, j3 = shi->i3;
+ float c0[3], c1[3], c2[3];
+ int acttang = obr->actmtface;
- if (tangent) {
- int j1 = shi->i1, j2 = shi->i2, j3 = shi->i3;
- float c0[3], c1[3], c2[3];
+ vlr_set_uv_indices(shi->vlr, &j1, &j2, &j3);
- vlr_set_uv_indices(shi->vlr, &j1, &j2, &j3);
+ /* cycle through all tangent in vlakren */
+ for (int i = 0; i < MAX_MTFACE; i++) {
+ const float *tangent = RE_vlakren_get_nmap_tangent(obr, shi->vlr, i, false);
+ if (!tangent)
+ continue;
copy_v3_v3(c0, &tangent[j1 * 4]);
copy_v3_v3(c1, &tangent[j2 * 4]);
@@ -965,13 +972,19 @@ void shade_input_set_shade_texco(ShadeInput *shi)
/* we don't normalize the interpolated TBN tangent
* corresponds better to how it's done in game engines */
- shi->nmaptang[0] = (tl * c2[0] - tu * c0[0] - tv * c1[0]);
- shi->nmaptang[1] = (tl * c2[1] - tu * c0[1] - tv * c1[1]);
- shi->nmaptang[2] = (tl * c2[2] - tu * c0[2] - tv * c1[2]);
+ shi->tangents[i][0] = (tl * c2[0] - tu * c0[0] - tv * c1[0]);
+ shi->tangents[i][1] = (tl * c2[1] - tu * c0[1] - tv * c1[1]);
+ shi->tangents[i][2] = (tl * c2[2] - tu * c0[2] - tv * c1[2]);
/* the sign is the same for all 3 vertices of any
* non degenerate triangle. */
- shi->nmaptang[3] = tangent[j1 * 4 + 3];
+ shi->tangents[i][3] = tangent[j1 * 4 + 3];
+
+ if (acttang == i && need_mikk_tangent) {
+ for (int m = 0; m < 4; m++) {
+ shi->nmaptang[m] = shi->tangents[i][m];
+ }
+ }
}
}
}