SL-18095 WIP -- Add Mikktspace tangent generation for PBR materials and switch to per-pixel binormal generation. Still bugged with some test content.
parent
abf788175c
commit
8ad7240a3b
|
|
@ -1836,6 +1836,50 @@
|
|||
<key>version</key>
|
||||
<string>0.16.561408</string>
|
||||
</map>
|
||||
<key>mikktspace</key>
|
||||
<map>
|
||||
<key>canonical_repo</key>
|
||||
<string>https://bitbucket.org/lindenlab/3p-mikktspace</string>
|
||||
<key>copyright</key>
|
||||
<string>Copyright (C) 2011 by Morten S. Mikkelsen</string>
|
||||
<key>description</key>
|
||||
<string>Mikktspace Tangent Generator</string>
|
||||
<key>license</key>
|
||||
<string>Copyright (C) 2011 by Morten S. Mikkelsen</string>
|
||||
<key>license_file</key>
|
||||
<string>mikktspace.txt</string>
|
||||
<key>name</key>
|
||||
<string>mikktspace</string>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>darwin64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>b48b7ac0792d3ea8f087d99d9e4a29d8</string>
|
||||
<key>url</key>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104415/914944/mikktspace-1-darwin64-574859.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
</map>
|
||||
<key>windows64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>02e9e5b6fe6788f4d2babb83ec544843</string>
|
||||
<key>url</key>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104406/914909/mikktspace-1-windows64-574859.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>1</string>
|
||||
</map>
|
||||
<key>minizip-ng</key>
|
||||
<map>
|
||||
<key>canonical_repo</key>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
# -*- cmake -*-
|
||||
|
||||
include(Variables)
|
||||
include(Mikktspace)
|
||||
|
||||
set(LLMATH_INCLUDE_DIRS
|
||||
${LIBS_OPEN_DIR}/llmath
|
||||
)
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include <stdint.h>
|
||||
#endif
|
||||
#include <cmath>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "llerror.h"
|
||||
|
||||
|
|
@ -52,6 +53,9 @@
|
|||
#include "llmeshoptimizer.h"
|
||||
#include "lltimer.h"
|
||||
|
||||
#include "mikktspace/mikktspace.h"
|
||||
#include "mikktspace/mikktspace.c" // insert mikktspace implementation into llvolume object file
|
||||
|
||||
#define DEBUG_SILHOUETTE_BINORMALS 0
|
||||
#define DEBUG_SILHOUETTE_NORMALS 0 // TomY: Use this to display normals using the silhouette
|
||||
#define DEBUG_SILHOUETTE_EDGE_MAP 0 // DaveP: Use this to display edge map using the silhouette
|
||||
|
|
@ -2096,9 +2100,9 @@ void LLVolume::regen()
|
|||
createVolumeFaces();
|
||||
}
|
||||
|
||||
void LLVolume::genTangents(S32 face)
|
||||
void LLVolume::genTangents(S32 face, bool mikktspace)
|
||||
{
|
||||
mVolumeFaces[face].createTangents();
|
||||
mVolumeFaces[face].createTangents(mikktspace);
|
||||
}
|
||||
|
||||
LLVolume::~LLVolume()
|
||||
|
|
@ -4797,6 +4801,17 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src)
|
|||
mTangents = NULL;
|
||||
}
|
||||
|
||||
if (src.mMikktSpaceTangents)
|
||||
{
|
||||
allocateTangents(src.mNumVertices, true);
|
||||
LLVector4a::memcpyNonAliased16((F32*)mMikktSpaceTangents, (F32*)src.mMikktSpaceTangents, vert_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
ll_aligned_free_16(mMikktSpaceTangents);
|
||||
mMikktSpaceTangents = nullptr;
|
||||
}
|
||||
|
||||
if (src.mWeights)
|
||||
{
|
||||
llassert(!mWeights); // don't orphan an old alloc here accidentally
|
||||
|
|
@ -4867,6 +4882,8 @@ void LLVolumeFace::freeData()
|
|||
mIndices = NULL;
|
||||
ll_aligned_free_16(mTangents);
|
||||
mTangents = NULL;
|
||||
ll_aligned_free_16(mMikktSpaceTangents);
|
||||
mMikktSpaceTangents = nullptr;
|
||||
ll_aligned_free_16(mWeights);
|
||||
mWeights = NULL;
|
||||
|
||||
|
|
@ -4988,6 +5005,9 @@ void LLVolumeFace::remap()
|
|||
ll_aligned_free_16(mTangents);
|
||||
mTangents = NULL;
|
||||
|
||||
ll_aligned_free_16(mMikktSpaceTangents);
|
||||
mMikktSpaceTangents = nullptr;
|
||||
|
||||
// Assign new values
|
||||
mIndices = remap_indices;
|
||||
mPositions = remap_positions;
|
||||
|
|
@ -5514,6 +5534,12 @@ bool LLVolumeFace::cacheOptimize()
|
|||
}
|
||||
}
|
||||
|
||||
llassert(mTangents == nullptr); // cache optimize called too late, tangents already generated
|
||||
llassert(mMikktSpaceTangents == nullptr);
|
||||
|
||||
// =====================================================================================
|
||||
// DEPRECATED -- cacheOptimize should always be called before tangents are generated
|
||||
// =====================================================================================
|
||||
LLVector4a* binorm = NULL;
|
||||
if (mTangents)
|
||||
{
|
||||
|
|
@ -5526,11 +5552,11 @@ bool LLVolumeFace::cacheOptimize()
|
|||
return false;
|
||||
}
|
||||
}
|
||||
// =====================================================================================
|
||||
|
||||
//allocate mapping of old indices to new indices
|
||||
//allocate mapping of old indices to new indices
|
||||
std::vector<S32> new_idx;
|
||||
|
||||
try
|
||||
try
|
||||
{
|
||||
new_idx.resize(mNumVertices, -1);
|
||||
}
|
||||
|
|
@ -5673,6 +5699,7 @@ void LLVolumeFace::swapData(LLVolumeFace& rhs)
|
|||
llswap(rhs.mPositions, mPositions);
|
||||
llswap(rhs.mNormals, mNormals);
|
||||
llswap(rhs.mTangents, mTangents);
|
||||
llswap(rhs.mMikktSpaceTangents, mMikktSpaceTangents);
|
||||
llswap(rhs.mTexCoords, mTexCoords);
|
||||
llswap(rhs.mIndices,mIndices);
|
||||
llswap(rhs.mNumVertices, mNumVertices);
|
||||
|
|
@ -6380,37 +6407,217 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
|
|||
void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal,
|
||||
const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent);
|
||||
|
||||
void LLVolumeFace::createTangents()
|
||||
|
||||
// data structures for tangent generation
|
||||
|
||||
// key for summing tangents
|
||||
// We will blend tangents wherever a common position and normal is found
|
||||
struct MikktKey
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME
|
||||
// Position
|
||||
LLVector3 p;
|
||||
// Normal
|
||||
LLVector3 n;
|
||||
|
||||
if (!mTangents)
|
||||
{
|
||||
allocateTangents(mNumVertices);
|
||||
bool operator==(const MikktKey& rhs) const { return p == rhs.p && n == rhs.n; }
|
||||
};
|
||||
|
||||
//generate tangents
|
||||
//LLVector4a* pos = mPositions;
|
||||
//LLVector2* tc = (LLVector2*) mTexCoords;
|
||||
LLVector4a* binorm = (LLVector4a*) mTangents;
|
||||
// sum of tangents and list of signs and index array indices for a given position and normal combination
|
||||
// sign must be kept separate from summed tangent because a single position and normal may have a different
|
||||
// tangent facing where UV seams exist
|
||||
struct MikktTangent
|
||||
{
|
||||
// tangent vector
|
||||
LLVector3 t;
|
||||
// signs
|
||||
std::vector<F32> s;
|
||||
// indices (in index array)
|
||||
std::vector<S32> i;
|
||||
};
|
||||
|
||||
LLVector4a* end = mTangents+mNumVertices;
|
||||
while (binorm < end)
|
||||
{
|
||||
(*binorm++).clear();
|
||||
}
|
||||
// hash function for MikktTangent
|
||||
namespace boost
|
||||
{
|
||||
template <>
|
||||
struct hash<LLVector3>
|
||||
{
|
||||
std::size_t operator()(LLVector3 const& k) const
|
||||
{
|
||||
size_t seed = 0;
|
||||
boost::hash_combine(seed, k.mV[0]);
|
||||
boost::hash_combine(seed, k.mV[1]);
|
||||
boost::hash_combine(seed, k.mV[2]);
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
|
||||
binorm = mTangents;
|
||||
template <>
|
||||
struct hash<MikktKey>
|
||||
{
|
||||
std::size_t operator()(MikktKey const& k) const
|
||||
{
|
||||
size_t seed = 0;
|
||||
boost::hash_combine(seed, k.p);
|
||||
boost::hash_combine(seed, k.n);
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
CalculateTangentArray(mNumVertices, mPositions, mNormals, mTexCoords, mNumIndices/3, mIndices, mTangents);
|
||||
// boost adapter
|
||||
namespace std
|
||||
{
|
||||
template<>
|
||||
struct hash<MikktKey>
|
||||
{
|
||||
std::size_t operator()(MikktKey const& k) const
|
||||
{
|
||||
return boost::hash<MikktKey>()(k);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
//normalize tangents
|
||||
for (U32 i = 0; i < mNumVertices; i++)
|
||||
{
|
||||
//binorm[i].normalize3fast();
|
||||
//bump map/planar projection code requires normals to be normalized
|
||||
mNormals[i].normalize3fast();
|
||||
}
|
||||
}
|
||||
struct MikktData
|
||||
{
|
||||
LLVolumeFace* face;
|
||||
std::unordered_map<MikktKey, MikktTangent > tangents;
|
||||
};
|
||||
|
||||
|
||||
void LLVolumeFace::createTangents(bool mikktspace)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
|
||||
|
||||
auto& tangents = mikktspace ? mMikktSpaceTangents : mTangents;
|
||||
|
||||
if (!tangents)
|
||||
{
|
||||
allocateTangents(mNumVertices, mikktspace);
|
||||
|
||||
if (mikktspace)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_VOLUME("mikktspace");
|
||||
SMikkTSpaceInterface ms;
|
||||
|
||||
ms.m_getNumFaces = [](const SMikkTSpaceContext* pContext)
|
||||
{
|
||||
MikktData* data = (MikktData*)pContext->m_pUserData;
|
||||
LLVolumeFace* face = data->face;
|
||||
return face->mNumIndices / 3;
|
||||
};
|
||||
|
||||
ms.m_getNumVerticesOfFace = [](const SMikkTSpaceContext* pContext, const int iFace)
|
||||
{
|
||||
return 3;
|
||||
};
|
||||
|
||||
ms.m_getPosition = [](const SMikkTSpaceContext* pContext, float fvPosOut[], const int iFace, const int iVert)
|
||||
{
|
||||
MikktData* data = (MikktData*)pContext->m_pUserData;
|
||||
LLVolumeFace* face = data->face;
|
||||
S32 idx = face->mIndices[iFace * 3 + iVert];
|
||||
auto& vert = face->mPositions[idx];
|
||||
F32* v = vert.getF32ptr();
|
||||
fvPosOut[0] = v[0];
|
||||
fvPosOut[1] = v[1];
|
||||
fvPosOut[2] = v[2];
|
||||
};
|
||||
|
||||
ms.m_getNormal = [](const SMikkTSpaceContext* pContext, float fvNormOut[], const int iFace, const int iVert)
|
||||
{
|
||||
MikktData* data = (MikktData*)pContext->m_pUserData;
|
||||
LLVolumeFace* face = data->face;
|
||||
S32 idx = face->mIndices[iFace * 3 + iVert];
|
||||
auto& norm = face->mNormals[idx];
|
||||
F32* n = norm.getF32ptr();
|
||||
fvNormOut[0] = n[0];
|
||||
fvNormOut[1] = n[1];
|
||||
fvNormOut[2] = n[2];
|
||||
};
|
||||
|
||||
ms.m_getTexCoord = [](const SMikkTSpaceContext* pContext, float fvTexcOut[], const int iFace, const int iVert)
|
||||
{
|
||||
MikktData* data = (MikktData*)pContext->m_pUserData;
|
||||
LLVolumeFace* face = data->face;
|
||||
S32 idx = face->mIndices[iFace * 3 + iVert];
|
||||
auto& tc = face->mTexCoords[idx];
|
||||
fvTexcOut[0] = tc.mV[0];
|
||||
fvTexcOut[1] = tc.mV[1];
|
||||
};
|
||||
|
||||
ms.m_setTSpaceBasic = [](const SMikkTSpaceContext* pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert)
|
||||
{
|
||||
MikktData* data = (MikktData*)pContext->m_pUserData;
|
||||
LLVolumeFace* face = data->face;
|
||||
S32 i = iFace * 3 + iVert;
|
||||
S32 idx = face->mIndices[i];
|
||||
|
||||
LLVector3 p(face->mPositions[idx].getF32ptr());
|
||||
LLVector3 n(face->mNormals[idx].getF32ptr());
|
||||
LLVector3 t(fvTangent);
|
||||
|
||||
MikktKey key = { p, n };
|
||||
|
||||
MikktTangent& mt = data->tangents[key];
|
||||
mt.t += t;
|
||||
mt.s.push_back(fSign);
|
||||
mt.i.push_back(i);
|
||||
};
|
||||
|
||||
ms.m_setTSpace = nullptr;
|
||||
|
||||
MikktData data;
|
||||
data.face = this;
|
||||
|
||||
SMikkTSpaceContext ctx = { &ms, &data };
|
||||
|
||||
genTangSpaceDefault(&ctx);
|
||||
|
||||
for (U32 i = 0; i < mNumVertices; ++i)
|
||||
{
|
||||
MikktKey key = { LLVector3(mPositions[i].getF32ptr()), LLVector3(mNormals[i].getF32ptr()) };
|
||||
MikktTangent& t = data.tangents[key];
|
||||
|
||||
//set tangent
|
||||
mMikktSpaceTangents[i].load3(t.t.mV);
|
||||
mMikktSpaceTangents[i].normalize3fast();
|
||||
|
||||
//set sign
|
||||
F32 sign = 0.f;
|
||||
for (int j = 0; j < t.i.size(); ++j)
|
||||
{
|
||||
if (mIndices[t.i[j]] == i)
|
||||
{
|
||||
sign = t.s[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
llassert(sign != 0.f);
|
||||
mMikktSpaceTangents[i].getF32ptr()[3] = sign;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//generate tangents
|
||||
LLVector4a* ptr = (LLVector4a*)tangents;
|
||||
|
||||
LLVector4a* end = mTangents + mNumVertices;
|
||||
while (ptr < end)
|
||||
{
|
||||
(*ptr++).clear();
|
||||
}
|
||||
|
||||
CalculateTangentArray(mNumVertices, mPositions, mNormals, mTexCoords, mNumIndices / 3, mIndices, tangents);
|
||||
}
|
||||
|
||||
//normalize normals
|
||||
for (U32 i = 0; i < mNumVertices; i++)
|
||||
{
|
||||
//bump map/planar projection code requires normals to be normalized
|
||||
mNormals[i].normalize3fast();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLVolumeFace::resizeVertices(S32 num_verts)
|
||||
|
|
@ -6511,10 +6718,11 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con
|
|||
mNumVertices++;
|
||||
}
|
||||
|
||||
void LLVolumeFace::allocateTangents(S32 num_verts)
|
||||
void LLVolumeFace::allocateTangents(S32 num_verts, bool mikktspace)
|
||||
{
|
||||
ll_aligned_free_16(mTangents);
|
||||
mTangents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
|
||||
auto& buff = mikktspace ? mMikktSpaceTangents : mTangents;
|
||||
ll_aligned_free_16(buff);
|
||||
buff = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
|
||||
}
|
||||
|
||||
void LLVolumeFace::allocateWeights(S32 num_verts)
|
||||
|
|
|
|||
|
|
@ -870,10 +870,10 @@ private:
|
|||
public:
|
||||
|
||||
BOOL create(LLVolume* volume, BOOL partial_build = FALSE);
|
||||
void createTangents();
|
||||
void createTangents(bool mikktspace = false);
|
||||
|
||||
void resizeVertices(S32 num_verts);
|
||||
void allocateTangents(S32 num_verts);
|
||||
void allocateTangents(S32 num_verts, bool mikktspace = false);
|
||||
void allocateWeights(S32 num_verts);
|
||||
void allocateJointIndices(S32 num_verts);
|
||||
void resizeIndices(S32 num_indices);
|
||||
|
|
@ -947,6 +947,7 @@ public:
|
|||
LLVector4a* mPositions; // Contains vertices, nortmals and texcoords
|
||||
LLVector4a* mNormals; // pointer into mPositions
|
||||
LLVector4a* mTangents;
|
||||
LLVector4a* mMikktSpaceTangents = nullptr; // for GLTF rendering, use mikkt space tangents
|
||||
LLVector2* mTexCoords; // pointer into mPositions
|
||||
|
||||
// mIndices contains mNumIndices amount of elements.
|
||||
|
|
@ -1028,7 +1029,7 @@ public:
|
|||
void setDirty() { mPathp->setDirty(); mProfilep->setDirty(); }
|
||||
|
||||
void regen();
|
||||
void genTangents(S32 face);
|
||||
void genTangents(S32 face, bool mikktspace = false);
|
||||
|
||||
BOOL isConvex() const;
|
||||
BOOL isCap(S32 face);
|
||||
|
|
|
|||
|
|
@ -10558,6 +10558,17 @@
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>RenderUseMikktSpace</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Use Mikkt Space tangents on GLTF materials.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>RenderUseTriStrips</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ uniform vec3 emissiveColor;
|
|||
|
||||
#ifdef HAS_NORMAL_MAP
|
||||
uniform sampler2D bumpMap;
|
||||
VARYING vec3 vary_tangent;
|
||||
flat in float vary_sign;
|
||||
#endif
|
||||
|
||||
#ifdef HAS_EMISSIVE_MAP
|
||||
|
|
@ -66,9 +68,6 @@ VARYING vec4 vertex_color;
|
|||
VARYING vec2 vary_texcoord0;
|
||||
#ifdef HAS_NORMAL_MAP
|
||||
VARYING vec3 vary_normal;
|
||||
VARYING vec3 vary_mat0;
|
||||
VARYING vec3 vary_mat1;
|
||||
VARYING vec3 vary_mat2;
|
||||
VARYING vec2 vary_texcoord1;
|
||||
#endif
|
||||
|
||||
|
|
@ -94,21 +93,14 @@ void main()
|
|||
|
||||
vec3 col = vertex_color.rgb * albedo.rgb;
|
||||
|
||||
#ifdef HAS_NORMAL_MAP
|
||||
vec4 norm = texture2D(bumpMap, vary_texcoord1.xy);
|
||||
norm.xyz = normalize(norm.xyz * 2 - 1);
|
||||
// from mikktspace.com
|
||||
vec4 vNt = texture2D(bumpMap, vary_texcoord1.xy)*2.0-1.0;
|
||||
float sign = vary_sign;
|
||||
vec3 vN = vary_normal;
|
||||
vec3 vT = vary_tangent.xyz;
|
||||
|
||||
vec3 tnorm = vec3(dot(norm.xyz,vary_mat0),
|
||||
dot(norm.xyz,vary_mat1),
|
||||
dot(norm.xyz,vary_mat2));
|
||||
#else
|
||||
vec4 norm = vec4(0,0,0,1.0);
|
||||
// vec3 tnorm = vary_normal;
|
||||
vec3 tnorm = vec3(0,0,1);
|
||||
#endif
|
||||
|
||||
tnorm = normalize(tnorm.xyz);
|
||||
norm.xyz = tnorm.xyz;
|
||||
vec3 vB = sign * cross(vN, vT);
|
||||
vec3 tnorm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN );
|
||||
|
||||
// RGB = Occlusion, Roughness, Metal
|
||||
// default values, see LLViewerTexture::sDefaultPBRORMImagep
|
||||
|
|
@ -155,6 +147,9 @@ void main()
|
|||
|
||||
tnorm *= gl_FrontFacing ? 1.0 : -1.0;
|
||||
|
||||
//col = vec3(0,0,0);
|
||||
//emissive = vary_tangent.xyz*0.5+0.5;
|
||||
//emissive = vec3(vary_sign*0.5+0.5);
|
||||
// See: C++: addDeferredAttachments(), GLSL: softenLightF
|
||||
frag_data[0] = vec4(col, 0.0); // Diffuse
|
||||
frag_data[1] = vec4(emissive, vertex_color.a); // PBR sRGB Emissive
|
||||
|
|
|
|||
|
|
@ -59,13 +59,7 @@ ATTRIBUTE vec2 texcoord0;
|
|||
ATTRIBUTE vec4 tangent;
|
||||
ATTRIBUTE vec2 texcoord1;
|
||||
|
||||
VARYING vec3 vary_mat0;
|
||||
VARYING vec3 vary_mat1;
|
||||
VARYING vec3 vary_mat2;
|
||||
|
||||
VARYING vec2 vary_texcoord1;
|
||||
#else
|
||||
VARYING vec3 vary_normal;
|
||||
#endif
|
||||
|
||||
#ifdef HAS_SPECULAR_MAP
|
||||
|
|
@ -75,6 +69,10 @@ VARYING vec2 vary_texcoord2;
|
|||
|
||||
VARYING vec4 vertex_color;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
VARYING vec3 vary_tangent;
|
||||
flat out float vary_sign;
|
||||
|
||||
VARYING vec3 vary_normal;
|
||||
|
||||
void main()
|
||||
{
|
||||
|
|
@ -113,9 +111,9 @@ void main()
|
|||
vec3 t = normalize((mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz);
|
||||
vec3 b = cross(n, t)*tangent.w;
|
||||
|
||||
vary_mat0 = vec3(t.x, b.x, n.x);
|
||||
vary_mat1 = vec3(t.y, b.y, n.y);
|
||||
vary_mat2 = vec3(t.z, b.z, n.z);
|
||||
//vary_mat0 = vec3(t.x, b.x, n.x);
|
||||
//vary_mat1 = vec3(t.y, b.y, n.y);
|
||||
//vary_mat2 = vec3(t.z, b.z, n.z);
|
||||
#else //HAS_NORMAL_MAP
|
||||
vary_normal = n;
|
||||
#endif //HAS_NORMAL_MAP
|
||||
|
|
@ -123,12 +121,16 @@ vary_normal = n;
|
|||
vec3 n = normalize(normal_matrix * normal);
|
||||
#ifdef HAS_NORMAL_MAP
|
||||
vec3 t = normalize(normal_matrix * tangent.xyz);
|
||||
vec3 b = cross(n,t)*tangent.w;
|
||||
vary_tangent = t;
|
||||
vary_sign = tangent.w;
|
||||
vary_normal = n;
|
||||
|
||||
//vec3 b = cross(n,t)*tangent.w;
|
||||
//vec3 t = cross(b,n) * binormal.w;
|
||||
|
||||
vary_mat0 = vec3(t.x, b.x, n.x);
|
||||
vary_mat1 = vec3(t.y, b.y, n.y);
|
||||
vary_mat2 = vec3(t.z, b.z, n.z);
|
||||
//vary_mat0 = vec3(t.x, b.x, n.x);
|
||||
//vary_mat1 = vec3(t.y, b.y, n.y);
|
||||
//vary_mat2 = vec3(t.z, b.z, n.z);
|
||||
#else //HAS_NORMAL_MAP
|
||||
vary_normal = n;
|
||||
#endif //HAS_NORMAL_MAP
|
||||
|
|
|
|||
|
|
@ -2166,14 +2166,19 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
|||
mVertexBuffer->getTangentStrider(tangent, mGeomIndex, mGeomCount, map_range);
|
||||
F32* tangents = (F32*) tangent.get();
|
||||
|
||||
mVObjp->getVolume()->genTangents(f);
|
||||
LLGLTFMaterial* gltf_mat = tep->getGLTFMaterial();
|
||||
static LLCachedControl<bool> use_mikktspace(gSavedSettings, "RenderUseMikktSpace");
|
||||
bool mikktspace = use_mikktspace && gltf_mat != nullptr;
|
||||
|
||||
mVObjp->getVolume()->genTangents(f, mikktspace);
|
||||
|
||||
LLVector4Logical mask;
|
||||
mask.clear();
|
||||
mask.setElement<3>();
|
||||
|
||||
LLVector4a* src = vf.mTangents;
|
||||
LLVector4a* end = vf.mTangents+num_vertices;
|
||||
LLVector4a* tbuff = mikktspace ? vf.mMikktSpaceTangents : vf.mTangents;
|
||||
LLVector4a* src = tbuff;
|
||||
LLVector4a* end = tbuff+num_vertices;
|
||||
|
||||
while (src < end)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue