summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NORSPEC-207.patch164
-rwxr-xr-xautobuild.xml1
-rwxr-xr-xindra/llcommon/llapr.cpp2
-rwxr-xr-xindra/llmath/llvector4a.inl20
-rwxr-xr-xindra/llmath/llvolume.cpp216
-rwxr-xr-xindra/llprimitive/lltextureentry.cpp2
-rwxr-xr-xindra/llrender/llgl.cpp5
-rwxr-xr-xindra/llrender/llglslshader.cpp5
-rwxr-xr-xindra/llrender/llrender.cpp43
-rwxr-xr-xindra/llrender/llrendertarget.cpp10
-rwxr-xr-xindra/llrender/llrendertarget.h2
-rwxr-xr-xindra/llrender/llshadermgr.cpp6
-rwxr-xr-xindra/llrender/llshadermgr.h6
-rwxr-xr-xindra/llrender/llvertexbuffer.cpp69
-rwxr-xr-xindra/newview/app_settings/settings.xml34
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/alphaF.glsl440
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/alphaV.glsl87
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl17
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl2
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl134
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl9
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/impostorF.glsl47
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/materialF.glsl162
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/materialV.glsl1
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl110
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl57
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl17
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl25
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl116
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl54
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/srgb.glsl46
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/srgb_mac.glsl54
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl17
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl157
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/waterF.glsl65
-rwxr-xr-xindra/newview/app_settings/shaders/class1/deferred/waterV.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/downsampleDepthF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/downsampleDepthRectF.glsl2
-rwxr-xr-xindra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl4
-rwxr-xr-xindra/newview/app_settings/shaders/class2/deferred/alphaV.glsl224
-rwxr-xr-xindra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl51
-rwxr-xr-xindra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl104
-rwxr-xr-xindra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl59
-rwxr-xr-xindra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl17
-rwxr-xr-xindra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl17
-rwxr-xr-xindra/newview/featuretable_mac.txt4
-rwxr-xr-xindra/newview/lldrawable.cpp2
-rwxr-xr-xindra/newview/lldrawpoolalpha.cpp77
-rwxr-xr-xindra/newview/lldrawpoolavatar.cpp124
-rw-r--r--indra/newview/lldrawpoolmaterials.cpp7
-rwxr-xr-xindra/newview/lldrawpoolsimple.cpp84
-rwxr-xr-xindra/newview/lldrawpoolsky.cpp1
-rwxr-xr-xindra/newview/lldrawpoolwater.cpp15
-rwxr-xr-xindra/newview/lldrawpoolwlsky.cpp1
-rwxr-xr-xindra/newview/llface.cpp106
-rwxr-xr-xindra/newview/llfloatertools.cpp4
-rwxr-xr-xindra/newview/llfloatertools.h2
-rw-r--r--indra/newview/llmaterialmgr.cpp87
-rwxr-xr-xindra/newview/llpanelface.cpp37
-rwxr-xr-xindra/newview/llpanelface.h46
-rwxr-xr-xindra/newview/llpanelvolume.cpp12
-rwxr-xr-xindra/newview/llselectmgr.cpp6
-rwxr-xr-xindra/newview/lltexturectrl.cpp13
-rwxr-xr-xindra/newview/lltooldraganddrop.cpp47
-rwxr-xr-xindra/newview/llviewerdisplay.cpp9
-rwxr-xr-xindra/newview/llviewerobject.cpp28
-rwxr-xr-xindra/newview/llviewerobject.h2
-rwxr-xr-xindra/newview/llviewerregion.cpp46
-rwxr-xr-xindra/newview/llviewerregion.h11
-rwxr-xr-xindra/newview/llviewershadermgr.cpp328
-rwxr-xr-xindra/newview/llviewershadermgr.h15
-rwxr-xr-xindra/newview/llvovolume.cpp56
-rwxr-xr-xindra/newview/pipeline.cpp744
-rw-r--r--indra/newview/skins/default/xui/en/panel_tools_texture.xml8
74 files changed, 3355 insertions, 1251 deletions
diff --git a/NORSPEC-207.patch b/NORSPEC-207.patch
deleted file mode 100644
index a1c1447bda..0000000000
--- a/NORSPEC-207.patch
+++ /dev/null
@@ -1,164 +0,0 @@
-diff -r fe4bab01522e indra/llprimitive/llrendermaterialtable.cpp
---- a/indra/llprimitive/llrendermaterialtable.cpp Wed May 15 17:57:21 2013 +0000
-+++ b/indra/llprimitive/llrendermaterialtable.cpp Wed May 22 14:23:04 2013 -0700
-@@ -184,6 +184,44 @@
- }
- }
-
-+// 'v' is an integer value for 100ths of radians (don't ask...)
-+//
-+void LLRenderMaterialEntry::LLRenderMaterial::setSpecularMapRotation(S32 v) const
-+{
-+ // Store the fact that we're using the new rotation rep
-+ //
-+ m_flags |= kNewSpecularMapRotation;
-+
-+ // Store 'sign bit' in our m_flags
-+ //
-+ m_flags &= ~kSpecularMapRotationNegative;
-+ m_flags |= (specularMapRotation < 0) ? kSpecularMapRotationNegative : 0;
-+
-+ specularRotation = abs(specularRotation);
-+ specularRotation = llmin(specularRotation, MAX_MATERIAL_MAP_ROTATION);
-+
-+ m_specularRotation = (U16)(abs(specularMapRotation));
-+}
-+
-+// 'v' is an integer value for 100ths of radians (don't ask...)
-+//
-+void LLRenderMaterialEntry::LLRenderMaterial::setNormalMapRotation(S32 v) const
-+{
-+
-+ // Store the fact that we're using the new rep for this material
-+ //
-+ m_flags |= kNewNormalMapRotation;
-+
-+ // Store 'sign bit' in our m_flags
-+ //
-+ m_flags &= ~kNormalMapRotationNegative;
-+ m_flags |= (normalMapRotation < 0) ? kNormalMapRotationNegative : 0;
-+
-+ normalRotation = abs(normalRotation);
-+ normalRotation = llmin(normalRotation, MAX_MATERIAL_MAP_ROTATION);
-+
-+ m_normalRotation = (U16)(abs(normalMapRotation));
-+}
-
- void LLRenderMaterialEntry::LLRenderMaterial::asLLSD( LLSD& dest ) const
- {
-@@ -193,20 +231,45 @@
- dest["NormOffsetY"] = (S32)m_normalOffsetY;
- dest["NormRepeatX"] = m_normalRepeatX;
- dest["NormRepeatY"] = m_normalRepeatY;
-- dest["NormRotation"] = (S32)m_normalRotation;
-+
-+ S32 value = (S32)m_normalMapRotation;
-+
-+ // If we don't have the flag for new rotations set,
-+ // then we need to convert it now
-+ if (!(m_flags & kNewNormalMapRotation))
-+ {
-+ F32 old_radians = ((F32)m_normalMapRotation / 10000.0f)
-+ S32 new_val = (S32)(old_radians * 100.0f);
-+ setNormalMapRotation(new_Val);
-+ }
-+
-+ dest["NormRotation"] = (m_flags & kNormalMapRotationNegative) ? -(S32)m_normalRotation : (S32)m_normalRotation;
-
- dest["SpecOffsetX"] = (S32)m_specularOffsetX;
- dest["SpecOffsetY"] = (S32)m_specularOffsetY;
- dest["SpecRepeatX"] = m_specularRepeatX;
- dest["SpecRepeatY"] = m_specularRepeatY;
-- dest["SpecRotation"] = (S32)m_specularRotation;
-+
-+
-+ value = (S32)m_specularRotation;
-+
-+ // If we don't have the flag for new rotations set,
-+ // then we need to convert it now
-+ if (!(m_flags & kNewSpecularMapRotation))
-+ {
-+ F32 old_radians = ((F32)m_specularMapRotation / 10000.0f)
-+ S32 new_val = (S32)(old_radians * 100.0f);
-+ setSpecularMapRotation(new_Val);
-+ }
-+
-+ dest["SpecRotation"] = (m_flags & kSpecularMapRotationNegative) ? -(S32)m_specularRotation : (S32)m_specularRotation;
-
- dest["SpecMap"] = m_specularMap;
- dest["SpecColor"] = m_specularLightColor.getValue();
- dest["SpecExp"] = (S32)m_specularLightExponent;
- dest["EnvIntensity"] = (S32)m_environmentIntensity;
- dest["AlphaMaskCutoff"] = (S32)m_alphaMaskCutoff;
-- dest["DiffuseAlphaMode"] = (S32)m_diffuseAlphaMode;
-+ dest["DiffuseAlphaMode"] = (S32)(m_diffuseAlphaMode & 0xF);
-
- }
-
-@@ -217,7 +280,10 @@
- m_normalOffsetY = (U16)materialDefinition["NormOffsetY"].asInteger();
- m_normalRepeatX = materialDefinition["NormRepeatX"].asInteger();
- m_normalRepeatY = materialDefinition["NormRepeatY"].asInteger();
-- m_normalRotation = (U16)materialDefinition["NormRotation"].asInteger();
-+
-+ S32 normalRotation = materialDefinition["NormRotation"].asInteger();
-+
-+ setNormalMapRotation(normalRotation);
-
- m_specularMap = materialDefinition["SpecMap"].asUUID();
-
-@@ -225,7 +291,10 @@
- m_specularOffsetY = (U16)materialDefinition["SpecOffsetY"].asInteger();
- m_specularRepeatX = materialDefinition["SpecRepeatX"].asInteger();
- m_specularRepeatY = materialDefinition["SpecRepeatY"].asInteger();
-- m_specularRotation = (U16)materialDefinition["SpecRotation"].asInteger();
-+
-+ S32 specularRotation = materialDefinition["SpecRotation"].asInteger();
-+
-+ setSpecularMapRotation(specularRotation);
-
- m_specularLightColor.setValue( materialDefinition["SpecColor"] );
- m_specularLightExponent = (U8)materialDefinition["SpecExp"].asInteger();
-diff -r fe4bab01522e indra/llprimitive/llrendermaterialtable.h
---- a/indra/llprimitive/llrendermaterialtable.h Wed May 15 17:57:21 2013 +0000
-+++ b/indra/llprimitive/llrendermaterialtable.h Wed May 22 14:23:04 2013 -0700
-@@ -89,11 +89,17 @@
-
- void computeID();
-
-+
- struct LLRenderMaterial
- {
- void asLLSD( LLSD& dest ) const;
- void setFromLLSD( const LLSD& materialDefinition );
-
-+ void setNormalMapRotation(S32 v);
-+ void setSpecularMapRotation(S32 v);
-+
-+ const S32 MAX_MATERIAL_MAP_ROTATION = 62800;
-+
- // 36 bytes
- LLUUID m_normalMap;
- LLUUID m_specularMap;
-@@ -119,7 +125,20 @@
- U8 m_specularLightExponent;
- U8 m_environmentIntensity;
- U8 m_alphaMaskCutoff;
-- U8 m_diffuseAlphaMode;
-+ U8 m_diffuseAlphaMode : 4;
-+ U8 m_flags : 4;
-+ };
-+
-+ // Flags stored in LLRenderMaterial::m_flags to differentiate 'old' rotation format
-+ // which doesn't handle negative or large rotations correctly from new format.
-+ // All ancient materials will have these flags unset as the values for diffuseAlphaMode
-+ // from which the bits were stolen never used more than the bottom 2 bits.
-+ //
-+ enum RenderMaterialFlags {
-+ kNewNormalMapRotation = 0x1,
-+ kNewSpecularMapRotation = 0x2,
-+ kNormalMapRotationNegative = 0x4,
-+ kSpecularMapRotationNegative = 0x8
- };
-
- friend struct eastl::hash<LLRenderMaterial>;
diff --git a/autobuild.xml b/autobuild.xml
index e047d4d686..b1478a46b2 100755
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -2638,7 +2638,6 @@
<array>
<string>/build</string>
<string>"/cfg=Release|Win32"</string>
- <string>"/CL_ADD=/m:1"</string>
</array>
</map>
<key>configure</key>
diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp
index a0802c6adf..b7815b0e35 100755
--- a/indra/llcommon/llapr.cpp
+++ b/indra/llcommon/llapr.cpp
@@ -226,7 +226,7 @@ void LLVolatileAPRPool::clearVolatileAPRPool()
llassert_always(mNumActiveRef > 0) ;
}
- llassert(mNumTotalRef < (FULL_VOLATILE_APR_POOL << 2)) ;
+ llassert(mNumTotalRef <= (FULL_VOLATILE_APR_POOL << 2)) ;
}
BOOL LLVolatileAPRPool::isFull()
diff --git a/indra/llmath/llvector4a.inl b/indra/llmath/llvector4a.inl
index 7c52ffef21..558fe09323 100755
--- a/indra/llmath/llvector4a.inl
+++ b/indra/llmath/llvector4a.inl
@@ -409,6 +409,26 @@ inline void LLVector4a::normalize3fast()
mQ = _mm_mul_ps( mQ, approxRsqrt );
}
+inline void LLVector4a::normalize3fast_checked(LLVector4a* d)
+{
+ if (!isFinite3())
+ {
+ *this = d ? *d : LLVector4a(0,1,0,1);
+ return;
+ }
+
+ LLVector4a lenSqrd; lenSqrd.setAllDot3( *this, *this );
+
+ if (lenSqrd.getF32ptr()[0] <= FLT_EPSILON)
+ {
+ *this = d ? *d : LLVector4a(0,1,0,1);
+ return;
+ }
+
+ const LLQuad approxRsqrt = _mm_rsqrt_ps(lenSqrd.mQ);
+ mQ = _mm_mul_ps( mQ, approxRsqrt );
+}
+
// Return true if this vector is normalized with respect to x,y,z up to tolerance
inline LLBool32 LLVector4a::isNormalized3( F32 tolerance ) const
{
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 14cebfe5aa..ad0ca618a0 100755
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -5936,7 +5936,7 @@ void LLVolumeFace::cacheOptimize()
}
if (mTangents)
{
- binorm[cur_idx] = mTangents[idx];
+ tangent[cur_idx] = mTangents[idx];
}
cur_idx++;
@@ -5958,7 +5958,7 @@ void LLVolumeFace::cacheOptimize()
mNormals = norm;
mTexCoords = tc;
mWeights = wght;
- mTangents = binorm;
+ mTangents = tangent;
//std::string result = llformat("ACMR pre/post: %.3f/%.3f -- %d triangles %d breaks", pre_acmr, post_acmr, mNumIndices/3, breaks);
//llinfos << result << llendl;
@@ -6306,6 +6306,43 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
cuv = (min_uv + max_uv)*0.5f;
+
+ LLVector4a tangent;
+ calc_tangent_from_triangle(
+ *norm,
+ tangent,
+ *mCenter, cuv,
+ pos[0], tc[0],
+ pos[1], tc[1]);
+
+ if (tangent.getLength3() < 0.01)
+ {
+ tangent.set(1,0,0,1);
+ }
+ else
+ {
+ LLVector4a default_tangent;
+ default_tangent.set(1,0,0,1);
+ tangent.normalize3fast_checked(&default_tangent);
+ }
+
+ LLVector4a normal;
+ LLVector4a d0, d1;
+
+ d0.setSub(*mCenter, pos[0]);
+ d1.setSub(*mCenter, pos[1]);
+
+ if (mTypeMask & TOP_MASK)
+ {
+ normal.setCross3(d0, d1);
+ }
+ else
+ {
+ normal.setCross3(d1, d0);
+ }
+
+ normal.normalize3fast_checked();
+
VertexData vd;
vd.setPosition(*mCenter);
vd.mTexCoord = cuv;
@@ -6318,6 +6355,14 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
num_vertices++;
}
+ allocateTangents(num_vertices);
+
+ for (S32 i = 0; i < num_vertices; i++)
+ {
+ mTangents[i].load4a(tangent.getF32ptr());
+ norm[i].load4a(normal.getF32ptr());
+ }
+
if (partial_build)
{
return TRUE;
@@ -6553,36 +6598,6 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
}
- LLVector4a d0,d1;
-
- d0.setSub(mPositions[mIndices[1]], mPositions[mIndices[0]]);
- d1.setSub(mPositions[mIndices[2]], mPositions[mIndices[0]]);
-
- LLVector4a normal;
- normal.setCross3(d0,d1);
-
- if (normal.dot3(normal).getF32() > F_APPROXIMATELY_ZERO)
- {
- normal.normalize3fast();
- }
- else
- { //degenerate, make up a value
- normal.set(0,0,1);
- }
-
- llassert(llfinite(normal.getF32ptr()[0]));
- llassert(llfinite(normal.getF32ptr()[1]));
- llassert(llfinite(normal.getF32ptr()[2]));
-
- llassert(!llisnan(normal.getF32ptr()[0]));
- llassert(!llisnan(normal.getF32ptr()[1]));
- llassert(!llisnan(normal.getF32ptr()[2]));
-
- for (S32 i = 0; i < num_vertices; i++)
- {
- norm[i].load4a(normal.getF32ptr());
- }
-
return TRUE;
}
@@ -6611,11 +6626,13 @@ void LLVolumeFace::createTangents()
CalculateTangentArray(mNumVertices, mPositions, mNormals, mTexCoords, mNumIndices/3, mIndices, mTangents);
//normalize tangents
+ LLVector4a default_norm;
+ default_norm.set(0,1,0,1);
for (U32 i = 0; i < mNumVertices; i++)
{
- //binorm[i].normalize3fast();
+ //tangent[i].normalize3fast();
//bump map/planar projection code requires normals to be normalized
- mNormals[i].normalize3fast();
+ mNormals[i].normalize3fast_checked();
}
}
}
@@ -6800,7 +6817,7 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat
//transform appended face normal and store
norm_mat.rotate(src_norm[i], dst_norm[i]);
- dst_norm[i].normalize3fast();
+ dst_norm[i].normalize3fast_checked();
//copy appended face texture coordinate
dst_tc[i] = src_tc[i];
@@ -7209,11 +7226,138 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
return TRUE;
}
+// Finds binormal based on three vertices with texture coordinates.
+// Fills in dummy values if the triangle has degenerate texture coordinates.
+void calc_binormal_from_triangle(LLVector4a& binormal,
+
+ const LLVector4a& pos0,
+ const LLVector2& tex0,
+ const LLVector4a& pos1,
+ const LLVector2& tex1,
+ const LLVector4a& pos2,
+ const LLVector2& tex2)
+{
+ LLVector4a rx0( pos0[VX], tex0.mV[VX], tex0.mV[VY] );
+ LLVector4a rx1( pos1[VX], tex1.mV[VX], tex1.mV[VY] );
+ LLVector4a rx2( pos2[VX], tex2.mV[VX], tex2.mV[VY] );
+
+ LLVector4a ry0( pos0[VY], tex0.mV[VX], tex0.mV[VY] );
+ LLVector4a ry1( pos1[VY], tex1.mV[VX], tex1.mV[VY] );
+ LLVector4a ry2( pos2[VY], tex2.mV[VX], tex2.mV[VY] );
+
+ LLVector4a rz0( pos0[VZ], tex0.mV[VX], tex0.mV[VY] );
+ LLVector4a rz1( pos1[VZ], tex1.mV[VX], tex1.mV[VY] );
+ LLVector4a rz2( pos2[VZ], tex2.mV[VX], tex2.mV[VY] );
+
+ LLVector4a lhs, rhs;
+
+ LLVector4a r0;
+ lhs.setSub(rx0, rx1); rhs.setSub(rx0, rx2);
+ r0.setCross3(lhs, rhs);
+
+ LLVector4a r1;
+ lhs.setSub(ry0, ry1); rhs.setSub(ry0, ry2);
+ r1.setCross3(lhs, rhs);
+
+ LLVector4a r2;
+ lhs.setSub(rz0, rz1); rhs.setSub(rz0, rz2);
+ r2.setCross3(lhs, rhs);
+
+ if( r0[VX] && r1[VX] && r2[VX] )
+ {
+ binormal.set(
+ -r0[VZ] / r0[VX],
+ -r1[VZ] / r1[VX],
+ -r2[VZ] / r2[VX]);
+ // binormal.normVec();
+ }
+ else
+ {
+ binormal.set( 0, 1 , 0 );
+ }
+}
+
+// Finds binormal based on three vertices with texture coordinates.
+// Fills in dummy values if the triangle has degenerate texture coordinates.
+void calc_tangent_from_triangle(
+ LLVector4a& normal,
+ LLVector4a& tangent_out,
+ const LLVector4a& v1,
+ const LLVector2& w1,
+ const LLVector4a& v2,
+ const LLVector2& w2,
+ const LLVector4a& v3,
+ const LLVector2& w3)
+{
+ const F32* v1ptr = v1.getF32ptr();
+ const F32* v2ptr = v2.getF32ptr();
+ const F32* v3ptr = v3.getF32ptr();
+
+ float x1 = v2ptr[0] - v1ptr[0];
+ float x2 = v3ptr[0] - v1ptr[0];
+ float y1 = v2ptr[1] - v1ptr[1];
+ float y2 = v3ptr[1] - v1ptr[1];
+ float z1 = v2ptr[2] - v1ptr[2];
+ float z2 = v3ptr[2] - v1ptr[2];
+
+ float s1 = w2.mV[0] - w1.mV[0];
+ float s2 = w3.mV[0] - w1.mV[0];
+ float t1 = w2.mV[1] - w1.mV[1];
+ float t2 = w3.mV[1] - w1.mV[1];
+
+ F32 rd = s1*t2-s2*t1;
+
+ float r = ((rd*rd) > FLT_EPSILON) ? 1.0F / rd : 1024.f; //some made up large ratio for division by zero
+
+ llassert(llfinite(r));
+ llassert(!llisnan(r));
+
+ LLVector4a sdir(
+ (t2 * x1 - t1 * x2) * r,
+ (t2 * y1 - t1 * y2) * r,
+ (t2 * z1 - t1 * z2) * r);
+
+ LLVector4a tdir(
+ (s1 * x2 - s2 * x1) * r,
+ (s1 * y2 - s2 * y1) * r,
+ (s1 * z2 - s2 * z1) * r);
+
+ LLVector4a n = normal;
+ LLVector4a t = sdir;
+
+ LLVector4a ncrosst;
+ ncrosst.setCross3(n,t);
+
+ // Gram-Schmidt orthogonalize
+ n.mul(n.dot3(t).getF32());
+
+ LLVector4a tsubn;
+ tsubn.setSub(t,n);
+
+ if (tsubn.dot3(tsubn).getF32() > F_APPROXIMATELY_ZERO)
+ {
+ tsubn.normalize3fast_checked();
+
+ // Calculate handedness
+ F32 handedness = ncrosst.dot3(tdir).getF32() < 0.f ? -1.f : 1.f;
+
+ tsubn.getF32ptr()[3] = handedness;
+
+ tangent_out = tsubn;
+ }
+ else
+ {
+ // degenerate, make up a value
+ //
+ tangent_out.set(0,0,1,1);
+ }
+
+}
+
//adapted from Lengyel, Eric. “Computing Tangent Space Basis Vectors for an Arbitrary Mesh”. Terathon Software 3D Graphics Library, 2001. http://www.terathon.com/code/tangent.html
void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal,
const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent)
{
- //LLVector4a *tan1 = new LLVector4a[vertexCount * 2];
LLVector4a* tan1 = (LLVector4a*) ll_aligned_malloc_16(vertexCount*2*sizeof(LLVector4a));
LLVector4a* tan2 = tan1 + vertexCount;
diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp
index 597f078490..0db75a0e82 100755
--- a/indra/llprimitive/lltextureentry.cpp
+++ b/indra/llprimitive/lltextureentry.cpp
@@ -545,7 +545,7 @@ S32 LLTextureEntry::setMaterialID(const LLMaterialID& pMaterialID)
{
mMaterialUpdatePending = true;
mMaterialID = pMaterialID;
- return TEM_CHANGE_NONE;
+ return TEM_CHANGE_TEXTURE;
}
mMaterialUpdatePending = false;
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index c3005f1722..a157cd94c4 100755
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -647,7 +647,8 @@ bool LLGLManager::initGL()
}
#if LL_DARWIN
else if ((mGLRenderer.find("9400M") != std::string::npos)
- || (mGLRenderer.find("9600M") != std::string::npos))
+ || (mGLRenderer.find("9600M") != std::string::npos)
+ || (mGLRenderer.find("9800M") != std::string::npos))
{
mIsMobileGF = TRUE;
}
@@ -1155,7 +1156,7 @@ void LLGLManager::initExtensions()
glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, (GLint*) &mGLMaxVertexRange);
glGetIntegerv(GL_MAX_ELEMENTS_INDICES, (GLint*) &mGLMaxIndexRange);
glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*) &mGLMaxTextureSize);
-
+
#if (LL_WINDOWS || LL_LINUX || LL_SOLARIS) && !LL_MESA_HEADLESS
LL_DEBUGS("RenderInit") << "GL Probe: Getting symbols" << LL_ENDL;
if (mHasVertexBufferObject)
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index ac16e30796..40aff36dac 100755
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -374,6 +374,11 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,
// Create program
mProgramObject = glCreateProgramObjectARB();
+
+#if LL_DARWIN
+ // work-around missing mix(vec3,vec3,bvec3)
+ mDefines["OLD_SELECT"] = "1";
+#endif
//compile new source
vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin();
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index c60eb8d9d9..f2f1b62be0 100755
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -1849,35 +1849,36 @@ void LLRender::flush()
sUIVerts += mCount;
}
- if (gDebugGL)
+ //store mCount in a local variable to avoid re-entrance (drawArrays may call flush)
+ U32 count = mCount;
+
+ if (mMode == LLRender::QUADS && !sGLCoreProfile)
{
- if (mMode == LLRender::QUADS && !sGLCoreProfile)
+ if (mCount%4 != 0)
{
- if (mCount%4 != 0)
- {
- llerrs << "Incomplete quad rendered." << llendl;
- }
+ count -= (mCount % 4);
+ llwarns << "Incomplete quad requested." << llendl;
}
-
- if (mMode == LLRender::TRIANGLES)
+ }
+
+ if (mMode == LLRender::TRIANGLES)
+ {
+ if (mCount%3 != 0)
{
- if (mCount%3 != 0)
- {
- llerrs << "Incomplete triangle rendered." << llendl;
- }
+ count -= (mCount % 3);
+ llwarns << "Incomplete triangle requested." << llendl;
}
-
- if (mMode == LLRender::LINES)
+ }
+
+ if (mMode == LLRender::LINES)
+ {
+ if (mCount%2 != 0)
{
- if (mCount%2 != 0)
- {
- llerrs << "Incomplete line rendered." << llendl;
- }
+ count -= (mCount % 2);
+ llwarns << "Incomplete line requested." << llendl;
}
}
-
- //store mCount in a local variable to avoid re-entrance (drawArrays may call flush)
- U32 count = mCount;
+
mCount = 0;
if (mBuffer->useVBOs() && !mBuffer->isLocked())
diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index d53c37a847..3e054f61b2 100755
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -79,7 +79,7 @@ LLRenderTarget::~LLRenderTarget()
release();
}
-void LLRenderTarget::resize(U32 resx, U32 resy, U32 color_fmt)
+void LLRenderTarget::resize(U32 resx, U32 resy)
{
//for accounting, get the number of pixels added/subtracted
S32 pix_diff = (resx*resy)-(mResX*mResY);
@@ -87,10 +87,12 @@ void LLRenderTarget::resize(U32 resx, U32 resy, U32 color_fmt)
mResX = resx;
mResY = resy;
+ llassert(mInternalFormat.size() == mTex.size());
+
for (U32 i = 0; i < mTex.size(); ++i)
{ //resize color attachments
gGL.getTexUnit(0)->bindManual(mUsage, mTex[i]);
- LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL, false);
+ LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, mInternalFormat[i], mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL, false);
sBytesAllocated += pix_diff*4;
}
@@ -572,8 +574,10 @@ void LLRenderTarget::copyContentsToFramebuffer(LLRenderTarget& source, S32 srcX0
{
if (!source.mFBO)
{
- llerrs << "Cannot copy framebuffer contents for non FBO render targets." << llendl;
+ llwarns << "Cannot copy framebuffer contents for non FBO render targets." << llendl;
+ return;
}
+
{
GLboolean write_depth = mask & GL_DEPTH_BUFFER_BIT ? TRUE : FALSE;
diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h
index 66a9874a6b..336441661c 100755
--- a/indra/llrender/llrendertarget.h
+++ b/indra/llrender/llrendertarget.h
@@ -79,7 +79,7 @@ public:
// CAUTION: if the GL runs out of memory attempting to resize, this render target will be undefined
// DO NOT use for screen space buffers or for scratch space for an image that might be uploaded
// DO use for render targets that resize often and aren't likely to ruin someone's day if they break
- void resize(U32 resx, U32 resy, U32 color_fmt);
+ void resize(U32 resx, U32 resy);
//add color buffer attachment
//limit of 4 color attachments per render target
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index fea4ee2819..63404abeff 100755
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -1137,11 +1137,13 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("projectionMap");
mReservedUniforms.push_back("global_gamma");
- mReservedUniforms.push_back("texture_gamma");
-
+ mReservedUniforms.push_back("texture_gamma");
+
mReservedUniforms.push_back("specular_color");
mReservedUniforms.push_back("env_intensity");
+ mReservedUniforms.push_back("display_gamma");
+
llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS);
std::set<std::string> dupe_check;
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index c049e935b8..3c282bf24f 100755
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -167,11 +167,13 @@ public:
DEFERRED_PROJECTION,
GLOBAL_GAMMA,
- TEXTURE_GAMMA,
-
+ TEXTURE_GAMMA,
+
SPECULAR_COLOR,
ENVIRONMENT_INTENSITY,
+ DISPLAY_GAMMA,
+
END_RESERVED_UNIFORMS
} eGLSLReservedUniforms;
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 01541026b1..fd7b846928 100755
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -753,10 +753,10 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
U16* idx = ((U16*) getIndicesPointer())+indices_offset;
stop_glerror();
- LLGLSLShader::startProfile();
- glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT,
+ LLGLSLShader::startProfile();
+ glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT,
idx);
- LLGLSLShader::stopProfile(count, mode);
+ LLGLSLShader::stopProfile(count, mode);
stop_glerror();
@@ -2209,11 +2209,39 @@ void LLVertexBuffer::bindForFeedback(U32 channel, U32 type, U32 index, U32 count
#endif
}
+void DumpComponents(U32 mask)
+{
+ llinfos <<
+ ((mask & LLVertexBuffer::MAP_VERTEX) ? "vertex:" : " ") <<
+ ((mask & LLVertexBuffer::MAP_NORMAL) ? "norms:" : " ") <<
+ ((mask & LLVertexBuffer::MAP_TEXCOORD0) ? "TC0:" : " ") <<
+ ((mask & LLVertexBuffer::MAP_TEXCOORD1) ? "TC1:" : " ") <<
+ ((mask & LLVertexBuffer::MAP_TEXCOORD2) ? "TC2:" : " ") <<
+ ((mask & LLVertexBuffer::MAP_TEXCOORD3) ? "TC3:" : " ") <<
+ ((mask & LLVertexBuffer::MAP_COLOR) ? "color:" : " ") <<
+ ((mask & LLVertexBuffer::MAP_EMISSIVE) ? "emissive:" : " ") <<
+ ((mask & LLVertexBuffer::MAP_TANGENT) ? "tangents" : " ") << llendl;
+}
+
// Set for rendering
void LLVertexBuffer::setBuffer(U32 data_mask)
{
flush();
+ if((getTypeMask() & data_mask) != data_mask)
+ {
+ if (gDebugGL)
+ {
+ // Dump info about what was missing
+ //
+ DumpComponents(data_mask & ~getTypeMask());
+ llwarns << "Missing VB stream components. ^^" << llendl;
+ }
+ // Make sure we don't write checks we can't cash below...
+ //
+ data_mask = (data_mask & getTypeMask());
+ }
+
//set up pointers if the data mask is different ...
bool setup = (sLastMask != data_mask);
@@ -2236,10 +2264,41 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
required_mask |= required;
}
}
-
+
if ((data_mask & required_mask) != required_mask)
{
- llwarns << "Shader consumption mismatches data provision." << llendl;
+
+ U32 unsatisfied_mask = (required_mask & ~data_mask);
+ U32 i = 0;
+
+ while (i < TYPE_MAX)
+ {
+ U32 unsatisfied_flag = unsatisfied_mask & (1 << i);
+ switch (unsatisfied_flag)
+ {
+ case MAP_VERTEX: llinfos << "Missing vert pos" << llendl; break;
+ case MAP_NORMAL: llinfos << "Missing normals" << llendl; break;
+ case MAP_TEXCOORD0: llinfos << "Missing TC 0" << llendl; break;
+ case MAP_TEXCOORD1: llinfos << "Missing TC 1" << llendl; break;
+ case MAP_TEXCOORD2: llinfos << "Missing TC 2" << llendl; break;
+ case MAP_TEXCOORD3: llinfos << "Missing TC 3" << llendl; break;
+ case MAP_COLOR: llinfos << "Missing vert color" << llendl; break;
+ case MAP_EMISSIVE: llinfos << "Missing emissive" << llendl; break;
+ case MAP_TANGENT: llinfos << "Missing tangent" << llendl; break;
+ case MAP_WEIGHT: llinfos << "Missing weight" << llendl; break;
+ case MAP_WEIGHT4: llinfos << "Missing weightx4" << llendl; break;
+ case MAP_CLOTHWEIGHT: llinfos << "Missing clothweight" << llendl; break;
+ case MAP_TEXTURE_INDEX: llinfos << "Missing tex index" << llendl; break;
+ default: llinfos << "Missing who effin knows: " << unsatisfied_flag << llendl;
+ }
+ }
+
+ if (unsatisfied_mask & (1 << TYPE_INDEX))
+ {
+ llinfos << "Missing indices" << llendl;
+ }
+
+ llerrs << "Shader consumption mismatches data provision." << llendl;
}
}
}
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 72916ccf8c..445ee50ee0 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -8604,6 +8604,18 @@
</array>
</map>
+ <key>RenderSpecularPrecision</key>
+ <map>
+ <key>Comment</key>
+ <string>Force 32-bit floating point LUT</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <real>0</real>
+ </map>
+
<key>RenderSpecularResX</key>
<map>
<key>Comment</key>
@@ -8894,6 +8906,17 @@
<key>Value</key>
<real>1.0</real>
</map>
+ <key>RenderDeferredDisplayGamma</key>
+ <map>
+ <key>Comment</key>
+ <string>Gamma ramp exponent for final correction before display gamma.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>2.2</real>
+ </map>
<key>RenderGLCoreProfile</key>
<map>
<key>Comment</key>
@@ -9621,6 +9644,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>RenderWaterMaterials</key>
+ <map>
+ <key>Comment</key>
+ <string>Water planar reflections include materials rendering.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>RenderWaterMipNormal</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
index 0899caa2af..cd7a76db28 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
@@ -35,6 +35,26 @@ out vec4 frag_color;
#define frag_color gl_FragColor
#endif
+uniform float display_gamma;
+uniform vec4 gamma;
+uniform vec4 lightnorm;
+uniform vec4 sunlight_color;
+uniform vec4 ambient;
+uniform vec4 blue_horizon;
+uniform vec4 blue_density;
+uniform float haze_horizon;
+uniform float haze_density;
+uniform float cloud_shadow;
+uniform float density_multiplier;
+uniform float distance_multiplier;
+uniform float max_y;
+uniform vec4 glow;
+uniform float scene_light_strength;
+uniform mat3 env_mat;
+uniform mat3 ssao_effect_mat;
+
+uniform vec3 sun_dir;
+
#if HAS_SHADOW
uniform sampler2DShadow shadowMap0;
uniform sampler2DShadow shadowMap1;
@@ -53,14 +73,8 @@ uniform float shadow_bias;
uniform sampler2D diffuseMap;
#endif
-vec3 atmosLighting(vec3 light);
-vec3 scaleSoftClip(vec3 light);
-
-VARYING vec3 vary_ambient;
-VARYING vec3 vary_directional;
VARYING vec3 vary_fragcoord;
VARYING vec3 vary_position;
-VARYING vec3 vary_pointlight_col;
VARYING vec2 vary_texcoord0;
VARYING vec3 vary_norm;
@@ -68,12 +82,73 @@ VARYING vec3 vary_norm;
VARYING vec4 vertex_color;
#endif
+vec3 vary_PositionEye;
+vec3 vary_SunlitColor;
+vec3 vary_AmblitColor;
+vec3 vary_AdditiveColor;
+vec3 vary_AtmosAttenuation;
+
+uniform mat4 inv_proj;
+uniform vec2 screen_res;
+
uniform vec4 light_position[8];
uniform vec3 light_direction[8];
uniform vec3 light_attenuation[8];
uniform vec3 light_diffuse[8];
-uniform vec2 screen_res;
+vec3 srgb_to_linear(vec3 cs)
+{
+ vec3 low_range = cs / vec3(12.92);
+ vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
+ bvec3 lte = lessThanEqual(cs,vec3(0.04045));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lte.r ? low_range.r : high_range.r;
+ result.g = lte.g ? low_range.g : high_range.g;
+ result.b = lte.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lte);
+#endif
+
+}
+
+vec3 linear_to_srgb(vec3 cl)
+{
+ cl = clamp(cl, vec3(0), vec3(1));
+ vec3 low_range = cl * 12.92;
+ vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
+ bvec3 lt = lessThan(cl,vec3(0.0031308));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lt.r ? low_range.r : high_range.r;
+ result.g = lt.g ? low_range.g : high_range.g;
+ result.b = lt.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lt);
+#endif
+
+}
+
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
+vec3 decode_normal (vec2 enc)
+{
+ vec2 fenc = enc*4-2;
+ float f = dot(fenc,fenc);
+ float g = sqrt(1-f/4);
+ vec3 n;
+ n.xy = fenc*g;
+ n.z = 1-f/2;
+ return n;
+}
vec3 calcDirectionalLight(vec3 n, vec3 l)
{
@@ -82,7 +157,7 @@ vec3 calcDirectionalLight(vec3 n, vec3 l)
return vec3(a,a,a);
}
-vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
+vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
{
//get light vector
vec3 lv = lp.xyz-v;
@@ -90,7 +165,9 @@ vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float
//get distance
float d = length(lv);
- float da = 0.0;
+ float da = 1.0;
+
+ vec3 col = vec3(0);
if (d > 0.0 && la > 0.0 && fa > 0.0)
{
@@ -99,20 +176,25 @@ vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float
//distance attenuation
float dist = d/la;
- da = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
- da *= da;
- da *= 1.4;
-
+ float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
+ dist_atten *= dist_atten;
+ dist_atten *= 2.0;
// spotlight coefficient.
float spot = max(dot(-ln, lv), is_pointlight);
da *= spot*spot; // GL_SPOT_EXPONENT=2
//angular attenuation
- da *= max(dot(n, lv), 0.0);
+ da *= max(dot(n, lv), 0.0);
+
+ float lit = max(da * dist_atten,0.0);
+
+ col = light_col * lit * diffuse;
+
+ // no spec for alpha shader...
}
- return vec3(da,da,da);
+ return max(col, vec3(0.0,0.0,0.0));
}
#if HAS_SHADOW
@@ -135,6 +217,237 @@ float pcfShadow(sampler2DShadow shadowMap, vec4 stc)
}
#endif
+#ifdef WATER_FOG
+uniform vec4 waterPlane;
+uniform vec4 waterFogColor;
+uniform float waterFogDensity;
+uniform float waterFogKS;
+
+vec4 applyWaterFogDeferred(vec3 pos, vec4 color)
+{
+ //normalize view vector
+ vec3 view = normalize(pos);
+ float es = -(dot(view, waterPlane.xyz));
+
+ //find intersection point with water plane and eye vector
+
+ //get eye depth
+ float e0 = max(-waterPlane.w, 0.0);
+
+ vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0);
+
+ //get object depth
+ float depth = length(pos - int_v);
+
+ //get "thickness" of water
+ float l = max(depth, 0.1);
+
+ float kd = waterFogDensity;
+ float ks = waterFogKS;
+ vec4 kc = waterFogColor;
+
+ float F = 0.98;
+
+ float t1 = -kd * pow(F, ks * e0);
+ float t2 = kd + ks * es;
+ float t3 = pow(F, t2*l) - 1.0;
+
+ float L = min(t1/t2*t3, 1.0);
+
+ float D = pow(0.98, l*kd);
+
+ color.rgb = color.rgb * D + kc.rgb * L;
+ color.a = kc.a + color.a;
+
+ return color;
+}
+#endif
+
+vec3 getSunlitColor()
+{
+ return vary_SunlitColor;
+}
+vec3 getAmblitColor()
+{
+ return vary_AmblitColor;
+}
+vec3 getAdditiveColor()
+{
+ return vary_AdditiveColor;
+}
+vec3 getAtmosAttenuation()
+{
+ return vary_AtmosAttenuation;
+}
+
+void setPositionEye(vec3 v)
+{
+ vary_PositionEye = v;
+}
+
+void setSunlitColor(vec3 v)
+{
+ vary_SunlitColor = v;
+}
+
+void setAmblitColor(vec3 v)
+{
+ vary_AmblitColor = v;
+}
+
+void setAdditiveColor(vec3 v)
+{
+ vary_AdditiveColor = v;
+}
+
+void setAtmosAttenuation(vec3 v)
+{
+ vary_AtmosAttenuation = v;
+}
+
+void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
+
+ vec3 P = inPositionEye;
+ setPositionEye(P);
+
+ vec3 tmpLightnorm = lightnorm.xyz;
+
+ vec3 Pn = normalize(P);
+ float Plen = length(P);
+
+ vec4 temp1 = vec4(0);
+ vec3 temp2 = vec3(0);
+ vec4 blue_weight;
+ vec4 haze_weight;
+ vec4 sunlight = sunlight_color;
+ vec4 light_atten;
+
+ //sunlight attenuation effect (hue and brightness) due to atmosphere
+ //this is used later for sunlight modulation at various altitudes
+ light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
+ //I had thought blue_density and haze_density should have equal weighting,
+ //but attenuation due to haze_density tends to seem too strong
+
+ temp1 = blue_density + vec4(haze_density);
+ blue_weight = blue_density / temp1;
+ haze_weight = vec4(haze_density) / temp1;
+
+ //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain)
+ temp2.y = max(0.0, tmpLightnorm.y);
+ temp2.y = 1. / temp2.y;
+ sunlight *= exp( - light_atten * temp2.y);
+
+ // main atmospheric scattering line integral
+ temp2.z = Plen * density_multiplier;
+
+ // Transparency (-> temp1)
+ // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier in a variable because the ati
+ // compiler gets confused.
+ temp1 = exp(-temp1 * temp2.z * distance_multiplier);
+
+ //final atmosphere attenuation factor
+ setAtmosAttenuation(temp1.rgb);
+
+ //compute haze glow
+ //(can use temp2.x as temp because we haven't used it yet)
+ temp2.x = dot(Pn, tmpLightnorm.xyz);
+ temp2.x = 1. - temp2.x;
+ //temp2.x is 0 at the sun and increases away from sun
+ temp2.x = max(temp2.x, .03); //was glow.y
+ //set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
+ temp2.x *= glow.x;
+ //higher glow.x gives dimmer glow (because next step is 1 / "angle")
+ temp2.x = pow(temp2.x, glow.z);
+ //glow.z should be negative, so we're doing a sort of (1 / "angle") function
+
+ //add "minimum anti-solar illumination"
+ temp2.x += .25;
+
+ //increase ambient when there are more clouds
+ vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow * 0.5;
+
+ /* decrease value and saturation (that in HSV, not HSL) for occluded areas
+ * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html
+ * // The following line of code performs the equivalent of:
+ * float ambAlpha = tmpAmbient.a;
+ * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis
+ * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue);
+ * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha);
+ */
+ tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a);
+
+ //haze color
+ setAdditiveColor(
+ vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient)
+ + (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x
+ + tmpAmbient)));
+
+ //brightness of surface both sunlight and ambient
+ setSunlitColor(vec3(sunlight * .5));
+ setAmblitColor(vec3(tmpAmbient * .25));
+ setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1));
+}
+
+vec3 atmosLighting(vec3 light)
+{
+ light *= getAtmosAttenuation().r;
+ light += getAdditiveColor();
+ return (2.0 * light);
+}
+
+vec3 atmosTransport(vec3 light) {
+ light *= getAtmosAttenuation().r;
+ light += getAdditiveColor() * 2.0;
+ return light;
+}
+vec3 atmosGetDiffuseSunlightColor()
+{
+ return getSunlitColor();
+}
+
+vec3 scaleDownLight(vec3 light)
+{
+ return (light / vec3(scene_light_strength, scene_light_strength, scene_light_strength));
+}
+
+vec3 scaleUpLight(vec3 light)
+{
+ return (light * vec3(scene_light_strength, scene_light_strength, scene_light_strength));
+}
+
+vec3 atmosAmbient(vec3 light)
+{
+ return getAmblitColor() + (light * vec3(0.5f, 0.5f, 0.5f));
+}
+
+vec3 atmosAffectDirectionalLight(float lightIntensity)
+{
+ return getSunlitColor() * vec3(lightIntensity, lightIntensity, lightIntensity);
+}
+
+vec3 scaleSoftClip(vec3 light)
+{
+ //soft clip effect:
+ vec3 zeroes = vec3(0.0f, 0.0f, 0.0f);
+ vec3 ones = vec3(1.0f, 1.0f, 1.0f);
+
+ light = ones - clamp(light, zeroes, ones);
+ light = ones - pow(light, gamma.xxx);
+
+ return light;
+}
+
+vec3 fullbrightAtmosTransport(vec3 light) {
+ float brightness = dot(light.rgb, vec3(0.33333));
+
+ return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness);
+}
+
+vec3 fullbrightScaleSoftClip(vec3 light)
+{
+ //soft clip effect:
+ return light;
+}
void main()
{
@@ -143,13 +456,15 @@ void main()
vec4 pos = vec4(vary_position, 1.0);
+ float shadow = 1.0;
-#if HAS_SHADOW
- float shadow = 0.0;
+#if HAS_SHADOW
vec4 spos = pos;
if (spos.z > -shadow_clip.w)
{
+ shadow = 0.0;
+
vec4 lpos;
vec4 near_split = shadow_clip*-0.75;
@@ -215,40 +530,77 @@ void main()
#else
vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy);
#endif
- vec4 gamma_diff = diff;
- diff.rgb = pow(diff.rgb, vec3(2.2f, 2.2f, 2.2f));
+#ifdef FOR_IMPOSTOR
+ vec4 color;
+ color.rgb = diff.rgb;
#ifdef USE_VERTEX_COLOR
- float vertex_color_alpha = vertex_color.a;
+ float final_alpha = diff.a * vertex_color.a;
+ diff.rgb *= vertex_color.rgb;
#else
- float vertex_color_alpha = 1.0;
+ float final_alpha = diff.a;
#endif
-
- vec3 normal = vary_norm;
-
- vec3 l = light_position[0].xyz;
- vec3 dlight = calcDirectionalLight(normal, l);
- dlight = dlight * vary_directional.rgb * vary_pointlight_col;
-#if HAS_SHADOW
- vec4 col = vec4(vary_ambient + dlight * shadow, vertex_color_alpha);
+ // Insure we don't pollute depth with invis pixels in impostor rendering
+ //
+ if (final_alpha < 0.01)
+ {
+ discard;
+ }
+#else
+
+#ifdef USE_VERTEX_COLOR
+ float final_alpha = diff.a * vertex_color.a;
+ diff.rgb *= vertex_color.rgb;
#else
- vec4 col = vec4(vary_ambient + dlight, vertex_color_alpha);
+ float final_alpha = diff.a;
#endif
- vec4 color = gamma_diff * col;
-
- color.rgb = atmosLighting(color.rgb);
+ vec4 gamma_diff = diff;
+ diff.rgb = srgb_to_linear(diff.rgb);
+
+ vec3 norm = vary_norm;
+
+ calcAtmospherics(pos.xyz, 1.0);
+
+ vec2 abnormal = encode_normal(norm.xyz);
+ norm.xyz = decode_normal(abnormal.xy);
+
+ float da = dot(norm.xyz, sun_dir.xyz);
+
+ float final_da = da;
+ final_da = min(final_da, shadow);
+ final_da = max(final_da, 0.0f);
+ final_da = min(final_da, 1.0f);
+ final_da = pow(final_da, 1.0/1.3);
+
+ vec4 color = vec4(0,0,0,0);
+
+ color.rgb = atmosAmbient(color.rgb);
+ color.a = final_alpha;
+
+ float ambient = abs(da);
+ ambient *= 0.5;
+ ambient *= ambient;
+ ambient = (1.0-ambient);
+
+ color.rgb *= ambient;
+ color.rgb += atmosAffectDirectionalLight(final_da);
+ color.rgb *= gamma_diff.rgb;
+
+ //color.rgb = mix(diff.rgb, color.rgb, final_alpha);
+
+ color.rgb = atmosLighting(color.rgb);
color.rgb = scaleSoftClip(color.rgb);
- color.rgb = pow(color.rgb, vec3(2.2));
- col = vec4(0,0,0,0);
+ vec4 light = vec4(0,0,0,0);
-
- #define LIGHT_LOOP(i) col.rgb += light_diffuse[i].rgb * calcPointLightOrSpotLight(pos.xyz, normal, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z);
+ color.rgb = srgb_to_linear(color.rgb);
+ #define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, diff.rgb, pos.xyz, norm, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z);
+
LIGHT_LOOP(1)
LIGHT_LOOP(2)
LIGHT_LOOP(3)
@@ -257,9 +609,19 @@ void main()
LIGHT_LOOP(6)
LIGHT_LOOP(7)
- color.rgb += diff.rgb * pow(vary_pointlight_col, vec3(2.2)) * col.rgb;
+ // keep it linear
+ //
+ color.rgb += light.rgb;
- color.rgb = pow(color.rgb, vec3(1.0/2.2));
+ // straight to display gamma, we're post-deferred
+ //
+ color.rgb = linear_to_srgb(color.rgb);
+
+#ifdef WATER_FOG
+ color = applyWaterFogDeferred(pos.xyz, color);
+#endif
+
+#endif
frag_color = color;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl
index 9d3ba564cd..60d414f2ff 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl
@@ -55,67 +55,18 @@ mat4 getSkinnedTransform();
#endif
#endif
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
-void calcAtmospherics(vec3 inPositionEye);
-
-vec3 atmosAmbient(vec3 light);
-vec3 atmosAffectDirectionalLight(float lightIntensity);
-vec3 scaleDownLight(vec3 light);
-vec3 scaleUpLight(vec3 light);
-
-VARYING vec3 vary_ambient;
-VARYING vec3 vary_directional;
VARYING vec3 vary_fragcoord;
VARYING vec3 vary_position;
-VARYING vec3 vary_pointlight_col;
#ifdef USE_VERTEX_COLOR
VARYING vec4 vertex_color;
#endif
VARYING vec2 vary_texcoord0;
-
VARYING vec3 vary_norm;
uniform float near_clip;
-uniform vec4 light_position[8];
-uniform vec3 light_direction[8];
-uniform vec3 light_attenuation[8];
-uniform vec3 light_diffuse[8];
-
-uniform vec3 sun_dir;
-
-vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
-{
- //get light vector
- vec3 lv = lp.xyz-v;
-
- //get distance
- float d = dot(lv,lv);
-
- float da = 0.0;
-
- if (d > 0.0 && la > 0.0 && fa > 0.0)
- {
- //normalize light vector
- lv = normalize(lv);
-
- //distance attenuation
- float dist2 = d/la;
- da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
-
- // spotlight coefficient.
- float spot = max(dot(-ln, lv), is_pointlight);
- da *= spot*spot; // GL_SPOT_EXPONENT=2
-
- //angular attenuation
- da *= max(dot(n, lv), 0.0);
- }
-
- return vec3(da,da,da);
-}
-
void main()
{
vec4 pos;
@@ -168,43 +119,10 @@ void main()
vary_norm = norm;
vary_position = pos.xyz;
- calcAtmospherics(pos.xyz);
-
-#ifndef USE_VERTEX_COLOR
- vec4 diffuse_color = vec4(1,1,1,1);
-#endif
- //vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.));
- vec4 col = vec4(0.0, 0.0, 0.0, diffuse_color.a);
-
- vec3 diff = diffuse_color.rgb;
-
-
-
- vary_pointlight_col = diff;
-
-
- col.rgb = vec3(0,0,0);
-
- // Add windlight lights
- col.rgb = atmosAmbient(col.rgb);
-
- float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
- ambient *= 0.5;
- ambient *= ambient;
- ambient = (1.0-ambient);
-
- col.rgb *= ambient;
-
- vary_ambient = col.rgb*diff.rgb;
-
- vary_directional.rgb = atmosAffectDirectionalLight(1.0f);
-
- col.rgb = col.rgb*diff.rgb;
-
#ifdef USE_VERTEX_COLOR
- vertex_color = col;
+ vertex_color = diffuse_color;
#endif
-
+
#ifdef HAS_SKIN
vary_fragcoord.xyz = frag_pos.xyz + vec3(0,0,near_clip);
#else
@@ -219,4 +137,3 @@ void main()
#endif
}
-
diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl
index 968a5f6b3d..a4f54dff70 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl
@@ -59,22 +59,6 @@ vec4 getPosition(vec2 pos_screen)
return pos;
}
-#ifdef SINGLE_FP_ONLY
-vec2 encode_normal(vec3 n)
-{
- vec2 sn;
- sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
- return sn;
-}
-
-vec3 decode_normal (vec2 enc)
-{
- vec3 n;
- n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
- n.z = sqrt(1.0f - dot(n.xy,n.xy));
- return n;
-}
-#else
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
@@ -91,7 +75,6 @@ vec3 decode_normal (vec2 enc)
n.z = 1-f/2;
return n;
}
-#endif
void main()
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
index 59d109b886..8525e13333 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
@@ -50,7 +50,7 @@ void main()
{
discard;
}
-
+
frag_data[0] = vec4(col.rgb, 0.0);
frag_data[1] = vec4(0,0,0,0);
vec3 nvn = normalize(vary_normal);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
index dc1dead656..f22b16965c 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
@@ -35,29 +35,143 @@ out vec4 frag_color;
uniform sampler2D diffuseMap;
#endif
+VARYING vec3 vary_position;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
-vec3 fullbrightAtmosTransport(vec3 light);
-vec3 fullbrightScaleSoftClip(vec3 light);
+vec3 srgb_to_linear(vec3 cs)
+{
+ vec3 low_range = cs / vec3(12.92);
+ vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
+ bvec3 lte = lessThanEqual(cs,vec3(0.04045));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lte.r ? low_range.r : high_range.r;
+ result.g = lte.g ? low_range.g : high_range.g;
+ result.b = lte.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lte);
+#endif
+
+}
+
+vec3 linear_to_srgb(vec3 cl)
+{
+ cl = clamp(cl, vec3(0), vec3(1));
+ vec3 low_range = cl * 12.92;
+ vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
+ bvec3 lt = lessThan(cl,vec3(0.0031308));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lt.r ? low_range.r : high_range.r;
+ result.g = lt.g ? low_range.g : high_range.g;
+ result.b = lt.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lt);
+#endif
+
+}
+
+vec3 fullbrightAtmosTransportDeferred(vec3 light)
+{
+ return light;
+}
+
+vec3 fullbrightScaleSoftClipDeferred(vec3 light)
+{
+ //soft clip effect:
+ return light;
+}
+
+#ifdef HAS_ALPHA_MASK
+uniform float minimum_alpha;
+#endif
+
+#ifdef WATER_FOG
+uniform vec4 waterPlane;
+uniform vec4 waterFogColor;
+uniform float waterFogDensity;
+uniform float waterFogKS;
+
+vec4 applyWaterFogDeferred(vec3 pos, vec4 color)
+{
+ //normalize view vector
+ vec3 view = normalize(pos);
+ float es = -(dot(view, waterPlane.xyz));
+
+ //find intersection point with water plane and eye vector
+
+ //get eye depth
+ float e0 = max(-waterPlane.w, 0.0);
+
+ vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0);
+
+ //get object depth
+ float depth = length(pos - int_v);
+
+ //get "thickness" of water
+ float l = max(depth, 0.1);
+
+ float kd = waterFogDensity;
+ float ks = waterFogKS;
+ vec4 kc = waterFogColor;
+
+ float F = 0.98;
+
+ float t1 = -kd * pow(F, ks * e0);
+ float t2 = kd + ks * es;
+ float t3 = pow(F, t2*l) - 1.0;
+
+ float L = min(t1/t2*t3, 1.0);
+
+ float D = pow(0.98, l*kd);
+
+ color.rgb = color.rgb * D + kc.rgb * L;
+ color.a = kc.a + color.a;
+
+ return color;
+}
+#endif
void main()
{
#if HAS_DIFFUSE_LOOKUP
- vec4 color = diffuseLookup(vary_texcoord0.xy)*vertex_color;
+ vec4 color = diffuseLookup(vary_texcoord0.xy);
#else
- vec4 color = texture2D(diffuseMap, vary_texcoord0.xy)*vertex_color;
+ vec4 color = texture2D(diffuseMap, vary_texcoord0.xy);
#endif
- color.rgb = pow(color.rgb,vec3(2.2f,2.2f,2.2f));
-
- color.rgb = fullbrightAtmosTransport(color.rgb);
+ float final_alpha = color.a * vertex_color.a;
- color.rgb = fullbrightScaleSoftClip(color.rgb);
+#ifdef HAS_ALPHA_MASK
+ if (color.a < minimum_alpha)
+ {
+ discard;
+ }
+#endif
+
+ color.rgb *= vertex_color.rgb;
+ color.rgb = srgb_to_linear(color.rgb);
+ color.rgb = fullbrightAtmosTransportDeferred(color.rgb);
+ color.rgb = fullbrightScaleSoftClipDeferred(color.rgb);
+
+ color.rgb = linear_to_srgb(color.rgb);
- color.rgb = pow(color.rgb, vec3(1.0/2.2));
+#ifdef WATER_FOG
+ vec3 pos = vary_position;
+ vec4 fogged = applyWaterFogDeferred(pos, vec4(color.rgb, final_alpha));
+ color.rgb = fogged.rgb;
+ color.a = fogged.a;
+#else
+ color.a = final_alpha;
+#endif
- frag_color = color;
+ frag_color.rgb = color.rgb;
+ frag_color.a = color.a;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl
index 3f09a15375..8e899e3e0f 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl
@@ -40,6 +40,9 @@ vec3 atmosAffectDirectionalLight(float lightIntensity);
vec3 scaleDownLight(vec3 light);
vec3 scaleUpLight(vec3 light);
+#ifdef WATER_FOG
+VARYING vec3 vary_position;
+#endif
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
@@ -53,7 +56,11 @@ void main()
passTextureIndex();
gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
-
+
+#ifdef WATER_FOG
+ vary_position = pos.xyz;
+#endif
+
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
calcAtmospherics(pos.xyz);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
index bc0719cb82..f8fdde43f9 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
@@ -38,6 +38,42 @@ uniform sampler2D specularMap;
VARYING vec2 vary_texcoord0;
+vec3 decode_normal (vec2 enc)
+{
+ vec2 fenc = enc*4-2;
+ float f = dot(fenc,fenc);
+ float g = sqrt(1-f/4);
+ vec3 n;
+ n.xy = fenc*g;
+ n.z = 1-f/2;
+ return n;
+}
+
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
+vec3 linear_to_srgb(vec3 cl)
+{
+ cl = clamp(cl, vec3(0), vec3(1));
+ vec3 low_range = cl * 12.92;
+ vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
+ bvec3 lt = lessThan(cl,vec3(0.0031308));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lt.r ? low_range.r : high_range.r;
+ result.g = lt.g ? low_range.g : high_range.g;
+ result.b = lt.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lt);
+#endif
+
+}
+
void main()
{
vec4 col = texture2D(diffuseMap, vary_texcoord0.xy);
@@ -47,7 +83,12 @@ void main()
discard;
}
- frag_data[0] = vec4(col.rgb, col.a * 0.005);
- frag_data[1] = texture2D(specularMap, vary_texcoord0.xy);
- frag_data[2] = vec4(texture2D(normalMap, vary_texcoord0.xy).xyz, 0.0);
+ vec4 norm = texture2D(normalMap, vary_texcoord0.xy);
+ vec4 spec = texture2D(specularMap, vary_texcoord0.xy);
+
+ col.rgb = linear_to_srgb(col.rgb);
+
+ frag_data[0] = vec4(col.rgb, 0.0);
+ frag_data[1] = spec;
+ frag_data[2] = vec4(norm.xy,0,0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
index 618ea747f5..8202b4978f 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
@@ -29,6 +29,44 @@
#define DIFFUSE_ALPHA_MODE_EMISSIVE 3
uniform float emissive_brightness;
+uniform float display_gamma;
+
+vec3 srgb_to_linear(vec3 cs)
+{
+ vec3 low_range = cs / vec3(12.92);
+ vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
+ bvec3 lte = lessThanEqual(cs,vec3(0.04045));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lte.r ? low_range.r : high_range.r;
+ result.g = lte.g ? low_range.g : high_range.g;
+ result.b = lte.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lte);
+#endif
+
+}
+
+vec3 linear_to_srgb(vec3 cl)
+{
+ cl = clamp(cl, vec3(0), vec3(1));
+ vec3 low_range = cl * 12.92;
+ vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
+ bvec3 lt = lessThan(cl,vec3(0.0031308));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lt.r ? low_range.r : high_range.r;
+ result.g = lt.g ? low_range.g : high_range.g;
+ result.b = lt.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lt);
+#endif
+
+}
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
@@ -114,6 +152,52 @@ uniform vec3 light_direction[8];
uniform vec3 light_attenuation[8];
uniform vec3 light_diffuse[8];
+#ifdef WATER_FOG
+uniform vec4 waterPlane;
+uniform vec4 waterFogColor;
+uniform float waterFogDensity;
+uniform float waterFogKS;
+
+vec4 applyWaterFogDeferred(vec3 pos, vec4 color)
+{
+ //normalize view vector
+ vec3 view = normalize(pos);
+ float es = -(dot(view, waterPlane.xyz));
+
+ //find intersection point with water plane and eye vector
+
+ //get eye depth
+ float e0 = max(-waterPlane.w, 0.0);
+
+ vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0);
+
+ //get object depth
+ float depth = length(pos - int_v);
+
+ //get "thickness" of water
+ float l = max(depth, 0.1);
+
+ float kd = waterFogDensity;
+ float ks = waterFogKS;
+ vec4 kc = waterFogColor;
+
+ float F = 0.98;
+
+ float t1 = -kd * pow(F, ks * e0);
+ float t2 = kd + ks * es;
+ float t3 = pow(F, t2*l) - 1.0;
+
+ float L = min(t1/t2*t3, 1.0);
+
+ float D = pow(0.98, l*kd);
+
+ color.rgb = color.rgb * D + kc.rgb * L;
+ color.a = kc.a + color.a;
+
+ return color;
+}
+#endif
+
vec3 calcDirectionalLight(vec3 n, vec3 l)
{
float a = max(dot(n,l),0.0);
@@ -142,7 +226,7 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spe
float dist = d/la;
float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
dist_atten *= dist_atten;
- dist_atten *= 1.4;
+ dist_atten *= 2.0;
// spotlight coefficient.
float spot = max(dot(-ln, lv), is_pointlight);
@@ -199,10 +283,13 @@ vec4 getPosition_d(vec2 pos_screen, float depth)
return pos;
}
+#ifndef WATER_FOG
vec3 getPositionEye()
{
return vary_PositionEye;
}
+#endif
+
vec3 getSunlitColor()
{
return vary_SunlitColor;
@@ -428,22 +515,6 @@ VARYING vec3 vary_normal;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
-#ifdef SINGLE_FP_ONLY
-vec2 encode_normal(vec3 n)
-{
- vec2 sn;
- sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
- return sn;
-}
-
-vec3 decode_normal (vec2 enc)
-{
- vec3 n;
- n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
- n.z = sqrt(1.0f - dot(n.xy,n.xy));
- return n;
-}
-#else
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
@@ -460,7 +531,6 @@ vec3 decode_normal (vec2 enc)
n.z = 1-f/2;
return n;
}
-#endif
void main()
{
@@ -475,8 +545,8 @@ void main()
#endif
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
- vec3 old_diffcol = diffcol.rgb;
- diffcol.rgb = pow(diffcol.rgb, vec3(2.2));
+ vec3 gamma_diff = diffcol.rgb;
+ diffcol.rgb = srgb_to_linear(diffcol.rgb);
#endif
#if HAS_SPECULAR_MAP
@@ -502,6 +572,9 @@ void main()
norm.xyz = tnorm;
norm.xyz = normalize(norm.xyz);
+ vec2 abnormal = encode_normal(norm.xyz);
+ norm.xyz = decode_normal(abnormal.xy);
+
vec4 final_color = diffcol;
#if (DIFFUSE_ALPHA_MODE != DIFFUSE_ALPHA_MODE_EMISSIVE)
@@ -597,7 +670,7 @@ void main()
vec4 diffuse = final_color;
float envIntensity = final_normal.z;
- vec3 col = vec3(0.0f,0.0f,0.0f);
+ vec3 col = vec3(0.0f,0.0f,0.0f);
float bloom = 0.0;
calcAtmospherics(pos.xyz, 1.0);
@@ -605,23 +678,27 @@ void main()
vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
float da =dot(norm.xyz, sun_dir.xyz);
+
float final_da = da;
final_da = min(final_da, shadow);
- final_da = max(final_da, diffuse.a);
+ //final_da = max(final_da, diffuse.a);
final_da = max(final_da, 0.0f);
+ final_da = min(final_da, 1.0f);
+ final_da = pow(final_da, 1.0/1.3);
col.rgb = atmosAmbient(col);
- float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
+ float ambient = min(abs(da), 1.0);
ambient *= 0.5;
ambient *= ambient;
ambient = (1.0-ambient);
col.rgb *= ambient;
- col.rgb = col.rgb + atmosAffectDirectionalLight(pow(final_da, 1.0/1.3));
- col.rgb *= old_diffcol.rgb;
-
+ col.rgb = col.rgb + atmosAffectDirectionalLight(final_da);
+
+ col.rgb *= gamma_diff.rgb;
+
float glare = 0.0;
@@ -643,7 +720,8 @@ void main()
col += spec_contrib;
}
- col = mix(col.rgb, old_diffcol.rgb, diffuse.a);
+
+ col = mix(col.rgb, diffcol.rgb, diffuse.a);
if (envIntensity > 0.0)
{
@@ -661,16 +739,20 @@ void main()
glare += cur_glare;
}
- col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a);
- col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);
+ //col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a);
+ //col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);
- //convert to linear space before adding local lights
- col = pow(col, vec3(2.2));
+ col = atmosLighting(col);
+ col = scaleSoftClip(col);
+ //convert to linear space before adding local lights
+ col = srgb_to_linear(col);
vec3 npos = normalize(-pos.xyz);
- #define LIGHT_LOOP(i) col.rgb = col.rgb + calcPointLightOrSpotLight(light_diffuse[i].rgb, npos, diffuse.rgb, final_specular, pos.xyz, norm.xyz, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, glare);
+ vec3 light = vec3(0,0,0);
+
+ #define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, npos, diffuse.rgb, final_specular, pos.xyz, norm.xyz, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, glare);
LIGHT_LOOP(1)
LIGHT_LOOP(2)
@@ -680,13 +762,22 @@ void main()
LIGHT_LOOP(6)
LIGHT_LOOP(7)
+ col.rgb += light.rgb;
+
+ glare = min(glare, 1.0);
+ float al = max(diffcol.a,glare)*vertex_color.a;
//convert to gamma space for display on screen
- col.rgb = pow(col.rgb, vec3(1.0/2.2));
+ col.rgb = linear_to_srgb(col.rgb);
+
+#ifdef WATER_FOG
+ vec4 temp = applyWaterFogDeferred(pos, vec4(col.rgb, al));
+ col.rgb = temp.rgb;
+ al = temp.a;
+#endif
frag_color.rgb = col.rgb;
- glare = min(glare, 1.0);
- frag_color.a = max(diffcol.a,glare)*vertex_color.a;
+ frag_color.a = al;
#else
frag_data[0] = final_color;
@@ -694,3 +785,4 @@ void main()
frag_data[2] = final_normal; // XY = Normal. Z = Env. intensity.
#endif
}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl
index b25032866b..393d1e69da 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl
@@ -142,3 +142,4 @@ vary_normal = n;
#endif
#endif
}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
index 868526d457..3ba6de8b76 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
@@ -45,9 +45,8 @@ uniform float sun_wash;
uniform int light_count;
-#define MAX_LIGHT_COUNT 16
-uniform vec4 light[MAX_LIGHT_COUNT];
-uniform vec4 light_col[MAX_LIGHT_COUNT];
+uniform vec4 light[LIGHT_COUNT];
+uniform vec4 light_col[LIGHT_COUNT];
VARYING vec4 vary_fragcoord;
uniform vec2 screen_res;
@@ -56,22 +55,6 @@ uniform float far_z;
uniform mat4 inv_proj;
-#ifdef SINGLE_FP_ONLY
-vec2 encode_normal(vec3 n)
-{
- vec2 sn;
- sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
- return sn;
-}
-
-vec3 decode_normal (vec2 enc)
-{
- vec3 n;
- n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
- n.z = sqrt(1.0f - dot(n.xy,n.xy));
- return n;
-}
-#else
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
@@ -88,7 +71,6 @@ vec3 decode_normal (vec2 enc)
n.z = 1-f/2;
return n;
}
-#endif
vec4 getPosition(vec2 pos_screen)
{
@@ -117,78 +99,66 @@ void main()
norm = normalize(norm);
vec4 spec = texture2DRect(specularRect, frag.xy);
vec3 diff = texture2DRect(diffuseRect, frag.xy).rgb;
+
float noise = texture2D(noiseMap, frag.xy/128.0).b;
vec3 out_col = vec3(0,0,0);
vec3 npos = normalize(-pos);
// As of OSX 10.6.7 ATI Apple's crash when using a variable size loop
- for (int i = 0; i < MAX_LIGHT_COUNT; ++i)
+ for (int i = 0; i < LIGHT_COUNT; ++i)
{
- bool light_contrib = (i < light_count);
-
vec3 lv = light[i].xyz-pos;
float dist = length(lv);
dist /= light[i].w;
- if (dist > 1.0)
+ if (dist <= 1.0)
{
- light_contrib = false;
- }
-
- float da = dot(norm, lv);
- if (da < 0.0)
- {
- light_contrib = false;
- }
-
- if (light_contrib)
- {
- lv = normalize(lv);
- da = dot(norm, lv);
+ float da = dot(norm, lv);
+ if (da > 0.0)
+ {
+ lv = normalize(lv);
+ da = dot(norm, lv);
- float fa = light_col[i].a+1.0;
- float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
- dist_atten *= dist_atten;
- dist_atten *= 2.0;
+ float fa = light_col[i].a+1.0;
+ float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
+ dist_atten *= dist_atten;
+ dist_atten *= 2.0;
- dist_atten *= noise;
+ dist_atten *= noise;
- float lit = da * dist_atten;
+ float lit = da * dist_atten;
- vec3 col = light_col[i].rgb*lit*diff;
+ vec3 col = light_col[i].rgb*lit*diff;
- //vec3 col = vec3(dist2, light_col[i].a, lit);
+ //vec3 col = vec3(dist2, light_col[i].a, lit);
- if (spec.a > 0.0)
- {
- lit = min(da*6.0, 1.0) * dist_atten;
- //vec3 ref = dot(pos+lv, norm);
- vec3 h = normalize(lv+npos);
- float nh = dot(norm, h);
- float nv = dot(norm, npos);
- float vh = dot(npos, h);
- float sa = nh;
- float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
-
- float gtdenom = 2 * nh;
- float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
-
- if (nh > 0.0)
+ if (spec.a > 0.0)
{
- float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
- col += lit*scol*light_col[i].rgb*spec.rgb;
- //col += spec.rgb;
+ lit = min(da*6.0, 1.0) * dist_atten;
+ //vec3 ref = dot(pos+lv, norm);
+ vec3 h = normalize(lv+npos);
+ float nh = dot(norm, h);
+ float nv = dot(norm, npos);
+ float vh = dot(npos, h);
+ float sa = nh;
+ float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
+
+ float gtdenom = 2 * nh;
+ float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
+
+ if (nh > 0.0)
+ {
+ float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
+ col += lit*scol*light_col[i].rgb*spec.rgb;
+ //col += spec.rgb;
+ }
}
- }
- out_col += col;
+ out_col += col;
+ }
}
}
- if (dot(out_col, out_col) <= 0.0)
- {
- discard;
- }
-
+
frag_color.rgb = out_col;
frag_color.a = 0.0;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
index 97bf49a605..ed68e38891 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
@@ -67,22 +67,6 @@ uniform vec2 screen_res;
uniform mat4 inv_proj;
-#ifdef SINGLE_FP_ONLY
-vec2 encode_normal(vec3 n)
-{
- vec2 sn;
- sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
- return sn;
-}
-
-vec3 decode_normal (vec2 enc)
-{
- vec3 n;
- n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
- n.z = sqrt(1.0f - dot(n.xy,n.xy));
- return n;
-}
-#else
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
@@ -99,17 +83,48 @@ vec3 decode_normal (vec2 enc)
n.z = 1-f/2;
return n;
}
+vec3 srgb_to_linear(vec3 cs)
+{
+ vec3 low_range = cs / vec3(12.92);
+ vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
+ bvec3 lte = lessThanEqual(cs,vec3(0.04045));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lte.r ? low_range.r : high_range.r;
+ result.g = lte.g ? low_range.g : high_range.g;
+ result.b = lte.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lte);
#endif
-vec4 correctWithGamma(vec4 col)
+}
+
+vec3 linear_to_srgb(vec3 cl)
{
- return vec4(pow(col.rgb, vec3(2.2)), col.a);
+ cl = clamp(cl, vec3(0), vec3(1));
+ vec3 low_range = cl * 12.92;
+ vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
+ bvec3 lt = lessThan(cl,vec3(0.0031308));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lt.r ? low_range.r : high_range.r;
+ result.g = lt.g ? low_range.g : high_range.g;
+ result.b = lt.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lt);
+#endif
+
}
+
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
- ret = correctWithGamma(ret);
+ ret.rgb = srgb_to_linear(ret.rgb);
vec2 dist = tc-vec2(0.5);
@@ -125,7 +140,7 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
- ret = correctWithGamma(ret);
+ ret.rgb = srgb_to_linear(ret.rgb);
vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
@@ -143,7 +158,7 @@ vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
- ret = correctWithGamma(ret);
+ ret.rgb = srgb_to_linear(ret.rgb);
vec2 dist = tc-vec2(0.5);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
index caf20ce707..106d48bd71 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
@@ -54,22 +54,6 @@ uniform vec2 screen_res;
uniform mat4 inv_proj;
uniform vec4 viewport;
-#ifdef SINGLE_FP_ONLY
-vec2 encode_normal(vec3 n)
-{
- vec2 sn;
- sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
- return sn;
-}
-
-vec3 decode_normal (vec2 enc)
-{
- vec3 n;
- n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
- n.z = sqrt(1.0f - dot(n.xy,n.xy));
- return n;
-}
-#else
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
@@ -86,7 +70,6 @@ vec3 decode_normal (vec2 enc)
n.z = 1-f/2;
return n;
}
-#endif
vec4 getPosition(vec2 pos_screen)
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
index 6f2cfae6d2..4e2f98aa29 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
@@ -36,11 +36,32 @@ uniform sampler2DRect diffuseRect;
uniform vec2 screen_res;
VARYING vec2 vary_fragcoord;
-uniform float texture_gamma;
+uniform float display_gamma;
+
+vec3 linear_to_srgb(vec3 cl)
+{
+ cl = clamp(cl, vec3(0), vec3(1));
+ vec3 low_range = cl * 12.92;
+ vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
+ bvec3 lt = lessThan(cl,vec3(0.0031308));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lt.r ? low_range.r : high_range.r;
+ result.g = lt.g ? low_range.g : high_range.g;
+ result.b = lt.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lt);
+#endif
+
+}
+
void main()
{
vec4 diff = texture2DRect(diffuseRect, vary_fragcoord);
- frag_color = pow(diff, vec4(texture_gamma, texture_gamma, texture_gamma, 1.0f));
+ diff.rgb = linear_to_srgb(diff.rgb);
+ frag_color = diff;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
index 08583ad0f2..ebe5e57bb7 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
@@ -78,22 +78,43 @@ vec3 vary_AtmosAttenuation;
uniform mat4 inv_proj;
uniform vec2 screen_res;
-#ifdef SINGLE_FP_ONLY
-vec2 encode_normal(vec3 n)
+vec3 srgb_to_linear(vec3 cs)
{
- vec2 sn;
- sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
- return sn;
+ vec3 low_range = cs / vec3(12.92);
+ vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
+ bvec3 lte = lessThanEqual(cs,vec3(0.04045));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lte.r ? low_range.r : high_range.r;
+ result.g = lte.g ? low_range.g : high_range.g;
+ result.b = lte.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lte);
+#endif
+
}
-vec3 decode_normal (vec2 enc)
+vec3 linear_to_srgb(vec3 cl)
{
- vec3 n;
- n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
- n.z = sqrt(1.0f - dot(n.xy,n.xy));
- return n;
-}
+ vec3 low_range = cl * 12.92;
+ vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
+ bvec3 lt = lessThan(cl,vec3(0.0031308));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lt.r ? low_range.r : high_range.r;
+ result.g = lt.g ? low_range.g : high_range.g;
+ result.b = lt.b ? low_range.b : high_range.b;
+ return result;
#else
+ return mix(high_range, low_range, lt);
+#endif
+
+}
+
+
vec3 decode_normal (vec2 enc)
{
vec2 fenc = enc*4-2;
@@ -104,7 +125,6 @@ vec3 decode_normal (vec2 enc)
n.z = 1-f/2;
return n;
}
-#endif
vec4 getPosition_d(vec2 pos_screen, float depth)
{
@@ -170,6 +190,53 @@ void setAtmosAttenuation(vec3 v)
vary_AtmosAttenuation = v;
}
+
+#ifdef WATER_FOG
+uniform vec4 waterPlane;
+uniform vec4 waterFogColor;
+uniform float waterFogDensity;
+uniform float waterFogKS;
+
+vec4 applyWaterFogDeferred(vec3 pos, vec4 color)
+{
+ //normalize view vector
+ vec3 view = normalize(pos);
+ float es = -(dot(view, waterPlane.xyz));
+
+ //find intersection point with water plane and eye vector
+
+ //get eye depth
+ float e0 = max(-waterPlane.w, 0.0);
+
+ vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0);
+
+ //get object depth
+ float depth = length(pos - int_v);
+
+ //get "thickness" of water
+ float l = max(depth, 0.1);
+
+ float kd = waterFogDensity;
+ float ks = waterFogKS;
+ vec4 kc = waterFogColor;
+
+ float F = 0.98;
+
+ float t1 = -kd * pow(F, ks * e0);
+ float t2 = kd + ks * es;
+ float t3 = pow(F, t2*l) - 1.0;
+
+ float L = min(t1/t2*t3, 1.0);
+
+ float D = pow(0.98, l*kd);
+
+ color.rgb = color.rgb * D + kc.rgb * L;
+ color.a = kc.a + color.a;
+
+ return color;
+}
+#endif
+
void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
vec3 P = inPositionEye;
@@ -324,13 +391,16 @@ void main()
float envIntensity = norm.z;
norm.xyz = decode_normal(norm.xy); // unpack norm
- float da = max(dot(norm.xyz, sun_dir.xyz), 0.0);
- da = pow(da, 1.0/1.3);
+ float da = dot(norm.xyz, sun_dir.xyz);
+
+ float final_da = max(0.0,da);
+ final_da = min(final_da, 1.0f);
+ final_da = pow(final_da, 1.0/1.3);
vec4 diffuse = texture2DRect(diffuseRect, tc);
//convert to gamma space
- diffuse.rgb = pow(diffuse.rgb, vec3(1.0/2.2));
+ diffuse.rgb = linear_to_srgb(diffuse.rgb);
vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
vec3 col;
@@ -346,7 +416,7 @@ void main()
col.rgb *= ambient;
- col += atmosAffectDirectionalLight(max(min(da, 1.0), 0.0));
+ col += atmosAffectDirectionalLight(final_da);
col *= diffuse.rgb;
@@ -383,16 +453,22 @@ void main()
if (norm.w < 0.5)
{
col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a);
- col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);
+ col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);
}
- col = pow(col, vec3(2.2));
+ #ifdef WATER_FOG
+ vec4 fogged = applyWaterFogDeferred(pos,vec4(col, bloom));
+ col = fogged.rgb;
+ bloom = fogged.a;
+ #endif
+
+ col = srgb_to_linear(col);
//col = vec3(1,0,1);
//col.g = envIntensity;
}
- frag_color.rgb = col;
-
+ frag_color.rgb = col.rgb;
frag_color.a = bloom;
}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl
index 1975b18652..48c9cd363c 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl
@@ -65,22 +65,6 @@ uniform vec2 screen_res;
uniform mat4 inv_proj;
-#ifdef SINGLE_FP_ONLY
-vec2 encode_normal(vec3 n)
-{
- vec2 sn;
- sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
- return sn;
-}
-
-vec3 decode_normal (vec2 enc)
-{
- vec3 n;
- n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
- n.z = sqrt(1.0f - dot(n.xy,n.xy));
- return n;
-}
-#else
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
@@ -97,11 +81,47 @@ vec3 decode_normal (vec2 enc)
n.z = 1-f/2;
return n;
}
+
+vec3 srgb_to_linear(vec3 cs)
+{
+ vec3 low_range = cs / vec3(12.92);
+ vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
+ bvec3 lte = lessThanEqual(cs,vec3(0.04045));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lte.r ? low_range.r : high_range.r;
+ result.g = lte.g ? low_range.g : high_range.g;
+ result.b = lte.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lte);
+#endif
+
+}
+
+vec3 linear_to_srgb(vec3 cl)
+{
+ cl = clamp(cl, vec3(0), vec3(1));
+ vec3 low_range = cl * 12.92;
+ vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
+ bvec3 lt = lessThan(cl,vec3(0.0031308));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lt.r ? low_range.r : high_range.r;
+ result.g = lt.g ? low_range.g : high_range.g;
+ result.b = lt.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lt);
#endif
+}
+
vec4 correctWithGamma(vec4 col)
{
- return vec4(pow(col.rgb, vec3(2.2)), col.a);
+ return vec4(srgb_to_linear(col.rgb), col.a);
}
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
diff --git a/indra/newview/app_settings/shaders/class1/deferred/srgb.glsl b/indra/newview/app_settings/shaders/class1/deferred/srgb.glsl
new file mode 100644
index 0000000000..587f3d5a94
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/srgb.glsl
@@ -0,0 +1,46 @@
+/**
+ * @file srgb.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+vec3 srgb_to_linear(vec3 cs)
+{
+ vec3 low_range = cs / vec3(12.92);
+ vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
+
+ bvec3 lte = lessThanEqual(cs,vec3(0.04045));
+ return mix(high_range, low_range, lte);
+
+}
+
+vec3 linear_to_srgb(vec3 cl)
+{
+ cl = clamp(cl, vec3(0), vec3(1));
+ vec3 low_range = cl * 12.92;
+ vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
+
+ bvec3 lt = lessThan(cl,vec3(0.0031308));
+ return mix(high_range, low_range, lt);
+
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/srgb_mac.glsl b/indra/newview/app_settings/shaders/class1/deferred/srgb_mac.glsl
new file mode 100644
index 0000000000..6cc1e6e798
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/srgb_mac.glsl
@@ -0,0 +1,54 @@
+/**
+ * @file srgb.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+vec3 srgb_to_linear(vec3 cs)
+{
+ vec3 low_range = cs / vec3(12.92);
+ vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
+
+ bvec3 lte = lessThanEqual(cs,vec3(0.04045));
+
+ vec3 result;
+ result.r = lte.r ? low_range.r : high_range.r;
+ result.g = lte.g ? low_range.g : high_range.g;
+ result.b = lte.b ? low_range.b : high_range.b;
+ return result;
+}
+
+vec3 linear_to_srgb(vec3 cl)
+{
+ cl = clamp(cl, vec3(0), vec3(1));
+ vec3 low_range = cl * 12.92;
+ vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
+
+ bvec3 lt = lessThan(cl,vec3(0.0031308));
+
+ vec3 result;
+ result.r = lt.r ? low_range.r : high_range.r;
+ result.g = lt.g ? low_range.g : high_range.g;
+ result.b = lt.b ? low_range.b : high_range.b;
+ return result;
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl
index 6653f57ee1..c0a5865bef 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl
@@ -49,22 +49,6 @@ VARYING vec2 vary_fragcoord;
uniform mat4 inv_proj;
uniform vec2 screen_res;
-#ifdef SINGLE_FP_ONLY
-vec2 encode_normal(vec3 n)
-{
- vec2 sn;
- sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
- return sn;
-}
-
-vec3 decode_normal (vec2 enc)
-{
- vec3 n;
- n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
- n.z = sqrt(1.0f - dot(n.xy,n.xy));
- return n;
-}
-#else
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
@@ -81,7 +65,6 @@ vec3 decode_normal (vec2 enc)
n.z = 1-f/2;
return n;
}
-#endif
vec4 getPosition(vec2 pos_screen)
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl
new file mode 100644
index 0000000000..78f841c733
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl
@@ -0,0 +1,157 @@
+/**
+ * @file underWaterF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_data[3];
+#else
+#define frag_data gl_FragData
+#endif
+
+uniform sampler2D diffuseMap;
+uniform sampler2D bumpMap;
+uniform sampler2D screenTex;
+uniform sampler2D refTex;
+uniform sampler2D screenDepth;
+
+uniform vec4 fogCol;
+uniform vec3 lightDir;
+uniform vec3 specular;
+uniform float lightExp;
+uniform vec2 fbScale;
+uniform float refScale;
+uniform float znear;
+uniform float zfar;
+uniform float kd;
+uniform vec4 waterPlane;
+uniform vec3 eyeVec;
+uniform vec4 waterFogColor;
+uniform float waterFogDensity;
+uniform float waterFogKS;
+uniform vec2 screenRes;
+
+//bigWave is (refCoord.w, view.w);
+VARYING vec4 refCoord;
+VARYING vec4 littleWave;
+VARYING vec4 view;
+
+vec3 srgb_to_linear(vec3 cs)
+{
+ vec3 low_range = cs / vec3(12.92);
+ vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
+ bvec3 lte = lessThanEqual(cs,vec3(0.04045));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lte.r ? low_range.r : high_range.r;
+ result.g = lte.g ? low_range.g : high_range.g;
+ result.b = lte.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lte);
+#endif
+
+}
+
+vec3 linear_to_srgb(vec3 cl)
+{
+ cl = clamp(cl, vec3(0), vec3(1));
+ vec3 low_range = cl * 12.92;
+ vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
+ bvec3 lt = lessThan(cl,vec3(0.0031308));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lt.r ? low_range.r : high_range.r;
+ result.g = lt.g ? low_range.g : high_range.g;
+ result.b = lt.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lt);
+#endif
+
+}
+
+vec2 encode_normal(vec3 n)
+{
+ float f = sqrt(8 * n.z + 8);
+ return n.xy / f + 0.5;
+}
+
+vec4 applyWaterFog(vec4 color, vec3 viewVec)
+{
+ //normalize view vector
+ vec3 view = normalize(viewVec);
+ float es = -view.z;
+
+ //find intersection point with water plane and eye vector
+
+ //get eye depth
+ float e0 = max(-waterPlane.w, 0.0);
+
+ //get object depth
+ float depth = length(viewVec);
+
+ //get "thickness" of water
+ float l = max(depth, 0.1);
+
+ float kd = waterFogDensity;
+ float ks = waterFogKS;
+ vec4 kc = waterFogColor;
+
+ float F = 0.98;
+
+ float t1 = -kd * pow(F, ks * e0);
+ float t2 = kd + ks * es;
+ float t3 = pow(F, t2*l) - 1.0;
+
+ float L = min(t1/t2*t3, 1.0);
+
+ float D = pow(0.98, l*kd);
+ //return vec4(1.0, 0.0, 1.0, 1.0);
+ return color * D + kc * L;
+ //depth /= 10.0;
+ //return vec4(depth,depth,depth,0.0);
+}
+
+void main()
+{
+ vec4 color;
+
+ //get detail normals
+ vec3 wave1 = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
+ vec3 wave2 = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
+ vec3 wave3 = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;
+ vec3 wavef = normalize(wave1+wave2+wave3);
+
+ //figure out distortion vector (ripply)
+ vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
+ distort = distort+wavef.xy*refScale;
+
+ vec4 fb = texture2D(screenTex, distort);
+
+ frag_data[0] = vec4(linear_to_srgb(fb.rgb), 1.0); // diffuse
+ frag_data[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec
+ frag_data[2] = vec4(encode_normal(wavef), 0.0, 0.0); // normalxyz, displace
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
index daa2fb390a..72c46e240d 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
@@ -67,6 +67,43 @@ VARYING vec4 littleWave;
VARYING vec4 view;
VARYING vec4 vary_position;
+vec3 srgb_to_linear(vec3 cs)
+{
+ vec3 low_range = cs / vec3(12.92);
+ vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
+ bvec3 lte = lessThanEqual(cs,vec3(0.04045));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lte.r ? low_range.r : high_range.r;
+ result.g = lte.g ? low_range.g : high_range.g;
+ result.b = lte.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lte);
+#endif
+
+}
+
+vec3 linear_to_srgb(vec3 cl)
+{
+ cl = clamp(cl, vec3(0), vec3(1));
+ vec3 low_range = cl * 12.92;
+ vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
+ bvec3 lt = lessThan(cl,vec3(0.0031308));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lt.r ? low_range.r : high_range.r;
+ result.g = lt.g ? low_range.g : high_range.g;
+ result.b = lt.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lt);
+#endif
+
+}
+
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
@@ -121,7 +158,7 @@ void main()
refcol *= df1 * 0.333;
vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5;
- //wavef.z *= max(-viewVec.z, 0.1);
+ wavef.z *= max(-viewVec.z, 0.1);
wavef = normalize(wavef);
float df2 = dot(viewVec, wavef) * fresnelScale+fresnelOffset;
@@ -131,13 +168,14 @@ void main()
vec2 refvec4 = distort+refdistort4/dmod;
float dweight = min(dist2*blurMultiplier, 1.0);
vec4 baseCol = texture2D(refTex, refvec4);
+
refcol = mix(baseCol*df2, refcol, dweight);
//get specular component
- //float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0);
+ float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0);
//harden specular
- //spec = pow(spec, 128.0);
+ spec = pow(spec, 128.0);
//figure out distortion vector (ripply)
vec2 distort2 = distort+wavef.xy*refScale/max(dmod*df1, 1.0);
@@ -148,24 +186,17 @@ void main()
// Note we actually want to use just df1, but multiplying by 0.999999 gets around an nvidia compiler bug
color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999);
- float shadow = 1.0;
vec4 pos = vary_position;
-
- //vec3 nz = texture2D(noiseMap, gl_FragCoord.xy/128.0).xyz;
- vec4 spos = pos;
- //spec *= shadow;
- //color.rgb += spec * specular;
-
+ color.rgb += spec * specular;
+
color.rgb = atmosTransport(color.rgb);
color.rgb = scaleSoftClip(color.rgb);
- //color.a = spec * sunAngle2;
+ color.a = spec * sunAngle2;
- //wavef.z *= 0.1f;
- //wavef = normalize(wavef);
- vec3 screenspacewavef = (norm_mat*vec4(wavef, 1.0)).xyz;
+ vec3 screenspacewavef = normalize((norm_mat*vec4(wavef, 1.0)).xyz);
- frag_data[0] = vec4(color.rgb, 0.5); // diffuse
- frag_data[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec
- frag_data[2] = vec4(encode_normal(screenspacewavef), 0.0, 0.0); // normalxyz, displace
+ frag_data[0] = vec4(color.rgb, color); // diffuse
+ frag_data[1] = vec4(0); // speccolor, spec
+ frag_data[2] = vec4(encode_normal(screenspacewavef.xyz*0.5+0.5), 0.05, 0);// normalxy, 0, 0
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl
index ece34dcc4e..9734acf005 100755
--- a/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl
@@ -85,7 +85,7 @@ void main()
pos.w = 1.0;
pos = modelview_matrix*pos;
- calcAtmospherics(view.xyz);
+ calcAtmospherics(pos.xyz);
//pass wave parameters to pixel shader
vec2 bigWave = (v.xy) * vec2(0.04,0.04) + d1 * time * 0.055;
diff --git a/indra/newview/app_settings/shaders/class1/interface/downsampleDepthF.glsl b/indra/newview/app_settings/shaders/class1/interface/downsampleDepthF.glsl
index 6523a06d22..f8efd7cb4a 100644
--- a/indra/newview/app_settings/shaders/class1/interface/downsampleDepthF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/downsampleDepthF.glsl
@@ -31,8 +31,6 @@ out vec4 frag_color;
uniform sampler2D depthMap;
-uniform float delta;
-
VARYING vec2 tc0;
VARYING vec2 tc1;
VARYING vec2 tc2;
diff --git a/indra/newview/app_settings/shaders/class1/interface/downsampleDepthRectF.glsl b/indra/newview/app_settings/shaders/class1/interface/downsampleDepthRectF.glsl
index 0e5dc08183..942c5888e7 100644
--- a/indra/newview/app_settings/shaders/class1/interface/downsampleDepthRectF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/downsampleDepthRectF.glsl
@@ -33,8 +33,6 @@ out vec4 frag_color;
uniform sampler2DRect depthMap;
-uniform float delta;
-
VARYING vec2 tc0;
VARYING vec2 tc1;
VARYING vec2 tc2;
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl
index eaaa7b208d..cad5b9ff04 100755
--- a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl
@@ -41,13 +41,13 @@ void default_lighting()
{
vec4 color = diffuseLookup(vary_texcoord0.xy);
+ color *= vertex_color;
+
if (color.a < minimum_alpha)
{
discard;
}
- color.rgb *= vertex_color.rgb;
-
color.rgb = atmosLighting(color.rgb);
color.rgb = scaleSoftClip(color.rgb);
diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl
deleted file mode 100755
index 13c6ffc607..0000000000
--- a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl
+++ /dev/null
@@ -1,224 +0,0 @@
-/**
- * @file alphaV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat3 normal_matrix;
-uniform mat4 texture_matrix0;
-uniform mat4 projection_matrix;
-uniform mat4 modelview_matrix;
-uniform mat4 modelview_projection_matrix;
-
-ATTRIBUTE vec3 position;
-
-#ifdef USE_INDEXED_TEX
-void passTextureIndex();
-#endif
-
-ATTRIBUTE vec3 normal;
-
-#ifdef USE_VERTEX_COLOR
-ATTRIBUTE vec4 diffuse_color;
-#endif
-
-ATTRIBUTE vec2 texcoord0;
-
-#ifdef HAS_SKIN
-mat4 getObjectSkinnedTransform();
-#else
-#ifdef IS_AVATAR_SKIN
-mat4 getSkinnedTransform();
-#endif
-#endif
-
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
-void calcAtmospherics(vec3 inPositionEye);
-
-vec3 calcDirectionalLight(vec3 n, vec3 l);
-
-vec3 atmosAmbient(vec3 light);
-vec3 atmosAffectDirectionalLight(float lightIntensity);
-vec3 scaleDownLight(vec3 light);
-vec3 scaleUpLight(vec3 light);
-
-VARYING vec3 vary_ambient;
-VARYING vec3 vary_directional;
-VARYING vec3 vary_fragcoord;
-VARYING vec3 vary_position;
-VARYING vec3 vary_pointlight_col;
-
-#ifdef USE_VERTEX_COLOR
-VARYING vec4 vertex_color;
-#endif
-
-VARYING vec2 vary_texcoord0;
-VARYING vec3 vary_norm;
-
-uniform float near_clip;
-uniform float shadow_offset;
-uniform float shadow_bias;
-
-uniform vec4 light_position[8];
-uniform vec3 light_direction[8];
-uniform vec3 light_attenuation[8];
-uniform vec3 light_diffuse[8];
-
-uniform vec3 sun_dir;
-
-vec3 calcDirectionalLight(vec3 n, vec3 l)
-{
- float a = max(dot(n,l),0.0);
- return vec3(a,a,a);
-}
-
-vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
-{
- //get light vector
- vec3 lv = lp.xyz-v;
-
- //get distance
- float d = dot(lv,lv);
-
- float da = 0.0;
-
- if (d > 0.0 && la > 0.0 && fa > 0.0)
- {
- //normalize light vector
- lv = normalize(lv);
-
- //distance attenuation
- float dist2 = d/la;
- da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
-
- // spotlight coefficient.
- float spot = max(dot(-ln, lv), is_pointlight);
- da *= spot*spot; // GL_SPOT_EXPONENT=2
-
- //angular attenuation
- da *= max(dot(n, lv), 0.0);
- }
-
- return vec3(da,da,da);
-}
-
-void main()
-{
- vec4 pos;
- vec3 norm;
-
- //transform vertex
-#ifdef HAS_SKIN
- mat4 trans = getObjectSkinnedTransform();
- trans = modelview_matrix * trans;
-
- pos = trans * vec4(position.xyz, 1.0);
-
- norm = position.xyz + normal.xyz;
- norm = normalize((trans * vec4(norm, 1.0)).xyz - pos.xyz);
- vec4 frag_pos = projection_matrix * pos;
- gl_Position = frag_pos;
-#else
-
-#ifdef IS_AVATAR_SKIN
- mat4 trans = getSkinnedTransform();
- vec4 pos_in = vec4(position.xyz, 1.0);
- pos.x = dot(trans[0], pos_in);
- pos.y = dot(trans[1], pos_in);
- pos.z = dot(trans[2], pos_in);
- pos.w = 1.0;
-
- norm.x = dot(trans[0].xyz, normal);
- norm.y = dot(trans[1].xyz, normal);
- norm.z = dot(trans[2].xyz, normal);
- norm = normalize(norm);
-
- vec4 frag_pos = projection_matrix * pos;
- gl_Position = frag_pos;
-#else
- norm = normalize(normal_matrix * normal);
- vec4 vert = vec4(position.xyz, 1.0);
- pos = (modelview_matrix * vert);
- gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
-#endif
-
-#endif
-
-#ifdef USE_INDEXED_TEX
- passTextureIndex();
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-#else
- vary_texcoord0 = texcoord0;
-#endif
-
- vary_norm = norm;
- float dp_directional_light = max(0.0, dot(norm, light_position[0].xyz));
- vary_position = pos.xyz + light_position[0].xyz * (1.0-dp_directional_light)*shadow_offset;
-
- calcAtmospherics(pos.xyz);
-
-#ifndef USE_VERTEX_COLOR
- vec4 diffuse_color = vec4(1,1,1,1);
-#endif
-
- //vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.));
- vec4 col = vec4(0.0, 0.0, 0.0, diffuse_color.a);
-
- vec3 dff = pow(diffuse_color.rgb, vec3(2.2f,2.2f,2.2f));
-
- vary_pointlight_col = dff;
-
- col.rgb = vec3(0,0,0);
-
- // Add windlight lights
- col.rgb = atmosAmbient(col.rgb);
-
- float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
- ambient *= 0.5;
- ambient *= ambient;
- ambient = (1.0-ambient);
-
- col.rgb *= ambient;
-
- vary_directional.rgb = atmosAffectDirectionalLight(1.0f);
- vary_ambient = col.rgb*dff;
-
- col.rgb = col.rgb*dff;
-
-#ifdef USE_VERTEX_COLOR
- vertex_color = col;
-#endif
-
-#ifdef HAS_SKIN
- vary_fragcoord.xyz = frag_pos.xyz + vec3(0,0,near_clip);
-#else
-
-#ifdef IS_AVATAR_SKIN
- vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip);
-#else
- pos = modelview_projection_matrix * vert;
- vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip);
-#endif
-
-#endif
-
-}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
index 780df9ed1a..df750d3cec 100755
--- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
@@ -68,22 +68,43 @@ uniform vec2 screen_res;
uniform mat4 inv_proj;
-#ifdef SINGLE_FP_ONLY
-vec2 encode_normal(vec3 n)
+vec3 srgb_to_linear(vec3 cs)
{
- vec2 sn;
- sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
- return sn;
+ vec3 low_range = cs / vec3(12.92);
+ vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
+ bvec3 lte = lessThanEqual(cs,vec3(0.04045));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lte.r ? low_range.r : high_range.r;
+ result.g = lte.g ? low_range.g : high_range.g;
+ result.b = lte.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lte);
+#endif
+
}
-vec3 decode_normal (vec2 enc)
+vec3 linear_to_srgb(vec3 cl)
{
- vec3 n;
- n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
- n.z = sqrt(1.0f - dot(n.xy,n.xy));
- return n;
-}
+ cl = clamp(cl, vec3(0), vec3(1));
+ vec3 low_range = cl * 12.92;
+ vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
+ bvec3 lt = lessThan(cl,vec3(0.0031308));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lt.r ? low_range.r : high_range.r;
+ result.g = lt.g ? low_range.g : high_range.g;
+ result.b = lt.b ? low_range.b : high_range.b;
+ return result;
#else
+ return mix(high_range, low_range, lt);
+#endif
+
+}
+
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
@@ -100,14 +121,12 @@ vec3 decode_normal (vec2 enc)
n.z = 1-f/2;
return n;
}
-#endif
vec4 correctWithGamma(vec4 col)
{
- return vec4(pow(col.rgb, vec3(2.2)), col.a);
+ return vec4(srgb_to_linear(col.rgb), col.a);
}
-
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
@@ -335,6 +354,10 @@ void main()
}
}
+
+ //not sure why, but this line prevents MATBUG-194
+ col = max(col, vec3(0.0));
+
frag_color.rgb = col;
frag_color.a = 0.0;
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
index 67bac1f7c2..cc34285d65 100755
--- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
@@ -78,22 +78,43 @@ vec3 vary_AtmosAttenuation;
uniform mat4 inv_proj;
uniform vec2 screen_res;
-#ifdef SINGLE_FP_ONLY
-vec2 encode_normal(vec3 n)
+vec3 srgb_to_linear(vec3 cs)
{
- vec2 sn;
- sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
- return sn;
+ vec3 low_range = cs / vec3(12.92);
+ vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
+ bvec3 lte = lessThanEqual(cs,vec3(0.04045));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lte.r ? low_range.r : high_range.r;
+ result.g = lte.g ? low_range.g : high_range.g;
+ result.b = lte.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lte);
+#endif
+
}
-vec3 decode_normal (vec2 enc)
+vec3 linear_to_srgb(vec3 cl)
{
- vec3 n;
- n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
- n.z = sqrt(1.0f - dot(n.xy,n.xy));
- return n;
-}
+ cl = clamp(cl, vec3(0), vec3(1));
+ vec3 low_range = cl * 12.92;
+ vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
+ bvec3 lt = lessThan(cl,vec3(0.0031308));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lt.r ? low_range.r : high_range.r;
+ result.g = lt.g ? low_range.g : high_range.g;
+ result.b = lt.b ? low_range.b : high_range.b;
+ return result;
#else
+ return mix(high_range, low_range, lt);
+#endif
+
+}
+
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
@@ -110,7 +131,6 @@ vec3 decode_normal (vec2 enc)
n.z = 1-f/2;
return n;
}
-#endif
vec4 getPosition_d(vec2 pos_screen, float depth)
{
@@ -263,6 +283,52 @@ void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1));
}
+#ifdef WATER_FOG
+uniform vec4 waterPlane;
+uniform vec4 waterFogColor;
+uniform float waterFogDensity;
+uniform float waterFogKS;
+
+vec4 applyWaterFogDeferred(vec3 pos, vec4 color)
+{
+ //normalize view vector
+ vec3 view = normalize(pos);
+ float es = -(dot(view, waterPlane.xyz));
+
+ //find intersection point with water plane and eye vector
+
+ //get eye depth
+ float e0 = max(-waterPlane.w, 0.0);
+
+ vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0);
+
+ //get object depth
+ float depth = length(pos - int_v);
+
+ //get "thickness" of water
+ float l = max(depth, 0.1);
+
+ float kd = waterFogDensity;
+ float ks = waterFogKS;
+ vec4 kc = waterFogColor;
+
+ float F = 0.98;
+
+ float t1 = -kd * pow(F, ks * e0);
+ float t2 = kd + ks * es;
+ float t3 = pow(F, t2*l) - 1.0;
+
+ float L = min(t1/t2*t3, 1.0);
+
+ float D = pow(0.98, l*kd);
+
+ color.rgb = color.rgb * D + kc.rgb * L;
+ color.a = kc.a + color.a;
+
+ return color;
+}
+#endif
+
vec3 atmosLighting(vec3 light)
{
light *= getAtmosAttenuation().r;
@@ -343,7 +409,7 @@ void main()
vec4 diffuse = texture2DRect(diffuseRect, tc);
//convert to gamma space
- diffuse.rgb = pow(diffuse.rgb, vec3(1.0/2.2));
+ diffuse.rgb = linear_to_srgb(diffuse.rgb);
vec3 col;
float bloom = 0.0;
@@ -402,19 +468,25 @@ void main()
envIntensity);
}
-
+
if (norm.w < 0.5)
{
col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a);
col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);
}
- col = pow(col, vec3(2.2));
+ #ifdef WATER_FOG
+ vec4 fogged = applyWaterFogDeferred(pos,vec4(col, bloom));
+ col = fogged.rgb;
+ bloom = fogged.a;
+ #endif
+
+ col = srgb_to_linear(col);
//col = vec3(1,0,1);
//col.g = envIntensity;
}
-
+
frag_color.rgb = col;
frag_color.a = bloom;
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
index fc0e6b2388..bb6afbbf62 100755
--- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
@@ -68,22 +68,6 @@ uniform vec2 screen_res;
uniform mat4 inv_proj;
-#ifdef SINGLE_FP_ONLY
-vec2 encode_normal(vec3 n)
-{
- vec2 sn;
- sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
- return sn;
-}
-
-vec3 decode_normal (vec2 enc)
-{
- vec3 n;
- n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
- n.z = sqrt(1.0f - dot(n.xy,n.xy));
- return n;
-}
-#else
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
@@ -100,11 +84,47 @@ vec3 decode_normal (vec2 enc)
n.z = 1-f/2;
return n;
}
+
+vec3 srgb_to_linear(vec3 cs)
+{
+ vec3 low_range = cs / vec3(12.92);
+ vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
+ bvec3 lte = lessThanEqual(cs,vec3(0.04045));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lte.r ? low_range.r : high_range.r;
+ result.g = lte.g ? low_range.g : high_range.g;
+ result.b = lte.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lte);
+#endif
+
+}
+
+vec3 linear_to_srgb(vec3 cl)
+{
+ cl = clamp(cl, vec3(0), vec3(1));
+ vec3 low_range = cl * 12.92;
+ vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
+ bvec3 lt = lessThan(cl,vec3(0.0031308));
+
+#ifdef OLD_SELECT
+ vec3 result;
+ result.r = lt.r ? low_range.r : high_range.r;
+ result.g = lt.g ? low_range.g : high_range.g;
+ result.b = lt.b ? low_range.b : high_range.b;
+ return result;
+#else
+ return mix(high_range, low_range, lt);
#endif
+}
+
vec4 correctWithGamma(vec4 col)
{
- return vec4(pow(col.rgb, vec3(2.2)), col.a);
+ return vec4(srgb_to_linear(col.rgb), col.a);
}
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
@@ -332,7 +352,10 @@ void main()
}
}
}
-
+
+ //not sure why, but this line prevents MATBUG-194
+ col = max(col, vec3(0.0));
+
frag_color.rgb = col;
frag_color.a = 0.0;
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
index 7b09dd29dd..95c09d3238 100755
--- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
@@ -65,22 +65,6 @@ uniform float shadow_offset;
uniform float spot_shadow_bias;
uniform float spot_shadow_offset;
-#ifdef SINGLE_FP_ONLY
-vec2 encode_normal(vec3 n)
-{
- vec2 sn;
- sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
- return sn;
-}
-
-vec3 decode_normal (vec2 enc)
-{
- vec3 n;
- n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
- n.z = sqrt(1.0f - dot(n.xy,n.xy));
- return n;
-}
-#else
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
@@ -97,7 +81,6 @@ vec3 decode_normal (vec2 enc)
n.z = 1-f/2;
return n;
}
-#endif
vec4 getPosition(vec2 pos_screen)
{
diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl
index 01e34ed792..b5ff6404ea 100755
--- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl
@@ -66,22 +66,6 @@ uniform float shadow_offset;
uniform float spot_shadow_bias;
uniform float spot_shadow_offset;
-#ifdef SINGLE_FP_ONLY
-vec2 encode_normal(vec3 n)
-{
- vec2 sn;
- sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
- return sn;
-}
-
-vec3 decode_normal (vec2 enc)
-{
- vec3 n;
- n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
- n.z = sqrt(1.0f - dot(n.xy,n.xy));
- return n;
-}
-#else
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
@@ -98,7 +82,6 @@ vec3 decode_normal (vec2 enc)
n.z = 1-f/2;
return n;
}
-#endif
vec4 getPosition(vec2 pos_screen)
{
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index 1c0d45c11b..0bdd425504 100755
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -309,8 +309,8 @@ RenderVolumeLODFactor 1 2.0
VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
WLSkyDetail 1 128
-RenderDeferred 1 0
-RenderDeferredSSAO 1 0
+RenderDeferred 1 1
+RenderDeferredSSAO 1 1
RenderShadowDetail 1 2
RenderFSAASamples 1 2
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index 8c9fd4152a..2a333157f2 100755
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -527,6 +527,8 @@ void LLDrawable::makeStatic(BOOL warning_enabled)
}
updatePartition();
}
+
+ llassert(isAvatar() || isRoot() || mParent->isStatic());
}
// Returns "distance" between target destination and resulting xfrom
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index c832e1401d..5ebc58fb7d 100755
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -93,15 +93,35 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
if (pass == 0)
{
- simple_shader = &gDeferredAlphaProgram;
- fullbright_shader = &gObjectFullbrightProgram;
+ if (LLPipeline::sImpostorRender)
+ {
+ simple_shader = &gDeferredAlphaImpostorProgram;
+ fullbright_shader = &gDeferredFullbrightProgram;
+ }
+ else if (LLPipeline::sUnderWaterRender)
+ {
+ simple_shader = &gDeferredAlphaWaterProgram;
+ fullbright_shader = &gDeferredFullbrightWaterProgram;
+ }
+ else
+ {
+ simple_shader = &gDeferredAlphaProgram;
+ fullbright_shader = &gDeferredFullbrightProgram;
+ }
+
+ F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
+
fullbright_shader->bind();
fullbright_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ fullbright_shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
fullbright_shader->unbind();
+
//prime simple shader (loads shadow relevant uniforms)
gPipeline.bindDeferredShader(*simple_shader);
+
+ simple_shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
}
- else
+ else if (!LLPipeline::sImpostorRender)
{
//update depth buffer sampler
gPipeline.mScreen.flush();
@@ -113,6 +133,23 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
gObjectFullbrightAlphaMaskProgram.setMinimumAlpha(0.33f);
}
+
+ if (LLPipeline::sRenderDeferred)
+ {
+ emissive_shader = &gDeferredEmissiveProgram;
+ }
+ else
+ {
+ if (LLPipeline::sUnderWaterRender)
+ {
+ emissive_shader = &gObjectEmissiveWaterProgram;
+ }
+ else
+ {
+ emissive_shader = &gObjectEmissiveProgram;
+ }
+ }
+
deferred_render = TRUE;
if (mVertexShaderLevel > 0)
{
@@ -124,7 +161,7 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
void LLDrawPoolAlpha::endPostDeferredPass(S32 pass)
{
- if (pass == 1)
+ if (pass == 1 && !LLPipeline::sImpostorRender)
{
gPipeline.mDeferredDepth.flush();
gPipeline.mScreen.bindTarget();
@@ -144,7 +181,13 @@ void LLDrawPoolAlpha::beginRenderPass(S32 pass)
{
LLFastTimer t(FTM_RENDER_ALPHA);
- if (LLPipeline::sUnderWaterRender)
+ if (LLPipeline::sImpostorRender)
+ {
+ simple_shader = &gObjectSimpleImpostorProgram;
+ fullbright_shader = &gObjectFullbrightProgram;
+ emissive_shader = &gObjectEmissiveProgram;
+ }
+ else if (LLPipeline::sUnderWaterRender)
{
simple_shader = &gObjectSimpleWaterProgram;
fullbright_shader = &gObjectFullbrightWaterProgram;
@@ -192,8 +235,13 @@ void LLDrawPoolAlpha::render(S32 pass)
gGL.setColorMask(true, true);
}
- LLGLDepthTest depth(GL_TRUE, LLDrawPoolWater::sSkipScreenCopy ||
- (deferred_render && pass == 1) ? GL_TRUE : GL_FALSE);
+ bool write_depth = LLDrawPoolWater::sSkipScreenCopy
+ || (deferred_render && pass == 1)
+ // we want depth written so that rendered alpha will
+ // contribute to the alpha mask used for impostors
+ || LLPipeline::sImpostorRenderAlphaDepthPass;
+
+ LLGLDepthTest depth(GL_TRUE, write_depth ? GL_TRUE : GL_FALSE);
if (deferred_render && pass == 1)
{
@@ -352,7 +400,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
LLMaterial* mat = NULL;
- if (deferred_render && !LLPipeline::sUnderWaterRender)
+ if (deferred_render)
{
mat = params.mMaterial;
}
@@ -396,6 +444,11 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
llassert(mask < LLMaterial::SHADER_COUNT);
target_shader = &(gDeferredMaterialProgram[mask]);
+ if (LLPipeline::sUnderWaterRender)
+ {
+ target_shader = &(gDeferredMaterialWaterProgram[mask]);
+ }
+
if (current_shader != target_shader)
{
gPipeline.bindDeferredShader(*target_shader);
@@ -500,12 +553,14 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
}
}
- params.mVertexBuffer->setBuffer(mask);
+ params.mVertexBuffer->setBuffer(mask & ~(params.mFullbright ? (LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2) : 0));
+
params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
// If this alpha mesh has glow, then draw it a second time to add the destination-alpha (=glow). Interleaving these state-changing calls could be expensive, but glow must be drawn Z-sorted with alpha.
- if (current_shader &&
+ if (current_shader &&
+ !LLPipeline::sImpostorRender &&
draw_glow_for_this_partition &&
params.mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE))
{
@@ -515,7 +570,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
emissive_shader->bind();
- // glow doesn't use vertex colors from the mesh data
params.mVertexBuffer->setBuffer((mask & ~LLVertexBuffer::MAP_COLOR) | LLVertexBuffer::MAP_EMISSIVE);
// do the actual drawing, again
@@ -545,3 +599,4 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
gPipeline.enableLightsDynamic();
}
}
+
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index a0024a231c..120920a4b0 100755
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -49,6 +49,7 @@
#include "llappviewer.h"
#include "llrendersphere.h"
#include "llviewerpartsim.h"
+#include "llviewercontrol.h" // for gSavedSettings
static U32 sDataMask = LLDrawPoolAvatar::VERTEX_DATA_MASK;
static U32 sBufferUsage = GL_STREAM_DRAW_ARB;
@@ -135,16 +136,6 @@ void LLDrawPoolAvatar::prerender()
{
sBufferUsage = GL_STREAM_DRAW_ARB;
}
-
- if (!mDrawFace.empty())
- {
- const LLFace *facep = mDrawFace[0];
- if (facep && facep->getDrawable())
- {
- LLVOAvatar* avatarp = (LLVOAvatar *)facep->getDrawable()->getVObj().get();
- updateRiggedVertexBuffers(avatarp);
- }
- }
}
LLMatrix4& LLDrawPoolAvatar::getModelView()
@@ -309,6 +300,11 @@ void LLDrawPoolAvatar::beginDeferredRiggedMaterialAlpha(S32 pass)
sVertexProgram = &gDeferredMaterialProgram[pass];
+ if (LLPipeline::sUnderWaterRender)
+ {
+ sVertexProgram = &(gDeferredMaterialWaterProgram[pass]);
+ }
+
gPipeline.bindDeferredShader(*sVertexProgram);
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP);
@@ -501,7 +497,7 @@ S32 LLDrawPoolAvatar::getNumDeferredPasses()
{
if (LLPipeline::sImpostorRender)
{
- return 3;
+ return 19;
}
else
{
@@ -687,12 +683,10 @@ void LLDrawPoolAvatar::beginDeferredImpostor()
}
sVertexProgram = &gDeferredImpostorProgram;
-
specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP);
normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::DEFERRED_NORMAL);
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
-
- sVertexProgram->bind();
+ gPipeline.bindDeferredShader(*sVertexProgram);
sVertexProgram->setMinimumAlpha(0.01f);
}
@@ -702,8 +696,9 @@ void LLDrawPoolAvatar::endDeferredImpostor()
sVertexProgram->disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL);
sVertexProgram->disableTexture(LLViewerShaderMgr::SPECULAR_MAP);
sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
- sVertexProgram->unbind();
- gGL.getTexUnit(0)->activate();
+ gPipeline.unbindDeferredShader(*sVertexProgram);
+ sVertexProgram = NULL;
+ sDiffuseChannel = 0;
}
void LLDrawPoolAvatar::beginDeferredRigid()
@@ -891,6 +886,8 @@ void LLDrawPoolAvatar::beginRiggedGlow()
sVertexProgram->bind();
sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, LLPipeline::sRenderDeferred ? 2.2f : 1.1f);
+ F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
+ sVertexProgram->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
}
}
@@ -943,6 +940,9 @@ void LLDrawPoolAvatar::beginRiggedFullbright()
else
{
sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+
+ F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
+ sVertexProgram->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
}
}
}
@@ -1044,6 +1044,8 @@ void LLDrawPoolAvatar::beginRiggedFullbrightShiny()
else
{
sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
+ sVertexProgram->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
}
}
}
@@ -1103,6 +1105,12 @@ void LLDrawPoolAvatar::beginDeferredRiggedMaterial(S32 pass)
return;
}
sVertexProgram = &gDeferredMaterialProgram[pass+LLMaterial::SHADER_COUNT];
+
+ if (LLPipeline::sUnderWaterRender)
+ {
+ sVertexProgram = &(gDeferredMaterialWaterProgram[pass+LLMaterial::SHADER_COUNT]);
+ }
+
sVertexProgram->bind();
normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP);
specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP);
@@ -1445,63 +1453,63 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
}
void LLDrawPoolAvatar::getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>& buffer, U32 data_mask, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face)
-{
- face->setGeomIndex(0);
- face->setIndicesIndex(0);
+ {
+ face->setGeomIndex(0);
+ face->setIndicesIndex(0);
- //rigged faces do not batch textures
- face->setTextureIndex(255);
+ //rigged faces do not batch textures
+ face->setTextureIndex(255);
- if (buffer.isNull() || buffer->getTypeMask() != data_mask || !buffer->isWriteable())
- { //make a new buffer
- if (sShaderLevel > 0)
- {
- buffer = new LLVertexBuffer(data_mask, GL_DYNAMIC_DRAW_ARB);
+ if (buffer.isNull() || buffer->getTypeMask() != data_mask || !buffer->isWriteable())
+ { //make a new buffer
+ if (sShaderLevel > 0)
+ {
+ buffer = new LLVertexBuffer(data_mask, GL_DYNAMIC_DRAW_ARB);
+ }
+ else
+ {
+ buffer = new LLVertexBuffer(data_mask, GL_STREAM_DRAW_ARB);
+ }
+ buffer->allocateBuffer(vol_face.mNumVertices, vol_face.mNumIndices, true);
}
else
- {
- buffer = new LLVertexBuffer(data_mask, GL_STREAM_DRAW_ARB);
+ { //resize existing buffer
+ buffer->resizeBuffer(vol_face.mNumVertices, vol_face.mNumIndices);
}
- buffer->allocateBuffer(vol_face.mNumVertices, vol_face.mNumIndices, true);
- }
- else
- { //resize existing buffer
- buffer->resizeBuffer(vol_face.mNumVertices, vol_face.mNumIndices);
- }
- face->setSize(vol_face.mNumVertices, vol_face.mNumIndices);
- face->setVertexBuffer(buffer);
+ face->setSize(vol_face.mNumVertices, vol_face.mNumIndices);
+ face->setVertexBuffer(buffer);
- U16 offset = 0;
+ U16 offset = 0;
- LLMatrix4 mat_vert = skin->mBindShapeMatrix;
- glh::matrix4f m((F32*) mat_vert.mMatrix);
- m = m.inverse().transpose();
+ LLMatrix4 mat_vert = skin->mBindShapeMatrix;
+ glh::matrix4f m((F32*) mat_vert.mMatrix);
+ m = m.inverse().transpose();
- F32 mat3[] =
- { m.m[0], m.m[1], m.m[2],
- m.m[4], m.m[5], m.m[6],
- m.m[8], m.m[9], m.m[10] };
+ F32 mat3[] =
+ { m.m[0], m.m[1], m.m[2],
+ m.m[4], m.m[5], m.m[6],
+ m.m[8], m.m[9], m.m[10] };
- LLMatrix3 mat_normal(mat3);
+ LLMatrix3 mat_normal(mat3);
- //let getGeometryVolume know if alpha should override shiny
- U32 type = gPipeline.getPoolTypeFromTE(face->getTextureEntry(), face->getTexture());
+ //let getGeometryVolume know if alpha should override shiny
+ U32 type = gPipeline.getPoolTypeFromTE(face->getTextureEntry(), face->getTexture());
- if (type == LLDrawPool::POOL_ALPHA)
- {
- face->setPoolType(LLDrawPool::POOL_ALPHA);
- }
- else
- {
- face->setPoolType(LLDrawPool::POOL_AVATAR);
- }
+ if (type == LLDrawPool::POOL_ALPHA)
+ {
+ face->setPoolType(LLDrawPool::POOL_ALPHA);
+ }
+ else
+ {
+ face->setPoolType(LLDrawPool::POOL_AVATAR);
+ }
//llinfos << "Rebuilt face " << face->getTEOffset() << " of " << face->getDrawable() << " at " << gFrameTimeSeconds << llendl;
- face->getGeometryVolume(*volume, face->getTEOffset(), mat_vert, mat_normal, offset, true);
+ face->getGeometryVolume(*volume, face->getTEOffset(), mat_vert, mat_normal, offset, true);
- buffer->flush();
-}
+ buffer->flush();
+ }
void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* face, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face)
{
diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp
index 08a36bddf1..d1b5080650 100644
--- a/indra/newview/lldrawpoolmaterials.cpp
+++ b/indra/newview/lldrawpoolmaterials.cpp
@@ -72,6 +72,12 @@ void LLDrawPoolMaterials::beginDeferredPass(S32 pass)
};
mShader = &(gDeferredMaterialProgram[shader_idx[pass]]);
+
+ if (LLPipeline::sUnderWaterRender)
+ {
+ mShader = &(gDeferredMaterialWaterProgram[shader_idx[pass]]);
+ }
+
mShader->bind();
diffuse_channel = mShader->enableTexture(LLShaderMgr::DIFFUSE_MAP);
@@ -215,3 +221,4 @@ void LLDrawPoolMaterials::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture,
gGL.matrixMode(LLRender::MM_MODELVIEW);
}
}
+
diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp
index 2cf9d833c6..8926f64c64 100755
--- a/indra/newview/lldrawpoolsimple.cpp
+++ b/indra/newview/lldrawpoolsimple.cpp
@@ -37,6 +37,7 @@
#include "llviewershadermgr.h"
#include "llrender.h"
+#define GE_FORCE_WORKAROUND LL_DARWIN
static LLGLSLShader* simple_shader = NULL;
static LLGLSLShader* fullbright_shader = NULL;
@@ -111,7 +112,14 @@ void LLDrawPoolGlow::render(S32 pass)
LLGLSLShader* shader = LLPipeline::sUnderWaterRender ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;
shader->bind();
- shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.f);
+ if (LLPipeline::sRenderDeferred)
+ {
+ shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ }
+ else
+ {
+ shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.f);
+ }
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
gGL.setColorMask(false, true);
@@ -148,7 +156,11 @@ void LLDrawPoolSimple::beginRenderPass(S32 pass)
{
LLFastTimer t(FTM_RENDER_SIMPLE);
- if (LLPipeline::sUnderWaterRender)
+ if (LLPipeline::sImpostorRender)
+ {
+ simple_shader = &gObjectSimpleImpostorProgram;
+ }
+ else if (LLPipeline::sUnderWaterRender)
{
simple_shader = &gObjectSimpleWaterProgram;
}
@@ -536,7 +548,15 @@ void LLDrawPoolFullbright::prerender()
void LLDrawPoolFullbright::beginPostDeferredPass(S32 pass)
{
- gDeferredFullbrightProgram.bind();
+ if (LLPipeline::sUnderWaterRender)
+ {
+ gDeferredFullbrightWaterProgram.bind();
+ }
+ else
+ {
+ gDeferredFullbrightProgram.bind();
+ }
+
}
void LLDrawPoolFullbright::renderPostDeferred(S32 pass)
@@ -550,7 +570,14 @@ void LLDrawPoolFullbright::renderPostDeferred(S32 pass)
void LLDrawPoolFullbright::endPostDeferredPass(S32 pass)
{
- gDeferredFullbrightProgram.unbind();
+ if (LLPipeline::sUnderWaterRender)
+ {
+ gDeferredFullbrightWaterProgram.unbind();
+ }
+ else
+ {
+ gDeferredFullbrightProgram.unbind();
+ }
LLRenderPass::endRenderPass(pass);
}
@@ -625,15 +652,35 @@ S32 LLDrawPoolFullbright::getNumPasses()
void LLDrawPoolFullbrightAlphaMask::beginPostDeferredPass(S32 pass)
{
- gObjectFullbrightAlphaMaskProgram.bind();
+
if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred)
{
+ gObjectFullbrightAlphaMaskProgram.bind();
gObjectFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
}
else
- {
+ {
+
+// Work-around until we can figure out why the right shader causes
+// the GeForce driver to go tango uniform on OS X 10.6.8 only
+//
+#if GE_FORCE_WORKAROUND
+ gObjectFullbrightAlphaMaskProgram.bind();
gObjectFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+#else
+ if (LLPipeline::sUnderWaterRender)
+ {
+ gDeferredFullbrightAlphaMaskWaterProgram.bind();
+ gDeferredFullbrightAlphaMaskWaterProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ }
+ else
+ {
+ gDeferredFullbrightAlphaMaskProgram.bind();
+ gDeferredFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
+ }
+#endif
}
+
}
void LLDrawPoolFullbrightAlphaMask::renderPostDeferred(S32 pass)
@@ -646,7 +693,30 @@ void LLDrawPoolFullbrightAlphaMask::renderPostDeferred(S32 pass)
void LLDrawPoolFullbrightAlphaMask::endPostDeferredPass(S32 pass)
{
- gObjectFullbrightAlphaMaskProgram.unbind();
+ if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred)
+ {
+ gObjectFullbrightAlphaMaskProgram.unbind();
+ }
+ else
+ {
+
+// Work-around until we can figure out why the right shader causes
+// the GeForce driver to go tango uniform on OS X 10.6.8 only
+//
+#if GE_FORCE_WORKAROUND
+ gObjectFullbrightAlphaMaskProgram.unbind();
+#else
+ if (LLPipeline::sUnderWaterRender)
+ {
+ gDeferredFullbrightAlphaMaskWaterProgram.unbind();
+ }
+ else
+ {
+ gDeferredFullbrightAlphaMaskProgram.unbind();
+ }
+#endif
+
+ }
LLRenderPass::endRenderPass(pass);
}
diff --git a/indra/newview/lldrawpoolsky.cpp b/indra/newview/lldrawpoolsky.cpp
index 7f7d9f65c6..ef8bdc3304 100755
--- a/indra/newview/lldrawpoolsky.cpp
+++ b/indra/newview/lldrawpoolsky.cpp
@@ -155,3 +155,4 @@ void LLDrawPoolSky::renderSkyCubeFace(U8 side)
void LLDrawPoolSky::endRenderPass( S32 pass )
{
}
+
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index 5ddc15df42..6774926f62 100755
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -522,13 +522,20 @@ void LLDrawPoolWater::shade()
F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - gAgent.getRegion()->getWaterHeight();
- if (deferred_render)
+ if (eyedepth < 0.f && LLPipeline::sWaterReflections)
{
- shader = &gDeferredWaterProgram;
+ if (deferred_render)
+ {
+ shader = &gDeferredUnderWaterProgram;
+ }
+ else
+ {
+ shader = &gUnderWaterProgram;
+ }
}
- else if (eyedepth < 0.f && LLPipeline::sWaterReflections)
+ else if (deferred_render)
{
- shader = &gUnderWaterProgram;
+ shader = &gDeferredWaterProgram;
}
else
{
diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp
index b5faff7968..53339222eb 100755
--- a/indra/newview/lldrawpoolwlsky.cpp
+++ b/indra/newview/lldrawpoolwlsky.cpp
@@ -420,3 +420,4 @@ void LLDrawPoolWLSky::restoreGL()
sCloudNoiseTexture = LLViewerTextureManager::getLocalTexture(sCloudNoiseRawImage.get(), TRUE);
}
}
+
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 9b2b778677..700b31f8d3 100755
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -768,7 +768,7 @@ bool less_than_max_mag(const LLVector4a& vec)
}
BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
- const LLMatrix4& mat_vert_in, BOOL global_volume)
+ const LLMatrix4& mat_vert_in, const LLMatrix3& mat_normal_in, BOOL global_volume)
{
//get bounding box
if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED))
@@ -777,6 +777,10 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
LLMatrix4a mat_vert;
mat_vert.loadu(mat_vert_in);
+ LLMatrix4a mat_normal;
+ mat_normal.loadu(mat_normal_in);
+
+ //VECTORIZE THIS
LLVector4a min,max;
if (f >= volume.getNumVolumeFaces())
@@ -793,68 +797,94 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
llassert(less_than_max_mag(max));
//min, max are in volume space, convert to drawable render space
+ LLVector4a center;
+ LLVector4a t;
+ t.setAdd(min, max);
+ t.mul(0.5f);
+ mat_vert.affineTransform(t, center);
+ LLVector4a size;
+ size.setSub(max, min);
+ size.mul(0.5f);
- //get 8 corners of bounding box
- LLVector4Logical mask[6];
+ llassert(less_than_max_mag(min));
+ llassert(less_than_max_mag(max));
- for (U32 i = 0; i < 6; ++i)
+ if (!global_volume)
{
- mask[i].clear();
+ //VECTORIZE THIS
+ LLVector4a scale;
+ scale.load3(mDrawablep->getVObj()->getScale().mV);
+ size.mul(scale);
}
- mask[0].setElement<2>(); //001
- mask[1].setElement<1>(); //010
- mask[2].setElement<1>(); //011
- mask[2].setElement<2>();
- mask[3].setElement<0>(); //100
- mask[4].setElement<0>(); //101
- mask[4].setElement<2>();
- mask[5].setElement<0>(); //110
- mask[5].setElement<1>();
+ mat_normal.mMatrix[0].normalize3fast();
+ mat_normal.mMatrix[1].normalize3fast();
+ mat_normal.mMatrix[2].normalize3fast();
- LLVector4a v[8];
+ LLVector4a v[4];
- v[6] = min;
- v[7] = max;
+ //get 4 corners of bounding box
+ mat_normal.rotate(size,v[0]);
- for (U32 i = 0; i < 6; ++i)
- {
- v[i].setSelectWithMask(mask[i], min, max);
- }
-
- LLVector4a tv[8];
+ //VECTORIZE THIS
+ LLVector4a scale;
+
+ scale.set(-1.f, -1.f, 1.f);
+ scale.mul(size);
+ mat_normal.rotate(scale, v[1]);
+
+ scale.set(1.f, -1.f, -1.f);
+ scale.mul(size);
+ mat_normal.rotate(scale, v[2]);
+
+ scale.set(-1.f, 1.f, -1.f);
+ scale.mul(size);
+ mat_normal.rotate(scale, v[3]);
- //transform bounding box into drawable space
- for (U32 i = 0; i < 8; ++i)
- {
- mat_vert.affineTransform(v[i], tv[i]);
- }
-
- //find bounding box
LLVector4a& newMin = mExtents[0];
LLVector4a& newMax = mExtents[1];
+
+ newMin = newMax = center;
+
+ llassert(less_than_max_mag(center));
+
+ for (U32 i = 0; i < 4; i++)
+ {
+ LLVector4a delta;
+ delta.setAbs(v[i]);
+ LLVector4a min;
+ min.setSub(center, delta);
+ LLVector4a max;
+ max.setAdd(center, delta);
- newMin = newMax = tv[0];
+ newMin.setMin(newMin,min);
+ newMax.setMax(newMax,max);
- for (U32 i = 1; i < 8; ++i)
- {
- newMin.setMin(newMin, tv[i]);
- newMax.setMax(newMax, tv[i]);
+ llassert(less_than_max_mag(newMin));
+ llassert(less_than_max_mag(newMax));
}
if (!mDrawablep->isActive())
- { // Shift position for region
+ {
LLVector4a offset;
offset.load3(mDrawablep->getRegion()->getOriginAgent().mV);
newMin.add(offset);
newMax.add(offset);
+
+ llassert(less_than_max_mag(newMin));
+ llassert(less_than_max_mag(newMax));
}
- LLVector4a t;
- t.setAdd(newMin,newMax);
+ t.setAdd(newMin, newMax);
t.mul(0.5f);
+ llassert(less_than_max_mag(t));
+
+ //VECTORIZE THIS
mCenterLocal.set(t.getF32ptr());
+
+ llassert(less_than_max_mag(newMin));
+ llassert(less_than_max_mag(newMax));
t.setSub(newMax,newMin);
mBoundingSphereRadius = t.getLength3().getF32()*0.5f;
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index 14923eec3c..7b25291da7 100755
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -1328,7 +1328,7 @@ void LLFloaterTools::getMediaState()
getChildView("media_tex")->setEnabled(bool_has_media && editable);
getChildView("edit_media")->setEnabled(bool_has_media && LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo && editable );
getChildView("delete_media")->setEnabled(bool_has_media && editable );
- getChildView("add_media")->setEnabled(( ! bool_has_media ) && editable );
+ getChildView("add_media")->setEnabled(editable);
// TODO: display a list of all media on the face - use 'identical' flag
}
else // not all face has media but at least one does.
@@ -1358,7 +1358,7 @@ void LLFloaterTools::getMediaState()
getChildView("media_tex")->setEnabled(TRUE);
getChildView("edit_media")->setEnabled(LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo);
getChildView("delete_media")->setEnabled(TRUE);
- getChildView("add_media")->setEnabled(FALSE );
+ getChildView("add_media")->setEnabled(editable);
}
media_info->setText(media_title);
diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h
index ecb0092a6f..189bae46c2 100755
--- a/indra/newview/llfloatertools.h
+++ b/indra/newview/llfloatertools.h
@@ -109,6 +109,8 @@ public:
static void setGridMode(S32 mode);
+ LLPanelFace* getPanelFace() { return mPanelFace; }
+
private:
void refresh();
void refreshMedia();
diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp
index 16871adc4d..658fea944d 100644
--- a/indra/newview/llmaterialmgr.cpp
+++ b/indra/newview/llmaterialmgr.cpp
@@ -51,12 +51,9 @@
#define MATERIALS_CAP_OBJECT_ID_FIELD "ID"
#define MATERIALS_CAP_MATERIAL_ID_FIELD "MaterialID"
-#define MATERIALS_GET_MAX_ENTRIES 50
#define MATERIALS_GET_TIMEOUT (60.f * 20)
-#define MATERIALS_POST_MAX_ENTRIES 50
#define MATERIALS_POST_TIMEOUT (60.f * 5)
#define MATERIALS_PUT_THROTTLE_SECS 1.f
-#define MATERIALS_PUT_MAX_ENTRIES 50
/**
* LLMaterialsResponder helper class
@@ -544,11 +541,9 @@ void LLMaterialMgr::onIdle(void*)
instancep->processGetAllQueue();
}
- static LLFrameTimer mPutTimer;
- if ( (!instancep->mPutQueue.empty()) && (mPutTimer.hasExpired()) )
+ if (!instancep->mPutQueue.empty())
{
instancep->processPutQueue();
- mPutTimer.resetWithExpiry(MATERIALS_PUT_THROTTLE_SECS);
}
}
@@ -565,14 +560,14 @@ void LLMaterialMgr::processGetQueue()
continue;
}
- const LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(region_id);
+ LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(region_id);
if (!regionp)
{
LL_WARNS("Materials") << "Unknown region with id " << region_id.asString() << LL_ENDL;
mGetQueue.erase(itRegionQueue);
continue;
}
- else if (!regionp->capabilitiesReceived())
+ else if (!regionp->capabilitiesReceived() || regionp->materialsCapThrottled())
{
continue;
}
@@ -595,8 +590,9 @@ void LLMaterialMgr::processGetQueue()
LLSD materialsData = LLSD::emptyArray();
material_queue_t& materials = itRegionQueue->second;
- material_queue_t::iterator loopMaterial = materials.begin();
- while ( (materials.end() != loopMaterial) && (materialsData.size() <= MATERIALS_GET_MAX_ENTRIES) )
+ U32 max_entries = regionp->getMaxMaterialsPerTransaction();
+ material_queue_t::iterator loopMaterial = materials.begin();
+ while ( (materials.end() != loopMaterial) && (materialsData.size() < max_entries) )
{
material_queue_t::iterator itMaterial = loopMaterial++;
materialsData.append((*itMaterial).asLLSD());
@@ -628,6 +624,7 @@ void LLMaterialMgr::processGetQueue()
LL_DEBUGS("Materials") << "POSTing to region '" << regionp->getName() << "' at '"<< capURL << " for " << materialsData.size() << " materials."
<< "\ndata: " << ll_pretty_print_sd(materialsData) << LL_ENDL;
LLHTTPClient::post(capURL, postData, materialsResponder);
+ regionp->resetMaterialsCapThrottle();
}
}
@@ -646,7 +643,7 @@ void LLMaterialMgr::processGetAllQueue()
clearGetQueues(region_id); // Invalidates region_id
continue;
}
- else if (!regionp->capabilitiesReceived())
+ else if (!regionp->capabilitiesReceived() || regionp->materialsCapThrottled())
{
continue;
}
@@ -663,6 +660,7 @@ void LLMaterialMgr::processGetAllQueue()
LL_DEBUGS("Materials") << "GET all for region " << region_id << "url " << capURL << LL_ENDL;
LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("GET", capURL, boost::bind(&LLMaterialMgr::onGetAllResponse, this, _1, _2, *itRegion));
LLHTTPClient::get(capURL, materialsResponder);
+ regionp->resetMaterialsCapThrottle();
mGetAllPending.insert(std::pair<LLUUID, F64>(region_id, LLFrameTimer::getTotalSeconds()));
mGetAllQueue.erase(itRegion); // Invalidates region_id
}
@@ -670,7 +668,7 @@ void LLMaterialMgr::processGetAllQueue()
void LLMaterialMgr::processPutQueue()
{
- typedef std::map<const LLViewerRegion*, LLSD> regionput_request_map;
+ typedef std::map<LLViewerRegion*, LLSD> regionput_request_map;
regionput_request_map requests;
put_queue_t::iterator loopQueue = mPutQueue.begin();
@@ -680,49 +678,54 @@ void LLMaterialMgr::processPutQueue()
const LLUUID& object_id = itQueue->first;
const LLViewerObject* objectp = gObjectList.findObject(object_id);
- if ( (!objectp) || (!objectp->getRegion()) )
+ if ( !objectp )
{
- LL_WARNS("Materials") << "Object or object region is NULL" << LL_ENDL;
-
+ LL_WARNS("Materials") << "Object is NULL" << LL_ENDL;
mPutQueue.erase(itQueue);
- continue;
}
-
- const LLViewerRegion* regionp = objectp->getRegion();
- if (!regionp->capabilitiesReceived())
- {
- continue;
- }
-
- LLSD& facesData = requests[regionp];
-
- facematerial_map_t& face_map = itQueue->second;
- facematerial_map_t::iterator itFace = face_map.begin();
- while ( (face_map.end() != itFace) && (facesData.size() < MATERIALS_GET_MAX_ENTRIES) )
+ else
{
- LLSD faceData = LLSD::emptyMap();
- faceData[MATERIALS_CAP_FACE_FIELD] = static_cast<LLSD::Integer>(itFace->first);
- faceData[MATERIALS_CAP_OBJECT_ID_FIELD] = static_cast<LLSD::Integer>(objectp->getLocalID());
- if (!itFace->second.isNull())
+ LLViewerRegion* regionp = objectp->getRegion();
+ if ( !regionp )
{
- faceData[MATERIALS_CAP_MATERIAL_FIELD] = itFace->second.asLLSD();
+ LL_WARNS("Materials") << "Object region is NULL" << LL_ENDL;
+ mPutQueue.erase(itQueue);
+ }
+ else if ( regionp->capabilitiesReceived() && !regionp->materialsCapThrottled())
+ {
+ LLSD& facesData = requests[regionp];
+
+ facematerial_map_t& face_map = itQueue->second;
+ U32 max_entries = regionp->getMaxMaterialsPerTransaction();
+ facematerial_map_t::iterator itFace = face_map.begin();
+ while ( (face_map.end() != itFace) && (facesData.size() < max_entries) )
+ {
+ LLSD faceData = LLSD::emptyMap();
+ faceData[MATERIALS_CAP_FACE_FIELD] = static_cast<LLSD::Integer>(itFace->first);
+ faceData[MATERIALS_CAP_OBJECT_ID_FIELD] = static_cast<LLSD::Integer>(objectp->getLocalID());
+ if (!itFace->second.isNull())
+ {
+ faceData[MATERIALS_CAP_MATERIAL_FIELD] = itFace->second.asLLSD();
+ }
+ facesData.append(faceData);
+ face_map.erase(itFace++);
+ }
+ if (face_map.empty())
+ {
+ mPutQueue.erase(itQueue);
+ }
}
- facesData.append(faceData);
- face_map.erase(itFace++);
- }
- if (face_map.empty())
- {
- mPutQueue.erase(itQueue);
}
}
for (regionput_request_map::const_iterator itRequest = requests.begin(); itRequest != requests.end(); ++itRequest)
{
- std::string capURL = itRequest->first->getCapability(MATERIALS_CAPABILITY_NAME);
+ LLViewerRegion* regionp = itRequest->first;
+ std::string capURL = regionp->getCapability(MATERIALS_CAPABILITY_NAME);
if (capURL.empty())
{
LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME
- << "' is not defined on region '" << itRequest->first->getName() << "'" << LL_ENDL;
+ << "' is not defined on region '" << regionp->getName() << "'" << LL_ENDL;
continue;
}
@@ -745,6 +748,7 @@ void LLMaterialMgr::processPutQueue()
LL_DEBUGS("Materials") << "put for " << itRequest->second.size() << " faces to region " << itRequest->first->getName() << LL_ENDL;
LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("PUT", capURL, boost::bind(&LLMaterialMgr::onPutResponse, this, _1, _2));
LLHTTPClient::put(capURL, putData, materialsResponder);
+ regionp->resetMaterialsCapThrottle();
}
else
{
@@ -773,7 +777,6 @@ void LLMaterialMgr::clearGetQueues(const LLUUID& region_id)
mGetAllPending.erase(region_id);
mGetAllCallbacks.erase(region_id);
}
-
void LLMaterialMgr::onRegionRemoved(LLViewerRegion* regionp)
{
clearGetQueues(regionp->getRegionID());
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 911af9df04..3869219da6 100755
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -66,7 +66,7 @@
#include "llvovolume.h"
#include "lluictrlfactory.h"
#include "llpluginclassmedia.h"
-#include "llviewertexturelist.h"
+#include "llviewertexturelist.h"// Update sel manager as to which channel we're editing so it can reflect the correct overlay UI
//
// Constant definitions for comboboxes
@@ -89,6 +89,19 @@ const S32 SHINY_TEXTURE = 4; // use supplied specular map
//
std::string USE_TEXTURE;
+LLRender::eTexIndex LLPanelFace::getTextureChannelToEdit()
+{
+ LLComboBox* combobox_matmedia = getChild<LLComboBox>("combobox matmedia");
+ LLComboBox* combobox_mattype = getChild<LLComboBox>("combobox mattype");
+
+ LLRender::eTexIndex channel_to_edit = (combobox_matmedia && combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ?
+ (combobox_mattype ? (LLRender::eTexIndex)combobox_mattype->getCurrentIndex() : LLRender::DIFFUSE_MAP) : LLRender::DIFFUSE_MAP;
+
+ channel_to_edit = (channel_to_edit == LLRender::NORMAL_MAP) ? (getCurrentNormalMap().isNull() ? LLRender::DIFFUSE_MAP : channel_to_edit) : channel_to_edit;
+ channel_to_edit = (channel_to_edit == LLRender::SPECULAR_MAP) ? (getCurrentSpecularMap().isNull() ? LLRender::DIFFUSE_MAP : channel_to_edit) : channel_to_edit;
+ return channel_to_edit;
+}
+
// Things the UI provides...
//
LLUUID LLPanelFace::getCurrentNormalMap() { return getChild<LLTextureCtrl>("bumpytexture control")->getImageAssetID(); }
@@ -1194,7 +1207,8 @@ void LLPanelFace::updateUI()
getChildView("checkbox fullbright")->setEnabled(editable);
getChild<LLUICtrl>("checkbox fullbright")->setTentative(!identical_fullbright);
}
-
+
+
// Repeats per meter
{
F32 repeats_diff = 1.f;
@@ -1218,6 +1232,9 @@ void LLPanelFace::updateUI()
F32 repeats = 1.0f;
U32 material_type = (combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ? combobox_mattype->getCurrentIndex() : MATTYPE_DIFFUSE;
+
+ LLSelectMgr::getInstance()->setTextureChannel(LLRender::eTexIndex(material_type));
+
switch (material_type)
{
default:
@@ -1328,18 +1345,6 @@ void LLPanelFace::updateUI()
getChild<LLColorSwatchCtrl>("shinycolorswatch")->set(material->getSpecularLightColor(),TRUE);
}
- // Update sel manager as to which channel we're editing so it can reflect the correct overlay UI
- // NORSPEC-103
- LLRender::eTexIndex channel_to_edit = (combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ? (LLRender::eTexIndex)combobox_mattype->getCurrentIndex() : LLRender::DIFFUSE_MAP;
-
- if ( ((channel_to_edit == LLRender::NORMAL_MAP) && material->getNormalID().isNull())
- ||((channel_to_edit == LLRender::SPECULAR_MAP) && material->getSpecularID().isNull()))
- {
- channel_to_edit = LLRender::DIFFUSE_MAP;
- }
-
- LLSelectMgr::getInstance()->setTextureChannel(channel_to_edit);
-
// Bumpy (normal)
texture_ctrl = getChild<LLTextureCtrl>("bumpytexture control");
texture_ctrl->setImageAssetID(material->getNormalID());
@@ -1365,10 +1370,6 @@ void LLPanelFace::updateUI()
updateBumpyControls(!material->getNormalID().isNull(), true);
}
}
- else
- {
- LLSelectMgr::getInstance()->setTextureChannel(LLRender::DIFFUSE_MAP);
- }
}
// Set variable values for numeric expressions
diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h
index 42c1f6bd48..46b3375f64 100755
--- a/indra/newview/llpanelface.h
+++ b/indra/newview/llpanelface.h
@@ -100,6 +100,19 @@ public:
void setMediaURL(const std::string& url);
void setMediaType(const std::string& mime_type);
+ LLMaterialPtr createDefaultMaterial(LLMaterialPtr current_material)
+ {
+ LLMaterialPtr new_material(!current_material.isNull() ? new LLMaterial(current_material->asLLSD()) : new LLMaterial());
+ llassert_always(new_material);
+
+ // Preserve old diffuse alpha mode or assert correct default blend mode as appropriate for the alpha channel content of the diffuse texture
+ //
+ new_material->setDiffuseAlphaMode(current_material.isNull() ? (isAlpha() ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE) : current_material->getDiffuseAlphaMode());
+ return new_material;
+ }
+
+ LLRender::eTexIndex getTextureChannelToEdit();
+
protected:
void getState();
@@ -178,6 +191,8 @@ protected:
static F32 valueGlow(LLViewerObject* object, S32 face);
+
+
private:
bool isAlpha() { return mIsAlpha; }
@@ -234,17 +249,32 @@ private:
{
if (_edit)
{
- LLMaterialPtr new_material(!current_material.isNull() ? new LLMaterial(current_material->asLLSD()) : new LLMaterial());
+ LLMaterialPtr new_material = _panel->createDefaultMaterial(current_material);
llassert_always(new_material);
// Determine correct alpha mode for current diffuse texture
// (i.e. does it have an alpha channel that makes alpha mode useful)
//
- U8 default_alpha_mode = (_panel->isAlpha() ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE);
+ // _panel->isAlpha() "lies" when one face has alpha and the rest do not (NORSPEC-329)
+ // need to get per-face answer to this question for sane alpha mode retention on updates.
+ //
+ bool is_alpha_face = object->isImageAlphaBlended(face);
+
+ // need to keep this original answer for valid comparisons in logic below
+ //
+ U8 original_default_alpha_mode = is_alpha_face ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
+
+ U8 default_alpha_mode = original_default_alpha_mode;
+
+ if (!current_material.isNull())
+ {
+ default_alpha_mode = current_material->getDiffuseAlphaMode();
+ }
- // Default to matching expected state of UI
+ // Insure we don't inherit the default of blend by accident...
+ // this will be stomped by a legit request to change the alpha mode by the apply() below
//
- new_material->setDiffuseAlphaMode(current_material.isNull() ? default_alpha_mode : current_material->getDiffuseAlphaMode());
+ new_material->setDiffuseAlphaMode(default_alpha_mode);
// Do "It"!
//
@@ -254,7 +284,13 @@ private:
LLUUID new_normal_map_id = new_material->getNormalID();
LLUUID new_spec_map_id = new_material->getSpecularID();
- bool is_default_blend_mode = (new_alpha_mode == default_alpha_mode);
+ if ((new_alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND) && !is_alpha_face)
+ {
+ new_alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
+ new_material->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE);
+ }
+
+ bool is_default_blend_mode = (new_alpha_mode == original_default_alpha_mode);
bool is_need_material = !is_default_blend_mode || !new_normal_map_id.isNull() || !new_spec_map_id.isNull();
if (!is_need_material)
diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp
index 02d363d795..a1d60b5b16 100755
--- a/indra/newview/llpanelvolume.cpp
+++ b/indra/newview/llpanelvolume.cpp
@@ -710,9 +710,19 @@ void LLPanelVolume::onLightCancelColor(const LLSD& data)
void LLPanelVolume::onLightCancelTexture(const LLSD& data)
{
LLTextureCtrl* LightTextureCtrl = getChild<LLTextureCtrl>("light texture control");
+
if (LightTextureCtrl)
{
- LightTextureCtrl->setImageAssetID(mLightSavedTexture);
+ LightTextureCtrl->setImageAssetID(LLUUID::null);
+ }
+
+ LLVOVolume *volobjp = (LLVOVolume *) mObject.get();
+ if(volobjp)
+ {
+ // Cancel the light texture as requested
+ // NORSPEC-292
+ //
+ volobjp->setLightTextureID(LLUUID::null);
}
}
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 0cbdbe16a3..7b397d46f3 100755
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -91,7 +91,7 @@
#include "llvovolume.h"
#include "pipeline.h"
#include "llviewershadermgr.h"
-
+#include "llpanelface.h"
#include "llglheaders.h"
LLViewerObject* getSelectedParentObject(LLViewerObject *object) ;
@@ -2534,7 +2534,7 @@ void LLSelectMgr::adjustTexturesByScale(BOOL send_to_sim, BOOL stretch)
if (tep && !tep->getMaterialParams().isNull())
{
LLMaterialPtr orig = tep->getMaterialParams();
- LLMaterialPtr p = new LLMaterial(orig->asLLSD());
+ LLMaterialPtr p = gFloaterTools->getPanelFace()->createDefaultMaterial(orig);
p->setNormalRepeat(normal_scale_s, normal_scale_t);
p->setSpecularRepeat(specular_scale_s, specular_scale_t);
@@ -2560,8 +2560,8 @@ void LLSelectMgr::adjustTexturesByScale(BOOL send_to_sim, BOOL stretch)
if (tep && !tep->getMaterialParams().isNull())
{
LLMaterialPtr orig = tep->getMaterialParams();
+ LLMaterialPtr p = gFloaterTools->getPanelFace()->createDefaultMaterial(orig);
- LLMaterialPtr p = new LLMaterial(orig->asLLSD());
p->setNormalRepeat(normal_scale_s, normal_scale_t);
p->setSpecularRepeat(specular_scale_s, specular_scale_t);
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 4676f7b251..2b1ed5858a 100755
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -133,7 +133,8 @@ public:
PermissionMask getFilterPermMask();
void updateFilterPermMask();
void commitIfImmediateSet();
-
+ void commitCancel();
+
void onFilterEdit(const std::string& search_string );
void setCanApply(bool can_preview, bool can_apply);
@@ -706,6 +707,14 @@ void LLFloaterTexturePicker::commitIfImmediateSet()
}
}
+void LLFloaterTexturePicker::commitCancel()
+{
+ if (!mNoCopyTextureSelected && mOwner && mCanApply)
+ {
+ mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_CANCEL);
+ }
+}
+
// static
void LLFloaterTexturePicker::onBtnSetToDefault(void* userdata)
{
@@ -733,7 +742,7 @@ void LLFloaterTexturePicker::onBtnNone(void* userdata)
{
LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
self->setImageID( LLUUID::null );
- self->commitIfImmediateSet();
+ self->commitCancel();
}
/*
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index e085834326..ef7d0cd81b 100755
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -58,6 +58,7 @@
#include "llviewerwindow.h"
#include "llvoavatarself.h"
#include "llworld.h"
+#include "llpanelface.h"
// syntactic sugar
#define callMemberFunction(object,ptrToMember) ((object).*(ptrToMember))
@@ -1163,7 +1164,51 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj,
// update viewer side image in anticipation of update from simulator
LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id);
LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT );
- hit_obj->setTEImage(hit_face, image);
+
+ LLTextureEntry* tep = hit_obj ? (hit_obj->getTE(hit_face)) : NULL;
+
+ LLPanelFace* panel_face = gFloaterTools->getPanelFace();
+
+ if (gFloaterTools->getVisible() && panel_face)
+ {
+ switch (LLSelectMgr::getInstance()->getTextureChannel())
+ {
+
+ case 0:
+ default:
+ {
+ hit_obj->setTEImage(hit_face, image);
+ }
+ break;
+
+ case 1:
+ {
+ LLMaterialPtr old_mat = tep->getMaterialParams();
+ LLMaterialPtr new_mat = panel_face->createDefaultMaterial(old_mat);
+ new_mat->setNormalID(asset_id);
+ tep->setMaterialParams(new_mat);
+ hit_obj->setTENormalMap(hit_face, asset_id);
+ LLMaterialMgr::getInstance()->put(hit_obj->getID(), hit_face, *new_mat);
+ }
+ break;
+
+ case 2:
+ {
+ LLMaterialPtr old_mat = tep->getMaterialParams();
+ LLMaterialPtr new_mat = panel_face->createDefaultMaterial(old_mat);
+ new_mat->setSpecularID(asset_id);
+ tep->setMaterialParams(new_mat);
+ hit_obj->setTESpecularMap(hit_face, asset_id);
+ LLMaterialMgr::getInstance()->put(hit_obj->getID(), hit_face, *new_mat);
+ }
+ break;
+ }
+ }
+ else
+ {
+ hit_obj->setTEImage(hit_face, image);
+ }
+
dialog_refresh_all();
// send the update to the simulator
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index f90b35a7bd..bbebeea3e0 100755
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -890,7 +890,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
{
gGL.setColorMask(true, true);
- if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
+ if (LLPipeline::sRenderDeferred)
{
gPipeline.mDeferredScreen.bindTarget();
glClearColor(1,0,1,1);
@@ -939,7 +939,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
gGL.setColorMask(true, false);
- if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
+ if (LLPipeline::sRenderDeferred)
{
gPipeline.renderGeomDeferred(*LLViewerCamera::getInstance());
}
@@ -976,7 +976,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
if (to_texture)
{
- if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
+ if (LLPipeline::sRenderDeferred)
{
gPipeline.mDeferredScreen.flush();
if(LLRenderTarget::sUseFBO)
@@ -1002,7 +1002,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
}
}
- if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
+ if (LLPipeline::sRenderDeferred)
{
gPipeline.renderDeferredLighting();
}
@@ -1623,3 +1623,4 @@ void display_cleanup()
{
gDisconnectedImagep = NULL;
}
+
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 6f7b2f40e6..0070240803 100755
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -4410,12 +4410,10 @@ S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMateri
void LLViewerObject::refreshMaterials()
{
- setChanged(ALL_CHANGED);
+ setChanged(TEXTURE);
if (mDrawable.notNull())
{
gPipeline.markTextured(mDrawable);
- gPipeline.markRebuild(mDrawable,LLDrawable::REBUILD_ALL);
- dirtySpatialGroup(TRUE);
}
}
@@ -4519,6 +4517,30 @@ LLViewerTexture *LLViewerObject::getTEImage(const U8 face) const
}
+bool LLViewerObject::isImageAlphaBlended(const U8 te) const
+{
+ LLViewerTexture* image = getTEImage(te);
+ LLGLenum format = image ? image->getPrimaryFormat() : GL_RGB;
+ switch (format)
+ {
+ case GL_RGBA:
+ case GL_ALPHA:
+ {
+ return true;
+ }
+ break;
+
+ case GL_RGB: break;
+ default:
+ {
+ llwarns << "Unexpected tex format in LLViewerObject::isImageAlphaBlended...returning no alpha." << llendl;
+ }
+ break;
+ }
+
+ return false;
+}
+
LLViewerTexture *LLViewerObject::getTENormalMap(const U8 face) const
{
// llassert(mTEImages);
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index ea0d55cda5..16f1f403d3 100755
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -339,6 +339,8 @@ public:
LLViewerTexture *getTENormalMap(const U8 te) const;
LLViewerTexture *getTESpecularMap(const U8 te) const;
+ bool isImageAlphaBlended(const U8 te) const;
+
void fitFaceTexture(const U8 face);
void sendTEUpdate() const; // Sends packed representation of all texture entry information
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 8422708add..e6fc82f761 100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1219,7 +1219,7 @@ void LLViewerRegion::getInfo(LLSD& info)
info["Region"]["Handle"]["y"] = (LLSD::Integer)y;
}
-void LLViewerRegion::getSimulatorFeatures(LLSD& sim_features)
+void LLViewerRegion::getSimulatorFeatures(LLSD& sim_features) const
{
sim_features = mSimulatorFeatures;
@@ -1944,3 +1944,47 @@ bool LLViewerRegion::dynamicPathfindingEnabled() const
mSimulatorFeatures["DynamicPathfindingEnabled"].asBoolean());
}
+void LLViewerRegion::resetMaterialsCapThrottle()
+{
+ F32 requests_per_sec = 1.0f; // original default;
+ if ( mSimulatorFeatures.has("RenderMaterialsCapability")
+ && mSimulatorFeatures["RenderMaterialsCapability"].isReal() )
+ {
+ requests_per_sec = mSimulatorFeatures["RenderMaterialsCapability"].asReal();
+ if ( requests_per_sec == 0.0f )
+ {
+ requests_per_sec = 1.0f;
+ LL_WARNS("Materials")
+ << "region '" << getName()
+ << "' returned zero for RenderMaterialsCapability; using default "
+ << requests_per_sec << " per second"
+ << LL_ENDL;
+ }
+ LL_DEBUGS("Materials") << "region '" << getName()
+ << "' RenderMaterialsCapability " << requests_per_sec
+ << LL_ENDL;
+ }
+ else
+ {
+ LL_DEBUGS("Materials")
+ << "region '" << getName()
+ << "' did not return RenderMaterialsCapability, using default "
+ << requests_per_sec << " per second"
+ << LL_ENDL;
+ }
+
+ mMaterialsCapThrottleTimer.resetWithExpiry( 1.0f / requests_per_sec );
+}
+
+U32 LLViewerRegion::getMaxMaterialsPerTransaction() const
+{
+ U32 max_entries = 50; // original hard coded default
+ if ( mSimulatorFeatures.has( "MaxMaterialsPerTransaction" )
+ && mSimulatorFeatures[ "MaxMaterialsPerTransaction" ].isInteger())
+ {
+ max_entries = mSimulatorFeatures[ "MaxMaterialsPerTransaction" ].asInteger();
+ }
+ return max_entries;
+}
+
+
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index 56cd0c9ea1..109baccf9a 100755
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -43,6 +43,7 @@
#include "llcapabilityprovider.h"
#include "m4math.h" // LLMatrix4
#include "llhttpclient.h"
+#include "llframetimer.h"
// Surface id's
#define LAND 1
@@ -293,7 +294,7 @@ public:
bool meshRezEnabled() const;
bool meshUploadEnabled() const;
- void getSimulatorFeatures(LLSD& info);
+ void getSimulatorFeatures(LLSD& info) const;
void setSimulatorFeatures(const LLSD& info);
@@ -342,7 +343,12 @@ public:
void getNeighboringRegionsStatus( std::vector<S32>& regions );
const LLViewerRegionImpl * getRegionImpl() const { return mImpl; }
LLViewerRegionImpl * getRegionImplNC() { return mImpl; }
+
+ // implements the materials capability throttle
+ bool materialsCapThrottled() const { return !mMaterialsCapThrottleTimer.hasExpired(); }
+ void resetMaterialsCapThrottle();
+ U32 getMaxMaterialsPerTransaction() const;
public:
struct CompareDistance
{
@@ -434,6 +440,9 @@ private:
BOOL mReleaseNotesRequested;
LLSD mSimulatorFeatures;
+
+ // the materials capability throttle
+ LLFrameTimer mMaterialsCapThrottleTimer;
};
inline BOOL LLViewerRegion::getRegionProtocol(U64 protocol) const
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index e24237522a..995eb599b8 100755
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -42,22 +42,6 @@
#include "llvosky.h"
#include "llrender.h"
-#if LL_DARWIN
-#include "OpenGL/OpenGL.h"
-
-// include spec exp clamp to fix older mac rendering artifacts
-//
-#define SINGLE_FP_PERMUTATION(shader) \
- if (gGLManager.mIsMobileGF) \
- { \
- shader.addPermutation("SINGLE_FP_ONLY","1"); \
- }
-
-
-#else
-#define SINGLE_FP_PERMUTATION(shader)
-#endif
-
#ifdef LL_RELEASE_FOR_DOWNLOAD
#define UNIFORM_ERRS LL_WARNS_ONCE("Shader")
#else
@@ -99,6 +83,7 @@ LLGLSLShader gAlphaMaskProgram;
//object shaders
LLGLSLShader gObjectSimpleProgram;
+LLGLSLShader gObjectSimpleImpostorProgram;
LLGLSLShader gObjectPreviewProgram;
LLGLSLShader gObjectSimpleWaterProgram;
LLGLSLShader gObjectSimpleAlphaMaskProgram;
@@ -184,6 +169,7 @@ LLGLSLShader gPostNightVisionProgram;
// Deferred rendering shaders
LLGLSLShader gDeferredImpostorProgram;
LLGLSLShader gDeferredWaterProgram;
+LLGLSLShader gDeferredUnderWaterProgram;
LLGLSLShader gDeferredDiffuseProgram;
LLGLSLShader gDeferredDiffuseAlphaMaskProgram;
LLGLSLShader gDeferredNonIndexedDiffuseProgram;
@@ -199,20 +185,26 @@ LLGLSLShader gDeferredTreeShadowProgram;
LLGLSLShader gDeferredAvatarProgram;
LLGLSLShader gDeferredAvatarAlphaProgram;
LLGLSLShader gDeferredLightProgram;
-LLGLSLShader gDeferredMultiLightProgram;
+LLGLSLShader gDeferredMultiLightProgram[16];
LLGLSLShader gDeferredSpotLightProgram;
LLGLSLShader gDeferredMultiSpotLightProgram;
LLGLSLShader gDeferredSunProgram;
LLGLSLShader gDeferredBlurLightProgram;
LLGLSLShader gDeferredSoftenProgram;
+LLGLSLShader gDeferredSoftenWaterProgram;
LLGLSLShader gDeferredShadowProgram;
LLGLSLShader gDeferredShadowCubeProgram;
LLGLSLShader gDeferredShadowAlphaMaskProgram;
LLGLSLShader gDeferredAvatarShadowProgram;
LLGLSLShader gDeferredAttachmentShadowProgram;
LLGLSLShader gDeferredAlphaProgram;
+LLGLSLShader gDeferredAlphaImpostorProgram;
+LLGLSLShader gDeferredAlphaWaterProgram;
LLGLSLShader gDeferredAvatarEyesProgram;
LLGLSLShader gDeferredFullbrightProgram;
+LLGLSLShader gDeferredFullbrightAlphaMaskProgram;
+LLGLSLShader gDeferredFullbrightWaterProgram;
+LLGLSLShader gDeferredFullbrightAlphaMaskWaterProgram;
LLGLSLShader gDeferredEmissiveProgram;
LLGLSLShader gDeferredPostProgram;
LLGLSLShader gDeferredCoFProgram;
@@ -230,6 +222,7 @@ LLGLSLShader gNormalMapGenProgram;
// Deferred materials shaders
LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];
+LLGLSLShader gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2];
LLViewerShaderMgr::LLViewerShaderMgr() :
mVertexShaderLevel(SHADER_COUNT, 0),
@@ -245,6 +238,7 @@ LLViewerShaderMgr::LLViewerShaderMgr() :
mShaderList.push_back(&gWaterProgram);
mShaderList.push_back(&gAvatarEyeballProgram);
mShaderList.push_back(&gObjectSimpleProgram);
+ mShaderList.push_back(&gObjectSimpleImpostorProgram);
mShaderList.push_back(&gObjectPreviewProgram);
mShaderList.push_back(&gImpostorProgram);
mShaderList.push_back(&gObjectFullbrightNoColorProgram);
@@ -295,6 +289,7 @@ LLViewerShaderMgr::LLViewerShaderMgr() :
mShaderList.push_back(&gUnderWaterProgram);
mShaderList.push_back(&gDeferredSunProgram);
mShaderList.push_back(&gDeferredSoftenProgram);
+ mShaderList.push_back(&gDeferredSoftenWaterProgram);
mShaderList.push_back(&gDeferredMaterialProgram[1]);
mShaderList.push_back(&gDeferredMaterialProgram[5]);
mShaderList.push_back(&gDeferredMaterialProgram[9]);
@@ -303,15 +298,30 @@ LLViewerShaderMgr::LLViewerShaderMgr() :
mShaderList.push_back(&gDeferredMaterialProgram[5+LLMaterial::SHADER_COUNT]);
mShaderList.push_back(&gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT]);
mShaderList.push_back(&gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT]);
+ mShaderList.push_back(&gDeferredMaterialWaterProgram[1]);
+ mShaderList.push_back(&gDeferredMaterialWaterProgram[5]);
+ mShaderList.push_back(&gDeferredMaterialWaterProgram[9]);
+ mShaderList.push_back(&gDeferredMaterialWaterProgram[13]);
+ mShaderList.push_back(&gDeferredMaterialWaterProgram[1+LLMaterial::SHADER_COUNT]);
+ mShaderList.push_back(&gDeferredMaterialWaterProgram[5+LLMaterial::SHADER_COUNT]);
+ mShaderList.push_back(&gDeferredMaterialWaterProgram[9+LLMaterial::SHADER_COUNT]);
+ mShaderList.push_back(&gDeferredMaterialWaterProgram[13+LLMaterial::SHADER_COUNT]);
+ mShaderList.push_back(&gDeferredAlphaProgram);
mShaderList.push_back(&gDeferredAlphaProgram);
+ mShaderList.push_back(&gDeferredAlphaImpostorProgram);
+ mShaderList.push_back(&gDeferredAlphaWaterProgram);
mShaderList.push_back(&gDeferredSkinnedAlphaProgram);
mShaderList.push_back(&gDeferredFullbrightProgram);
+ mShaderList.push_back(&gDeferredFullbrightAlphaMaskProgram);
+ mShaderList.push_back(&gDeferredFullbrightWaterProgram);
+ mShaderList.push_back(&gDeferredFullbrightAlphaMaskWaterProgram);
mShaderList.push_back(&gDeferredFullbrightShinyProgram);
mShaderList.push_back(&gDeferredSkinnedFullbrightShinyProgram);
mShaderList.push_back(&gDeferredSkinnedFullbrightProgram);
mShaderList.push_back(&gDeferredEmissiveProgram);
mShaderList.push_back(&gDeferredAvatarEyesProgram);
mShaderList.push_back(&gDeferredWaterProgram);
+ mShaderList.push_back(&gDeferredUnderWaterProgram);
mShaderList.push_back(&gDeferredAvatarAlphaProgram);
mShaderList.push_back(&gDeferredWLSkyProgram);
mShaderList.push_back(&gDeferredWLCloudProgram);
@@ -721,6 +731,7 @@ void LLViewerShaderMgr::unloadShaders()
gObjectFullbrightNoColorProgram.unload();
gObjectFullbrightNoColorWaterProgram.unload();
gObjectSimpleProgram.unload();
+ gObjectSimpleImpostorProgram.unload();
gObjectPreviewProgram.unload();
gImpostorProgram.unload();
gObjectSimpleAlphaMaskProgram.unload();
@@ -1128,12 +1139,16 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredImpostorProgram.unload();
gDeferredTerrainProgram.unload();
gDeferredLightProgram.unload();
- gDeferredMultiLightProgram.unload();
+ for (U32 i = 0; i < LL_DEFERRED_MULTI_LIGHT_COUNT; ++i)
+ {
+ gDeferredMultiLightProgram[i].unload();
+ }
gDeferredSpotLightProgram.unload();
gDeferredMultiSpotLightProgram.unload();
gDeferredSunProgram.unload();
gDeferredBlurLightProgram.unload();
gDeferredSoftenProgram.unload();
+ gDeferredSoftenWaterProgram.unload();
gDeferredShadowProgram.unload();
gDeferredShadowCubeProgram.unload();
gDeferredShadowAlphaMaskProgram.unload();
@@ -1142,7 +1157,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAvatarProgram.unload();
gDeferredAvatarAlphaProgram.unload();
gDeferredAlphaProgram.unload();
+ gDeferredAlphaWaterProgram.unload();
gDeferredFullbrightProgram.unload();
+ gDeferredFullbrightAlphaMaskProgram.unload();
+ gDeferredFullbrightWaterProgram.unload();
+ gDeferredFullbrightAlphaMaskWaterProgram.unload();
gDeferredEmissiveProgram.unload();
gDeferredAvatarEyesProgram.unload();
gDeferredPostProgram.unload();
@@ -1151,6 +1170,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredPostGammaCorrectProgram.unload();
gFXAAProgram.unload();
gDeferredWaterProgram.unload();
+ gDeferredUnderWaterProgram.unload();
gDeferredWLSkyProgram.unload();
gDeferredWLCloudProgram.unload();
gDeferredStarProgram.unload();
@@ -1162,6 +1182,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)
{
gDeferredMaterialProgram[i].unload();
+ gDeferredMaterialWaterProgram[i].unload();
}
return TRUE;
}
@@ -1170,7 +1191,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
- gDeferredDiffuseProgram.mName = "Deferred Diffuse Shader";
+ gDeferredDiffuseProgram.mName = "Deferred Diffuse Shader";
gDeferredDiffuseProgram.mShaderFiles.clear();
gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseIndexedF.glsl", GL_FRAGMENT_SHADER_ARB));
@@ -1246,11 +1267,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
gDeferredSkinnedAlphaProgram.mName = "Deferred Skinned Alpha Shader";
- gDeferredSkinnedAlphaProgram.mFeatures.atmosphericHelpers = true;
gDeferredSkinnedAlphaProgram.mFeatures.hasObjectSkinning = true;
- gDeferredSkinnedAlphaProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredSkinnedAlphaProgram.mFeatures.hasGamma = true;
- gDeferredSkinnedAlphaProgram.mFeatures.hasAtmospherics = true;
gDeferredSkinnedAlphaProgram.mFeatures.calculatesLighting = false;
gDeferredSkinnedAlphaProgram.mFeatures.hasLighting = false;
gDeferredSkinnedAlphaProgram.mFeatures.isAlphaLighting = true;
@@ -1260,8 +1277,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredSkinnedAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
gDeferredSkinnedAlphaProgram.addPermutation("USE_DIFFUSE_TEX", "1");
- gDeferredSkinnedAlphaProgram.addPermutation("USE_VERTEX_COLOR", "1");
gDeferredSkinnedAlphaProgram.addPermutation("HAS_SKIN", "1");
+ gDeferredSkinnedAlphaProgram.addPermutation("USE_VERTEX_COLOR", "1");
gDeferredSkinnedAlphaProgram.addPermutation("HAS_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0");
success = gDeferredSkinnedAlphaProgram.createShader(NULL, NULL);
@@ -1289,6 +1306,15 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
+ gDeferredMaterialWaterProgram[1].mFeatures.hasLighting = false;
+ gDeferredMaterialWaterProgram[5].mFeatures.hasLighting = false;
+ gDeferredMaterialWaterProgram[9].mFeatures.hasLighting = false;
+ gDeferredMaterialWaterProgram[13].mFeatures.hasLighting = false;
+ gDeferredMaterialWaterProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
+ gDeferredMaterialWaterProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
+ gDeferredMaterialWaterProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
+ gDeferredMaterialWaterProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
+
for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)
{
if (success)
@@ -1308,8 +1334,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
bool has_skin = i & 0x10;
gDeferredMaterialProgram[i].addPermutation("HAS_SKIN",has_skin ? "1" : "0");
- SINGLE_FP_PERMUTATION(gDeferredMaterialProgram[i]);
-
if (has_skin)
{
gDeferredMaterialProgram[i].mFeatures.hasObjectSkinning = true;
@@ -1317,6 +1341,34 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
success = gDeferredMaterialProgram[i].createShader(NULL, NULL);
}
+
+ if (success)
+ {
+ gDeferredMaterialWaterProgram[i].mName = llformat("Deferred Underwater Material Shader %d", i);
+
+ U32 alpha_mode = i & 0x3;
+
+ gDeferredMaterialWaterProgram[i].mShaderFiles.clear();
+ gDeferredMaterialWaterProgram[i].mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredMaterialWaterProgram[i].mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredMaterialWaterProgram[i].mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredMaterialWaterProgram[i].mShaderGroup = LLGLSLShader::SG_WATER;
+
+ gDeferredMaterialWaterProgram[i].addPermutation("HAS_NORMAL_MAP", i & 0x8? "1" : "0");
+ gDeferredMaterialWaterProgram[i].addPermutation("HAS_SPECULAR_MAP", i & 0x4 ? "1" : "0");
+ gDeferredMaterialWaterProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode));
+ gDeferredMaterialWaterProgram[i].addPermutation("HAS_SUN_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0");
+ bool has_skin = i & 0x10;
+ gDeferredMaterialWaterProgram[i].addPermutation("HAS_SKIN",has_skin ? "1" : "0");
+ gDeferredMaterialWaterProgram[i].addPermutation("WATER_FOG","1");
+
+ if (has_skin)
+ {
+ gDeferredMaterialWaterProgram[i].mFeatures.hasObjectSkinning = true;
+ }
+
+ success = gDeferredMaterialWaterProgram[i].createShader(NULL, NULL);//&mWLUniforms);
+ }
}
gDeferredMaterialProgram[1].mFeatures.hasLighting = true;
@@ -1328,6 +1380,14 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
+ gDeferredMaterialWaterProgram[1].mFeatures.hasLighting = true;
+ gDeferredMaterialWaterProgram[5].mFeatures.hasLighting = true;
+ gDeferredMaterialWaterProgram[9].mFeatures.hasLighting = true;
+ gDeferredMaterialWaterProgram[13].mFeatures.hasLighting = true;
+ gDeferredMaterialWaterProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
+ gDeferredMaterialWaterProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
+ gDeferredMaterialWaterProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
+ gDeferredMaterialWaterProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
if (success)
@@ -1368,22 +1428,21 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
- SINGLE_FP_PERMUTATION(gDeferredLightProgram);
-
success = gDeferredLightProgram.createShader(NULL, NULL);
}
- if (success)
+ for (U32 i = 0; i < LL_DEFERRED_MULTI_LIGHT_COUNT; i++)
{
- gDeferredMultiLightProgram.mName = "Deferred MultiLight Shader";
- gDeferredMultiLightProgram.mShaderFiles.clear();
- gDeferredMultiLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredMultiLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightF.glsl", GL_FRAGMENT_SHADER_ARB));
- gDeferredMultiLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
-
- SINGLE_FP_PERMUTATION(gDeferredMultiLightProgram);
-
- success = gDeferredMultiLightProgram.createShader(NULL, NULL);
+ if (success)
+ {
+ gDeferredMultiLightProgram[i].mName = llformat("Deferred MultiLight Shader %d", i);
+ gDeferredMultiLightProgram[i].mShaderFiles.clear();
+ gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredMultiLightProgram[i].mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredMultiLightProgram[i].addPermutation("LIGHT_COUNT", llformat("%d", i+1));
+ success = gDeferredMultiLightProgram[i].createShader(NULL, NULL);
+ }
}
if (success)
@@ -1394,8 +1453,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/spotLightF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
- SINGLE_FP_PERMUTATION(gDeferredSpotLightProgram);
-
success = gDeferredSpotLightProgram.createShader(NULL, NULL);
}
@@ -1407,8 +1464,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredMultiSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
- SINGLE_FP_PERMUTATION(gDeferredMultiSpotLightProgram);
-
success = gDeferredMultiSpotLightProgram.createShader(NULL, NULL);
}
@@ -1436,8 +1491,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSunProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));
gDeferredSunProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
- SINGLE_FP_PERMUTATION(gDeferredSunProgram);
-
success = gDeferredSunProgram.createShader(NULL, NULL);
}
@@ -1449,19 +1502,14 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredBlurLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
- SINGLE_FP_PERMUTATION(gDeferredBlurLightProgram);
-
success = gDeferredBlurLightProgram.createShader(NULL, NULL);
}
if (success)
{
gDeferredAlphaProgram.mName = "Deferred Alpha Shader";
- gDeferredAlphaProgram.mFeatures.atmosphericHelpers = true;
+
gDeferredAlphaProgram.mFeatures.calculatesLighting = false;
- gDeferredAlphaProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredAlphaProgram.mFeatures.hasGamma = true;
- gDeferredAlphaProgram.mFeatures.hasAtmospherics = true;
gDeferredAlphaProgram.mFeatures.hasLighting = false;
gDeferredAlphaProgram.mFeatures.isAlphaLighting = true;
gDeferredAlphaProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
@@ -1478,12 +1526,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredAlphaProgram.addPermutation("USE_INDEXED_TEX", "1");
- gDeferredAlphaProgram.addPermutation("USE_VERTEX_COLOR", "1");
gDeferredAlphaProgram.addPermutation("HAS_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0");
+ gDeferredAlphaProgram.addPermutation("USE_VERTEX_COLOR", "1");
gDeferredAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
- SINGLE_FP_PERMUTATION(gDeferredAlphaProgram);
-
success = gDeferredAlphaProgram.createShader(NULL, NULL);
// Hack
@@ -1493,6 +1539,72 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
+ gDeferredAlphaImpostorProgram.mName = "Deferred Alpha Shader";
+
+ gDeferredAlphaImpostorProgram.mFeatures.calculatesLighting = false;
+ gDeferredAlphaImpostorProgram.mFeatures.hasLighting = false;
+ gDeferredAlphaImpostorProgram.mFeatures.isAlphaLighting = true;
+ gDeferredAlphaImpostorProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
+ if (mVertexShaderLevel[SHADER_DEFERRED] < 1)
+ {
+ gDeferredAlphaImpostorProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ }
+ else
+ { //shave off some texture units for shadow maps
+ gDeferredAlphaImpostorProgram.mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1);
+ }
+
+ gDeferredAlphaImpostorProgram.mShaderFiles.clear();
+ gDeferredAlphaImpostorProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredAlphaImpostorProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredAlphaImpostorProgram.addPermutation("USE_INDEXED_TEX", "1");
+ gDeferredAlphaImpostorProgram.addPermutation("HAS_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0");
+ gDeferredAlphaImpostorProgram.addPermutation("USE_VERTEX_COLOR", "1");
+ gDeferredAlphaImpostorProgram.addPermutation("FOR_IMPOSTOR", "1");
+
+ gDeferredAlphaImpostorProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+
+ success = gDeferredAlphaImpostorProgram.createShader(NULL, NULL);
+
+ // Hack
+ gDeferredAlphaImpostorProgram.mFeatures.calculatesLighting = true;
+ gDeferredAlphaImpostorProgram.mFeatures.hasLighting = true;
+ }
+
+ if (success)
+ {
+ gDeferredAlphaWaterProgram.mName = "Deferred Alpha Underwater Shader";
+ gDeferredAlphaWaterProgram.mFeatures.calculatesLighting = false;
+ gDeferredAlphaWaterProgram.mFeatures.hasLighting = false;
+ gDeferredAlphaWaterProgram.mFeatures.isAlphaLighting = true;
+ gDeferredAlphaWaterProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
+ if (mVertexShaderLevel[SHADER_DEFERRED] < 1)
+ {
+ gDeferredAlphaWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ }
+ else
+ { //shave off some texture units for shadow maps
+ gDeferredAlphaWaterProgram.mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1);
+ }
+ gDeferredAlphaWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+ gDeferredAlphaWaterProgram.mShaderFiles.clear();
+ gDeferredAlphaWaterProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredAlphaWaterProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredAlphaWaterProgram.addPermutation("USE_INDEXED_TEX", "1");
+ gDeferredAlphaWaterProgram.addPermutation("WATER_FOG", "1");
+ gDeferredAlphaWaterProgram.addPermutation("USE_VERTEX_COLOR", "1");
+ gDeferredAlphaWaterProgram.addPermutation("HAS_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0");
+ gDeferredAlphaWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+
+ success = gDeferredAlphaWaterProgram.createShader(NULL, NULL);
+
+ // Hack
+ gDeferredAlphaWaterProgram.mFeatures.calculatesLighting = true;
+ gDeferredAlphaWaterProgram.mFeatures.hasLighting = true;
+ }
+
+ if (success)
+ {
gDeferredAvatarEyesProgram.mName = "Deferred Avatar Eyes Shader";
gDeferredAvatarEyesProgram.mFeatures.calculatesAtmospherics = true;
gDeferredAvatarEyesProgram.mFeatures.hasGamma = true;
@@ -1521,6 +1633,54 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
+ gDeferredFullbrightAlphaMaskProgram.mName = "Deferred Fullbright Alpha Masking Shader";
+ gDeferredFullbrightAlphaMaskProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredFullbrightAlphaMaskProgram.mFeatures.hasGamma = true;
+ gDeferredFullbrightAlphaMaskProgram.mFeatures.hasTransport = true;
+ gDeferredFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ gDeferredFullbrightAlphaMaskProgram.mShaderFiles.clear();
+ gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredFullbrightAlphaMaskProgram.addPermutation("HAS_ALPHA_MASK","1");
+ gDeferredFullbrightAlphaMaskProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ success = gDeferredFullbrightAlphaMaskProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gDeferredFullbrightWaterProgram.mName = "Deferred Fullbright Underwater Shader";
+ gDeferredFullbrightWaterProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredFullbrightWaterProgram.mFeatures.hasGamma = true;
+ gDeferredFullbrightWaterProgram.mFeatures.hasTransport = true;
+ gDeferredFullbrightWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ gDeferredFullbrightWaterProgram.mShaderFiles.clear();
+ gDeferredFullbrightWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredFullbrightWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredFullbrightWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+ gDeferredFullbrightWaterProgram.addPermutation("WATER_FOG","1");
+ success = gDeferredFullbrightWaterProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gDeferredFullbrightAlphaMaskWaterProgram.mName = "Deferred Fullbright Underwater Alpha Masking Shader";
+ gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasGamma = true;
+ gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasTransport = true;
+ gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.clear();
+ gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredFullbrightAlphaMaskWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredFullbrightAlphaMaskWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+ gDeferredFullbrightAlphaMaskWaterProgram.addPermutation("HAS_ALPHA_MASK","1");
+ gDeferredFullbrightAlphaMaskWaterProgram.addPermutation("WATER_FOG","1");
+ success = gDeferredFullbrightAlphaMaskWaterProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
gDeferredFullbrightShinyProgram.mName = "Deferred FullbrightShiny Shader";
gDeferredFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true;
gDeferredFullbrightShinyProgram.mFeatures.hasGamma = true;
@@ -1593,6 +1753,20 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
+ // load water shader
+ gDeferredUnderWaterProgram.mName = "Deferred Under Water Shader";
+ gDeferredUnderWaterProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredUnderWaterProgram.mFeatures.hasGamma = true;
+ gDeferredUnderWaterProgram.mFeatures.hasTransport = true;
+ gDeferredUnderWaterProgram.mShaderFiles.clear();
+ gDeferredUnderWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredUnderWaterProgram.mShaderFiles.push_back(make_pair("deferred/underWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredUnderWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ success = gDeferredUnderWaterProgram.createShader(NULL, &mWaterUniforms);
+ }
+
+ if (success)
+ {
gDeferredSoftenProgram.mName = "Deferred Soften Shader";
gDeferredSoftenProgram.mShaderFiles.clear();
gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER_ARB));
@@ -1600,8 +1774,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSoftenProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
- SINGLE_FP_PERMUTATION(gDeferredSoftenProgram);
-
if (gSavedSettings.getBOOL("RenderDeferredSSAO"))
{ //if using SSAO, take screen space light map into account as if shadows are enabled
gDeferredSoftenProgram.mShaderLevel = llmax(gDeferredSoftenProgram.mShaderLevel, 2);
@@ -1612,6 +1784,25 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
+ gDeferredSoftenWaterProgram.mName = "Deferred Soften Underwater Shader";
+ gDeferredSoftenWaterProgram.mShaderFiles.clear();
+ gDeferredSoftenWaterProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredSoftenWaterProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER_ARB));
+
+ gDeferredSoftenWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ gDeferredSoftenWaterProgram.addPermutation("WATER_FOG", "1");
+ gDeferredSoftenWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+
+ if (gSavedSettings.getBOOL("RenderDeferredSSAO"))
+ { //if using SSAO, take screen space light map into account as if shadows are enabled
+ gDeferredSoftenWaterProgram.mShaderLevel = llmax(gDeferredSoftenWaterProgram.mShaderLevel, 2);
+ }
+
+ success = gDeferredSoftenWaterProgram.createShader(NULL, &mWLUniforms);
+ }
+
+ if (success)
+ {
gDeferredShadowProgram.mName = "Deferred Shadow Shader";
gDeferredShadowProgram.mShaderFiles.clear();
gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowV.glsl", GL_VERTEX_SHADER_ARB));
@@ -1692,12 +1883,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
gDeferredAvatarAlphaProgram.mName = "Avatar Alpha Shader";
- gDeferredAvatarAlphaProgram.mFeatures.atmosphericHelpers = true;
gDeferredAvatarAlphaProgram.mFeatures.hasSkinning = true;
gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = false;
- gDeferredAvatarAlphaProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredAvatarAlphaProgram.mFeatures.hasGamma = true;
- gDeferredAvatarAlphaProgram.mFeatures.hasAtmospherics = true;
gDeferredAvatarAlphaProgram.mFeatures.hasLighting = false;
gDeferredAvatarAlphaProgram.mFeatures.isAlphaLighting = true;
gDeferredAvatarAlphaProgram.mFeatures.disableTextureIndex = true;
@@ -1836,6 +2023,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectFullbrightNoColorProgram.unload();
gObjectFullbrightNoColorWaterProgram.unload();
gObjectSimpleProgram.unload();
+ gObjectSimpleImpostorProgram.unload();
gObjectPreviewProgram.unload();
gImpostorProgram.unload();
gObjectSimpleAlphaMaskProgram.unload();
@@ -2258,6 +2446,27 @@ BOOL LLViewerShaderMgr::loadShadersObject()
if (success)
{
+ gObjectSimpleImpostorProgram.mName = "Simple Impostor Shader";
+ gObjectSimpleImpostorProgram.mFeatures.calculatesLighting = true;
+ gObjectSimpleImpostorProgram.mFeatures.calculatesAtmospherics = true;
+ gObjectSimpleImpostorProgram.mFeatures.hasGamma = true;
+ gObjectSimpleImpostorProgram.mFeatures.hasAtmospherics = true;
+ gObjectSimpleImpostorProgram.mFeatures.hasLighting = true;
+ gObjectSimpleImpostorProgram.mFeatures.mIndexedTextureChannels = 0;
+ // force alpha mask version of lighting so we can weed out
+ // transparent pixels from impostor temp buffer
+ //
+ gObjectSimpleImpostorProgram.mFeatures.hasAlphaMask = true;
+ gObjectSimpleImpostorProgram.mShaderFiles.clear();
+ gObjectSimpleImpostorProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
+ gObjectSimpleImpostorProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectSimpleImpostorProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
+
+ success = gObjectSimpleImpostorProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
gObjectSimpleWaterProgram.mName = "Simple Water Shader";
gObjectSimpleWaterProgram.mFeatures.calculatesLighting = true;
gObjectSimpleWaterProgram.mFeatures.calculatesAtmospherics = true;
@@ -3191,3 +3400,4 @@ LLViewerShaderMgr::shader_iter LLViewerShaderMgr::endShaders() const
{
return mShaderList.end();
}
+
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index 438853cd6f..e4684c19d5 100755
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -30,6 +30,8 @@
#include "llshadermgr.h"
#include "llmaterial.h"
+#define LL_DEFERRED_MULTI_LIGHT_COUNT 16
+
class LLViewerShaderMgr: public LLShaderMgr
{
public:
@@ -240,6 +242,7 @@ extern LLGLSLShader gOneTextureNoColorProgram;
//object shaders
extern LLGLSLShader gObjectSimpleProgram;
+extern LLGLSLShader gObjectSimpleImpostorProgram;
extern LLGLSLShader gObjectPreviewProgram;
extern LLGLSLShader gObjectSimpleAlphaMaskProgram;
extern LLGLSLShader gObjectSimpleWaterProgram;
@@ -328,6 +331,7 @@ extern LLGLSLShader gPostNightVisionProgram;
// Deferred rendering shaders
extern LLGLSLShader gDeferredImpostorProgram;
extern LLGLSLShader gDeferredWaterProgram;
+extern LLGLSLShader gDeferredUnderWaterProgram;
extern LLGLSLShader gDeferredDiffuseProgram;
extern LLGLSLShader gDeferredDiffuseAlphaMaskProgram;
extern LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskProgram;
@@ -341,13 +345,14 @@ extern LLGLSLShader gDeferredTerrainProgram;
extern LLGLSLShader gDeferredTreeProgram;
extern LLGLSLShader gDeferredTreeShadowProgram;
extern LLGLSLShader gDeferredLightProgram;
-extern LLGLSLShader gDeferredMultiLightProgram;
+extern LLGLSLShader gDeferredMultiLightProgram[LL_DEFERRED_MULTI_LIGHT_COUNT];
extern LLGLSLShader gDeferredSpotLightProgram;
extern LLGLSLShader gDeferredMultiSpotLightProgram;
extern LLGLSLShader gDeferredSunProgram;
extern LLGLSLShader gDeferredBlurLightProgram;
extern LLGLSLShader gDeferredAvatarProgram;
extern LLGLSLShader gDeferredSoftenProgram;
+extern LLGLSLShader gDeferredSoftenWaterProgram;
extern LLGLSLShader gDeferredShadowProgram;
extern LLGLSLShader gDeferredShadowCubeProgram;
extern LLGLSLShader gDeferredShadowAlphaMaskProgram;
@@ -360,7 +365,12 @@ extern LLGLSLShader gDeferredPostGammaCorrectProgram;
extern LLGLSLShader gDeferredAvatarShadowProgram;
extern LLGLSLShader gDeferredAttachmentShadowProgram;
extern LLGLSLShader gDeferredAlphaProgram;
+extern LLGLSLShader gDeferredAlphaImpostorProgram;
extern LLGLSLShader gDeferredFullbrightProgram;
+extern LLGLSLShader gDeferredFullbrightAlphaMaskProgram;
+extern LLGLSLShader gDeferredAlphaWaterProgram;
+extern LLGLSLShader gDeferredFullbrightWaterProgram;
+extern LLGLSLShader gDeferredFullbrightAlphaMaskWaterProgram;
extern LLGLSLShader gDeferredEmissiveProgram;
extern LLGLSLShader gDeferredAvatarEyesProgram;
extern LLGLSLShader gDeferredAvatarAlphaProgram;
@@ -374,5 +384,6 @@ extern LLGLSLShader gNormalMapGenProgram;
// Deferred materials shaders
extern LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];
-
+extern LLGLSLShader gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2];
#endif
+
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index e6385dceea..113bdd2ce3 100755
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -1114,7 +1114,7 @@ void LLVOVolume::sculpt()
S32 max_discard = mSculptTexture->getMaxDiscardLevel();
if (discard_level > max_discard)
{
- discard_level = max_discard; // clamp to the best we can do
+ discard_level = max_discard; // clamp to the best we can do
}
if(discard_level > MAX_DISCARD_LEVEL)
{
@@ -1458,7 +1458,7 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)
continue;
}
res &= face->genVolumeBBoxes(*volume, i,
- mRelativeXform,
+ mRelativeXform, mRelativeXformInvTrans,
(mVolumeImpl && mVolumeImpl->isVolumeGlobal()) || force_global);
if (rebuild)
@@ -2596,6 +2596,7 @@ void LLVOVolume::setLightTextureID(LLUUID id)
if (hasLightTexture())
{
setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE, FALSE, true);
+ parameterChanged(LLNetworkData::PARAMS_LIGHT_IMAGE, true);
mLightTexture = NULL;
}
}
@@ -2613,7 +2614,8 @@ void LLVOVolume::setSpotLightParams(LLVector3 params)
void LLVOVolume::setIsLight(BOOL is_light)
{
- if (is_light != getIsLight())
+ BOOL was_light = getIsLight();
+ if (is_light != was_light)
{
if (is_light)
{
@@ -2798,7 +2800,7 @@ void LLVOVolume::updateSpotLightPriority()
bool LLVOVolume::isLightSpotlight() const
{
LLLightImageParams* params = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
- if (params)
+ if (params && getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE))
{
return params->isLightSpotlight();
}
@@ -3728,8 +3730,30 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
{
LLFace* face = mDrawable->getFace(face_hit);
+ bool ignore_alpha = false;
+
+ const LLTextureEntry* te = face->getTextureEntry();
+ if (te)
+ {
+ LLMaterial* mat = te->getMaterialParams();
+ if (mat)
+ {
+ U8 mode = mat->getDiffuseAlphaMode();
+
+ if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE ||
+ mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE)
+ {
+ ignore_alpha = true;
+ }
+ }
+ }
+
if (face &&
- (pick_transparent || !face->getTexture() || !face->getTexture()->hasGLTexture() || face->getTexture()->getMask(face->surfaceToTexture(tc, p, n))))
+ (ignore_alpha ||
+ pick_transparent ||
+ !face->getTexture() ||
+ !face->getTexture()->hasGLTexture() ||
+ face->getTexture()->getMask(face->surfaceToTexture(tc, p, n))))
{
local_end = p;
if (face_hitp != NULL)
@@ -4839,14 +4863,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
if (is_rigged)
{
- if (!drawablep->isState(LLDrawable::RIGGED))
- {
- drawablep->setState(LLDrawable::RIGGED);
-
- //first time this is drawable is being marked as rigged,
- // do another LoD update to use avatar bounding box
- vobj->updateLOD();
- }
+ drawablep->setState(LLDrawable::RIGGED);
}
else
{
@@ -5367,19 +5384,24 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE;
}
- bool use_legacy_bump = te->getBumpmap() && (!mat || mat->getNormalID().isNull());
+ bool use_legacy_bump = te->getBumpmap() && (te->getBumpmap() < 18) && (!mat || mat->getNormalID().isNull());
+ bool opaque = te->getColor().mV[3] >= 0.999f;
if (mat && LLPipeline::sRenderDeferred && !hud_group)
{
bool material_pass = false;
- if (fullbright)
+ // do NOT use 'fullbright' for this logic or you risk sending
+ // things without normals down the materials pipeline and will
+ // render poorly if not crash NORSPEC-240,314
+ //
+ if (te->getFullbright())
{
if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
{
- if (te->getColor().mV[3] >= 0.999f)
+ if (opaque)
{
- material_pass = true;
+ registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK);
}
else
{
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index f49395da34..c4286e73eb 100755
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -111,6 +111,8 @@
#include "llpathinglib.h"
#include "llfloaterpathfindingconsole.h"
#include "llfloaterpathfindingcharacters.h"
+#include "llfloatertools.h"
+#include "llpanelface.h"
#include "llpathfindingpathtool.h"
#ifdef _DEBUG
@@ -120,6 +122,10 @@
//#define DEBUG_INDICES
#endif
+// Expensive and currently broken
+//
+#define MATERIALS_IN_REFLECTIONS 0
+
bool gShiftFrame = false;
//cached settings
@@ -163,7 +169,6 @@ S32 LLPipeline::RenderGlowIterations;
F32 LLPipeline::RenderGlowWidth;
F32 LLPipeline::RenderGlowStrength;
BOOL LLPipeline::RenderDepthOfField;
-BOOL LLPipeline::RenderDepthOfFieldInEditMode;
F32 LLPipeline::CameraFocusTransitionTime;
F32 LLPipeline::CameraFNumber;
F32 LLPipeline::CameraFocalLength;
@@ -1233,14 +1238,31 @@ void LLPipeline::createGLBuffers()
updateRenderDeferred();
+ bool materials_in_water = false;
+
+#if MATERIALS_IN_REFLECTIONS
+ materials_in_water = gSavedSettings.getS32("RenderWaterMaterials");
+#endif
+
if (LLPipeline::sWaterReflections)
{ //water reflection texture
U32 res = (U32) llmax(gSavedSettings.getS32("RenderWaterRefResolution"), 512);
+ // Set up SRGB targets if we're doing deferred-path reflection rendering
+ //
+ if (LLPipeline::sRenderDeferred && materials_in_water)
+ {
+ mWaterRef.allocate(res,res,GL_SRGB8_ALPHA8,TRUE,FALSE);
+ //always use FBO for mWaterDis so it can be used for avatar texture bakes
+ mWaterDis.allocate(res,res,GL_SRGB8_ALPHA8,TRUE,FALSE,LLTexUnit::TT_TEXTURE, true);
+ }
+ else
+ {
mWaterRef.allocate(res,res,GL_RGBA,TRUE,FALSE);
//always use FBO for mWaterDis so it can be used for avatar texture bakes
mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE,LLTexUnit::TT_TEXTURE, true);
}
+ }
mHighlight.allocate(256,256,GL_RGBA, FALSE, FALSE);
@@ -1402,9 +1424,15 @@ void LLPipeline::createLUTBuffers()
}
}
- LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_R16F, 1, &mLightFunc);
+ U32 pix_format = GL_R16F;
+#if LL_DARWIN
+ // Need to work around limited precision with 10.6.8 and older drivers
+ //
+ pix_format = GL_R32F;
+#endif
+ LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, pix_format, 1, &mLightFunc);
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc);
- LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_R16F, lightResX, lightResY, GL_RED, GL_FLOAT, ls, false);
+ LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, pix_format, lightResX, lightResY, GL_RED, GL_FLOAT, ls, false);
//LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_UNSIGNED_BYTE, lightResX, lightResY, GL_RED, GL_UNSIGNED_BYTE, ls, false);
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR);
@@ -2443,7 +2471,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
if (to_texture)
{
- if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
+ if (LLPipeline::sRenderDeferred)
{
mOcclusionDepth.bindTarget();
}
@@ -2588,7 +2616,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
if (to_texture)
{
- if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
+ if (LLPipeline::sRenderDeferred)
{
mOcclusionDepth.flush();
}
@@ -3959,7 +3987,7 @@ void LLPipeline::postSort(LLCamera& camera)
{
mSelectedFaces.clear();
- LLPipeline::setRenderHighlightTextureChannel(LLSelectMgr::getInstance()->getTextureChannel());
+ LLPipeline::setRenderHighlightTextureChannel(gFloaterTools->getPanelFace()->getTextureChannelToEdit());
// Draw face highlights for selected faces.
if (LLSelectMgr::getInstance()->getTEMode())
@@ -5383,7 +5411,7 @@ void LLPipeline::renderDebug()
if (i > 3)
{ //render shadow frusta as volumes
if (mShadowFrustPoints[i-4].empty())
- {
+ {
continue;
}
@@ -8527,7 +8555,7 @@ void LLPipeline::renderDeferredLighting()
if (RenderDeferredAtmospheric)
{ //apply sunlight contribution
LLFastTimer ftm(FTM_ATMOSPHERICS);
- bindDeferredShader(gDeferredSoftenProgram);
+ bindDeferredShader(LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram);
{
LLGLDepthTest depth(GL_FALSE);
LLGLDisable blend(GL_BLEND);
@@ -8549,7 +8577,7 @@ void LLPipeline::renderDeferredLighting()
gGL.popMatrix();
}
- unbindDeferredShader(gDeferredSoftenProgram);
+ unbindDeferredShader(LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram);
}
{ //render non-deferred geometry (fullbright, alpha, etc)
@@ -8742,10 +8770,6 @@ void LLPipeline::renderDeferredLighting()
vert[2].set(3,1,0);
{
- bindDeferredShader(gDeferredMultiLightProgram);
-
- mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
-
LLGLDepthTest depth(GL_FALSE);
//full screen blit
@@ -8757,7 +8781,7 @@ void LLPipeline::renderDeferredLighting()
U32 count = 0;
- const U32 max_count = 8;
+ const U32 max_count = LL_DEFERRED_MULTI_LIGHT_COUNT;
LLVector4 light[max_count];
LLVector4 col[max_count];
@@ -8780,18 +8804,20 @@ void LLPipeline::renderDeferredLighting()
count++;
if (count == max_count || fullscreen_lights.empty())
{
- gDeferredMultiLightProgram.uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count);
- gDeferredMultiLightProgram.uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*) light);
- gDeferredMultiLightProgram.uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*) col);
- gDeferredMultiLightProgram.uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z);
+ U32 idx = count-1;
+ bindDeferredShader(gDeferredMultiLightProgram[idx]);
+ gDeferredMultiLightProgram[idx].uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count);
+ gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*) light);
+ gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*) col);
+ gDeferredMultiLightProgram[idx].uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z);
far_z = 0.f;
count = 0;
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ unbindDeferredShader(gDeferredMultiLightProgram[idx]);
}
}
- unbindDeferredShader(gDeferredMultiLightProgram);
-
bindDeferredShader(gDeferredMultiSpotLightProgram);
gDeferredMultiSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION);
@@ -8872,9 +8898,9 @@ void LLPipeline::renderDeferredLighting()
gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mScreen.getWidth(), mScreen.getHeight());
- F32 gamma = 1.0/2.2;
+ F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
- gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, gamma);
+ gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
gGL.begin(LLRender::TRIANGLE_STRIP);
gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
@@ -8953,6 +8979,537 @@ void LLPipeline::renderDeferredLighting()
}
+void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target)
+{
+ if (!sCull)
+ {
+ return;
+ }
+
+ {
+ LLFastTimer ftm(FTM_RENDER_DEFERRED);
+
+ LLViewerCamera* camera = LLViewerCamera::getInstance();
+
+ {
+ LLGLDepthTest depth(GL_TRUE);
+ mDeferredDepth.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(),
+ 0, 0, mDeferredDepth.getWidth(), mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+ }
+
+ LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
+
+ if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
+ {
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
+ }
+
+ //ati doesn't seem to love actually using the stencil buffer on FBO's
+ LLGLDisable stencil(GL_STENCIL_TEST);
+ //glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF);
+ //glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+
+ gGL.setColorMask(true, true);
+
+ //draw a cube around every light
+ LLVertexBuffer::unbind();
+
+ LLGLEnable cull(GL_CULL_FACE);
+ LLGLEnable blend(GL_BLEND);
+
+ glh::matrix4f mat = glh_copy_matrix(gGLModelView);
+
+ LLStrider<LLVector3> vert;
+ mDeferredVB->getVertexStrider(vert);
+
+ vert[0].set(-1,1,0);
+ vert[1].set(-1,-3,0);
+ vert[2].set(3,1,0);
+
+ {
+ setupHWLights(NULL); //to set mSunDir;
+ LLVector4 dir(mSunDir, 0.f);
+ glh::vec4f tc(dir.mV);
+ mat.mult_matrix_vec(tc);
+ mTransformedSunDir.set(tc.v);
+ }
+
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+
+ if (RenderDeferredSSAO || RenderShadowDetail > 0)
+ {
+ mDeferredLight.bindTarget();
+ { //paint shadow/SSAO light map (direct lighting lightmap)
+ LLFastTimer ftm(FTM_SUN_SHADOW);
+ bindDeferredShader(gDeferredSunProgram);
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ glClearColor(1,1,1,1);
+ mDeferredLight.clear(GL_COLOR_BUFFER_BIT);
+ glClearColor(0,0,0,0);
+
+ glh::matrix4f inv_trans = glh_get_current_modelview().inverse().transpose();
+
+ const U32 slice = 32;
+ F32 offset[slice*3];
+ for (U32 i = 0; i < 4; i++)
+ {
+ for (U32 j = 0; j < 8; j++)
+ {
+ glh::vec3f v;
+ v.set_value(sinf(6.284f/8*j), cosf(6.284f/8*j), -(F32) i);
+ v.normalize();
+ inv_trans.mult_matrix_vec(v);
+ v.normalize();
+ offset[(i*8+j)*3+0] = v.v[0];
+ offset[(i*8+j)*3+1] = v.v[2];
+ offset[(i*8+j)*3+2] = v.v[1];
+ }
+ }
+
+ gDeferredSunProgram.uniform3fv("offset", slice, offset);
+ gDeferredSunProgram.uniform2f("screenRes", mDeferredLight.getWidth(), mDeferredLight.getHeight());
+
+ {
+ LLGLDisable blend(GL_BLEND);
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
+ stop_glerror();
+ mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ stop_glerror();
+ }
+
+ unbindDeferredShader(gDeferredSunProgram);
+ }
+ mDeferredLight.flush();
+ }
+
+ stop_glerror();
+ gGL.popMatrix();
+ stop_glerror();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ stop_glerror();
+ gGL.popMatrix();
+ stop_glerror();
+
+ target->bindTarget();
+
+ //clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky
+ glClearColor(0,0,0,0);
+ target->clear(GL_COLOR_BUFFER_BIT);
+
+ if (RenderDeferredAtmospheric)
+ { //apply sunlight contribution
+ LLFastTimer ftm(FTM_ATMOSPHERICS);
+ bindDeferredShader(gDeferredSoftenProgram);
+ {
+ LLGLDepthTest depth(GL_FALSE);
+ LLGLDisable blend(GL_BLEND);
+ LLGLDisable test(GL_ALPHA_TEST);
+
+ //full screen blit
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
+ mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+ gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
+ }
+
+ unbindDeferredShader(gDeferredSoftenProgram);
+ }
+
+ { //render non-deferred geometry (fullbright, alpha, etc)
+ LLGLDisable blend(GL_BLEND);
+ LLGLDisable stencil(GL_STENCIL_TEST);
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
+
+ gPipeline.pushRenderTypeMask();
+
+ gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY,
+ LLPipeline::RENDER_TYPE_CLOUDS,
+ LLPipeline::RENDER_TYPE_WL_SKY,
+ LLPipeline::END_RENDER_TYPES);
+
+
+ renderGeomPostDeferred(*LLViewerCamera::getInstance(), false);
+ gPipeline.popRenderTypeMask();
+ }
+
+ BOOL render_local = RenderLocalLights;
+
+ if (render_local)
+ {
+ gGL.setSceneBlendType(LLRender::BT_ADD);
+ std::list<LLVector4> fullscreen_lights;
+ LLDrawable::drawable_list_t spot_lights;
+ LLDrawable::drawable_list_t fullscreen_spot_lights;
+
+ for (U32 i = 0; i < 2; i++)
+ {
+ mTargetShadowSpotLight[i] = NULL;
+ }
+
+ std::list<LLVector4> light_colors;
+
+ LLVertexBuffer::unbind();
+
+ {
+ bindDeferredShader(gDeferredLightProgram);
+
+ if (mCubeVB.isNull())
+ {
+ mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB);
+ }
+
+ mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE);
+ for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter)
+ {
+ LLDrawable* drawablep = *iter;
+
+ LLVOVolume* volume = drawablep->getVOVolume();
+ if (!volume)
+ {
+ continue;
+ }
+
+ if (volume->isAttachment())
+ {
+ if (!sRenderAttachedLights)
+ {
+ continue;
+ }
+ }
+
+
+ LLVector4a center;
+ center.load3(drawablep->getPositionAgent().mV);
+ const F32* c = center.getF32ptr();
+ F32 s = volume->getLightRadius()*1.5f;
+
+ LLColor3 col = volume->getLightColor();
+
+ if (col.magVecSquared() < 0.001f)
+ {
+ continue;
+ }
+
+ if (s <= 0.001f)
+ {
+ continue;
+ }
+
+ LLVector4a sa;
+ sa.splat(s);
+ if (camera->AABBInFrustumNoFarClip(center, sa) == 0)
+ {
+ continue;
+ }
+
+ sVisibleLightCount++;
+
+ if (camera->getOrigin().mV[0] > c[0] + s + 0.2f ||
+ camera->getOrigin().mV[0] < c[0] - s - 0.2f ||
+ camera->getOrigin().mV[1] > c[1] + s + 0.2f ||
+ camera->getOrigin().mV[1] < c[1] - s - 0.2f ||
+ camera->getOrigin().mV[2] > c[2] + s + 0.2f ||
+ camera->getOrigin().mV[2] < c[2] - s - 0.2f)
+ { //draw box if camera is outside box
+ if (render_local)
+ {
+ if (volume->isLightSpotlight())
+ {
+ drawablep->getVOVolume()->updateSpotLightPriority();
+ spot_lights.push_back(drawablep);
+ continue;
+ }
+
+ /*col.mV[0] = powf(col.mV[0], 2.2f);
+ col.mV[1] = powf(col.mV[1], 2.2f);
+ col.mV[2] = powf(col.mV[2], 2.2f);*/
+
+ LLFastTimer ftm(FTM_LOCAL_LIGHTS);
+ gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);
+ gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
+ gDeferredLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
+ gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
+ gGL.syncMatrices();
+
+ mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center));
+ stop_glerror();
+ }
+ }
+ else
+ {
+ if (volume->isLightSpotlight())
+ {
+ drawablep->getVOVolume()->updateSpotLightPriority();
+ fullscreen_spot_lights.push_back(drawablep);
+ continue;
+ }
+
+ glh::vec3f tc(c);
+ mat.mult_matrix_vec(tc);
+
+ fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s));
+ light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f));
+ }
+ }
+ unbindDeferredShader(gDeferredLightProgram);
+ }
+
+ if (!spot_lights.empty())
+ {
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE);
+ bindDeferredShader(gDeferredSpotLightProgram);
+
+ mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
+ gDeferredSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION);
+
+ for (LLDrawable::drawable_list_t::iterator iter = spot_lights.begin(); iter != spot_lights.end(); ++iter)
+ {
+ LLFastTimer ftm(FTM_PROJECTORS);
+ LLDrawable* drawablep = *iter;
+
+ LLVOVolume* volume = drawablep->getVOVolume();
+
+ LLVector4a center;
+ center.load3(drawablep->getPositionAgent().mV);
+ const F32* c = center.getF32ptr();
+ F32 s = volume->getLightRadius()*1.5f;
+
+ sVisibleLightCount++;
+
+ setupSpotLight(gDeferredSpotLightProgram, drawablep);
+
+ LLColor3 col = volume->getLightColor();
+ /*col.mV[0] = powf(col.mV[0], 2.2f);
+ col.mV[1] = powf(col.mV[1], 2.2f);
+ col.mV[2] = powf(col.mV[2], 2.2f);*/
+
+ gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);
+ gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
+ gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
+ gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
+ gGL.syncMatrices();
+
+ mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center));
+ }
+ gDeferredSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION);
+ unbindDeferredShader(gDeferredSpotLightProgram);
+ }
+
+ //reset mDeferredVB to fullscreen triangle
+ mDeferredVB->getVertexStrider(vert);
+ vert[0].set(-1,1,0);
+ vert[1].set(-1,-3,0);
+ vert[2].set(3,1,0);
+
+ {
+ LLGLDepthTest depth(GL_FALSE);
+
+ //full screen blit
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+
+ U32 count = 0;
+
+ const U32 max_count = LL_DEFERRED_MULTI_LIGHT_COUNT;
+ LLVector4 light[max_count];
+ LLVector4 col[max_count];
+
+ F32 far_z = 0.f;
+
+ while (!fullscreen_lights.empty())
+ {
+ LLFastTimer ftm(FTM_FULLSCREEN_LIGHTS);
+ light[count] = fullscreen_lights.front();
+ fullscreen_lights.pop_front();
+ col[count] = light_colors.front();
+ light_colors.pop_front();
+
+ /*col[count].mV[0] = powf(col[count].mV[0], 2.2f);
+ col[count].mV[1] = powf(col[count].mV[1], 2.2f);
+ col[count].mV[2] = powf(col[count].mV[2], 2.2f);*/
+
+ far_z = llmin(light[count].mV[2]-light[count].mV[3], far_z);
+ //col[count] = pow4fsrgb(col[count], 2.2f);
+ count++;
+ if (count == max_count || fullscreen_lights.empty())
+ {
+ U32 idx = count-1;
+ bindDeferredShader(gDeferredMultiLightProgram[idx]);
+ gDeferredMultiLightProgram[idx].uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count);
+ gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*) light);
+ gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*) col);
+ gDeferredMultiLightProgram[idx].uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z);
+ far_z = 0.f;
+ count = 0;
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ }
+ }
+
+ unbindDeferredShader(gDeferredMultiLightProgram[0]);
+
+ bindDeferredShader(gDeferredMultiSpotLightProgram);
+
+ gDeferredMultiSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION);
+
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
+ for (LLDrawable::drawable_list_t::iterator iter = fullscreen_spot_lights.begin(); iter != fullscreen_spot_lights.end(); ++iter)
+ {
+ LLFastTimer ftm(FTM_PROJECTORS);
+ LLDrawable* drawablep = *iter;
+
+ LLVOVolume* volume = drawablep->getVOVolume();
+
+ LLVector3 center = drawablep->getPositionAgent();
+ F32* c = center.mV;
+ F32 s = volume->getLightRadius()*1.5f;
+
+ sVisibleLightCount++;
+
+ glh::vec3f tc(c);
+ mat.mult_matrix_vec(tc);
+
+ setupSpotLight(gDeferredMultiSpotLightProgram, drawablep);
+
+ LLColor3 col = volume->getLightColor();
+
+ /*col.mV[0] = powf(col.mV[0], 2.2f);
+ col.mV[1] = powf(col.mV[1], 2.2f);
+ col.mV[2] = powf(col.mV[2], 2.2f);*/
+
+ gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v);
+ gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
+ gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
+ gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
+ mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ }
+
+ gDeferredMultiSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION);
+ unbindDeferredShader(gDeferredMultiSpotLightProgram);
+
+ gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
+ }
+ }
+
+ gGL.setColorMask(true, true);
+ }
+
+ /*target->flush();
+
+ //gamma correct lighting
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+
+ {
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE);
+
+ LLVector2 tc1(0,0);
+ LLVector2 tc2((F32) target->getWidth()*2,
+ (F32) target->getHeight()*2);
+
+ target->bindTarget();
+ // Apply gamma correction to the frame here.
+ gDeferredPostGammaCorrectProgram.bind();
+ //mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ S32 channel = 0;
+ channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, target->getUsage());
+ if (channel > -1)
+ {
+ target->bindTexture(0,channel);
+ gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+ }
+
+ gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, target->getWidth(), target->getHeight());
+
+ F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
+
+ gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
+
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
+ gGL.vertex2f(-1,-1);
+
+ gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
+ gGL.vertex2f(-1,3);
+
+ gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
+ gGL.vertex2f(3,-1);
+
+ gGL.end();
+
+ gGL.getTexUnit(channel)->unbind(target->getUsage());
+ gDeferredPostGammaCorrectProgram.unbind();
+ target->flush();
+ }
+
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
+
+ target->bindTarget();*/
+
+ { //render non-deferred geometry (alpha, fullbright, glow)
+ LLGLDisable blend(GL_BLEND);
+ LLGLDisable stencil(GL_STENCIL_TEST);
+
+ pushRenderTypeMask();
+ andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA,
+ LLPipeline::RENDER_TYPE_FULLBRIGHT,
+ LLPipeline::RENDER_TYPE_VOLUME,
+ LLPipeline::RENDER_TYPE_GLOW,
+ LLPipeline::RENDER_TYPE_BUMP,
+ LLPipeline::RENDER_TYPE_PASS_SIMPLE,
+ LLPipeline::RENDER_TYPE_PASS_ALPHA,
+ LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_PASS_BUMP,
+ LLPipeline::RENDER_TYPE_PASS_POST_BUMP,
+ LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT,
+ LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY,
+ LLPipeline::RENDER_TYPE_PASS_GLOW,
+ LLPipeline::RENDER_TYPE_PASS_GRASS,
+ LLPipeline::RENDER_TYPE_PASS_SHINY,
+ LLPipeline::RENDER_TYPE_PASS_INVISIBLE,
+ LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY,
+ LLPipeline::RENDER_TYPE_AVATAR,
+ LLPipeline::RENDER_TYPE_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK,
+ END_RENDER_TYPES);
+
+ renderGeomPostDeferred(*LLViewerCamera::getInstance());
+ popRenderTypeMask();
+ }
+
+ //target->flush();
+}
+
void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
{
//construct frustum
@@ -9199,6 +9756,12 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
water_clip = 1;
}
+ bool materials_in_water = false;
+
+#if MATERIALS_IN_REFLECTIONS
+ materials_in_water = gSavedSettings.getS32("RenderWaterMaterials");
+#endif
+
if (!LLViewerCamera::getInstance()->cameraUnderWater())
{ //generate planar reflection map
@@ -9207,7 +9770,9 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
LLPipeline::sUseOcclusion = 0;
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
glClearColor(0,0,0,0);
+
mWaterRef.bindTarget();
+
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER0;
gGL.setColorMask(true, true);
mWaterRef.clear();
@@ -9256,11 +9821,27 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
updateCull(camera, result);
stateSort(camera, result);
+ if (LLPipeline::sRenderDeferred && materials_in_water)
+ {
+ mWaterRef.flush();
+
+ gPipeline.grabReferences(result);
+ gPipeline.mDeferredScreen.bindTarget();
+ gGL.setColorMask(true, true);
+ glClearColor(0,0,0,0);
+ gPipeline.mDeferredScreen.clear();
+
+ renderGeomDeferred(camera);
+ }
+ else
+ {
renderGeom(camera, TRUE);
+ }
gPipeline.popRenderTypeMask();
}
+ gGL.setColorMask(true, false);
gPipeline.pushRenderTypeMask();
clearRenderTypeMask(LLPipeline::RENDER_TYPE_WATER,
@@ -9298,9 +9879,23 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
{
gPipeline.grabReferences(ref_result);
LLGLUserClipPlane clip_plane(plane, mat, projection);
+
+ if (LLPipeline::sRenderDeferred && materials_in_water)
+ {
+ renderGeomDeferred(camera);
+ }
+ else
+ {
renderGeom(camera);
}
}
+ }
+
+ if (LLPipeline::sRenderDeferred && materials_in_water)
+ {
+ gPipeline.mDeferredScreen.flush();
+ renderDeferredLightingToRT(&mWaterRef);
+ }
gPipeline.popRenderTypeMask();
}
@@ -9336,10 +9931,12 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
LLViewerCamera::updateFrustumPlanes(camera);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
LLColor4& col = LLDrawPoolWater::sWaterFogColor;
glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);
mWaterDis.bindTarget();
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER1;
+
mWaterDis.getViewport(gGLViewport);
if (!LLPipeline::sUnderWaterRender || LLDrawPoolWater::sNeedsReflectionUpdate)
@@ -9355,14 +9952,36 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
gGL.setColorMask(true, true);
mWaterDis.clear();
+
+
gGL.setColorMask(true, false);
+
+ if (LLPipeline::sRenderDeferred && materials_in_water)
+ {
+ mWaterDis.flush();
+ gPipeline.mDeferredScreen.bindTarget();
+ gGL.setColorMask(true, true);
+ glClearColor(0,0,0,0);
+ gPipeline.mDeferredScreen.clear();
+ gPipeline.grabReferences(result);
+ renderGeomDeferred(camera);
+ }
+ else
+ {
renderGeom(camera);
+ }
+ if (LLPipeline::sRenderDeferred && materials_in_water)
+ {
+ gPipeline.mDeferredScreen.flush();
+ renderDeferredLightingToRT(&mWaterDis);
+ }
}
- LLPipeline::sUnderWaterRender = FALSE;
mWaterDis.flush();
+ LLPipeline::sUnderWaterRender = FALSE;
+
}
last_update = LLDrawPoolWater::sNeedsReflectionUpdate && LLDrawPoolWater::sNeedsDistortionUpdate;
@@ -9769,14 +10388,14 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector
const LLPlane& cp = camera.getAgentPlane(j);
F32 dist = cp.dist(pp[i]);
if (dist > 0.05f) //point is above some plane, not contained
- {
+ {
found = false;
break;
- }
- }
+ }
+ }
- if (found)
- {
+ if (found)
+ {
fp.push_back(pp[i]);
}
}
@@ -10688,29 +11307,37 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
}
else
{
- andRenderTypeMask(LLPipeline::RENDER_TYPE_VOLUME,
- LLPipeline::RENDER_TYPE_AVATAR,
+ andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA,
+ LLPipeline::RENDER_TYPE_FULLBRIGHT,
+ LLPipeline::RENDER_TYPE_VOLUME,
+ LLPipeline::RENDER_TYPE_GLOW,
LLPipeline::RENDER_TYPE_BUMP,
- LLPipeline::RENDER_TYPE_GRASS,
- LLPipeline::RENDER_TYPE_SIMPLE,
- LLPipeline::RENDER_TYPE_FULLBRIGHT,
- LLPipeline::RENDER_TYPE_ALPHA,
- LLPipeline::RENDER_TYPE_INVISIBLE,
LLPipeline::RENDER_TYPE_PASS_SIMPLE,
LLPipeline::RENDER_TYPE_PASS_ALPHA,
LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_PASS_BUMP,
+ LLPipeline::RENDER_TYPE_PASS_POST_BUMP,
LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT,
LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK,
LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY,
+ LLPipeline::RENDER_TYPE_PASS_GLOW,
+ LLPipeline::RENDER_TYPE_PASS_GRASS,
LLPipeline::RENDER_TYPE_PASS_SHINY,
LLPipeline::RENDER_TYPE_PASS_INVISIBLE,
LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY,
+ LLPipeline::RENDER_TYPE_AVATAR,
+ LLPipeline::RENDER_TYPE_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_INVISIBLE,
+ LLPipeline::RENDER_TYPE_SIMPLE,
END_RENDER_TYPES);
}
S32 occlusion = sUseOcclusion;
sUseOcclusion = 0;
+
sReflectionRender = sRenderDeferred ? FALSE : TRUE;
+
sShadowRender = TRUE;
sImpostorRender = TRUE;
@@ -10805,22 +11432,26 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
if (!avatar->mImpostor.isComplete())
{
LLFastTimer t(FTM_IMPOSTOR_ALLOCATE);
- avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,FALSE);
+
if (LLPipeline::sRenderDeferred)
{
+ avatar->mImpostor.allocate(resX,resY,GL_SRGB8_ALPHA8,TRUE,FALSE);
addDeferredAttachments(avatar->mImpostor);
}
+ else
+ {
+ avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,FALSE);
+ }
gGL.getTexUnit(0)->bind(&avatar->mImpostor);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
}
- else if(resX != avatar->mImpostor.getWidth() ||
- resY != avatar->mImpostor.getHeight())
+ else if(resX != avatar->mImpostor.getWidth() || resY != avatar->mImpostor.getHeight())
{
LLFastTimer t(FTM_IMPOSTOR_RESIZE);
- avatar->mImpostor.resize(resX,resY,GL_RGBA);
+ avatar->mImpostor.resize(resX,resY);
}
avatar->mImpostor.bindTarget();
@@ -10830,7 +11461,23 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
{
avatar->mImpostor.clear();
renderGeomDeferred(camera);
+
+ renderGeomPostDeferred(camera);
+
+ // Shameless hack time: render it all again,
+ // this time writing the depth
+ // values we need to generate the alpha mask below
+ // while preserving the alpha-sorted color rendering
+ // from the previous pass
+ //
+ sImpostorRenderAlphaDepthPass = true;
+ // depth-only here...
+ //
+ gGL.setColorMask(false,false);
renderGeomPostDeferred(camera);
+
+ sImpostorRenderAlphaDepthPass = false;
+
}
else
{
@@ -10838,10 +11485,26 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
glScissor(0, 0, resX, resY);
avatar->mImpostor.clear();
renderGeom(camera);
+
+ // Shameless hack time: render it all again,
+ // this time writing the depth
+ // values we need to generate the alpha mask below
+ // while preserving the alpha-sorted color rendering
+ // from the previous pass
+ //
+ sImpostorRenderAlphaDepthPass = true;
+
+ // depth-only here...
+ //
+ gGL.setColorMask(false,false);
+ renderGeom(camera);
+
+ sImpostorRenderAlphaDepthPass = false;
}
{ //create alpha mask based on depth buffer (grey out if muted)
LLFastTimer t(FTM_IMPOSTOR_BACKGROUND);
+
if (LLPipeline::sRenderDeferred)
{
GLuint buff = GL_COLOR_ATTACHMENT0;
@@ -11226,6 +11889,3 @@ void LLPipeline::restoreHiddenObject( const LLUUID& id )
}
}
-
-
-
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 5ac2ec2b20..426c0c4915 100644
--- a/indra/newview/skins/default/xui/en/panel_tools_texture.xml
+++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml
@@ -663,7 +663,7 @@
label_width="205"
layout="topleft"
left="10"
- min_val="-1"
+ min_val="0"
name="bumpyOffsetU"
width="265" />
<spinner
@@ -674,7 +674,7 @@
label_width="205"
layout="topleft"
left="10"
- min_val="-1"
+ min_val="0"
name="bumpyOffsetV"
width="265" />
<spinner
@@ -726,7 +726,7 @@
label_width="205"
layout="topleft"
left="10"
- min_val="-1"
+ min_val="0"
name="shinyOffsetU"
width="265" />
<spinner
@@ -737,7 +737,7 @@
label_width="205"
layout="topleft"
left="10"
- min_val="-1"
+ min_val="0"
name="shinyOffsetV"
width="265" />
<check_box