diff options
| -rw-r--r-- | indra/cmake/LLMath.cmake | 1 | ||||
| -rw-r--r-- | indra/llmath/llvolume.cpp | 573 | ||||
| -rw-r--r-- | indra/llmath/llvolume.h | 2 | ||||
| -rw-r--r-- | indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl | 84 | ||||
| -rw-r--r-- | indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl | 78 | ||||
| -rw-r--r-- | indra/newview/llface.cpp | 6 | 
6 files changed, 199 insertions, 545 deletions
| diff --git a/indra/cmake/LLMath.cmake b/indra/cmake/LLMath.cmake index 3cbb7ad561..513ff9f81d 100644 --- a/indra/cmake/LLMath.cmake +++ b/indra/cmake/LLMath.cmake @@ -2,6 +2,7 @@  include(Variables)  include(Mikktspace) +include(MESHOPTIMIZER)  set(LLMATH_INCLUDE_DIRS      ${LIBS_OPEN_DIR}/llmath diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 539db9d0e1..fca9471f14 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -56,6 +56,8 @@  #include "mikktspace/mikktspace.h"  #include "mikktspace/mikktspace.c" // insert mikktspace implementation into llvolume object file +#include "meshoptimizer/meshoptimizer.h" +  #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 @@ -2102,7 +2104,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,251 +5380,186 @@ public:  	}  }; +// data structures for tangent generation + +struct MikktData +{ +    LLVolumeFace* face; +    std::vector<LLVector3> p; +    std::vector<LLVector3> n; +    std::vector<LLVector2> tc; +    std::vector<LLVector4> w; +    std::vector<LLVector4> t; + +    MikktData(LLVolumeFace* f) +        : face(f) +    { +        U32 count = face->mNumIndices; + +        p.resize(count); +        n.resize(count); +        tc.resize(count); +        t.resize(count); + +        if (face->mWeights) +        { +            w.resize(count); +        } + +        for (int i = 0; i < face->mNumIndices; ++i) +        { +            U32 idx = face->mIndices[i]; + +            p[i].set(face->mPositions[idx].getF32ptr()); +            n[i].set(face->mNormals[idx].getF32ptr()); +            tc[i].set(face->mTexCoords[idx]); + +            if (face->mWeights) +            { +                w[i].set(face->mWeights[idx].getF32ptr()); +            } +        } +    } +}; +  bool LLVolumeFace::cacheOptimize()  { //optimize for vertex cache according to Forsyth method:  -  // http://home.comcast.net/~tom_forsyth/papers/fast_vert_cache_opt.html -	 +    LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;  	llassert(!mOptimized);  	mOptimized = TRUE; -	LLVCacheLRU cache; -	 -	if (mNumVertices < 3 || mNumIndices < 3) -	{ //nothing to do -		return true; -	} - -	//mapping of vertices to triangles and indices -	std::vector<LLVCacheVertexData> vertex_data; - -	//mapping of triangles do vertices -	std::vector<LLVCacheTriangleData> triangle_data; +    allocateTangents(mNumVertices, true); -	try -	{ -		triangle_data.resize(mNumIndices / 3); -		vertex_data.resize(mNumVertices); +    SMikkTSpaceInterface ms; -        for (U32 i = 0; i < mNumIndices; i++) -        { //populate vertex data and triangle data arrays -            U16 idx = mIndices[i]; -            U32 tri_idx = i / 3; +    ms.m_getNumFaces = [](const SMikkTSpaceContext* pContext) +    { +        MikktData* data = (MikktData*)pContext->m_pUserData; +        LLVolumeFace* face = data->face; +        return face->mNumIndices / 3; +    }; -            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]); -        } -    } -    catch (std::bad_alloc&) +    ms.m_getNumVerticesOfFace = [](const SMikkTSpaceContext* pContext, const int iFace)      { -        // resize or push_back failed -        LL_WARNS("LLVOLUME") << "Resize for " << mNumVertices << " vertices failed" << LL_ENDL; -        return false; -    } +        return 3; +    }; -	/*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]]); -		} +    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]; +    }; -		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]; +    }; -		pre_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]; +    }; -	for (U32 i = 0; i < mNumVertices; i++) -	{ //initialize score values (no cache -- might try a fifo cache here) -		LLVCacheVertexData& data = vertex_data[i]; +    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]; -		data.mScore = find_vertex_score(data); -		data.mActiveTriangles = data.mTriangles.size(); +        LLVector3 p(face->mPositions[idx].getF32ptr()); +        LLVector3 n(face->mNormals[idx].getF32ptr()); +        LLVector3 t(fvTangent); -		for (U32 j = 0; j < data.mActiveTriangles; ++j) -		{ -			data.mTriangles[j]->mScore += data.mScore; -		} -	} +        data->t[i].set(fvTangent); +        data->t[i].mV[3] = fSign; +    }; -	//sort triangle data by score -	std::sort(triangle_data.begin(), triangle_data.end()); +    ms.m_setTSpace = nullptr; -	std::vector<U16> new_indices; +    MikktData data(this); -	LLVCacheTriangleData* tri; +    SMikkTSpaceContext ctx = { &ms, &data }; -	//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(); +    genTangSpaceDefault(&ctx); -	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(); -	} +    //re-weld +    meshopt_Stream mos[] =  +    { +        { &data.p[0], sizeof(LLVector3), sizeof(LLVector3) }, +        { &data.n[0], sizeof(LLVector3), sizeof(LLVector3) }, +        { &data.t[0], sizeof(LLVector4), sizeof(LLVector4) }, +        { &data.tc[0], sizeof(LLVector2), sizeof(LLVector2) }, +        { data.w.empty() ? nullptr : &data.w[0], sizeof(LLVector4), sizeof(LLVector4) } +    }; -	for (U32 i = 0; i < mNumIndices; ++i) -	{ -		mIndices[i] = new_indices[i]; -	} +    std::vector<U32> remap; +    remap.resize(data.p.size()); -	/*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; -		} +    U32 stream_count = data.w.empty() ? 4 : 5; -		for (U32 i = 0; i < mNumIndices; ++i) -		{ -			test_cache.addVertex(&vertex_data[mIndices[i]]); -		} -		 -		post_acmr = (F32) test_cache.mMisses/(mNumIndices/3); -	}*/ +    U32 vert_count = meshopt_generateVertexRemapMulti(&remap[0], nullptr, data.p.size(), data.p.size(), mos, stream_count); -	//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); +    std::vector<U32> indices; +    indices.resize(mNumIndices); -	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; -		} -	} +    //copy results back into volume +    resizeVertices(vert_count); -    llassert(mTangents == nullptr); // cache optimize called too late, tangents already generated -    llassert(mMikktSpaceTangents == nullptr); +    if (!data.w.empty()) +    { +        allocateWeights(vert_count); +    } -    // ===================================================================================== -    // 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; -		} -	} -    // ===================================================================================== +    allocateTangents(mNumVertices, true); -    //allocate mapping of old indices to new indices -	std::vector<S32> 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; -	} - -	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; +    for (int i = 0; i < mNumIndices; ++i) +    { +        U32 src_idx = i; +        U32 dst_idx = remap[i]; +        mIndices[i] = dst_idx; -			//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]; -			} +        mPositions[dst_idx].load3(data.p[src_idx].mV); +        mNormals[dst_idx].load3(data.n[src_idx].mV); +        mTexCoords[dst_idx] = data.tc[src_idx]; +        +        mMikktSpaceTangents[dst_idx].loadua(data.t[src_idx].mV); -			cur_idx++; -		} -	} +        if (mWeights) +        { +            mWeights[dst_idx].loadua(data.w[src_idx].mV); +        } +    } -	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 +    // cache optimize index buffer -	mPositions = pos; -	mNormals = norm; -	mTexCoords = tc; -	mWeights = wght;     -	mTangents = binorm; +    // meshopt needs scratch space, do some pointer shuffling to avoid an extra index buffer copy +    U16* src_indices = mIndices; +    mIndices = nullptr; +    resizeIndices(mNumIndices); -	//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; +    meshopt_optimizeVertexCache<U16>(mIndices, src_indices, mNumIndices, mNumVertices); +     +    ll_aligned_free_16(src_indices);  	return true;  } @@ -6407,209 +6349,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<F32> s; -    // indices (in index array) -    std::vector<S32> i; -}; - -// 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; -}; - - -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 +6376,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..5573c02a60 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,27 @@ 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 33d6a205e7..3f69815e38 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,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			{  				LLVector4a tangent_out;  				mat_normal.rotate(*src, tangent_out); -				tangent_out.normalize3fast();  				tangent_out.setSelectWithMask(mask, *src, tangent_out);  				tangent_out.store4a(tangents); | 
