From c822da9fe644e4a420caabb30a25b487ce75c099 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 9 Sep 2022 20:56:22 -0500 Subject: SL-18095 WIP -- Allow mikktspace generator to add more vertices (skip re-welding step for now). --- indra/llmath/llvolume.cpp | 551 ++++++--------------- indra/llmath/llvolume.h | 2 +- .../shaders/class1/deferred/pbropaqueF.glsl | 84 +--- .../shaders/class1/deferred/pbropaqueV.glsl | 77 +-- indra/newview/llface.cpp | 7 +- 5 files changed, 171 insertions(+), 550 deletions(-) diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 539db9d0e1..0ce1577d00 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2102,7 +2102,12 @@ void LLVolume::regen() void LLVolume::genTangents(S32 face, bool mikktspace) { - mVolumeFaces[face].createTangents(mikktspace); + // generate legacy tangents for the specified face + // if mikktspace is true, only generate tangents if mikktspace tangents are not present (handles the case for non-mesh prims) + if (!mikktspace || mVolumeFaces[face].mMikktSpaceTangents == nullptr) + { + mVolumeFaces[face].createTangents(); + } } LLVolume::~LLVolume() @@ -5373,252 +5378,155 @@ public: } }; +// data structures for tangent generation -bool LLVolumeFace::cacheOptimize() -{ //optimize for vertex cache according to Forsyth method: - // http://home.comcast.net/~tom_forsyth/papers/fast_vert_cache_opt.html - - llassert(!mOptimized); - mOptimized = TRUE; - - LLVCacheLRU cache; - - if (mNumVertices < 3 || mNumIndices < 3) - { //nothing to do - return true; - } +struct MikktData +{ + LLVolumeFace* face; + std::vector p; + std::vector n; + std::vector tc; + std::vector w; + std::vector t; + + MikktData(LLVolumeFace* f) + : face(f) + { + U32 count = face->mNumIndices; - //mapping of vertices to triangles and indices - std::vector vertex_data; + p.resize(count); + n.resize(count); + tc.resize(count); + t.resize(count); - //mapping of triangles do vertices - std::vector triangle_data; + if (face->mWeights) + { + w.resize(count); + } - try - { - triangle_data.resize(mNumIndices / 3); - vertex_data.resize(mNumVertices); + for (int i = 0; i < face->mNumIndices; ++i) + { + U32 idx = face->mIndices[i]; - for (U32 i = 0; i < mNumIndices; i++) - { //populate vertex data and triangle data arrays - U16 idx = mIndices[i]; - U32 tri_idx = i / 3; + p[i].set(face->mPositions[idx].getF32ptr()); + n[i].set(face->mNormals[idx].getF32ptr()); + tc[i].set(face->mTexCoords[idx]); - vertex_data[idx].mTriangles.push_back(&(triangle_data[tri_idx])); - vertex_data[idx].mIdx = idx; - triangle_data[tri_idx].mVertex[i % 3] = &(vertex_data[idx]); + if (face->mWeights) + { + w[i].set(face->mWeights[idx].getF32ptr()); + } } } - catch (std::bad_alloc&) - { - // resize or push_back failed - LL_WARNS("LLVOLUME") << "Resize for " << mNumVertices << " vertices failed" << LL_ENDL; - return false; - } - - /*F32 pre_acmr = 1.f; - //measure cache misses from before rebuild - { - LLVCacheFIFO test_cache; - for (U32 i = 0; i < mNumIndices; ++i) - { - test_cache.addVertex(&vertex_data[mIndices[i]]); - } - - for (U32 i = 0; i < mNumVertices; i++) - { - vertex_data[i].mCacheTag = -1; - } - - pre_acmr = (F32) test_cache.mMisses/(mNumIndices/3); - }*/ - - for (U32 i = 0; i < mNumVertices; i++) - { //initialize score values (no cache -- might try a fifo cache here) - LLVCacheVertexData& data = vertex_data[i]; - - data.mScore = find_vertex_score(data); - data.mActiveTriangles = data.mTriangles.size(); +}; - for (U32 j = 0; j < data.mActiveTriangles; ++j) - { - data.mTriangles[j]->mScore += data.mScore; - } - } - //sort triangle data by score - std::sort(triangle_data.begin(), triangle_data.end()); +bool LLVolumeFace::cacheOptimize() +{ //optimize for vertex cache according to Forsyth method: + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; + llassert(!mOptimized); + mOptimized = TRUE; - std::vector new_indices; + allocateTangents(mNumVertices, true); - LLVCacheTriangleData* tri; + SMikkTSpaceInterface ms; - //prime pump by adding first triangle to cache; - tri = &(triangle_data[0]); - cache.addTriangle(tri); - new_indices.push_back(tri->mVertex[0]->mIdx); - new_indices.push_back(tri->mVertex[1]->mIdx); - new_indices.push_back(tri->mVertex[2]->mIdx); - tri->complete(); + ms.m_getNumFaces = [](const SMikkTSpaceContext* pContext) + { + MikktData* data = (MikktData*)pContext->m_pUserData; + LLVolumeFace* face = data->face; + return face->mNumIndices / 3; + }; - U32 breaks = 0; - for (U32 i = 1; i < mNumIndices/3; ++i) - { - cache.updateScores(); - tri = cache.mBestTriangle; - if (!tri) - { - breaks++; - for (U32 j = 0; j < triangle_data.size(); ++j) - { - if (triangle_data[j].mActive) - { - tri = &(triangle_data[j]); - break; - } - } - } - - cache.addTriangle(tri); - new_indices.push_back(tri->mVertex[0]->mIdx); - new_indices.push_back(tri->mVertex[1]->mIdx); - new_indices.push_back(tri->mVertex[2]->mIdx); - tri->complete(); - } + ms.m_getNumVerticesOfFace = [](const SMikkTSpaceContext* pContext, const int iFace) + { + return 3; + }; - for (U32 i = 0; i < mNumIndices; ++i) - { - mIndices[i] = new_indices[i]; - } + 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]; + }; - /*F32 post_acmr = 1.f; - //measure cache misses from after rebuild - { - LLVCacheFIFO test_cache; - for (U32 i = 0; i < mNumVertices; i++) - { - vertex_data[i].mCacheTag = -1; - } + 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]; + }; - for (U32 i = 0; i < mNumIndices; ++i) - { - test_cache.addVertex(&vertex_data[mIndices[i]]); - } - - post_acmr = (F32) test_cache.mMisses/(mNumIndices/3); - }*/ + 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]; + }; - //optimize for pre-TnL cache - - //allocate space for new buffer - S32 num_verts = mNumVertices; - S32 size = ((num_verts*sizeof(LLVector2)) + 0xF) & ~0xF; - LLVector4a* pos = (LLVector4a*) ll_aligned_malloc<64>(sizeof(LLVector4a)*2*num_verts+size); - if (pos == NULL) - { - LL_WARNS("LLVOLUME") << "Allocation of positions vector[" << sizeof(LLVector4a) * 2 * num_verts + size << "] failed. " << LL_ENDL; - return false; - } - LLVector4a* norm = pos + num_verts; - LLVector2* tc = (LLVector2*) (norm + num_verts); + 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]; - LLVector4a* wght = NULL; - if (mWeights) - { - wght = (LLVector4a*)ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); - if (wght == NULL) - { - ll_aligned_free<64>(pos); - LL_WARNS("LLVOLUME") << "Allocation of weights[" << sizeof(LLVector4a) * num_verts << "] failed" << LL_ENDL; - return false; - } - } + LLVector3 p(face->mPositions[idx].getF32ptr()); + LLVector3 n(face->mNormals[idx].getF32ptr()); + LLVector3 t(fvTangent); - llassert(mTangents == nullptr); // cache optimize called too late, tangents already generated - llassert(mMikktSpaceTangents == nullptr); + data->t[i].set(fvTangent); + data->t[i].mV[3] = fSign; + }; - // ===================================================================================== - // DEPRECATED -- cacheOptimize should always be called before tangents are generated - // ===================================================================================== - LLVector4a* binorm = NULL; - if (mTangents) - { - binorm = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); - if (binorm == NULL) - { - ll_aligned_free<64>(pos); - ll_aligned_free_16(wght); - LL_WARNS("LLVOLUME") << "Allocation of binormals[" << sizeof(LLVector4a)*num_verts << "] failed" << LL_ENDL; - return false; - } - } - // ===================================================================================== + ms.m_setTSpace = nullptr; - //allocate mapping of old indices to new indices - std::vector new_idx; - try - { - new_idx.resize(mNumVertices, -1); - } - catch (std::bad_alloc&) - { - ll_aligned_free<64>(pos); - ll_aligned_free_16(wght); - ll_aligned_free_16(binorm); - LL_WARNS("LLVOLUME") << "Resize failed: " << mNumVertices << LL_ENDL; - return false; - } + MikktData data(this); - S32 cur_idx = 0; - for (U32 i = 0; i < mNumIndices; ++i) - { - U16 idx = mIndices[i]; - if (new_idx[idx] == -1) - { //this vertex hasn't been added yet - new_idx[idx] = cur_idx; + SMikkTSpaceContext ctx = { &ms, &data }; - //copy vertex data - pos[cur_idx] = mPositions[idx]; - norm[cur_idx] = mNormals[idx]; - tc[cur_idx] = mTexCoords[idx]; - if (mWeights) - { - wght[cur_idx] = mWeights[idx]; - } - if (mTangents) - { - binorm[cur_idx] = mTangents[idx]; - } + genTangSpaceDefault(&ctx); + + resizeVertices(data.p.size()); + resizeIndices(data.p.size()); + + if (!data.w.empty()) + { + allocateWeights(data.w.size()); + } - cur_idx++; - } - } + allocateTangents(mNumVertices, true); - for (U32 i = 0; i < mNumIndices; ++i) - { - mIndices[i] = new_idx[mIndices[i]]; - } - - ll_aligned_free<64>(mPositions); - // DO NOT free mNormals and mTexCoords as they are part of mPositions buffer - ll_aligned_free_16(mWeights); - ll_aligned_free_16(mTangents); -#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS - ll_aligned_free_16(mJointIndices); - ll_aligned_free_16(mJustWeights); - mJustWeights = NULL; - mJointIndices = NULL; // filled in later as necessary by skinning code for acceleration -#endif + for (int i = 0; i < mNumIndices; ++i) + { + mIndices[i] = i; - mPositions = pos; - mNormals = norm; - mTexCoords = tc; - mWeights = wght; - mTangents = binorm; + mPositions[i].load3(data.p[i].mV); + mNormals[i].load3(data.n[i].mV); + mTexCoords[i] = data.tc[i]; + + mMikktSpaceTangents[i].loadua(data.t[i].mV); - //std::string result = llformat("ACMR pre/post: %.3f/%.3f -- %d triangles %d breaks", pre_acmr, post_acmr, mNumIndices/3, breaks); - //LL_INFOS() << result << LL_ENDL; + if (mWeights) + { + mWeights[i].loadua(data.w[i].mV); + } + } + return true; } @@ -6407,209 +6315,25 @@ 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); - -// data structures for tangent generation - -// key for summing tangents -// We will blend tangents wherever a common position and normal is found -struct MikktKey -{ - // Position - LLVector3 p; - // Normal - LLVector3 n; - - bool operator==(const MikktKey& rhs) const { return p == rhs.p && n == rhs.n; } -}; - -// 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 s; - // indices (in index array) - std::vector i; -}; - -// hash function for MikktTangent -namespace boost -{ - template <> - struct hash - { - 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 - { - 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 - { - std::size_t operator()(MikktKey const& k) const - { - return boost::hash()(k); - } - }; -} - -struct MikktData -{ - LLVolumeFace* face; - std::unordered_map tangents; -}; - - -void LLVolumeFace::createTangents(bool mikktspace) +void LLVolumeFace::createTangents() { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; - auto& tangents = mikktspace ? mMikktSpaceTangents : mTangents; - - if (!tangents) + + if (!mTangents) { - allocateTangents(mNumVertices, mikktspace); + allocateTangents(mNumVertices); + + //generate tangents + LLVector4a* ptr = (LLVector4a*)mTangents; - if (mikktspace) + LLVector4a* end = mTangents + mNumVertices; + while (ptr < end) { - 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; - } + (*ptr++).clear(); } - 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); - } + CalculateTangentArray(mNumVertices, mPositions, mNormals, mTexCoords, mNumIndices / 3, mIndices, mTangents); //normalize normals for (U32 i = 0; i < mNumVertices; i++) @@ -6618,6 +6342,7 @@ void LLVolumeFace::createTangents(bool mikktspace) mNormals[i].normalize3fast(); } } + } void LLVolumeFace::resizeVertices(S32 num_verts) diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 8c604c5d1a..f1feaade58 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -870,7 +870,7 @@ private: public: BOOL create(LLVolume* volume, BOOL partial_build = FALSE); - void createTangents(bool mikktspace = false); + void createTangents(); void resizeVertices(S32 num_verts); void allocateTangents(S32 num_verts, bool mikktspace = false); diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl index 69019667de..ca304f749a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl @@ -25,61 +25,34 @@ /*[EXTRA_CODE_HERE]*/ -#define DEBUG_PBR_LIGHT_TYPE 0 // Output Diffuse=0.75, Emissive=0, ORM=0,0,0 - -#define DEBUG_BASIC 0 -#define DEBUG_VERTEX 0 -#define DEBUG_NORMAL_MAP 0 // Output packed normal map "as is" to diffuse -#define DEBUG_NORMAL_OUT 0 // Output unpacked normal to diffuse -#define DEBUG_ORM 0 // Output Occlusion Roughness Metal "as is" to diffuse -#define DEBUG_POSITION 0 - uniform sampler2D diffuseMap; //always in sRGB space uniform float metallicFactor; uniform float roughnessFactor; uniform vec3 emissiveColor; +uniform sampler2D bumpMap; +uniform sampler2D emissiveMap; +uniform sampler2D specularMap; // Packed: Occlusion, Metal, Roughness -#ifdef HAS_NORMAL_MAP - uniform sampler2D bumpMap; - VARYING vec3 vary_tangent; - flat in float vary_sign; -#endif - -#ifdef HAS_EMISSIVE_MAP - uniform sampler2D emissiveMap; -#endif - -#ifdef HAS_SPECULAR_MAP - uniform sampler2D specularMap; // Packed: Occlusion, Metal, Roughness -#endif - -uniform samplerCube environmentMap; -uniform mat3 env_mat; - -#ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_data[4]; -#else -#define frag_data gl_FragData -#endif VARYING vec3 vary_position; VARYING vec4 vertex_color; -VARYING vec2 vary_texcoord0; -#ifdef HAS_NORMAL_MAP VARYING vec3 vary_normal; -VARYING vec2 vary_texcoord1; -#endif +VARYING vec3 vary_tangent; +flat in float vary_sign; -#ifdef HAS_SPECULAR_MAP - VARYING vec2 vary_texcoord2; -#endif +VARYING vec2 vary_texcoord0; +VARYING vec2 vary_texcoord1; +VARYING vec2 vary_texcoord2; uniform float minimum_alpha; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff() vec2 encode_normal(vec3 n); vec3 linear_to_srgb(vec3 c); +uniform mat3 normal_matrix; + void main() { // IF .mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; @@ -94,11 +67,11 @@ void main() vec3 col = vertex_color.rgb * albedo.rgb; // from mikktspace.com - vec4 vNt = texture2D(bumpMap, vary_texcoord1.xy)*2.0-1.0; + vec3 vNt = texture2D(bumpMap, vary_texcoord1.xy).xyz*2.0-1.0; float sign = vary_sign; vec3 vN = vary_normal; vec3 vT = vary_tangent.xyz; - + vec3 vB = sign * cross(vN, vT); vec3 tnorm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN ); @@ -107,49 +80,20 @@ void main() // occlusion 1.0 // roughness 0.0 // metal 0.0 -#ifdef HAS_SPECULAR_MAP vec3 spec = texture2D(specularMap, vary_texcoord2.xy).rgb; -#else - vec3 spec = vec3(1,0,0); -#endif spec.g *= roughnessFactor; spec.b *= metallicFactor; vec3 emissive = emissiveColor; -#ifdef HAS_EMISSIVE_MAP emissive *= texture2D(emissiveMap, vary_texcoord0.xy).rgb; -#endif - -#if DEBUG_PBR_LIGHT_TYPE - col.rgb = vec3(0.75); - emissive = vec3(0); - spec.rgb = vec3(0); -#endif -#if DEBUG_BASIC - col.rgb = vec3( 1, 0, 1 ); -#endif -#if DEBUG_VERTEX - col.rgb = vertex_color.rgb; -#endif -#if DEBUG_NORMAL_MAP - col.rgb = texture2D(bumpMap, vary_texcoord1.xy).rgb; -#endif -#if DEBUG_NORMAL_OUT - col.rgb = vary_normal; -#endif -#if DEBUG_ORM - col.rgb = linear_to_srgb(spec); -#endif -#if DEBUG_POSITION - col.rgb = vary_position.xyz; -#endif tnorm *= gl_FrontFacing ? 1.0 : -1.0; + //spec.rgb = vec3(1,1,0); //col = vec3(0,0,0); //emissive = vary_tangent.xyz*0.5+0.5; - //emissive = vec3(vary_sign*0.5+0.5); + //emissive = vec3(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 e17d91af38..c90a17993f 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl @@ -37,41 +37,24 @@ uniform mat3 normal_matrix; uniform mat4 modelview_projection_matrix; #endif -#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) - -#if !defined(HAS_SKIN) -uniform mat4 modelview_matrix; -#endif - -VARYING vec3 vary_position; - -#endif - uniform mat4 texture_matrix0; ATTRIBUTE vec3 position; ATTRIBUTE vec4 diffuse_color; ATTRIBUTE vec3 normal; -ATTRIBUTE vec2 texcoord0; - - -#ifdef HAS_NORMAL_MAP ATTRIBUTE vec4 tangent; +ATTRIBUTE vec2 texcoord0; ATTRIBUTE vec2 texcoord1; +ATTRIBUTE vec2 texcoord2; +VARYING vec2 vary_texcoord0; VARYING vec2 vary_texcoord1; -#endif - -#ifdef HAS_SPECULAR_MAP -ATTRIBUTE vec2 texcoord2; VARYING vec2 vary_texcoord2; -#endif VARYING vec4 vertex_color; -VARYING vec2 vary_texcoord0; + VARYING vec3 vary_tangent; flat out float vary_sign; - VARYING vec3 vary_normal; void main() @@ -83,64 +66,28 @@ void main() vec3 pos = (mat*vec4(position.xyz,1.0)).xyz; -#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) - vary_position = pos; -#endif - gl_Position = projection_matrix*vec4(pos,1.0); #else //transform vertex gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); - #endif vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; - -#ifdef HAS_NORMAL_MAP vary_texcoord1 = (texture_matrix0 * vec4(texcoord1,0,1)).xy; -#endif - -#ifdef HAS_SPECULAR_MAP vary_texcoord2 = (texture_matrix0 * vec4(texcoord2,0,1)).xy; -#endif #ifdef HAS_SKIN - vec3 n = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz); -#ifdef HAS_NORMAL_MAP - 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); -#else //HAS_NORMAL_MAP -vary_normal = n; -#endif //HAS_NORMAL_MAP + vec3 n = (mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz; + vec3 t = (mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz; #else //HAS_SKIN - vec3 n = normalize(normal_matrix * normal); -#ifdef HAS_NORMAL_MAP - vec3 t = normalize(normal_matrix * tangent.xyz); - vary_tangent = t; - vary_sign = tangent.w; - vary_normal = n; + vec3 n = normal_matrix * normal; + vec3 t = normal_matrix * tangent.xyz; +#endif - //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); -#else //HAS_NORMAL_MAP - vary_normal = n; -#endif //HAS_NORMAL_MAP -#endif //HAS_SKIN + vary_tangent = normalize(t); + vary_sign = tangent.w; + vary_normal = normalize(n); vertex_color = diffuse_color; - -#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) -#if !defined(HAS_SKIN) - vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz; -#endif -#endif } diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index f35b4b6d91..83d35b7f3c 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -2177,6 +2177,11 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, mask.setElement<3>(); LLVector4a* tbuff = mikktspace ? vf.mMikktSpaceTangents : vf.mTangents; + if (tbuff == nullptr) + { // non-mesh prims will not have mikktspace tangents + tbuff = vf.mTangents; + } + LLVector4a* src = tbuff; LLVector4a* end = tbuff+num_vertices; @@ -2184,7 +2189,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, { LLVector4a tangent_out; mat_normal.rotate(*src, tangent_out); - tangent_out.normalize3fast(); + tangent_out.normalize3(); tangent_out.setSelectWithMask(mask, *src, tangent_out); tangent_out.store4a(tangents); -- cgit v1.2.3