summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorPtolemy <ptolemy@lindenlab.com>2022-09-09 06:36:00 -0700
committerPtolemy <ptolemy@lindenlab.com>2022-09-09 06:36:00 -0700
commit0fdef555ba5e0dc8e1e1bd8f2db0543d59bc318a (patch)
treed0d075cf0b24a181fe7dbc00ac36ffc3e2d9394e /indra
parentc94a521c6ab4f6c42c61087df78252930e7865a3 (diff)
parent8fb18e9a5d1f42fa86ca1cc2a4306edccb7065c5 (diff)
Merge branch 'DRTVWR-559' of bitbucket.org:lindenlab/viewer into DRTVWR-559
Diffstat (limited to 'indra')
-rw-r--r--indra/cmake/LLMath.cmake3
-rw-r--r--indra/cmake/Mikktspace.cmake6
-rw-r--r--indra/llcommon/llworkerthread.cpp1
-rw-r--r--indra/llmath/llvolume.cpp272
-rw-r--r--indra/llmath/llvolume.h7
-rw-r--r--indra/newview/app_settings/settings.xml11
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl3
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl31
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl28
-rw-r--r--indra/newview/lldrawpoolpbropaque.cpp2
-rw-r--r--indra/newview/llface.cpp11
-rw-r--r--indra/newview/llpanelface.cpp26
-rw-r--r--indra/newview/llpanelprofile.cpp2
-rw-r--r--indra/newview/skins/default/xui/en/panel_tools_texture.xml2
14 files changed, 319 insertions, 86 deletions
diff --git a/indra/cmake/LLMath.cmake b/indra/cmake/LLMath.cmake
index 893920ae6f..3cbb7ad561 100644
--- a/indra/cmake/LLMath.cmake
+++ b/indra/cmake/LLMath.cmake
@@ -1,5 +1,8 @@
# -*- cmake -*-
+include(Variables)
+include(Mikktspace)
+
set(LLMATH_INCLUDE_DIRS
${LIBS_OPEN_DIR}/llmath
)
diff --git a/indra/cmake/Mikktspace.cmake b/indra/cmake/Mikktspace.cmake
new file mode 100644
index 0000000000..9fd2becba4
--- /dev/null
+++ b/indra/cmake/Mikktspace.cmake
@@ -0,0 +1,6 @@
+# -*- cmake -*-
+include(Prebuilt)
+
+if (NOT USESYSTEMLIBS)
+ use_prebuilt_binary(mikktspace)
+endif (NOT USESYSTEMLIBS)
diff --git a/indra/llcommon/llworkerthread.cpp b/indra/llcommon/llworkerthread.cpp
index 02ce4823b8..bd2eb2089c 100644
--- a/indra/llcommon/llworkerthread.cpp
+++ b/indra/llcommon/llworkerthread.cpp
@@ -97,6 +97,7 @@ S32 LLWorkerThread::update(F32 max_time_ms)
{
if (worker->getFlags(LLWorkerClass::WCF_WORK_FINISHED))
{
+ worker->setFlags(LLWorkerClass::WCF_DELETE_REQUESTED);
delete_list.push_back(worker);
mDeleteList.erase(curiter);
}
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 4a069b0f63..539db9d0e1 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -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;
+ }
+ };
+
+ 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;
+ }
+ };
+}
+
+// boost adapter
+namespace std
+{
+ template<>
+ struct hash<MikktKey>
+ {
+ std::size_t operator()(MikktKey const& k) const
+ {
+ return boost::hash<MikktKey>()(k);
+ }
+ };
+}
+
+struct MikktData
+{
+ LLVolumeFace* face;
+ std::unordered_map<MikktKey, MikktTangent > tangents;
+};
- binorm = mTangents;
- CalculateTangentArray(mNumVertices, mPositions, mNormals, mTexCoords, mNumIndices/3, mIndices, mTangents);
+void LLVolumeFace::createTangents(bool mikktspace)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
- //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();
- }
- }
+ 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)
diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h
index 9697952f5b..8c604c5d1a 100644
--- a/indra/llmath/llvolume.h
+++ b/indra/llmath/llvolume.h
@@ -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);
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index cd33690075..9508c1dc2d 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -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>
diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
index 67f4c59c3f..51afda2791 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
@@ -41,6 +41,7 @@ uniform sampler2D specularMap;
VARYING vec2 vary_texcoord0;
vec3 linear_to_srgb(vec3 c);
+vec2 encode_normal (vec3 n);
void main()
{
@@ -56,5 +57,5 @@ void main()
frag_data[0] = vec4(col.rgb, 0.0);
frag_data[1] = spec;
- frag_data[2] = norm; // TODO: Should .w be set?
+ frag_data[2] = vec4(encode_normal(norm.xyz),0,GBUFFER_FLAG_HAS_ATMOS);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl
index 7a13abc7e8..69019667de 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl
@@ -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
@@ -153,6 +145,11 @@ void main()
col.rgb = vary_position.xyz;
#endif
+ 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
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl
index a2606ed771..e17d91af38 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl
@@ -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
diff --git a/indra/newview/lldrawpoolpbropaque.cpp b/indra/newview/lldrawpoolpbropaque.cpp
index 9fc3d51cad..e1614904b4 100644
--- a/indra/newview/lldrawpoolpbropaque.cpp
+++ b/indra/newview/lldrawpoolpbropaque.cpp
@@ -146,6 +146,8 @@ void LLDrawPoolPBROpaque::renderDeferred(S32 pass)
shader->uniform1f(LLShaderMgr::METALLIC_FACTOR, pparams->mGLTFMaterial->mMetallicFactor);
shader->uniform3fv(LLShaderMgr::EMISSIVE_COLOR, 1, pparams->mGLTFMaterial->mEmissiveColor.mV);
+ LLGLDisable cull_face(mat->mDoubleSided ? GL_CULL_FACE : 0);
+
if (rigged)
{
if (pparams->mAvatar.notNull() && (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash))
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 52aacb607c..f35b4b6d91 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -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)
{
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index c205efb436..ac4c76351d 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -188,7 +188,6 @@ BOOL LLPanelFace::postBuild()
LLColorSwatchCtrl* mShinyColorSwatch;
LLComboBox* mComboTexGen;
- LLComboBox* mComboMatMedia;
LLCheckBoxCtrl *mCheckFullbright;
@@ -199,10 +198,11 @@ BOOL LLPanelFace::postBuild()
setMouseOpaque(FALSE);
- LLTextureCtrl* pbr_ctrl = getChild<LLTextureCtrl>("pbr_control");
+ LLTextureCtrl* pbr_ctrl = findChild<LLTextureCtrl>("pbr_control");
if (pbr_ctrl)
{
- pbr_ctrl->setDefaultImageAssetID(LLUUID(gSavedSettings.getString("DefaultObjectTexture")));
+ pbr_ctrl->setDefaultImageAssetID(LLUUID::null);
+ pbr_ctrl->setBlankImageAssetID(LLUUID::null); // should there be some empty default material?
pbr_ctrl->setCommitCallback(boost::bind(&LLPanelFace::onCommitPbr, this, _2));
pbr_ctrl->setOnCancelCallback(boost::bind(&LLPanelFace::onCancelPbr, this, _2));
pbr_ctrl->setOnSelectCallback(boost::bind(&LLPanelFace::onSelectPbr, this, _2));
@@ -321,22 +321,22 @@ BOOL LLPanelFace::postBuild()
mComboTexGen->setFollows(FOLLOWS_LEFT | FOLLOWS_TOP);
}
- mComboMatMedia = getChild<LLComboBox>("combobox matmedia");
- if(mComboMatMedia)
+ LLComboBox* combo_mat_media = findChild<LLComboBox>("combobox matmedia");
+ if(combo_mat_media)
{
- mComboMatMedia->setCommitCallback(LLPanelFace::onCommitMaterialsMedia,this);
- mComboMatMedia->selectNthItem(MATMEDIA_MATERIAL);
+ combo_mat_media->setCommitCallback(LLPanelFace::onCommitMaterialsMedia,this);
+ combo_mat_media->selectNthItem(MATMEDIA_MATERIAL);
}
- LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
+ LLRadioGroup* radio_mat_type = findChild<LLRadioGroup>("radio_material_type");
if(radio_mat_type)
{
radio_mat_type->setCommitCallback(LLPanelFace::onCommitMaterialType, this);
radio_mat_type->selectNthItem(MATTYPE_DIFFUSE);
}
- LLRadioGroup* radio_pbr_type = getChild<LLRadioGroup>("radio_pbr_type");
- if (radio_mat_type)
+ LLRadioGroup* radio_pbr_type = findChild<LLRadioGroup>("radio_pbr_type");
+ if (radio_pbr_type)
{
radio_pbr_type->setCommitCallback(LLPanelFace::onCommitPbrType, this);
radio_pbr_type->selectNthItem(PBRTYPE_ALBEDO);
@@ -1660,7 +1660,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
clearCtrls();
// Disable non-UICtrls
- LLTextureCtrl* pbr_ctrl = getChild<LLTextureCtrl>("pbr_control");
+ LLTextureCtrl* pbr_ctrl = findChild<LLTextureCtrl>("pbr_control");
if (pbr_ctrl)
{
pbr_ctrl->setImageAssetID(LLUUID::null);
@@ -2126,7 +2126,7 @@ void LLPanelFace::onSelectPbr(const LLSD& data)
{
LLSelectMgr::getInstance()->saveSelectedObjectTextures();
- LLTextureCtrl* pbr_ctrl = getChild<LLTextureCtrl>("pbr_control");
+ LLTextureCtrl* pbr_ctrl = findChild<LLTextureCtrl>("pbr_control");
if (!pbr_ctrl) return;
if (!pbr_ctrl->getTentative())
{
@@ -3646,7 +3646,7 @@ void LLPanelFace::onTextureSelectionChanged(LLInventoryItem* itemp)
void LLPanelFace::onPbrSelectionChanged(LLInventoryItem* itemp)
{
- LLTextureCtrl* pbr_ctrl = getChild<LLTextureCtrl>("pbr_control");
+ LLTextureCtrl* pbr_ctrl = findChild<LLTextureCtrl>("pbr_control");
if (pbr_ctrl)
{
LLUUID obj_owner_id;
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index 29c9329a26..09e568e9ac 100644
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -887,8 +887,6 @@ BOOL LLPanelProfileSecondLife::postBuild()
mDiscardDescriptionChanges->setCommitCallback([this](LLUICtrl*, void*) { onDiscardDescriptionChanges(); }, nullptr);
mDescriptionEdit->setKeystrokeCallback([this](LLTextEditor* caller) { onSetDescriptionDirty(); });
- getChild<LLButton>("open_notes")->setCommitCallback([this](LLUICtrl*, void*) { onOpenNotes(); }, nullptr);
-
mCanSeeOnlineIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); });
mCantSeeOnlineIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); });
mCanSeeOnMapIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); });
diff --git a/indra/newview/skins/default/xui/en/panel_tools_texture.xml b/indra/newview/skins/default/xui/en/panel_tools_texture.xml
index 54a00da294..9bdfff41d8 100644
--- a/indra/newview/skins/default/xui/en/panel_tools_texture.xml
+++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml
@@ -252,8 +252,6 @@
width="64" />
<texture_picker
can_apply_immediately="true"
- default_image_name="Default"
- fallback_image="materials_ui_x_24.png"
follows="left|top"
height="80"
label="PBR "