Merge branch 'master' of git://github.com/Shyotl/SingularityViewer

This commit is contained in:
Latif Khalifa
2013-11-02 07:25:36 +01:00
121 changed files with 8416 additions and 3292 deletions

View File

@@ -166,7 +166,8 @@ void calc_tangent_from_triangle(
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
float r = ((rd*rd) > FLT_EPSILON) ? (1.0f / rd)
: ((rd > 0.0f) ? 1024.f : -1024.f); //some made up large ratio for division by zero
llassert(llfinite(r));
llassert(!llisnan(r));
@@ -6801,7 +6802,8 @@ void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVe
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
float r = ((rd*rd) > FLT_EPSILON) ? (1.0f / rd)
: ((rd > 0.0f) ? 1024.f : -1024.f); //some made up large ratio for division by zero
llassert(llfinite(r));
llassert(!llisnan(r));

View File

@@ -37,53 +37,46 @@
const S32 PS_PART_DATA_BLOCK_SIZE = 4 + 2 + 4 + 4 + 2 + 2; // 18
const S32 PS_DATA_BLOCK_SIZE = 68 + PS_PART_DATA_BLOCK_SIZE; // 68 + 18 = 86
const S32 PS_PART_DATA_GLOW_SIZE = 2;
const S32 PS_PART_DATA_BLEND_SIZE = 2;
const S32 PS_LEGACY_PART_DATA_BLOCK_SIZE = 4 + 2 + 4 + 4 + 2 + 2; //18
const S32 PS_SYS_DATA_BLOCK_SIZE = 68;
const S32 PS_MAX_DATA_BLOCK_SIZE = PS_SYS_DATA_BLOCK_SIZE+
PS_LEGACY_PART_DATA_BLOCK_SIZE +
PS_PART_DATA_BLEND_SIZE +
PS_PART_DATA_GLOW_SIZE+
8; //two S32 size fields
const S32 PS_LEGACY_DATA_BLOCK_SIZE = PS_SYS_DATA_BLOCK_SIZE + PS_LEGACY_PART_DATA_BLOCK_SIZE;
const U32 PART_DATA_MASK = LLPartData::LL_PART_DATA_GLOW | LLPartData::LL_PART_DATA_BLEND;
const F32 MAX_PART_SCALE = 4.f;
BOOL LLPartData::pack(LLDataPacker &dp)
bool LLPartData::hasGlow() const
{
LLColor4U coloru;
dp.packU32(mFlags, "pdflags");
dp.packFixed(mMaxAge, "pdmaxage", FALSE, 8, 8);
coloru.setVec(mStartColor);
dp.packColor4U(coloru, "pdstartcolor");
coloru.setVec(mEndColor);
dp.packColor4U(coloru, "pdendcolor");
dp.packFixed(mStartScale.mV[0], "pdstartscalex", FALSE, 3, 5);
dp.packFixed(mStartScale.mV[1], "pdstartscaley", FALSE, 3, 5);
dp.packFixed(mEndScale.mV[0], "pdendscalex", FALSE, 3, 5);
dp.packFixed(mEndScale.mV[1], "pdendscaley", FALSE, 3, 5);
return TRUE;
return mStartGlow > 0.f || mEndGlow > 0.f;
}
LLSD LLPartData::asLLSD() const
bool LLPartData::hasBlendFunc() const
{
LLSD sd = LLSD();
sd["pdflags"] = ll_sd_from_U32(mFlags);
sd["pdmaxage"] = mMaxAge;
sd["pdstartcolor"] = ll_sd_from_color4(mStartColor);
sd["pdendcolor"] = ll_sd_from_color4(mEndColor);
sd["pdstartscale"] = ll_sd_from_vector2(mStartScale);
sd["pdendscale"] = ll_sd_from_vector2(mEndScale);
return sd;
return mBlendFuncSource != LLPartData::LL_PART_BF_SOURCE_ALPHA || mBlendFuncDest != LLPartData::LL_PART_BF_ONE_MINUS_SOURCE_ALPHA;
}
bool LLPartData::fromLLSD(LLSD& sd)
S32 LLPartData::getSize() const
{
mFlags = ll_U32_from_sd(sd["pdflags"]);
mMaxAge = (F32)sd["pdmaxage"].asReal();
mStartColor = ll_color4_from_sd(sd["pdstartcolor"]);
mEndColor = ll_color4_from_sd(sd["pdendcolor"]);
mStartScale = ll_vector2_from_sd(sd["pdstartscale"]);
mEndScale = ll_vector2_from_sd(sd["pdendscale"]);
return true;
S32 size = PS_LEGACY_PART_DATA_BLOCK_SIZE;
if (hasGlow()) size += PS_PART_DATA_GLOW_SIZE;
if (hasBlendFunc()) size += PS_PART_DATA_BLEND_SIZE;
return size;
}
BOOL LLPartData::unpack(LLDataPacker &dp)
BOOL LLPartData::unpackLegacy(LLDataPacker &dp)
{
LLColor4U coloru;
@@ -98,9 +91,70 @@ BOOL LLPartData::unpack(LLDataPacker &dp)
dp.unpackFixed(mStartScale.mV[1], "pdstartscaley", FALSE, 3, 5);
dp.unpackFixed(mEndScale.mV[0], "pdendscalex", FALSE, 3, 5);
dp.unpackFixed(mEndScale.mV[1], "pdendscaley", FALSE, 3, 5);
mStartGlow = 0.f;
mEndGlow = 0.f;
mBlendFuncSource = LLPartData::LL_PART_BF_SOURCE_ALPHA;
mBlendFuncDest = LLPartData::LL_PART_BF_ONE_MINUS_SOURCE_ALPHA;
return TRUE;
}
BOOL LLPartData::unpack(LLDataPacker &dp)
{
S32 size = 0;
dp.unpackS32(size, "partsize");
unpackLegacy(dp);
size -= PS_LEGACY_PART_DATA_BLOCK_SIZE;
if (mFlags & LL_PART_DATA_GLOW)
{
if (size < PS_PART_DATA_GLOW_SIZE) return FALSE;
U8 tmp_glow = 0;
dp.unpackU8(tmp_glow,"pdstartglow");
mStartGlow = tmp_glow / 255.f;
dp.unpackU8(tmp_glow,"pdendglow");
mEndGlow = tmp_glow / 255.f;
size -= PS_PART_DATA_GLOW_SIZE;
}
else
{
mStartGlow = 0.f;
mEndGlow = 0.f;
}
if (mFlags & LL_PART_DATA_BLEND)
{
if (size < PS_PART_DATA_BLEND_SIZE) return FALSE;
dp.unpackU8(mBlendFuncSource,"pdblendsource");
dp.unpackU8(mBlendFuncDest,"pdblenddest");
size -= PS_PART_DATA_BLEND_SIZE;
}
else
{
mBlendFuncSource = LLPartData::LL_PART_BF_SOURCE_ALPHA;
mBlendFuncDest = LLPartData::LL_PART_BF_ONE_MINUS_SOURCE_ALPHA;
}
if (size > 0)
{ //leftover bytes, unrecognized parameters
U8 feh = 0;
while (size > 0)
{ //read remaining bytes in block
dp.unpackU8(feh, "whippang");
size--;
}
//this particle system won't display properly, better to not show anything
return FALSE;
}
return TRUE;
}
void LLPartData::setFlags(const U32 flags)
{
@@ -148,6 +202,18 @@ void LLPartData::setEndAlpha(const F32 alpha)
mEndColor.mV[3] = alpha;
}
// static
bool LLPartData::validBlendFunc(S32 func)
{
if (func >= 0
&& func < LL_PART_BF_COUNT
&& func != UNSUPPORTED_DEST_ALPHA
&& func != UNSUPPORTED_ONE_MINUS_DEST_ALPHA)
{
return true;
}
return false;
}
LLPartSysData::LLPartSysData()
{
@@ -160,6 +226,10 @@ LLPartSysData::LLPartSysData()
mPartData.mStartScale = LLVector2(1.f, 1.f);
mPartData.mEndScale = LLVector2(1.f, 1.f);
mPartData.mMaxAge = 10.0;
mPartData.mBlendFuncSource = LLPartData::LL_PART_BF_SOURCE_ALPHA;
mPartData.mBlendFuncDest = LLPartData::LL_PART_BF_ONE_MINUS_SOURCE_ALPHA;
mPartData.mStartGlow = 0.f;
mPartData.mEndGlow = 0.f;
mMaxAge = 0.0;
mStartAge = 0.0;
@@ -175,38 +245,7 @@ LLPartSysData::LLPartSysData()
mNumParticles = 0;
}
BOOL LLPartSysData::pack(LLDataPacker &dp)
{
dp.packU32(mCRC, "pscrc");
dp.packU32(mFlags, "psflags");
dp.packU8(mPattern, "pspattern");
dp.packFixed(mMaxAge, "psmaxage", FALSE, 8, 8);
dp.packFixed(mStartAge, "psstartage", FALSE, 8, 8);
dp.packFixed(mInnerAngle, "psinnerangle", FALSE, 3, 5);
dp.packFixed(mOuterAngle, "psouterangle", FALSE, 3, 5);
dp.packFixed(mBurstRate, "psburstrate", FALSE, 8, 8);
dp.packFixed(mBurstRadius, "psburstradius", FALSE, 8, 8);
dp.packFixed(mBurstSpeedMin, "psburstspeedmin", FALSE, 8, 8);
dp.packFixed(mBurstSpeedMax, "psburstspeedmax", FALSE, 8, 8);
dp.packU8(mBurstPartCount, "psburstpartcount");
dp.packFixed(mAngularVelocity.mV[0], "psangvelx", TRUE, 8, 7);
dp.packFixed(mAngularVelocity.mV[1], "psangvely", TRUE, 8, 7);
dp.packFixed(mAngularVelocity.mV[2], "psangvelz", TRUE, 8, 7);
dp.packFixed(mPartAccel.mV[0], "psaccelx", TRUE, 8, 7);
dp.packFixed(mPartAccel.mV[1], "psaccely", TRUE, 8, 7);
dp.packFixed(mPartAccel.mV[2], "psaccelz", TRUE, 8, 7);
dp.packUUID(mPartImageID, "psuuid");
dp.packUUID(mTargetUUID, "pstargetuuid");
mPartData.pack(dp);
return TRUE;
}
BOOL LLPartSysData::unpack(LLDataPacker &dp)
BOOL LLPartSysData::unpackSystem(LLDataPacker &dp)
{
dp.unpackU32(mCRC, "pscrc");
dp.unpackU32(mFlags, "psflags");
@@ -232,20 +271,58 @@ BOOL LLPartSysData::unpack(LLDataPacker &dp)
dp.unpackUUID(mPartImageID, "psuuid");
dp.unpackUUID(mTargetUUID, "pstargetuuid");
mPartData.unpack(dp);
return TRUE;
}
BOOL LLPartSysData::unpackLegacy(LLDataPacker &dp)
{
unpackSystem(dp);
mPartData.unpackLegacy(dp);
return TRUE;
}
BOOL LLPartSysData::unpack(LLDataPacker &dp)
{
// syssize is currently unused. Adding now when modifying the 'version to make extensible in the future
S32 size = 0;
dp.unpackS32(size, "syssize");
if (size != PS_SYS_DATA_BLOCK_SIZE)
{ //unexpected size, this viewer doesn't know how to parse this particle system
//skip to LLPartData block
U8 feh = 0;
for (U32 i = 0; i < size; ++i)
{
dp.unpackU8(feh, "whippang");
}
dp.unpackS32(size, "partsize");
//skip LLPartData block
for (U32 i = 0; i < size; ++i)
{
dp.unpackU8(feh, "whippang");
}
return FALSE;
}
unpackSystem(dp);
return mPartData.unpack(dp);
}
std::ostream& operator<<(std::ostream& s, const LLPartSysData &data)
{
s << "Flags: " << std::hex << data.mFlags << std::dec;
s << " Pattern: " << std::hex << (U32) data.mPattern << std::dec << "\n";
s << "Flags: " << std::hex << data.mFlags;
s << " Pattern: " << std::hex << (U32) data.mPattern << "\n";
s << "Age: [" << data.mStartAge << ", " << data.mMaxAge << "]\n";
s << "Angle: [" << data.mInnerAngle << ", " << data.mOuterAngle << "]\n";
s << "Burst Rate: " << data.mBurstRate << "\n";
s << "Burst Radius: " << data.mBurstRadius << "\n";
s << "Burst Speed: [" << data.mBurstSpeedMin << ", " << data.mBurstSpeedMax << "]\n";
s << "Burst Part Count: " << std::hex << (U32) data.mBurstPartCount << std::dec << "\n";
s << "Burst Part Count: " << std::hex << (U32) data.mBurstPartCount << "\n";
s << "Angular Velocity: " << data.mAngularVelocity << "\n";
s << "Accel: " << data.mPartAccel;
return s;
@@ -253,7 +330,7 @@ std::ostream& operator<<(std::ostream& s, const LLPartSysData &data)
BOOL LLPartSysData::isNullPS(const S32 block_num)
{
U8 ps_data_block[PS_DATA_BLOCK_SIZE];
U8 ps_data_block[PS_MAX_DATA_BLOCK_SIZE];
U32 crc;
S32 size;
@@ -264,14 +341,28 @@ BOOL LLPartSysData::isNullPS(const S32 block_num)
{
return TRUE;
}
else if (size != PS_DATA_BLOCK_SIZE)
if (size > PS_MAX_DATA_BLOCK_SIZE)
{
llwarns << "PSBlock is wrong size for particle system data - got " << size << ", expecting " << PS_DATA_BLOCK_SIZE << llendl;
//size is too big, newer particle version unsupported
return TRUE;
}
gMessageSystem->getBinaryData("ObjectData", "PSBlock", ps_data_block, PS_DATA_BLOCK_SIZE, block_num, PS_DATA_BLOCK_SIZE);
LLDataPackerBinaryBuffer dp(ps_data_block, PS_DATA_BLOCK_SIZE);
gMessageSystem->getBinaryData("ObjectData", "PSBlock", ps_data_block, size, block_num, PS_MAX_DATA_BLOCK_SIZE);
LLDataPackerBinaryBuffer dp(ps_data_block, size);
if (size > PS_LEGACY_DATA_BLOCK_SIZE)
{
// non legacy systems pack a size before the CRC
S32 tmp = 0;
dp.unpackS32(tmp, "syssize");
if (tmp > PS_SYS_DATA_BLOCK_SIZE)
{ //unknown system data block size, don't know how to parse it, treat as NULL
return TRUE;
}
}
dp.unpackU32(crc, "crc");
if (crc == 0)
@@ -281,50 +372,37 @@ BOOL LLPartSysData::isNullPS(const S32 block_num)
return FALSE;
}
//static
BOOL LLPartSysData::packNull()
{
U8 ps_data_block[PS_DATA_BLOCK_SIZE];
gMessageSystem->addBinaryData("PSBlock", ps_data_block, 0);
return TRUE;
}
BOOL LLPartSysData::packBlock()
{
U8 ps_data_block[PS_DATA_BLOCK_SIZE];
LLDataPackerBinaryBuffer dp(ps_data_block, PS_DATA_BLOCK_SIZE);
pack(dp);
// Add to message
gMessageSystem->addBinaryData("PSBlock", ps_data_block, PS_DATA_BLOCK_SIZE);
return TRUE;
}
BOOL LLPartSysData::unpackBlock(const S32 block_num)
{
U8 ps_data_block[PS_DATA_BLOCK_SIZE];
U8 ps_data_block[PS_MAX_DATA_BLOCK_SIZE];
// Check size of block
S32 size = gMessageSystem->getSize("ObjectData", block_num, "PSBlock");
if (size != PS_DATA_BLOCK_SIZE)
if (size > PS_MAX_DATA_BLOCK_SIZE)
{
llwarns << "PSBlock is wrong size for particle system data - got " << size << ", expecting " << PS_DATA_BLOCK_SIZE << llendl;
// Larger packets are newer and unsupported
return FALSE;
}
// Get from message
gMessageSystem->getBinaryData("ObjectData", "PSBlock", ps_data_block, PS_DATA_BLOCK_SIZE, block_num, PS_DATA_BLOCK_SIZE);
gMessageSystem->getBinaryData("ObjectData", "PSBlock", ps_data_block, size, block_num, PS_MAX_DATA_BLOCK_SIZE);
LLDataPackerBinaryBuffer dp(ps_data_block, PS_DATA_BLOCK_SIZE);
unpack(dp);
LLDataPackerBinaryBuffer dp(ps_data_block, size);
return TRUE;
if (size == PS_LEGACY_DATA_BLOCK_SIZE)
{
return unpackLegacy(dp);
}
else
{
return unpack(dp);
}
}
bool LLPartSysData::isLegacyCompatible() const
{
return !mPartData.hasGlow() && !mPartData.hasBlendFunc();
}
void LLPartSysData::clampSourceParticleRate()

View File

@@ -70,7 +70,12 @@ enum LLPSScriptFlags
LLPS_SRC_TARGET_UUID,
LLPS_SRC_OMEGA,
LLPS_SRC_ANGLE_BEGIN,
LLPS_SRC_ANGLE_END
LLPS_SRC_ANGLE_END,
LLPS_PART_BLEND_FUNC_SOURCE,
LLPS_PART_BLEND_FUNC_DEST,
LLPS_PART_START_GLOW,
LLPS_PART_END_GLOW
};
@@ -83,11 +88,13 @@ public:
mParameter(0.f)
{
}
BOOL unpackLegacy(LLDataPacker &dp);
BOOL unpack(LLDataPacker &dp);
BOOL pack(LLDataPacker &dp);
LLSD asLLSD() const;
operator LLSD() const {return asLLSD(); }
bool fromLLSD(LLSD& sd);
bool hasGlow() const;
bool hasBlendFunc() const;
// Masks for the different particle flags
enum
@@ -102,17 +109,39 @@ public:
LL_PART_TARGET_LINEAR_MASK = 0x80, // Particle uses a direct linear interpolation
LL_PART_EMISSIVE_MASK = 0x100, // Particle is "emissive", instead of being lit
LL_PART_BEAM_MASK = 0x200, // Particle is a "beam" connecting source and target
LL_PART_RIBBON_MASK = 0x400, // Particles are joined together into one continuous triangle strip
// Not implemented yet!
//LL_PART_RANDOM_ACCEL_MASK = 0x100, // Particles have random acceleration
//LL_PART_RANDOM_VEL_MASK = 0x200, // Particles have random velocity shifts"
//LL_PART_TRAIL_MASK = 0x400, // Particles have historical "trails"
//sYSTEM SET FLAGS
LL_PART_DATA_GLOW = 0x10000,
LL_PART_DATA_BLEND = 0x20000,
// Viewer side use only!
LL_PART_HUD = 0x40000000,
LL_PART_DEAD_MASK = 0x80000000,
};
enum
{
LL_PART_BF_ONE = 0,
LL_PART_BF_ZERO = 1,
LL_PART_BF_DEST_COLOR = 2,
LL_PART_BF_SOURCE_COLOR = 3,
LL_PART_BF_ONE_MINUS_DEST_COLOR = 4,
LL_PART_BF_ONE_MINUS_SOURCE_COLOR = 5,
UNSUPPORTED_DEST_ALPHA = 6,
LL_PART_BF_SOURCE_ALPHA = 7,
UNSUPPORTED_ONE_MINUS_DEST_ALPHA = 8,
LL_PART_BF_ONE_MINUS_SOURCE_ALPHA = 9,
LL_PART_BF_COUNT = 10
};
static bool validBlendFunc(S32 func);
void setFlags(const U32 flags);
void setMaxAge(const F32 max_age);
void setStartScale(const F32 xs, F32 ys);
@@ -126,6 +155,9 @@ public:
friend class LLPartSysData;
friend class LLViewerPartSourceScript;
private:
S32 getSize() const;
// These are public because I'm really lazy...
public:
U32 mFlags; // Particle state/interpolators in effect
@@ -137,6 +169,12 @@ public:
LLVector3 mPosOffset; // Offset from source if using FOLLOW_SOURCE
F32 mParameter; // A single floating point parameter
F32 mStartGlow;
F32 mEndGlow;
U8 mBlendFuncSource;
U8 mBlendFuncDest;
};
@@ -146,15 +184,13 @@ public:
LLPartSysData();
BOOL unpack(LLDataPacker &dp);
BOOL pack(LLDataPacker &dp);
BOOL unpackLegacy(LLDataPacker &dp);
BOOL unpackBlock(const S32 block_num);
BOOL packBlock();
static BOOL packNull();
static BOOL isNullPS(const S32 block_num); // Returns FALSE if this is a "NULL" particle system (i.e. no system)
bool isLegacyCompatible() const;
// Different masks for effects on the source
enum
{
@@ -187,7 +223,12 @@ public:
void clampSourceParticleRate();
friend std::ostream& operator<<(std::ostream& s, const LLPartSysData &data); // Stream a
S32 getdataBlockSize() const;
private:
BOOL unpackSystem(LLDataPacker &dp);
public:
// Public because I'm lazy....

View File

@@ -38,6 +38,8 @@
#include "lldatapacker.h"
#include "llsdutil_math.h"
#include "llprimtexturelist.h"
#include "imageids.h"
#include "llmaterialid.h"
/**
* exported constants
@@ -1062,7 +1064,7 @@ S32 LLPrimitive::unpackTEField(U8 *cur_ptr, U8 *buffer_end, U8 *data_ptr, U8 dat
while ((cur_ptr < buffer_end) && (*cur_ptr != 0))
{
// llinfos << "TE exception" << llendl;
LL_DEBUGS("TEFieldDecode") << "TE exception" << LL_ENDL;
i = 0;
while (*cur_ptr & 0x80)
{
@@ -1077,14 +1079,16 @@ S32 LLPrimitive::unpackTEField(U8 *cur_ptr, U8 *buffer_end, U8 *data_ptr, U8 dat
if (i & 0x01)
{
htonmemcpy(data_ptr+(j*data_size),cur_ptr,type,data_size);
// char foo[64];
// sprintf(foo,"%x %x",*(data_ptr+(j*data_size)), *(data_ptr+(j*data_size)+1));
// llinfos << "Assigning " << foo << " to face " << j << llendl;
LL_DEBUGS("TEFieldDecode") << "Assigning " ;
char foo[64];
sprintf(foo,"%x %x",*(data_ptr+(j*data_size)), *(data_ptr+(j*data_size)+1));
LL_CONT << foo << " to face " << j << LL_ENDL;
}
i = i >> 1;
}
cur_ptr += data_size;
}
llassert(cur_ptr <= buffer_end); // buffer underrun
return (S32)(cur_ptr - start_loc);
}

View File

@@ -159,6 +159,11 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * 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();
for ( ; fileIter != mShaderFiles.end(); fileIter++ )

View File

@@ -1075,6 +1075,15 @@ LLRender::~LLRender()
void LLRender::init()
{
if (sGLCoreProfile && !LLVertexBuffer::sUseVAO)
{ //bind a dummy vertex array object so we're core profile compliant
#ifdef GL_ARB_vertex_array_object
U32 ret;
glGenVertexArrays(1, &ret);
glBindVertexArray(ret);
#endif
}
llassert_always(mBuffer.isNull()) ;
stop_glerror();
mBuffer = new LLVertexBuffer(immediate_mask, 0);
@@ -2295,6 +2304,22 @@ void LLRender::diffuseColor4ubv(const U8* c)
}
}
void LLRender::diffuseColor4ub(U8 r, U8 g, U8 b, U8 a)
{
LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL);
if (shader)
{
shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, r/255.f, g/255.f, b/255.f, a/255.f);
}
else
{
glColor4ub(r,g,b,a);
}
}
void LLRender::debugTexUnits(void)
{
LL_INFOS("TextureUnit") << "Active TexUnit: " << mCurrTextureUnitIndex << LL_ENDL;

View File

@@ -262,6 +262,14 @@ class LLRender
friend class LLTexUnit;
public:
enum eTexIndex
{
DIFFUSE_MAP = 0,
NORMAL_MAP,
SPECULAR_MAP,
NUM_TEXTURE_CHANNELS,
};
typedef enum {
TRIANGLES = 0,
TRIANGLE_STRIP,
@@ -390,6 +398,7 @@ public:
void diffuseColor4f(F32 r, F32 g, F32 b, F32 a);
void diffuseColor4fv(const F32* c);
void diffuseColor4ubv(const U8* c);
void diffuseColor4ub(U8 r, U8 g, U8 b, U8 a);
void vertexBatchPreTransformed(LLVector4a* verts, S32 vert_count);
void vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, S32 vert_count);

View File

@@ -534,8 +534,11 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
range = mShaderObjects.equal_range(filename);
for (std::multimap<std::string, CachedObjectInfo>::iterator it = range.first; it != range.second;++it)
{
if((*it).second.mLevel == shader_level && (*it).second.mType == type)
if((*it).second.mLevel == shader_level && (*it).second.mType == type && (*it).second.mDefinitions == (defines ? *defines : std::map<std::string, std::string>()))
{
llinfos << "Loading cached shader for " << filename << llendl;
return (*it).second.mHandle;
}
}
GLenum error = GL_NO_ERROR;
@@ -713,6 +716,8 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
}
*/
text[count++] = strdup("#define HAS_DIFFUSE_LOOKUP 1\n");
//uniform declartion
for (S32 i = 0; i < texture_index_channels; ++i)
{
@@ -770,6 +775,10 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
llerrs << "Indexed texture rendering requires GLSL 1.30 or later." << llendl;
}
}
else
{
text[count++] = strdup("#define HAS_DIFFUSE_LOOKUP 0\n");
}
//copy file into memory
while( fgets((char *)buff, 1024, file) != NULL && count < LL_ARRAY_SIZE(text) )
@@ -918,7 +927,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
if (ret)
{
// Add shader file to map
mShaderObjects.insert(make_pair(filename,CachedObjectInfo(ret,try_gpu_class,type)));
mShaderObjects.insert(make_pair(filename,CachedObjectInfo(ret,try_gpu_class,type,defines)));
shader_level = try_gpu_class;
}
else
@@ -1129,6 +1138,7 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("minimum_alpha");
mReservedUniforms.push_back("emissive_brightness");
mReservedUniforms.push_back("shadow_matrix");
mReservedUniforms.push_back("env_mat");
@@ -1191,6 +1201,12 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("projectionMap");
mReservedUniforms.push_back("norm_mat");
mReservedUniforms.push_back("global_gamma");
mReservedUniforms.push_back("texture_gamma");
mReservedUniforms.push_back("specular_color");
mReservedUniforms.push_back("env_intensity");
mReservedUniforms.push_back("matrixPalette");
mReservedUniforms.push_back("screenTex");
@@ -1230,6 +1246,7 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("alpha_ramp");
mReservedUniforms.push_back("origin");
mReservedUniforms.push_back("display_gamma");
llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS);
std::set<std::string> dupe_check;

View File

@@ -111,6 +111,7 @@ public:
GLOW_DELTA,
MINIMUM_ALPHA,
EMISSIVE_BRIGHTNESS,
DEFERRED_SHADOW_MATRIX,
DEFERRED_ENV_MAT,
@@ -168,7 +169,14 @@ public:
DEFERRED_PROJECTION,
DEFERRED_NORM_MATRIX,
GLOBAL_GAMMA,
TEXTURE_GAMMA,
SPECULAR_COLOR,
ENVIRONMENT_INTENSITY,
AVATAR_MATRIX,
WATER_SCREENTEX,
WATER_SCREENDEPTH,
WATER_REFTEX,
@@ -204,7 +212,9 @@ public:
TERRAIN_DETAIL2,
TERRAIN_DETAIL3,
TERRAIN_ALPHARAMP,
SHINY_ORIGIN,
DISPLAY_GAMMA,
END_RESERVED_UNIFORMS
} eGLSLReservedUniforms;
@@ -228,11 +238,12 @@ public:
public:
struct CachedObjectInfo
{
CachedObjectInfo(GLhandleARB handle, U32 level, GLenum type) :
mHandle(handle), mLevel(level), mType(type) {}
CachedObjectInfo(GLhandleARB handle, U32 level, GLenum type, std::map<std::string,std::string> *definitions) :
mHandle(handle), mLevel(level), mType(type), mDefinitions(definitions ? *definitions : std::map<std::string,std::string>()){}
GLhandleARB mHandle; //Actual handle of the opengl shader object.
U32 mLevel; //Level /might/ not be needed, but it's stored to ensure there's no change in behavior.
GLenum mType; //GL_VERTEX_SHADER_ARB or GL_FRAGMENT_SHADER_ARB. Tracked because some utility shaders can be loaded as both types (carefully).
std::map<std::string,std::string> mDefinitions;
};
// Map of shader names to compiled
std::multimap<std::string, CachedObjectInfo > mShaderObjects; //Singu Note: Packing more info here. Doing such provides capability to skip unneeded duplicate loading..

View File

@@ -2035,7 +2035,10 @@ bool LLVertexBuffer::getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 inde
{
return VertexBufferStrider<LLVector2,TYPE_TEXCOORD1>::get(*this, strider, index, count, map_range);
}
bool LLVertexBuffer::getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index, S32 count, bool map_range)
{
return VertexBufferStrider<LLVector2,TYPE_TEXCOORD2>::get(*this, strider, index, count, map_range);
}
bool LLVertexBuffer::getNormalStrider(LLStrider<LLVector3>& strider, S32 index, S32 count, bool map_range)
{
return VertexBufferStrider<LLVector3,TYPE_NORMAL>::get(*this, strider, index, count, map_range);
@@ -2371,7 +2374,8 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
if (data_mask & MAP_COLOR)
{
S32 loc = TYPE_COLOR;
void* ptr = (void*)(base + mOffsets[TYPE_COLOR]);
//bind emissive instead of color pointer if emissive is present
void* ptr = (data_mask & MAP_EMISSIVE) ? (void*)(base + mOffsets[TYPE_EMISSIVE]) : (void*)(base + mOffsets[TYPE_COLOR]);
glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], ptr);
}
if (data_mask & MAP_EMISSIVE)
@@ -2379,6 +2383,12 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
S32 loc = TYPE_EMISSIVE;
void* ptr = (void*)(base + mOffsets[TYPE_EMISSIVE]);
glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr);
if (!(data_mask & MAP_COLOR))
{ //map emissive to color channel when color is not also being bound to avoid unnecessary shader swaps
loc = TYPE_COLOR;
glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr);
}
}
if (data_mask & MAP_WEIGHT)
{

View File

@@ -246,6 +246,7 @@ public:
bool getIndexStrider(LLStrider<U16>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getTexCoord0Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getNormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getTangentStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getTangentStrider(LLStrider<LLVector4a>& strider, S32 index=0, S32 count = -1, bool map_range = false);

View File

@@ -155,6 +155,7 @@ set(viewer_SOURCE_FILES
lldrawpoolavatar.cpp
lldrawpoolbump.cpp
lldrawpoolground.cpp
lldrawpoolmaterials.cpp
lldrawpoolsimple.cpp
lldrawpoolsky.cpp
lldrawpoolterrain.cpp
@@ -671,6 +672,7 @@ set(viewer_HEADER_FILES
lldrawpoolalpha.h
lldrawpoolavatar.h
lldrawpoolbump.h
lldrawpoolmaterials.h
lldrawpoolground.h
lldrawpoolsimple.h
lldrawpoolsky.h

View File

@@ -25,31 +25,429 @@
#extension GL_ARB_texture_rectangle : enable
#define INDEXED 1
#define NON_INDEXED 2
#define NON_INDEXED_NO_COLOR 3
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
#define frag_color gl_FragColor
#endif
uniform sampler2DRect depthMap;
//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;
vec4 diffuseLookup(vec2 texcoord);
uniform vec3 sun_dir;
uniform vec2 screen_res;
#if HAS_SHADOW
uniform sampler2DShadow shadowMap0;
uniform sampler2DShadow shadowMap1;
uniform sampler2DShadow shadowMap2;
uniform sampler2DShadow shadowMap3;
vec3 atmosLighting(vec3 light);
vec3 scaleSoftClip(vec3 light);
uniform vec2 shadow_res;
uniform mat4 shadow_matrix[6];
uniform vec4 shadow_clip;
uniform float shadow_bias;
#endif
#ifdef USE_DIFFUSE_TEX
uniform sampler2D diffuseMap;
#endif
VARYING vec3 vary_ambient;
VARYING vec3 vary_directional;
VARYING vec3 vary_fragcoord;
VARYING vec3 vary_position;
VARYING vec3 vary_pointlight_col;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
VARYING vec3 vary_norm;
#ifdef USE_VERTEX_COLOR
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];
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)
{
float a = max(dot(n,l),0.0);
a = pow(a, 1.0/1.3);
return vec3(a,a,a);
}
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;
//get distance
float d = length(lv);
float da = 1.0;
vec3 col = vec3(0);
if (d > 0.0 && la > 0.0 && fa > 0.0)
{
//normalize light vector
lv = normalize(lv);
//distance attenuation
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 *= 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);
float lit = max(da * dist_atten,0.0);
col = light_col * lit * diffuse;
// no spec for alpha shader...
}
return max(col, vec3(0.0,0.0,0.0));
}
#if HAS_SHADOW
float pcfShadow(sampler2DShadow shadowMap, vec4 stc)
{
stc.xyz /= stc.w;
stc.z += shadow_bias;
stc.x = floor(stc.x*shadow_res.x + fract(stc.y*shadow_res.y*12345))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here
float cs = shadow2D(shadowMap, stc.xyz).x;
float shadow = cs;
shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
return shadow*0.2;
}
#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()
{
@@ -58,16 +456,172 @@ void main()
vec4 pos = vec4(vary_position, 1.0);
vec4 diff= diffuseLookup(vary_texcoord0.xy);
float shadow = 1.0;
vec4 col = vec4(vary_ambient + vary_directional.rgb, vertex_color.a);
vec4 color = diff * col;
#if HAS_SHADOW
vec4 spos = pos;
if (spos.z > -shadow_clip.w)
{
shadow = 0.0;
vec4 lpos;
vec4 near_split = shadow_clip*-0.75;
vec4 far_split = shadow_clip*-1.25;
vec4 transition_domain = near_split-far_split;
float weight = 0.0;
if (spos.z < near_split.z)
{
lpos = shadow_matrix[3]*spos;
float w = 1.0;
w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
shadow += pcfShadow(shadowMap3, lpos)*w;
weight += w;
shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
}
if (spos.z < near_split.y && spos.z > far_split.z)
{
lpos = shadow_matrix[2]*spos;
float w = 1.0;
w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
shadow += pcfShadow(shadowMap2, lpos)*w;
weight += w;
}
if (spos.z < near_split.x && spos.z > far_split.y)
{
lpos = shadow_matrix[1]*spos;
float w = 1.0;
w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
shadow += pcfShadow(shadowMap1, lpos)*w;
weight += w;
}
if (spos.z > far_split.x)
{
lpos = shadow_matrix[0]*spos;
float w = 1.0;
w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
shadow += pcfShadow(shadowMap0, lpos)*w;
weight += w;
}
shadow /= weight;
}
else
{
shadow = 1.0;
}
#endif
#ifdef USE_INDEXED_TEX
vec4 diff = diffuseLookup(vary_texcoord0.xy);
#else
vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy);
#endif
#ifdef FOR_IMPOSTOR
vec4 color;
color.rgb = diff.rgb;
#ifdef USE_VERTEX_COLOR
float final_alpha = diff.a * vertex_color.a;
diff.rgb *= vertex_color.rgb;
#else
float final_alpha = diff.a;
#endif
// 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
float final_alpha = diff.a;
#endif
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 += diff.rgb * vary_pointlight_col.rgb;
vec4 light = vec4(0,0,0,0);
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)
LIGHT_LOOP(4)
LIGHT_LOOP(5)
LIGHT_LOOP(6)
LIGHT_LOOP(7)
// keep it linear
//
color.rgb += light.rgb;
// 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;
}

View File

@@ -1,92 +0,0 @@
/**
* @file alphaNonIndexedNoColorF.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2005, 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$
*/
#extension GL_ARB_texture_rectangle : enable
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
#define frag_color gl_FragColor
#endif
uniform float minimum_alpha;
uniform sampler2DRect depthMap;
uniform sampler2D diffuseMap;
uniform vec2 screen_res;
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;
uniform mat4 inv_proj;
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2DRect(depthMap, pos_screen.xy).a;
vec2 sc = pos_screen.xy*2.0;
sc /= screen_res;
sc -= vec2(1.0,1.0);
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
vec4 pos = inv_proj * ndc;
pos /= pos.w;
pos.w = 1.0;
return pos;
}
void main()
{
vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
frag *= screen_res;
vec4 pos = vec4(vary_position, 1.0);
vec4 diff= texture2D(diffuseMap,vary_texcoord0.xy);
if (diff.a < minimum_alpha)
{
discard;
}
vec4 col = vec4(vary_ambient + vary_directional.rgb, 1.0);
vec4 color = diff * col;
color.rgb = atmosLighting(color.rgb);
color.rgb = scaleSoftClip(color.rgb);
color.rgb += diff.rgb * vary_pointlight_col.rgb;
frag_color = color;
}

View File

@@ -1,144 +0,0 @@
/**
* @file alphaSkinnedV.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 mat4 projection_matrix;
uniform mat4 modelview_matrix;
ATTRIBUTE vec3 position;
ATTRIBUTE vec3 normal;
ATTRIBUTE vec4 diffuse_color;
ATTRIBUTE vec2 texcoord0;
mat4 getObjectSkinnedTransform();
void calcAtmospherics(vec3 inPositionEye);
float calcDirectionalLight(vec3 n, vec3 l);
vec3 atmosAmbient(vec3 light);
vec3 atmosAffectDirectionalLight(float lightIntensity);
VARYING vec3 vary_position;
VARYING vec3 vary_ambient;
VARYING vec3 vary_directional;
VARYING vec3 vary_fragcoord;
VARYING vec3 vary_pointlight_col;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
uniform float near_clip;
uniform vec4 light_position[8];
uniform vec3 light_direction[8];
uniform vec3 light_attenuation[8];
uniform vec3 light_diffuse[8];
float calcDirectionalLight(vec3 n, vec3 l)
{
float a = max(dot(n,l),0.0);
return a;
}
float 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 da;
}
void main()
{
vary_texcoord0 = texcoord0;
vec4 pos;
vec3 norm;
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;
vary_position = pos.xyz;
calcAtmospherics(pos.xyz);
vec4 col = vec4(0.0, 0.0, 0.0, diffuse_color.a);
// Collect normal lights
col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z);
col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z);
col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z);
col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z);
vary_pointlight_col = col.rgb*diffuse_color.rgb;
col.rgb = vec3(0,0,0);
// Add windlight lights
col.rgb = atmosAmbient(vec3(0.));
vary_ambient = col.rgb*diffuse_color.rgb;
vary_directional = diffuse_color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), (1.0-diffuse_color.a)*(1.0-diffuse_color.a)));
col.rgb = min(col.rgb*diffuse_color.rgb, 1.0);
vertex_color = col;
vary_fragcoord.xyz = frag_pos.xyz + vec3(0,0,near_clip);
}

View File

@@ -23,126 +23,118 @@
* $/LicenseInfo$
*/
#define INDEXED 1
#define NON_INDEXED 2
#define NON_INDEXED_NO_COLOR 3
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;
vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
void calcAtmospherics(vec3 inPositionEye);
#ifdef HAS_SKIN
mat4 getObjectSkinnedTransform();
#else
#ifdef IS_AVATAR_SKIN
mat4 getSkinnedTransform();
#endif
#endif
float 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;
VARYING vec2 vary_texcoord0;
#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];
float calcDirectionalLight(vec3 n, vec3 l)
{
float a = max(dot(n,l),0.0);
return a;
}
float 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 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);
passTextureIndex();
vec4 pos = (modelview_matrix * vert);
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
vec3 norm = normalize(normal_matrix * normal);
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);
vary_norm = norm;
vary_position = pos.xyz;
//vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.));
vec4 col = vec4(0.0, 0.0, 0.0, diffuse_color.a);
#ifdef USE_VERTEX_COLOR
vertex_color = diffuse_color;
#endif
#ifdef HAS_SKIN
vary_fragcoord.xyz = frag_pos.xyz + vec3(0,0,near_clip);
#else
// Collect normal lights
col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z);
col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z);
col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z);
col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z);
vary_pointlight_col = col.rgb*diffuse_color.rgb;
col.rgb = vec3(0,0,0);
// Add windlight lights
col.rgb = atmosAmbient(vec3(0.));
vary_ambient = col.rgb*diffuse_color.rgb;
vary_directional.rgb = diffuse_color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), (1.0-diffuse_color.a)*(1.0-diffuse_color.a)));
col.rgb = col.rgb*diffuse_color.rgb;
vertex_color = col;
#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
}

View File

@@ -39,7 +39,12 @@ void main()
mat = modelview_matrix * mat;
vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz;
vec4 p = projection_matrix * vec4(pos, 1.0);
#if !DEPTH_CLAMP
p.z = max(p.z, -p.w+0.01);
gl_Position = p;
#else
gl_Position = p;
#endif
}

View File

@@ -47,6 +47,7 @@ VARYING vec3 vary_directional;
VARYING vec3 vary_fragcoord;
VARYING vec3 vary_pointlight_col;
VARYING vec2 vary_texcoord0;
VARYING vec3 vary_norm;
uniform float near_clip;
@@ -112,6 +113,7 @@ void main()
norm.y = dot(trans[1].xyz, normal);
norm.z = dot(trans[2].xyz, normal);
norm = normalize(norm);
vary_norm = norm;
vec4 frag_pos = projection_matrix * pos;
gl_Position = frag_pos;

View File

@@ -1,153 +0,0 @@
/**
* @file avatarAlphaV.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 mat4 projection_matrix;
ATTRIBUTE vec3 position;
ATTRIBUTE vec3 normal;
ATTRIBUTE vec2 texcoord0;
vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
mat4 getSkinnedTransform();
void calcAtmospherics(vec3 inPositionEye);
float calcDirectionalLight(vec3 n, vec3 l);
float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);
vec3 atmosAmbient(vec3 light);
vec3 atmosAffectDirectionalLight(float lightIntensity);
vec3 scaleDownLight(vec3 light);
vec3 scaleUpLight(vec3 light);
VARYING vec3 vary_position;
VARYING vec3 vary_ambient;
VARYING vec3 vary_directional;
VARYING vec3 vary_fragcoord;
VARYING vec3 vary_pointlight_col;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
uniform float near_clip;
uniform vec4 color;
uniform vec4 light_position[8];
uniform vec3 light_direction[8];
uniform vec3 light_attenuation[8];
uniform vec3 light_diffuse[8];
float calcDirectionalLight(vec3 n, vec3 l)
{
float a = max(dot(n,l),0.0);
return a;
}
float 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 da;
}
void main()
{
vary_texcoord0 = texcoord0;
vec4 pos;
vec3 norm;
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;
vary_position = pos.xyz;
calcAtmospherics(pos.xyz);
vec4 col = vec4(0.0, 0.0, 0.0, 1.0);
// Collect normal lights
col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z);
col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z);
col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z);
col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z);
vary_pointlight_col = col.rgb*color.rgb;
col.rgb = vec3(0,0,0);
// Add windlight lights
col.rgb = atmosAmbient(vec3(0.));
vary_ambient = col.rgb*color.rgb;
vary_directional = color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), 0.0));
col.rgb = col.rgb * color.rgb;
vertex_color = col;
vary_fragcoord.xyz = frag_pos.xyz + vec3(0,0,near_clip);
}

View File

@@ -31,25 +31,22 @@ out vec4 frag_data[3];
uniform sampler2D diffuseMap;
uniform float minimum_alpha;
VARYING vec3 vary_normal;
VARYING vec2 vary_texcoord0;
vec3 pack(vec3 norm)
vec2 encode_normal(vec3 n)
{
//#define PACK_NORMALS
#ifdef PACK_NORMALS
float p = sqrt(8.0*norm.z+8.0);
return vec3(norm.xy/p + 0.5, 0.0);
#else
return norm.xyz*0.5+0.5;
#endif
float f = sqrt(8 * n.z + 8);
return n.xy / f + 0.5;
}
void main()
{
vec4 diff = texture2D(diffuseMap, vary_texcoord0.xy);
if (diff.a < 0.2)
if (diff.a < minimum_alpha)
{
discard;
}
@@ -57,6 +54,6 @@ void main()
frag_data[0] = vec4(diff.rgb, 0.0);
frag_data[1] = vec4(0,0,0,0);
vec3 nvn = normalize(vary_normal);
frag_data[2] = vec4(pack(nvn), 0.0);
frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
}

View File

@@ -64,24 +64,28 @@ vec4 getPosition(vec2 pos_screen)
return pos;
}
vec3 unpack(vec2 tc)
vec2 encode_normal(vec3 n)
{
//#define PACK_NORMALS
#ifdef PACK_NORMALS
vec2 enc = texture2DRect(normalMap, tc).xy;
enc = enc*4.0-2.0;
float prod = dot(enc,enc);
return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5);
#else
vec3 norm = texture2DRect(normalMap, tc).xyz;
return norm*2.0-1.0;
#endif
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;
}
void main()
{
vec2 tc = vary_fragcoord.xy;
vec3 norm = unpack(tc); // unpack norm
vec3 norm = texture2DRect(normalMap, tc).xyz;
norm = decode_normal(norm.xy); // unpack norm
vec3 pos = getPosition(tc).xyz;
vec4 ccol = texture2DRect(lightMap, tc).rgba;
@@ -93,11 +97,12 @@ void main()
vec4 col = defined_weight.xyxx * ccol;
// relax tolerance according to distance to avoid speckling artifacts, as angles and distances are a lot more abrupt within a small screen area at larger distances
float pointplanedist_tolerance_pow2 = pos.z*-0.001;
float pointplanedist_tolerance_pow2 = pos.z*pos.z*0.00005;
// perturb sampling origin slightly in screen-space to hide edge-ghosting artifacts where smoothing radius is quite large
vec2 tc_v = fract(0.5 * tc.xy); // we now have floor(mod(tc,2.0))*0.5
float tc_mod = 2.0 * abs(tc_v.x - tc_v.y); // diff of x,y makes checkerboard
float tc_mod = 0.5*(tc.x + tc.y); // mod(tc.x+tc.y,2)
tc_mod -= floor(tc_mod);
tc_mod *= 2.0;
tc += ( (tc_mod - 0.5) * getKern(1).z * dlt * 0.5 );
for (int i = 1; i < 4; i++)

View File

@@ -39,15 +39,10 @@ VARYING vec3 vary_mat2;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
vec3 pack(vec3 norm)
vec2 encode_normal(vec3 n)
{
//#define PACK_NORMALS
#ifdef PACK_NORMALS
float p = sqrt(8.0*norm.z+8.0);
return vec3(norm.xy/p + 0.5, 0.0);
#else
return norm.xyz*0.5+0.5;
#endif
float f = sqrt(8 * n.z + 8);
return n.xy / f + 0.5;
}
void main()
@@ -63,5 +58,5 @@ void main()
frag_data[1] = vertex_color.aaaa; // spec
//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
vec3 nvn = normalize(tnorm);
frag_data[2] = vec4(pack(nvn), 0.0);
frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, 0.0);
}

View File

@@ -102,11 +102,6 @@ void main()
/// Gamma correct for WL (soft clip effect).
frag_data[0] = vec4(scaleSoftClip(color.rgb), alpha1);
frag_data[1] = vec4(0.0,0.0,0.0,0.0);
//#define PACK_NORMALS
#ifdef PACK_NORMALS
frag_data[2] = vec4(0.5,0.5,0.0,0.0);
#else
frag_data[2] = vec4(0.0,0.0,1.0,0.0);
#endif
}

View File

@@ -37,15 +37,10 @@ VARYING vec3 vary_normal;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
vec3 pack(vec3 norm)
vec2 encode_normal(vec3 n)
{
//#define PACK_NORMALS
#ifdef PACK_NORMALS
float p = sqrt(8.0*norm.z+8.0);
return vec3(norm.xy/p + 0.5, 0.0);
#else
return norm.xyz*0.5+0.5;
#endif
float f = sqrt(8 * n.z + 8);
return n.xy / f + 0.5;
}
void main()
@@ -60,6 +55,6 @@ void main()
frag_data[0] = vec4(col.rgb, 0.0);
frag_data[1] = vec4(0,0,0,0); // spec
vec3 nvn = normalize(vary_normal);
frag_data[2] = vec4(pack(nvn),0.0);
frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
}

View File

@@ -36,15 +36,10 @@ uniform float minimum_alpha;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
vec3 pack(vec3 norm)
vec2 encode_normal(vec3 n)
{
//#define PACK_NORMALS
#ifdef PACK_NORMALS
float p = sqrt(8.0*norm.z+8.0);
return vec3(norm.xy/p + 0.5, 0.0);
#else
return norm.xyz*0.5+0.5;
#endif
float f = sqrt(8 * n.z + 8);
return n.xy / f + 0.5;
}
void main()
@@ -55,9 +50,9 @@ void main()
{
discard;
}
frag_data[0] = vec4(col.rgb, 0.0);
frag_data[1] = vec4(0,0,0,0);
vec3 nvn = normalize(vary_normal);
frag_data[2] = vec4(pack(nvn), 0.0);
frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
}

View File

@@ -37,15 +37,10 @@ uniform sampler2D diffuseMap;
VARYING vec3 vary_normal;
VARYING vec2 vary_texcoord0;
vec3 pack(vec3 norm)
vec2 encode_normal(vec3 n)
{
//#define PACK_NORMALS
#ifdef PACK_NORMALS
float p = sqrt(8.0*norm.z+8.0);
return vec3(norm.xy/p + 0.5, 0.0);
#else
return norm.xyz*0.5+0.5;
#endif
float f = sqrt(8 * n.z + 8);
return n.xy / f + 0.5;
}
void main()
@@ -60,6 +55,6 @@ void main()
frag_data[0] = vec4(col.rgb, 0.0);
frag_data[1] = vec4(0,0,0,0); // spec
vec3 nvn = normalize(vary_normal);
frag_data[2] = vec4(pack(nvn),0.0);
frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
}

View File

@@ -35,15 +35,10 @@ VARYING vec3 vary_normal;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
vec3 pack(vec3 norm)
vec2 encode_normal(vec3 n)
{
//#define PACK_NORMALS
#ifdef PACK_NORMALS
float p = sqrt(8.0*norm.z+8.0);
return vec3(norm.xy/p + 0.5, 0.0);
#else
return norm.xyz*0.5+0.5;
#endif
float f = sqrt(8 * n.z + 8);
return n.xy / f + 0.5;
}
void main()
@@ -53,6 +48,6 @@ void main()
frag_data[1] = vertex_color.aaaa; // spec
//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
vec3 nvn = normalize(vary_normal);
frag_data[2] = vec4(pack(nvn),0.0);
frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, 0.0);
}

View File

@@ -33,24 +33,22 @@ VARYING vec3 vary_normal;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
vec3 pack(vec3 norm)
vec2 encode_normal(vec3 n)
{
//#define PACK_NORMALS
#ifdef PACK_NORMALS
float p = sqrt(8.0*norm.z+8.0);
return vec3(norm.xy/p + 0.5, 0.0);
#else
return norm.xyz*0.5+0.5;
#endif
float f = sqrt(8 * n.z + 8);
return n.xy / f + 0.5;
}
void main()
{
vec3 col = vertex_color.rgb * diffuseLookup(vary_texcoord0.xy).rgb;
vec3 spec;
spec.rgb = vec3(vertex_color.a);
frag_data[0] = vec4(col, 0.0);
frag_data[1] = vertex_color.aaaa; // spec
//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
frag_data[1] = vec4(spec, vertex_color.a); // spec
vec3 nvn = normalize(vary_normal);
frag_data[2] = vec4(pack(nvn),0.0);
frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, 0.0);
}

View File

@@ -42,7 +42,7 @@ void main()
float shadow = 1.0;
vec4 color = diffuseLookup(vary_texcoord0.xy)*vertex_color;
color.rgb = pow(color.rgb, vec3(2.2));
color.rgb = fullbrightAtmosTransport(color.rgb);
color.rgb = fullbrightScaleSoftClip(color.rgb);

View File

@@ -31,22 +31,145 @@ out vec4 frag_color;
#define frag_color gl_FragColor
#endif
#if !HAS_DIFFUSE_LOOKUP
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()
{
float shadow = 1.0;
#if HAS_DIFFUSE_LOOKUP
vec4 color = diffuseLookup(vary_texcoord0.xy);
#else
vec4 color = texture2D(diffuseMap, vary_texcoord0.xy);
#endif
vec4 color = diffuseLookup(vary_texcoord0.xy)*vertex_color;
float final_alpha = color.a * vertex_color.a;
#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 = fullbrightAtmosTransport(color.rgb);
color.rgb = linear_to_srgb(color.rgb);
color.rgb = fullbrightScaleSoftClip(color.rgb);
#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
color.a = .0;
frag_color = color;

View File

@@ -1,5 +1,5 @@
/**
* @file alphaF.glsl
* @file fullbrightShinyF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -23,7 +23,7 @@
* $/LicenseInfo$
*/
#extension GL_ARB_texture_rectangle : enable
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
@@ -31,59 +31,42 @@ out vec4 frag_color;
#define frag_color gl_FragColor
#endif
uniform sampler2DRect depthMap;
#ifndef diffuseLookup
uniform sampler2D diffuseMap;
#endif
uniform vec2 screen_res;
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 vec4 vertex_color;
VARYING vec2 vary_texcoord0;
VARYING vec3 vary_texcoord1;
uniform mat4 inv_proj;
uniform samplerCube environmentMap;
vec4 getPosition(vec2 pos_screen)
vec3 fullbrightShinyAtmosTransport(vec3 light);
vec3 fullbrightScaleSoftClip(vec3 light);
void main()
{
float depth = texture2DRect(depthMap, pos_screen.xy).a;
vec2 sc = pos_screen.xy*2.0;
sc /= screen_res;
sc -= vec2(1.0,1.0);
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
vec4 pos = inv_proj * ndc;
pos /= pos.w;
pos.w = 1.0;
return pos;
}
#if HAS_DIFFUSE_LOOKUP
vec4 color = diffuseLookup(vary_texcoord0.xy);
#else
vec4 color = texture2D(diffuseMap, vary_texcoord0.xy);
#endif
void main()
{
vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
frag *= screen_res;
vec4 pos = vec4(vary_position, 1.0);
color.rgb *= vertex_color.rgb;
vec4 diff= texture2D(diffuseMap,vary_texcoord0.xy);
vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;
color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a);
vec4 col = vec4(vary_ambient + vary_directional.rgb, vertex_color.a);
vec4 color = diff * col;
color.rgb = pow(color.rgb,vec3(2.2f,2.2f,2.2f));
color.rgb = atmosLighting(color.rgb);
color.rgb = fullbrightShinyAtmosTransport(color.rgb);
color.rgb = fullbrightScaleSoftClip(color.rgb);
color.rgb = scaleSoftClip(color.rgb);
color.a = 0.0;
color.rgb += diff.rgb * vary_pointlight_col.rgb;
color.rgb = pow(color.rgb, vec3(1.0/2.2));
frag_color = color;
//frag_color = vec4(1,0,1,1);
//frag_color = vec4(1,0,1,1)*shadow;
}

View File

@@ -0,0 +1,67 @@
/**
* @file fullbrightShinyV.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 texture_matrix1;
uniform mat4 modelview_matrix;
uniform mat4 modelview_projection_matrix;
void calcAtmospherics(vec3 inPositionEye);
uniform vec4 origin;
ATTRIBUTE vec3 position;
void passTextureIndex();
ATTRIBUTE vec3 normal;
ATTRIBUTE vec4 diffuse_color;
ATTRIBUTE vec2 texcoord0;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
VARYING vec3 vary_texcoord1;
void main()
{
//transform vertex
vec4 vert = vec4(position.xyz,1.0);
passTextureIndex();
vec4 pos = (modelview_matrix * vert);
gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
vec3 norm = normalize(normal_matrix * normal);
vec3 ref = reflect(pos.xyz, -norm);
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
vary_texcoord1 = (texture_matrix1*vec4(ref,1.0)).xyz;
calcAtmospherics(pos.xyz);
vertex_color = diffuse_color;
}

View File

@@ -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,11 +56,15 @@ 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);
vertex_color = diffuse_color;

View File

@@ -24,6 +24,7 @@
*/
#extension GL_ARB_texture_rectangle : enable
#extension GL_ARB_shader_texture_lod : enable
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;

View File

@@ -1,190 +0,0 @@
/**
* @file giF.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$
*/
#extension GL_ARB_texture_rectangle : enable
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
#define frag_color gl_FragColor
#endif
uniform sampler2DRect depthMap;
uniform sampler2DRect normalMap;
uniform sampler2D noiseMap;
uniform sampler2D diffuseGIMap;
uniform sampler2D normalGIMap;
uniform sampler2D depthGIMap;
uniform sampler2D lightFunc;
// Inputs
VARYING vec2 vary_fragcoord;
uniform vec2 screen_res;
uniform mat4 inv_proj;
uniform mat4 gi_mat; //gPipeline.mGIMatrix - eye space to sun space
uniform mat4 gi_mat_proj; //gPipeline.mGIMatrixProj - eye space to projected sun space
uniform mat4 gi_norm_mat; //gPipeline.mGINormalMatrix - eye space normal to sun space normal matrix
uniform mat4 gi_inv_proj; //gPipeline.mGIInvProj - projected sun space to sun space
uniform float gi_radius;
uniform float gi_intensity;
uniform int gi_samples;
uniform vec2 gi_kern[25];
uniform vec2 gi_scale;
uniform vec3 gi_quad;
uniform vec3 gi_spec;
uniform float gi_direction_weight;
uniform float gi_light_offset;
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2DRect(depthMap, pos_screen.xy).a;
vec2 sc = pos_screen.xy*2.0;
sc /= screen_res;
sc -= vec2(1.0,1.0);
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
vec4 pos = inv_proj * ndc;
pos /= pos.w;
pos.w = 1.0;
return pos;
}
vec4 getGIPosition(vec2 gi_tc)
{
float depth = texture2D(depthGIMap, gi_tc).a;
vec2 sc = gi_tc*2.0;
sc -= vec2(1.0, 1.0);
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
vec4 pos = gi_inv_proj*ndc;
pos.xyz /= pos.w;
pos.w = 1.0;
return pos;
}
vec3 giAmbient(vec3 pos, vec3 norm)
{
vec4 gi_c = gi_mat_proj * vec4(pos, 1.0);
gi_c.xyz /= gi_c.w;
vec4 gi_pos = gi_mat*vec4(pos,1.0);
vec3 gi_norm = (gi_norm_mat*vec4(norm,1.0)).xyz;
gi_norm = normalize(gi_norm);
vec2 tcx = gi_norm.xy;
vec2 tcy = gi_norm.yx;
vec4 eye_pos = gi_mat*vec4(0,0,0,1.0);
vec3 eye_dir = normalize(gi_pos.xyz-eye_pos.xyz/eye_pos.w);
//vec3 eye_dir = vec3(0,0,-1);
//eye_dir = (gi_norm_mat*vec4(eye_dir, 1.0)).xyz;
//eye_dir = normalize(eye_dir);
//float round_x = gi_scale.x;
//float round_y = gi_scale.y;
vec3 debug = texture2D(normalGIMap, gi_c.xy).rgb*0.5+0.5;
debug.xz = vec2(0.0,0.0);
//debug = fract(debug);
float round_x = 1.0/64.0;
float round_y = 1.0/64.0;
//gi_c.x = floor(gi_c.x/round_x+0.5)*round_x;
//gi_c.y = floor(gi_c.y/round_y+0.5)*round_y;
float fda = 0.0;
vec3 fdiff = vec3(0,0,0);
vec3 rcol = vec3(0,0,0);
float fsa = 0.0;
for (int i = -1; i < 2; i+=2 )
{
for (int j = -1; j < 2; j+=2)
{
vec2 tc = vec2(i, j)*0.75;
vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0+tc*0.5).xyz;
//tc += gi_norm.xy*nz.z;
tc += nz.xy*2.0;
tc /= gi_samples;
tc += gi_c.xy;
vec3 lnorm = -normalize(texture2D(normalGIMap, tc.xy).xyz*2.0-1.0);
vec3 lpos = getGIPosition(tc.xy).xyz;
vec3 at = lpos-gi_pos.xyz;
float dist = dot(at,at);
float da = clamp(1.0/(gi_spec.x*dist), 0.0, 1.0);
if (da > 0.0)
{
//add angular attenuation
vec3 ldir = at;
float ang_atten = clamp(dot(ldir, gi_norm), 0.0, 1.0);
float ld = -dot(ldir, lnorm);
if (ang_atten > 0.0 && ld < 0.0)
{
vec3 diff = texture2D(diffuseGIMap, tc.xy).xyz;
da = da*ang_atten;
fda += da;
fdiff += diff*da;
}
}
}
}
fdiff /= max(gi_spec.y*fda, gi_quad.z);
fdiff = clamp(fdiff, vec3(0), vec3(1));
vec3 ret = fda*fdiff;
//ret = ret*ret*gi_quad.x+ret*gi_quad.y+gi_quad.z;
//fda *= nz.z;
//rcol.rgb *= gi_intensity;
//return rcol.rgb+vary_AmblitColor.rgb*0.25;
//return vec4(debug, 0.0);
//return vec4(fda*fdiff, 0.0);
return clamp(ret,vec3(0.0), vec3(1.0));
//return debug.xyz;
}
void main()
{
vec2 pos_screen = vary_fragcoord.xy;
vec4 pos = getPosition(pos_screen);
vec3 norm = texture2DRect(normalMap, pos_screen).xyz;
norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
frag_color.xyz = giAmbient(pos, norm);
}

View File

@@ -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);
}

View File

@@ -0,0 +1,788 @@
/**
* @file materialF.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$
*/
#define DIFFUSE_ALPHA_MODE_IGNORE 0
#define DIFFUSE_ALPHA_MODE_BLEND 1
#define DIFFUSE_ALPHA_MODE_MASK 2
#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)
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
#define frag_color gl_FragColor
#endif
#if HAS_SUN_SHADOW
uniform sampler2DShadow shadowMap0;
uniform sampler2DShadow shadowMap1;
uniform sampler2DShadow shadowMap2;
uniform sampler2DShadow shadowMap3;
uniform mat4 shadow_matrix[6];
uniform vec4 shadow_clip;
uniform vec2 shadow_res;
uniform float shadow_bias;
float pcfShadow(sampler2DShadow shadowMap, vec4 stc)
{
stc.xyz /= stc.w;
stc.z += shadow_bias;
stc.x = floor(stc.x*shadow_res.x + fract(stc.y*shadow_res.y*12345))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here
float cs = shadow2D(shadowMap, stc.xyz).x;
float shadow = cs;
shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
return shadow*0.2;
}
#endif
uniform samplerCube environmentMap;
uniform sampler2D lightFunc;
// Inputs
uniform vec4 morphFactor;
uniform vec3 camPosLocal;
//uniform vec4 camPosWorld;
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;
VARYING vec2 vary_fragcoord;
VARYING vec3 vary_position;
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];
#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);
return vec3(a,a,a);
}
vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spec, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, inout float glare)
{
//get light vector
vec3 lv = lp.xyz-v;
//get distance
float d = length(lv);
float da = 1.0;
vec3 col = vec3(0,0,0);
if (d > 0.0 && la > 0.0 && fa > 0.0)
{
//normalize light vector
lv = normalize(lv);
//distance attenuation
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 *= 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);
float lit = max(da * dist_atten, 0.0);
col = light_col*lit*diffuse;
if (spec.a > 0.0)
{
//vec3 ref = dot(pos+lv, norm);
vec3 h = normalize(lv+npos);
float nh = dot(n, h);
float nv = dot(n, 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);
vec3 speccol = lit*scol*light_col.rgb*spec.rgb;
col += speccol;
float cur_glare = max(speccol.r, speccol.g);
cur_glare = max(cur_glare, speccol.b);
glare = max(glare, speccol.r);
glare += max(cur_glare, 0.0);
//col += spec.rgb;
}
}
}
return max(col, vec3(0.0,0.0,0.0));
}
vec4 getPosition_d(vec2 pos_screen, float depth)
{
vec2 sc = pos_screen.xy*2.0;
sc /= screen_res;
sc -= vec2(1.0,1.0);
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
vec4 pos = inv_proj * ndc;
pos /= pos.w;
pos.w = 1.0;
return pos;
}
#ifndef WATER_FOG
vec3 getPositionEye()
{
return vary_PositionEye;
}
#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;
}
#else
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
#else
#define frag_data gl_FragData
#endif
#endif
uniform sampler2D diffuseMap;
#if HAS_NORMAL_MAP
uniform sampler2D bumpMap;
#endif
#if HAS_SPECULAR_MAP
uniform sampler2D specularMap;
VARYING vec2 vary_texcoord2;
#endif
uniform float env_intensity;
uniform vec4 specular_color; // specular color RGB and specular exponent (glossiness) in alpha
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
uniform float minimum_alpha;
#endif
#if HAS_NORMAL_MAP
VARYING vec3 vary_mat0;
VARYING vec3 vary_mat1;
VARYING vec3 vary_mat2;
VARYING vec2 vary_texcoord1;
#else
VARYING vec3 vary_normal;
#endif
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
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;
}
void main()
{
vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy);
diffcol.rgb *= vertex_color.rgb;
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
if (diffcol.a < minimum_alpha)
{
discard;
}
#endif
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
vec3 gamma_diff = diffcol.rgb;
diffcol.rgb = srgb_to_linear(diffcol.rgb);
#endif
#if HAS_SPECULAR_MAP
vec4 spec = texture2D(specularMap, vary_texcoord2.xy);
spec.rgb *= specular_color.rgb;
#else
vec4 spec = vec4(specular_color.rgb, 1.0);
#endif
#if HAS_NORMAL_MAP
vec4 norm = texture2D(bumpMap, vary_texcoord1.xy);
norm.xyz = norm.xyz * 2 - 1;
vec3 tnorm = vec3(dot(norm.xyz,vary_mat0),
dot(norm.xyz,vary_mat1),
dot(norm.xyz,vary_mat2));
#else
vec4 norm = vec4(0,0,0,1.0);
vec3 tnorm = vary_normal;
#endif
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)
final_color.a = emissive_brightness;
#else
final_color.a = max(final_color.a, emissive_brightness);
#endif
vec4 final_specular = spec;
#if HAS_SPECULAR_MAP
vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity * spec.a, 0.0);
final_specular.a = specular_color.a * norm.a;
#else
vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity, 0.0);
final_specular.a = specular_color.a;
#endif
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
//forward rendering, output just lit RGBA
vec3 pos = vary_position;
#if HAS_SUN_SHADOW
float shadow = 0.0;
vec4 spos = vec4(pos,1.0);
if (spos.z > -shadow_clip.w)
{
vec4 lpos;
vec4 near_split = shadow_clip*-0.75;
vec4 far_split = shadow_clip*-1.25;
vec4 transition_domain = near_split-far_split;
float weight = 0.0;
if (spos.z < near_split.z)
{
lpos = shadow_matrix[3]*spos;
float w = 1.0;
w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
shadow += pcfShadow(shadowMap3, lpos)*w;
weight += w;
shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
}
if (spos.z < near_split.y && spos.z > far_split.z)
{
lpos = shadow_matrix[2]*spos;
float w = 1.0;
w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
shadow += pcfShadow(shadowMap2, lpos)*w;
weight += w;
}
if (spos.z < near_split.x && spos.z > far_split.y)
{
lpos = shadow_matrix[1]*spos;
float w = 1.0;
w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
shadow += pcfShadow(shadowMap1, lpos)*w;
weight += w;
}
if (spos.z > far_split.x)
{
lpos = shadow_matrix[0]*spos;
float w = 1.0;
w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
shadow += pcfShadow(shadowMap0, lpos)*w;
weight += w;
}
shadow /= weight;
}
else
{
shadow = 1.0;
}
#else
float shadow = 1.0;
#endif
spec = final_specular;
vec4 diffuse = final_color;
float envIntensity = final_normal.z;
vec3 col = vec3(0.0f,0.0f,0.0f);
float bloom = 0.0;
calcAtmospherics(pos.xyz, 1.0);
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, 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(da), 1.0);
ambient *= 0.5;
ambient *= ambient;
ambient = (1.0-ambient);
col.rgb *= ambient;
col.rgb = col.rgb + atmosAffectDirectionalLight(final_da);
col.rgb *= gamma_diff.rgb;
float glare = 0.0;
if (spec.a > 0.0) // specular reflection
{
// the old infinite-sky shiny reflection
//
float sa = dot(refnormpersp, sun_dir.xyz);
vec3 dumbshiny = vary_SunlitColor*shadow*(texture2D(lightFunc, vec2(sa, spec.a)).r);
// add the two types of shiny together
vec3 spec_contrib = dumbshiny * spec.rgb;
bloom = dot(spec_contrib, spec_contrib) / 6;
glare = max(spec_contrib.r, spec_contrib.g);
glare = max(glare, spec_contrib.b);
col += spec_contrib;
}
col = mix(col.rgb, diffcol.rgb, diffuse.a);
if (envIntensity > 0.0)
{
//add environmentmap
vec3 env_vec = env_mat * refnormpersp;
vec3 refcol = textureCube(environmentMap, env_vec).rgb;
col = mix(col.rgb, refcol,
envIntensity);
float cur_glare = max(refcol.r, refcol.g);
cur_glare = max(cur_glare, refcol.b);
cur_glare *= envIntensity*4.0;
glare += cur_glare;
}
//col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a);
//col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);
col = atmosLighting(col);
col = scaleSoftClip(col);
//convert to linear space before adding local lights
col = srgb_to_linear(col);
vec3 npos = normalize(-pos.xyz);
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)
LIGHT_LOOP(3)
LIGHT_LOOP(4)
LIGHT_LOOP(5)
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 = 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;
frag_color.a = al;
#else
frag_data[0] = final_color;
frag_data[1] = final_specular; // XYZ = Specular color. W = Specular exponent.
frag_data[2] = final_normal; // XY = Normal. Z = Env. intensity.
#endif
}

View File

@@ -0,0 +1,145 @@
/**
* @file bumpV.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$
*/
#define DIFFUSE_ALPHA_MODE_IGNORE 0
#define DIFFUSE_ALPHA_MODE_BLEND 1
#define DIFFUSE_ALPHA_MODE_MASK 2
#define DIFFUSE_ALPHA_MODE_EMISSIVE 3
#if HAS_SKIN
uniform mat4 modelview_matrix;
uniform mat4 projection_matrix;
mat4 getObjectSkinnedTransform();
#else
uniform mat3 normal_matrix;
uniform mat4 modelview_projection_matrix;
#endif
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
#if !HAS_SKIN
uniform mat4 modelview_matrix;
#endif
VARYING vec3 vary_position;
#endif
uniform mat4 texture_matrix0;
ATTRIBUTE vec3 position;
ATTRIBUTE vec4 diffuse_color;
ATTRIBUTE vec3 normal;
ATTRIBUTE vec2 texcoord0;
#if HAS_NORMAL_MAP
ATTRIBUTE vec4 tangent;
ATTRIBUTE vec2 texcoord1;
VARYING vec3 vary_mat0;
VARYING vec3 vary_mat1;
VARYING vec3 vary_mat2;
VARYING vec2 vary_texcoord1;
#else
VARYING vec3 vary_normal;
#endif
#if HAS_SPECULAR_MAP
ATTRIBUTE vec2 texcoord2;
VARYING vec2 vary_texcoord2;
#endif
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
void main()
{
#if HAS_SKIN
mat4 mat = getObjectSkinnedTransform();
mat = modelview_matrix * mat;
vec3 pos = (mat*vec4(position.xyz,1.0)).xyz;
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
vary_position = pos;
#endif
gl_Position = projection_matrix*vec4(pos,1.0);
#else
//transform vertex
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
#endif
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
#if HAS_NORMAL_MAP
vary_texcoord1 = (texture_matrix0 * vec4(texcoord1,0,1)).xy;
#endif
#if HAS_SPECULAR_MAP
vary_texcoord2 = (texture_matrix0 * vec4(texcoord2,0,1)).xy;
#endif
#if HAS_SKIN
vec3 n = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz);
#if HAS_NORMAL_MAP
vec3 t = normalize((mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz);
vec3 b = cross(n, t)*tangent.w;
vary_mat0 = vec3(t.x, b.x, n.x);
vary_mat1 = vec3(t.y, b.y, n.y);
vary_mat2 = vec3(t.z, b.z, n.z);
#else //HAS_NORMAL_MAP
vary_normal = n;
#endif //HAS_NORMAL_MAP
#else //HAS_SKIN
vec3 n = normalize(normal_matrix * normal);
#if HAS_NORMAL_MAP
vec3 t = normalize(normal_matrix * tangent.xyz);
vec3 b = cross(n,t)*tangent.w;
//vec3 t = cross(b,n) * binormal.w;
vary_mat0 = vec3(t.x, b.x, n.x);
vary_mat1 = vec3(t.y, b.y, n.y);
vary_mat2 = vec3(t.z, b.z, n.z);
#else //HAS_NORMAL_MAP
vary_normal = n;
#endif //HAS_NORMAL_MAP
#endif //HAS_SKIN
vertex_color = diffuse_color;
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
#if !HAS_SKIN
vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz;
#endif
#endif
}

View File

@@ -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,6 +55,23 @@ uniform float far_z;
uniform mat4 inv_proj;
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;
}
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2DRect(depthMap, pos_screen.xy).r;
@@ -69,20 +85,6 @@ vec4 getPosition(vec2 pos_screen)
return pos;
}
vec3 unpack(vec2 tc)
{
//#define PACK_NORMALS
#ifdef PACK_NORMALS
vec2 enc = texture2DRect(normalMap, tc).xy;
enc = enc*4.0-2.0;
float prod = dot(enc,enc);
return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5);
#else
vec3 norm = texture2DRect(normalMap, tc).xyz;
return norm*2.0-1.0;
#endif
}
void main()
{
vec2 frag = (vary_fragcoord.xy*0.5+0.5)*screen_res;
@@ -92,70 +94,71 @@ void main()
discard;
}
vec3 norm = unpack(frag.xy); // unpack norm
//norm = normalize(norm); // may be superfluous
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
norm = decode_normal(norm.xy); // unpack norm
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 dist2 = dot(lv,lv);
dist2 /= light[i].w;
if (dist2 > 1.0)
float dist = length(lv);
dist /= light[i].w;
if (dist <= 1.0)
{
light_contrib = false;
}
float da = dot(norm, lv);
if (da < 0.0)
{
light_contrib = false;
}
if (light_contrib)
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-(dist2-1.0*(1.0-fa))/fa, 0.0, 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;
float lit = da * dist_atten;
vec3 col = light_col[i].rgb*lit*diff;
//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);
float sa = dot(normalize(lv+npos),norm);
if (sa > 0.0)
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)
{
sa = texture2D(lightFunc, vec2(sa, spec.a)).r * min(dist_atten*4.0, 1.0);
sa *= noise;
col += da*sa*light_col[i].rgb*spec.rgb;
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;
}
}
if (dot(out_col, out_col) <= 0.0)
{
discard;
}
frag_color.rgb = out_col;
frag_color.a = 0.0;
}

View File

@@ -32,6 +32,7 @@ out vec4 frag_color;
//class 1 -- no shadows
#extension GL_ARB_texture_rectangle : enable
#extension GL_ARB_shader_texture_lod : enable
uniform sampler2DRect diffuseRect;
uniform sampler2DRect specularRect;
@@ -40,6 +41,7 @@ uniform sampler2DRect normalMap;
uniform samplerCube environmentMap;
uniform sampler2D noiseMap;
uniform sampler2D projectionMap;
uniform sampler2D lightFunc;
uniform mat4 proj_mat; //screen space to light space
uniform float proj_near; //near clip for projection
@@ -66,9 +68,64 @@ uniform vec2 screen_res;
uniform mat4 inv_proj;
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 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 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
ret.rgb = srgb_to_linear(ret.rgb);
vec2 dist = tc-vec2(0.5);
@@ -84,6 +141,7 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
ret.rgb = srgb_to_linear(ret.rgb);
vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
@@ -101,6 +159,7 @@ vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
ret.rgb = srgb_to_linear(ret.rgb);
vec2 dist = tc-vec2(0.5);
@@ -125,20 +184,6 @@ vec4 getPosition(vec2 pos_screen)
return pos;
}
vec3 unpack(vec2 tc)
{
//#define PACK_NORMALS
#ifdef PACK_NORMALS
vec2 enc = texture2DRect(normalMap, tc).xy;
enc = enc*4.0-2.0;
float prod = dot(enc,enc);
return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5);
#else
vec3 norm = texture2DRect(normalMap, tc).xyz;
return norm*2.0-1.0;
#endif
}
void main()
{
vec4 frag = vary_fragcoord;
@@ -148,16 +193,19 @@ void main()
vec3 pos = getPosition(frag.xy).xyz;
vec3 lv = center.xyz-pos.xyz;
float dist2 = dot(lv,lv);
dist2 /= size;
if (dist2 > 1.0)
float dist = length(lv);
dist /= size;
if (dist > 1.0)
{
discard;
}
vec3 norm = unpack(frag.xy); // unpack norm
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
float envIntensity = norm.z;
norm = decode_normal(norm.xy);
//norm = normalize(norm); // may be superfluous
norm = normalize(norm);
float l_dist = -dot(lv, proj_n);
vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
@@ -169,7 +217,10 @@ void main()
proj_tc.xyz /= proj_tc.w;
float fa = falloff+1.0;
float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0);
float dist_atten = min(1.0-(dist-1.0*(1.0-fa))/fa, 1.0);
dist_atten *= dist_atten;
dist_atten *= 2.0;
if (dist_atten <= 0.0)
{
discard;
@@ -182,7 +233,8 @@ void main()
vec3 col = vec3(0,0,0);
vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb;
vec3 dlit = vec3(0, 0, 0);
float noise = texture2D(noiseMap, frag.xy/128.0).b;
if (proj_tc.z > 0.0 &&
proj_tc.x < 1.0 &&
@@ -200,14 +252,13 @@ void main()
vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
vec3 lcol = color.rgb * plcol.rgb * plcol.a;
dlit = color.rgb * plcol.rgb * plcol.a;
lit = da * dist_atten * noise;
col = lcol*lit*diff_tex;
col = dlit*lit*diff_tex;
amb_da += (da*0.5)*proj_ambiance;
}
//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
@@ -216,13 +267,38 @@ void main()
amb_da *= dist_atten * noise;
amb_da = min(amb_da, 1.0-lit);
col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
col += amb_da*color.rgb*diff_tex*amb_plcol.rgb*amb_plcol.a;
}
vec4 spec = texture2DRect(specularRect, frag.xy);
if (spec.a > 0.0)
{
dlit *= min(da*6.0, 1.0) * dist_atten;
vec3 npos = -normalize(pos);
//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 += dlit*scol*spec.rgb;
//col += spec.rgb;
}
}
if (envIntensity > 0.0)
{
vec3 ref = reflect(normalize(pos), norm);
@@ -235,12 +311,10 @@ void main()
vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
stc /= stc.w;
if (stc.z > 0.0)
{
stc.xy /= stc.w;
float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0);
float fatten = clamp(envIntensity*envIntensity+envIntensity*0.25, 0.25, 1.0);
stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
@@ -249,8 +323,7 @@ void main()
stc.x > 0.0 &&
stc.y > 0.0)
{
vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb;
col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod).rgb*spec.rgb;
}
}
}

View File

@@ -54,6 +54,23 @@ uniform vec2 screen_res;
uniform mat4 inv_proj;
uniform vec4 viewport;
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;
}
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2DRect(depthMap, pos_screen.xy).r;
@@ -67,20 +84,6 @@ vec4 getPosition(vec2 pos_screen)
return pos;
}
vec3 unpack(vec2 tc)
{
//#define PACK_NORMALS
#ifdef PACK_NORMALS
vec2 enc = texture2DRect(normalMap, tc).xy;
enc = enc*4.0-2.0;
float prod = dot(enc,enc);
return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5);
#else
vec3 norm = texture2DRect(normalMap, tc).xyz;
return norm*2.0-1.0;
#endif
}
void main()
{
vec4 frag = vary_fragcoord;
@@ -90,21 +93,22 @@ void main()
vec3 pos = getPosition(frag.xy).xyz;
vec3 lv = trans_center.xyz-pos;
float dist2 = dot(lv,lv);
dist2 /= size;
if (dist2 > 1.0)
float dist = length(lv);
dist /= size;
if (dist > 1.0)
{
discard;
}
vec3 norm = unpack(frag.xy); // unpack norm
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
norm = decode_normal(norm.xy); // unpack norm
float da = dot(norm, lv);
if (da < 0.0)
{
discard;
}
//norm = normalize(norm); // may be superfluous
norm = normalize(norm);
lv = normalize(lv);
da = dot(norm, lv);
@@ -112,20 +116,33 @@ void main()
vec3 col = texture2DRect(diffuseRect, frag.xy).rgb;
float fa = falloff+1.0;
float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
float lit = da * dist_atten * noise;
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 lit = da * dist_atten * noise;
col = color.rgb*lit*col;
vec4 spec = texture2DRect(specularRect, frag.xy);
if (spec.a > 0.0)
{
float sa = dot(normalize(lv-normalize(pos)),norm);
if (sa > 0.0)
lit = min(da*6.0, 1.0) * dist_atten;
vec3 npos = -normalize(pos);
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)
{
sa = texture2D(lightFunc, vec2(sa, spec.a)).r * min(dist_atten*4.0, 1.0);
sa *= noise;
col += da*sa*color.rgb*spec.rgb;
float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
col += lit*scol*color.rgb*spec.rgb;
}
}

View File

@@ -37,7 +37,7 @@ VARYING vec3 trans_center;
void main()
{
//transform vertex
vec3 p = position*sqrt(size)+center;
vec3 p = position*size+center;
vec4 pos = modelview_projection_matrix * vec4(p.xyz, 1.0);
vary_fragcoord = pos;
trans_center = (modelview_matrix*vec4(center.xyz, 1.0)).xyz;

View File

@@ -0,0 +1,67 @@
/**
* @file postDeferredGammaCorrect.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$
*/
#extension GL_ARB_texture_rectangle : enable
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
#define frag_color gl_FragColor
#endif
uniform sampler2DRect diffuseRect;
uniform vec2 screen_res;
VARYING vec2 vary_fragcoord;
//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);
diff.rgb = linear_to_srgb(diff.rgb);
frag_color = diff;
}

View File

@@ -61,11 +61,7 @@ void main()
/// Gamma correct for WL (soft clip effect).
frag_data[0] = vec4(scaleSoftClip(color.rgb), 1.0);
frag_data[1] = vec4(vary_HazeColor.a,0.0,0.0,0.0);
//#define PACK_NORMALS
#ifdef PACK_NORMALS
frag_data[2] = vec4(0.5,0.5,0.0,0.0);
#else
frag_data[2] = vec4(0.0,0.0,1.0,0.0);
#endif
frag_data[2] = vec4(0.5,0.5,0.0,1.0);
}

View File

@@ -24,6 +24,7 @@
*/
#extension GL_ARB_texture_rectangle : enable
#extension GL_ARB_shader_texture_lod : enable
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
@@ -60,6 +61,7 @@ uniform float density_multiplier;
uniform float distance_multiplier;
uniform float max_y;
uniform vec4 glow;
uniform float global_gamma;
uniform float scene_light_strength;
uniform mat3 env_mat;
uniform float ssao_effect;
@@ -77,6 +79,54 @@ vec3 vary_AtmosAttenuation;
uniform mat4 inv_proj;
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)
{
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;
float f = dot(fenc,fenc);
float g = sqrt(1-f/4);
vec3 n;
n.xy = fenc*g;
n.z = 1-f/2;
return n;
}
vec4 getPosition_d(vec2 pos_screen, float depth)
{
vec2 sc = pos_screen.xy*2.0;
@@ -142,6 +192,52 @@ 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;
@@ -230,6 +326,15 @@ vec3 atmosTransport(vec3 light) {
light += getAdditiveColor() * 2.0;
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 atmosGetDiffuseSunlightColor()
{
return getSunlitColor();
@@ -264,18 +369,10 @@ vec3 scaleSoftClip(vec3 light)
return light;
}
vec3 unpack(vec2 tc)
vec3 fullbrightScaleSoftClip(vec3 light)
{
//#define PACK_NORMALS
#ifdef PACK_NORMALS
vec2 enc = texture2DRect(normalMap, tc).xy;
enc = enc*4.0-2.0;
float prod = dot(enc,enc);
return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5);
#else
vec3 norm = texture2DRect(normalMap, tc).xyz;
return norm*2.0-1.0;
#endif
//soft clip effect:
return light;
}
float luminance(vec3 color)
@@ -290,57 +387,95 @@ void main()
vec2 tc = vary_fragcoord.xy;
float depth = texture2DRect(depthMap, tc.xy).r;
vec3 pos = getPosition_d(tc, depth).xyz;
vec3 norm = unpack(tc); // unpack norm
vec4 norm = texture2DRect(normalMap, tc);
float envIntensity = norm.z;
norm.xyz = decode_normal(norm.xy); // unpack norm
float da = max(dot(norm.xyz, sun_dir.xyz), 0.0);
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 = linear_to_srgb(diffuse.rgb);
vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
vec3 col;
float bloom = 0.0;
if (diffuse.a < 0.9)
{
bloom = spec.r*norm.w;
if (norm.w < 0.5)
{
calcAtmospherics(pos.xyz, 1.0);
col = atmosAmbient(vec3(0));
col += atmosAffectDirectionalLight(max(min(da, 1.0), diffuse.a));
float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
ambient *= 0.5;
ambient *= ambient;
ambient = (1.0-ambient);
col.rgb *= ambient;
col += atmosAffectDirectionalLight(final_da);
col *= diffuse.rgb;
vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
if (spec.a > 0.0) // specular reflection
{
// the old infinite-sky shiny reflection
//
vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
float sa = dot(refnormpersp, sun_dir.xyz);
vec3 dumbshiny = vary_SunlitColor*(texture2D(lightFunc, vec2(sa, spec.a)).r);
// add the two types of shiny together
vec3 spec_contrib = dumbshiny * spec.rgb;
bloom = dot(spec_contrib, spec_contrib) / 4;
bloom = dot(spec_contrib, spec_contrib) / 6;
col += spec_contrib;
//add environmentmap
vec3 env_vec = env_mat * refnormpersp;
vec3 env = textureCube(environmentMap, env_vec).rgb;
bloom = (luminance(env) - .45)*.25;
col = mix(col.rgb, env,
max(spec.a-diffuse.a*2.0, 0.0));
}
col = atmosLighting(col);
col = scaleSoftClip(col);
col = mix(col.rgb, diffuse.rgb, diffuse.a);
if (envIntensity > 0.0)
{ //add environmentmap
vec3 env_vec = env_mat * refnormpersp;
vec3 refcol = textureCube(environmentMap, env_vec).rgb;
bloom = (luminance(refcol) - .45)*.25;
col = mix(col.rgb, refcol,
envIntensity);
}
//if (norm.w < 0.5)
{
col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a);
col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);
//bloom += (luminance(col))*.075; //This looks nice, but requires a larger glow rendertarget.
}
col = mix(col, diffuse.rgb, diffuse.a);
}
else
{
bloom = spec.r;
col = diffuse.rgb;
#ifdef WATER_FOG
vec4 fogged = applyWaterFogDeferred(pos,vec4(col, bloom));
col = fogged.rgb;
bloom = fogged.a;
#endif
}
else
{
col = diffuse.rgb;
}
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;
}

View File

@@ -23,7 +23,9 @@
* $/LicenseInfo$
*/
#extension GL_ARB_texture_rectangle : enable
#extension GL_ARB_shader_texture_lod : enable
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
@@ -32,8 +34,6 @@ out vec4 frag_color;
//class 1 -- no shadows
#extension GL_ARB_texture_rectangle : enable
uniform sampler2DRect diffuseRect;
uniform sampler2DRect specularRect;
uniform sampler2DRect depthMap;
@@ -41,6 +41,7 @@ uniform sampler2DRect normalMap;
uniform samplerCube environmentMap;
uniform sampler2D noiseMap;
uniform sampler2D projectionMap;
uniform sampler2D lightFunc;
uniform mat4 proj_mat; //screen space to light space
uniform float proj_near; //near clip for projection
@@ -57,20 +58,79 @@ uniform float far_clip;
uniform vec3 proj_origin; //origin of projection to be used for angular attenuation
uniform float sun_wash;
uniform float size;
uniform vec3 color;
uniform float falloff;
uniform float size;
VARYING vec4 vary_fragcoord;
VARYING vec3 trans_center;
VARYING vec4 vary_fragcoord;
uniform vec2 screen_res;
uniform mat4 inv_proj;
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 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(srgb_to_linear(col.rgb), col.a);
}
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
ret = correctWithGamma(ret);
vec2 dist = tc-vec2(0.5);
@@ -86,6 +146,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);
vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
@@ -103,6 +164,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);
vec2 dist = tc-vec2(0.5);
@@ -127,20 +189,6 @@ vec4 getPosition(vec2 pos_screen)
return pos;
}
vec3 unpack(vec2 tc)
{
//#define PACK_NORMALS
#ifdef PACK_NORMALS
vec2 enc = texture2DRect(normalMap, tc).xy;
enc = enc*4.0-2.0;
float prod = dot(enc,enc);
return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5);
#else
vec3 norm = texture2DRect(normalMap, tc).xyz;
return norm*2.0-1.0;
#endif
}
void main()
{
vec4 frag = vary_fragcoord;
@@ -150,16 +198,19 @@ void main()
vec3 pos = getPosition(frag.xy).xyz;
vec3 lv = trans_center.xyz-pos.xyz;
float dist2 = dot(lv,lv);
dist2 /= size;
if (dist2 > 1.0)
float dist = length(lv);
dist /= size;
if (dist > 1.0)
{
discard;
}
vec3 norm = unpack(frag.xy); // unpack norm
//norm = normalize(norm); // may be superfluous
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
float envIntensity = norm.z;
norm = decode_normal(norm.xy);
norm = normalize(norm);
float l_dist = -dot(lv, proj_n);
vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
@@ -171,7 +222,10 @@ void main()
proj_tc.xyz /= proj_tc.w;
float fa = falloff+1.0;
float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0);
float dist_atten = min(1.0-(dist-1.0*(1.0-fa))/fa, 1.0);
dist_atten *= dist_atten;
dist_atten *= 2.0;
if (dist_atten <= 0.0)
{
discard;
@@ -185,31 +239,35 @@ void main()
vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb;
vec4 spec = texture2DRect(specularRect, frag.xy);
float noise = texture2D(noiseMap, frag.xy/128.0).b;
vec3 dlit = vec3(0, 0, 0);
if (proj_tc.z > 0.0 &&
proj_tc.x < 1.0 &&
proj_tc.y < 1.0 &&
proj_tc.x > 0.0 &&
proj_tc.y > 0.0)
{
float lit = 0.0;
float amb_da = proj_ambiance;
float lit = 0.0;
if (da > 0.0)
{
lit = da * dist_atten * noise;
float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
float lod = diff * proj_lod;
vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
vec3 lcol = color.rgb * plcol.rgb * plcol.a;
dlit = color.rgb * plcol.rgb * plcol.a;
lit = da * dist_atten * noise;
col = lcol*lit*diff_tex;
amb_da += (da*0.5)*proj_ambiance;
col = dlit*lit*diff_tex;
//amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;
}
//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
@@ -218,13 +276,37 @@ void main()
amb_da *= dist_atten * noise;
amb_da = min(amb_da, 1.0-lit);
col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a*diff_tex.rgb;
}
vec4 spec = texture2DRect(specularRect, frag.xy);
if (spec.a > 0.0)
{
dlit *= min(da*6.0, 1.0) * dist_atten;
vec3 npos = -normalize(pos);
//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 += dlit*scol*spec.rgb;
//col += spec.rgb;
}
}
if (envIntensity > 0.0)
{
vec3 ref = reflect(normalize(pos), norm);
@@ -242,8 +324,9 @@ void main()
{
stc.xy /= stc.w;
float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0);
float fatten = clamp(envIntensity*envIntensity+envIntensity*0.5, 0.25, 1.0);
//stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
if (stc.x < 1.0 &&
@@ -251,8 +334,7 @@ void main()
stc.x > 0.0 &&
stc.y > 0.0)
{
vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb;
col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod-envIntensity*proj_lod).rgb*spec.rgb;
}
}
}

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -42,10 +42,5 @@ void main()
frag_data[0] = vec4(col.rgb,col.a*custom_alpha);
frag_data[1] = vec4(0,0,0,0);
//#define PACK_NORMALS
#ifdef PACK_NORMALS
frag_data[2] = vec4(0.5,0.5,0.0,0.0);
#else
frag_data[2] = vec4(0.0,0.0,1.0,0.0);
#endif
frag_data[2] = vec4(0.5,0.5,0.0,1.0);
}

View File

@@ -49,6 +49,23 @@ VARYING vec2 vary_fragcoord;
uniform mat4 inv_proj;
uniform vec2 screen_res;
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;
}
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2DRect(depthMap, pos_screen.xy).r;
@@ -115,19 +132,6 @@ float calcAmbientOcclusion(vec4 pos, vec3 norm)
return (rtn * rtn);
}
vec3 unpack(vec2 tc)
{
//#define PACK_NORMALS
#ifdef PACK_NORMALS
vec2 enc = texture2DRect(normalMap, tc).xy;
enc = enc*4.0-2.0;
float prod = dot(enc,enc);
return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5);
#else
vec3 norm = texture2DRect(normalMap, tc).xyz;
return norm*2.0-1.0;
#endif
}
void main()
{
vec2 pos_screen = vary_fragcoord.xy;
@@ -136,7 +140,8 @@ void main()
vec4 pos = getPosition(pos_screen);
vec3 norm = unpack(pos_screen); // unpack norm
vec3 norm = texture2DRect(normalMap, pos_screen).xyz;
norm = decode_normal(norm.xy);
frag_color[0] = 1.0;
frag_color[1] = calcAmbientOcclusion(pos, norm);

View File

@@ -39,15 +39,10 @@ VARYING vec3 vary_normal;
VARYING vec4 vary_texcoord0;
VARYING vec4 vary_texcoord1;
vec3 pack(vec3 norm)
vec2 encode_normal(vec3 n)
{
//#define PACK_NORMALS
#ifdef PACK_NORMALS
float p = sqrt(8.0*norm.z+8.0);
return vec3(norm.xy/p + 0.5, 0.0);
#else
return norm.xyz*0.5+0.5;
#endif
float f = sqrt(8 * n.z + 8);
return n.xy / f + 0.5;
}
void main()
@@ -67,6 +62,6 @@ void main()
frag_data[0] = vec4(outColor.rgb, 0.0);
frag_data[1] = vec4(0,0,0,0);
vec3 nvn = normalize(vary_normal);
frag_data[2] = vec4(pack(nvn),0.0);
frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
}

View File

@@ -37,15 +37,10 @@ VARYING vec2 vary_texcoord0;
uniform float minimum_alpha;
vec3 pack(vec3 norm)
vec2 encode_normal(vec3 n)
{
//#define PACK_NORMALS
#ifdef PACK_NORMALS
float p = sqrt(8.0*norm.z+8.0);
return vec3(norm.xy/p + 0.5, 0.0);
#else
return norm.xyz*0.5+0.5;
#endif
float f = sqrt(8 * n.z + 8);
return n.xy / f + 0.5;
}
void main()
@@ -59,5 +54,5 @@ void main()
frag_data[0] = vec4(vertex_color.rgb*col.rgb, 0.0);
frag_data[1] = vec4(0,0,0,0);
vec3 nvn = normalize(vary_normal);
frag_data[2] = vec4(pack(nvn),0.0);
frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
}

View File

@@ -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
}

View File

@@ -67,15 +67,47 @@ VARYING vec4 littleWave;
VARYING vec4 view;
VARYING vec4 vary_position;
vec3 pack(vec3 norm)
vec3 srgb_to_linear(vec3 cs)
{
//#define PACK_NORMALS
#ifdef PACK_NORMALS
float p = sqrt(8.0*norm.z+8.0);
return vec3(norm.xy/p + 0.5, 0.0);
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 norm.xyz*0.5+0.5;
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;
}
void main()
@@ -126,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;
@@ -136,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);
@@ -153,25 +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(pack(screenspacewavef), 0.5);
frag_data[0] = vec4(color.rgb, color.a); // 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
}

View File

@@ -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;

View File

@@ -48,40 +48,40 @@ float wave(vec2 v, float t, float f, vec2 d, float s)
void main()
{
//transform vertex
vec4 pos = vec4(position.xyz, 1.0);
mat4 modelViewProj = modelview_projection_matrix;
vec4 oPosition;
//get view vector
vec3 oEyeVec;
oEyeVec.xyz = position.xyz-eyeVec;
oEyeVec.xyz = pos.xyz-eyeVec;
float d = length(oEyeVec.xy);
float ld = min(d, 2560.0);
vec3 lpos = position;
lpos.xy = eyeVec.xy + oEyeVec.xy/d*ld;
pos.xy = eyeVec.xy + oEyeVec.xy/d*ld;
view.xyz = oEyeVec;
d = clamp(ld/1536.0-0.5, 0.0, 1.0);
d *= d;
oPosition = vec4(lpos, 1.0);
oPosition = vec4(position, 1.0);
oPosition.z = mix(oPosition.z, max(eyeVec.z*0.75, 0.0), d);
oPosition = modelViewProj * oPosition;
refCoord.xyz = oPosition.xyz + vec3(0,0,0.2);
//get wave position parameter (create sweeping horizontal waves)
vec3 v = lpos;
vec3 v = pos.xyz;
v.x += (cos(v.x*0.08/*+time*0.01*/)+sin(v.y*0.02))*6.0;
//push position for further horizon effect.
vec4 pos;
pos.xyz = oEyeVec.xyz*(waterHeight/oEyeVec.z);
pos.w = 1.0;
pos = modelview_matrix*pos;
calcAtmospherics(view.xyz);
calcAtmospherics(pos.xyz);
//pass wave parameters to pixel shader

View File

@@ -31,8 +31,6 @@ out vec4 frag_color;
uniform sampler2D depthMap;
uniform float delta;
VARYING vec2 tc0;
VARYING vec2 tc1;
VARYING vec2 tc2;

View File

@@ -33,8 +33,6 @@ out vec4 frag_color;
uniform sampler2DRect depthMap;
uniform float delta;
VARYING vec2 tc0;
VARYING vec2 tc1;
VARYING vec2 tc2;

View File

@@ -41,13 +41,15 @@ VARYING vec2 vary_texcoord0;
void default_lighting()
{
vec4 color = texture2D(diffuseMap,vary_texcoord0.xy) * vertex_color;
vec4 color = texture2D(diffuseMap,vary_texcoord0.xy);
if (color.a < minimum_alpha)
{
discard;
}
color.rgb *= vertex_color.rgb;
color.rgb = atmosLighting(color.rgb);
color.rgb = scaleSoftClip(color.rgb);

View File

@@ -30,6 +30,7 @@ out vec4 frag_color;
#endif
uniform float minimum_alpha;
uniform float texture_gamma;
vec3 fullbrightAtmosTransport(vec3 light);
vec3 fullbrightScaleSoftClip(vec3 light);
@@ -39,13 +40,16 @@ VARYING vec2 vary_texcoord0;
void fullbright_lighting()
{
vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color;
vec4 color = diffuseLookup(vary_texcoord0.xy);
if (color.a < minimum_alpha)
{
discard;
}
color.rgb *= vertex_color.rgb;
color.rgb = pow(color.rgb, vec3(texture_gamma));
color.rgb = fullbrightAtmosTransport(color.rgb);
color.rgb = fullbrightScaleSoftClip(color.rgb);

View File

@@ -32,6 +32,8 @@ out vec4 frag_color;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
uniform float texture_gamma;
vec3 fullbrightAtmosTransport(vec3 light);
vec3 fullbrightScaleSoftClip(vec3 light);
@@ -39,10 +41,14 @@ void fullbright_lighting()
{
vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color;
color.rgb = pow(color.rgb, vec3(texture_gamma));
color.rgb = fullbrightAtmosTransport(color.rgb);
color.rgb = fullbrightScaleSoftClip(color.rgb);
color.rgb = pow(color.rgb, vec3(1.0/texture_gamma));
frag_color = color;
}

View File

@@ -30,6 +30,7 @@ out vec4 frag_color;
#endif
uniform float minimum_alpha;
uniform float texture_gamma;
vec3 fullbrightAtmosTransport(vec3 light);
vec3 fullbrightScaleSoftClip(vec3 light);
@@ -41,17 +42,22 @@ VARYING vec2 vary_texcoord0;
void fullbright_lighting()
{
vec4 color = texture2D(diffuseMap,vary_texcoord0.xy) * vertex_color;
vec4 color = texture2D(diffuseMap,vary_texcoord0.xy);
if (color.a < minimum_alpha)
{
discard;
}
color.rgb *= vertex_color.rgb;
color.rgb = pow(color.rgb, vec3(texture_gamma));
color.rgb = fullbrightAtmosTransport(color.rgb);
color.rgb = fullbrightScaleSoftClip(color.rgb);
color.rgb = pow(color.rgb, vec3(1.0/texture_gamma));
frag_color = color;
}

View File

@@ -31,7 +31,7 @@ out vec4 frag_color;
uniform float minimum_alpha;
vec4 diffuseLookup(vec2 texcoord);
/* vec4 diffuseLookup(vec2 texcoord); */
vec3 fullbrightAtmosTransport(vec3 light);
vec4 applyWaterFog(vec4 color);

View File

@@ -1,168 +0,0 @@
/**
* @file alphaF.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$
*/
#extension GL_ARB_texture_rectangle : enable
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
#define frag_color gl_FragColor
#endif
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
uniform sampler2DRectShadow shadowMap0;
uniform sampler2DRectShadow shadowMap1;
uniform sampler2DRectShadow shadowMap2;
uniform sampler2DRectShadow shadowMap3;
uniform sampler2DRect depthMap;
uniform mat4 shadow_matrix[6];
uniform vec4 shadow_clip;
uniform vec2 screen_res;
uniform vec2 shadow_res;
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;
uniform float shadow_bias;
uniform mat4 inv_proj;
float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc)
{
stc.xyz /= stc.w;
stc.z += shadow_bias;
stc.x = floor(stc.x + fract(stc.y*12345)); // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here
float cs = shadow2DRect(shadowMap, stc.xyz).x;
float shadow = cs;
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(2.0, 1.5, 0.0)).x;
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(1.0, -1.5, 0.0)).x;
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-1.0, 1.5, 0.0)).x;
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-2.0, -1.5, 0.0)).x;
return shadow*0.2;
}
void main()
{
vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
frag *= screen_res;
float shadow = 0.0;
vec4 pos = vec4(vary_position, 1.0);
vec4 spos = pos;
if (spos.z > -shadow_clip.w)
{
vec4 lpos;
vec4 near_split = shadow_clip*-0.75;
vec4 far_split = shadow_clip*-1.25;
vec4 transition_domain = near_split-far_split;
float weight = 0.0;
if (spos.z < near_split.z)
{
lpos = shadow_matrix[3]*spos;
lpos.xy *= shadow_res;
float w = 1.0;
w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
shadow += pcfShadow(shadowMap3, lpos)*w;
weight += w;
shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
}
if (spos.z < near_split.y && spos.z > far_split.z)
{
lpos = shadow_matrix[2]*spos;
lpos.xy *= shadow_res;
float w = 1.0;
w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
shadow += pcfShadow(shadowMap2, lpos)*w;
weight += w;
}
if (spos.z < near_split.x && spos.z > far_split.y)
{
lpos = shadow_matrix[1]*spos;
lpos.xy *= shadow_res;
float w = 1.0;
w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
shadow += pcfShadow(shadowMap1, lpos)*w;
weight += w;
}
if (spos.z > far_split.x)
{
lpos = shadow_matrix[0]*spos;
lpos.xy *= shadow_res;
float w = 1.0;
w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
shadow += pcfShadow(shadowMap0, lpos)*w;
weight += w;
}
shadow /= weight;
}
else
{
shadow = 1.0;
}
vec4 diff = diffuseLookup(vary_texcoord0.xy);
vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, vertex_color.a);
vec4 color = diff * col;
color.rgb = atmosLighting(color.rgb);
color.rgb = scaleSoftClip(color.rgb);
color.rgb += diff.rgb * vary_pointlight_col.rgb;
frag_color = color;
}

View File

@@ -1,182 +0,0 @@
/**
* @file alphaF.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$
*/
#extension GL_ARB_texture_rectangle : enable
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
#define frag_color gl_FragColor
#endif
uniform sampler2DRectShadow shadowMap0;
uniform sampler2DRectShadow shadowMap1;
uniform sampler2DRectShadow shadowMap2;
uniform sampler2DRectShadow shadowMap3;
uniform sampler2DRect depthMap;
uniform sampler2D diffuseMap;
uniform mat4 shadow_matrix[6];
uniform vec4 shadow_clip;
uniform vec2 screen_res;
uniform vec2 shadow_res;
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 vec4 vertex_color;
uniform float shadow_bias;
uniform mat4 inv_proj;
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2DRect(depthMap, pos_screen.xy).a;
vec2 sc = pos_screen.xy*2.0;
sc /= screen_res;
sc -= vec2(1.0,1.0);
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
vec4 pos = inv_proj * ndc;
pos.xyz /= pos.w;
pos.w = 1.0;
return pos;
}
float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc)
{
stc.xyz /= stc.w;
stc.z += shadow_bias;
stc.x = floor(stc.x + fract(stc.y*12345)); // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here
float cs = shadow2DRect(shadowMap, stc.xyz).x;
float shadow = cs;
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(2.0, 1.5, 0.0)).x;
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(1.0, -1.5, 0.0)).x;
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-1.0, 1.5, 0.0)).x;
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-2.0, -1.5, 0.0)).x;
return shadow*0.2;
}
void main()
{
vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
frag *= screen_res;
float shadow = 0.0;
vec4 pos = vec4(vary_position, 1.0);
vec4 spos = pos;
if (spos.z > -shadow_clip.w)
{
vec4 lpos;
vec4 near_split = shadow_clip*-0.75;
vec4 far_split = shadow_clip*-1.25;
vec4 transition_domain = near_split-far_split;
float weight = 0.0;
if (spos.z < near_split.z)
{
lpos = shadow_matrix[3]*spos;
lpos.xy *= shadow_res;
float w = 1.0;
w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
shadow += pcfShadow(shadowMap3, lpos)*w;
weight += w;
shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
}
if (spos.z < near_split.y && spos.z > far_split.z)
{
lpos = shadow_matrix[2]*spos;
lpos.xy *= shadow_res;
float w = 1.0;
w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
shadow += pcfShadow(shadowMap2, lpos)*w;
weight += w;
}
if (spos.z < near_split.x && spos.z > far_split.y)
{
lpos = shadow_matrix[1]*spos;
lpos.xy *= shadow_res;
float w = 1.0;
w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
shadow += pcfShadow(shadowMap1, lpos)*w;
weight += w;
}
if (spos.z > far_split.x)
{
lpos = shadow_matrix[0]*spos;
lpos.xy *= shadow_res;
float w = 1.0;
w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
shadow += pcfShadow(shadowMap0, lpos)*w;
weight += w;
}
shadow /= weight;
}
else
{
shadow = 1.0;
}
vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy);
vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, vertex_color.a);
vec4 color = diff * col;
color.rgb = atmosLighting(color.rgb);
color.rgb = scaleSoftClip(color.rgb);
color.rgb += diff.rgb * vary_pointlight_col.rgb;
frag_color = color;
}

View File

@@ -1,187 +0,0 @@
/**
* @file alphaNonIndexedNoColorF.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2005, 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$
*/
#extension GL_ARB_texture_rectangle : enable
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
#define frag_color gl_FragColor
#endif
uniform float minimum_alpha;
uniform sampler2DRectShadow shadowMap0;
uniform sampler2DRectShadow shadowMap1;
uniform sampler2DRectShadow shadowMap2;
uniform sampler2DRectShadow shadowMap3;
uniform sampler2DRect depthMap;
uniform sampler2D diffuseMap;
uniform mat4 shadow_matrix[6];
uniform vec4 shadow_clip;
uniform vec2 screen_res;
uniform vec2 shadow_res;
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;
uniform float shadow_bias;
uniform mat4 inv_proj;
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2DRect(depthMap, pos_screen.xy).a;
vec2 sc = pos_screen.xy*2.0;
sc /= screen_res;
sc -= vec2(1.0,1.0);
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
vec4 pos = inv_proj * ndc;
pos.xyz /= pos.w;
pos.w = 1.0;
return pos;
}
float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc)
{
stc.xyz /= stc.w;
stc.z += shadow_bias;
stc.x = floor(stc.x + fract(stc.y*12345)); // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here
float cs = shadow2DRect(shadowMap, stc.xyz).x;
float shadow = cs;
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(2.0, 1.5, 0.0)).x;
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(1.0, -1.5, 0.0)).x;
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-1.0, 1.5, 0.0)).x;
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-2.0, -1.5, 0.0)).x;
return shadow*0.2;
}
void main()
{
vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
frag *= screen_res;
float shadow = 0.0;
vec4 pos = vec4(vary_position, 1.0);
vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy);
if (diff.a < minimum_alpha)
{
discard;
}
vec4 spos = pos;
if (spos.z > -shadow_clip.w)
{
vec4 lpos;
vec4 near_split = shadow_clip*-0.75;
vec4 far_split = shadow_clip*-1.25;
vec4 transition_domain = near_split-far_split;
float weight = 0.0;
if (spos.z < near_split.z)
{
lpos = shadow_matrix[3]*spos;
lpos.xy *= shadow_res;
float w = 1.0;
w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
shadow += pcfShadow(shadowMap3, lpos)*w;
weight += w;
shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
}
if (spos.z < near_split.y && spos.z > far_split.z)
{
lpos = shadow_matrix[2]*spos;
lpos.xy *= shadow_res;
float w = 1.0;
w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
shadow += pcfShadow(shadowMap2, lpos)*w;
weight += w;
}
if (spos.z < near_split.x && spos.z > far_split.y)
{
lpos = shadow_matrix[1]*spos;
lpos.xy *= shadow_res;
float w = 1.0;
w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
shadow += pcfShadow(shadowMap1, lpos)*w;
weight += w;
}
if (spos.z > far_split.x)
{
lpos = shadow_matrix[0]*spos;
lpos.xy *= shadow_res;
float w = 1.0;
w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
shadow += pcfShadow(shadowMap0, lpos)*w;
weight += w;
}
shadow /= weight;
}
else
{
shadow = 1.0;
}
vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, 1.0);
vec4 color = diff * col;
color.rgb = atmosLighting(color.rgb);
color.rgb = scaleSoftClip(color.rgb);
color.rgb += diff.rgb * vary_pointlight_col.rgb;
frag_color = color;
}

View File

@@ -1,155 +0,0 @@
/**
* @file alphaSkinnedV.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 mat4 projection_matrix;
uniform mat4 texture_matrix0;
uniform mat4 modelview_matrix;
uniform mat4 modelview_projection_matrix;
ATTRIBUTE vec3 position;
ATTRIBUTE vec3 normal;
ATTRIBUTE vec4 diffuse_color;
ATTRIBUTE vec2 texcoord0;
vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
void calcAtmospherics(vec3 inPositionEye);
float calcDirectionalLight(vec3 n, vec3 l);
mat4 getObjectSkinnedTransform();
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;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
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];
float calcDirectionalLight(vec3 n, vec3 l)
{
float a = max(dot(n,l),0.0);
return a;
}
float 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 da;
}
void main()
{
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
mat4 mat = getObjectSkinnedTransform();
mat = modelview_matrix * mat;
vec3 pos = (mat*vec4(position, 1.0)).xyz;
gl_Position = projection_matrix * vec4(pos, 1.0);
vec4 n = vec4(position, 1.0);
n.xyz += normal.xyz;
n.xyz = (mat*n).xyz;
n.xyz = normalize(n.xyz-pos.xyz);
vec3 norm = n.xyz;
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);
//vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.));
vec4 col = vec4(0.0, 0.0, 0.0, diffuse_color.a);
// Collect normal lights
col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z);
col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z);
col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z);
col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z);
vary_pointlight_col = col.rgb*diffuse_color.rgb;
col.rgb = vec3(0,0,0);
// Add windlight lights
col.rgb = atmosAmbient(vec3(0.));
vary_ambient = col.rgb*diffuse_color.rgb;
vary_directional.rgb = diffuse_color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), (1.0-diffuse_color.a)*(1.0-diffuse_color.a)));
col.rgb = min(col.rgb*diffuse_color.rgb, 1.0);
vertex_color = col;
pos.xyz = (modelview_projection_matrix * vec4(position.xyz, 1.0)).xyz;
vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip);
}

View File

@@ -1,150 +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 modelview_matrix;
uniform mat4 modelview_projection_matrix;
ATTRIBUTE vec3 position;
void passTextureIndex();
ATTRIBUTE vec3 normal;
ATTRIBUTE vec4 diffuse_color;
ATTRIBUTE vec2 texcoord0;
vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
void calcAtmospherics(vec3 inPositionEye);
float 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;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
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];
float calcDirectionalLight(vec3 n, vec3 l)
{
float a = max(dot(n,l),0.0);
return a;
}
float 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 da;
}
void main()
{
//transform vertex
vec4 vert = vec4(position.xyz, 1.0);
passTextureIndex();
vec4 pos = (modelview_matrix * vert);
gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
vec3 norm = normalize(normal_matrix * normal);
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);
//vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.));
vec4 col = vec4(0.0, 0.0, 0.0, diffuse_color.a);
// Collect normal lights
col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z);
col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z);
col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z);
col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z);
vary_pointlight_col = col.rgb*diffuse_color.rgb;
col.rgb = vec3(0,0,0);
// Add windlight lights
col.rgb = atmosAmbient(vec3(0.));
vary_ambient = col.rgb*diffuse_color.rgb;
vary_directional.rgb = diffuse_color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), (1.0-diffuse_color.a)*(1.0-diffuse_color.a)));
col.rgb = col.rgb*diffuse_color.rgb;
vertex_color = col;
pos = modelview_projection_matrix * vert;
vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip);
}

View File

@@ -1,153 +0,0 @@
/**
* @file avatarAlphaV.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 mat4 projection_matrix;
ATTRIBUTE vec3 position;
ATTRIBUTE vec3 normal;
ATTRIBUTE vec2 texcoord0;
vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
mat4 getSkinnedTransform();
void calcAtmospherics(vec3 inPositionEye);
float calcDirectionalLight(vec3 n, vec3 l);
float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);
vec3 atmosAmbient(vec3 light);
vec3 atmosAffectDirectionalLight(float lightIntensity);
vec3 scaleDownLight(vec3 light);
vec3 scaleUpLight(vec3 light);
VARYING vec3 vary_position;
VARYING vec3 vary_ambient;
VARYING vec3 vary_directional;
VARYING vec3 vary_fragcoord;
VARYING vec3 vary_pointlight_col;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
uniform vec4 color;
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];
float calcDirectionalLight(vec3 n, vec3 l)
{
float a = max(dot(n,l),0.0);
return a;
}
float 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 da;
}
void main()
{
vary_texcoord0 = texcoord0;
vec4 pos;
vec3 norm;
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);
gl_Position = projection_matrix * pos;
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);
vec4 col = vec4(0.0, 0.0, 0.0, 1.0);
// Collect normal lights
col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z);
col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z);
col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z);
col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z);
vary_pointlight_col = col.rgb*color.rgb;
col.rgb = vec3(0,0,0);
// Add windlight lights
col.rgb = atmosAmbient(vec3(0.));
vary_ambient = col.rgb*color.rgb;
vary_directional = atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), 0.0));
col.rgb = col.rgb*color.rgb;
vertex_color = col;
vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip);
}

View File

@@ -24,6 +24,7 @@
*/
#extension GL_ARB_texture_rectangle : enable
#extension GL_ARB_shader_texture_lod : enable
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
@@ -39,6 +40,7 @@ uniform samplerCube environmentMap;
uniform sampler2DRect lightMap;
uniform sampler2D noiseMap;
uniform sampler2D projectionMap;
uniform sampler2D lightFunc;
uniform mat4 proj_mat; //screen space to light space
uniform float proj_near; //near clip for projection
@@ -67,10 +69,70 @@ uniform vec2 screen_res;
uniform mat4 inv_proj;
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;
}
vec4 correctWithGamma(vec4 col)
{
return vec4(srgb_to_linear(col.rgb), col.a);
}
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
ret = correctWithGamma(ret);
vec2 dist = tc-vec2(0.5);
float det = max(1.0-lod/(proj_lod*0.5), 0.0);
@@ -85,7 +147,8 @@ 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);
vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
float det = min(lod/(proj_lod*0.5), 1.0);
@@ -102,6 +165,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);
vec2 dist = tc-vec2(0.5);
@@ -126,20 +190,6 @@ vec4 getPosition(vec2 pos_screen)
return pos;
}
vec3 unpack(vec2 tc)
{
//#define PACK_NORMALS
#ifdef PACK_NORMALS
vec2 enc = texture2DRect(normalMap, tc).xy;
enc = enc*4.0-2.0;
float prod = dot(enc,enc);
return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5);
#else
vec3 norm = texture2DRect(normalMap, tc).xyz;
return norm*2.0-1.0;
#endif
}
void main()
{
vec4 frag = vary_fragcoord;
@@ -149,9 +199,9 @@ void main()
vec3 pos = getPosition(frag.xy).xyz;
vec3 lv = center.xyz-pos.xyz;
float dist2 = dot(lv,lv);
dist2 /= size;
if (dist2 > 1.0)
float dist = length(lv);
dist /= size;
if (dist > 1.0)
{
discard;
}
@@ -167,9 +217,13 @@ void main()
shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0);
}
vec3 norm = unpack(frag.xy); // unpack norm
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
//norm = normalize(norm); // may be superfluous
float envIntensity = norm.z;
norm = decode_normal(norm.xy);
norm = normalize(norm);
float l_dist = -dot(lv, proj_n);
vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
@@ -181,7 +235,9 @@ void main()
proj_tc.xyz /= proj_tc.w;
float fa = falloff+1.0;
float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0);
float dist_atten = min(1.0-(dist-1.0*(1.0-fa))/fa, 1.0);
dist_atten *= dist_atten;
dist_atten *= 2.0;
if (dist_atten <= 0.0)
{
discard;
@@ -190,11 +246,15 @@ void main()
lv = proj_origin-pos.xyz;
lv = normalize(lv);
float da = dot(norm, lv);
vec3 col = vec3(0,0,0);
vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb;
vec4 spec = texture2DRect(specularRect, frag.xy);
vec3 dlit = vec3(0, 0, 0);
float noise = texture2D(noiseMap, frag.xy/128.0).b;
if (proj_tc.z > 0.0 &&
proj_tc.x < 1.0 &&
@@ -202,21 +262,21 @@ void main()
proj_tc.x > 0.0 &&
proj_tc.y > 0.0)
{
float lit = 0.0;
float amb_da = proj_ambiance;
float lit = 0.0;
if (da > 0.0)
{
lit = da * dist_atten * noise;
float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
float lod = diff * proj_lod;
vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
vec3 lcol = color.rgb * plcol.rgb * plcol.a;
dlit = color.rgb * plcol.rgb * plcol.a;
lit = da * dist_atten * noise;
col = lcol*lit*diff_tex*shadow;
col = dlit*lit*diff_tex*shadow;
amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;
}
@@ -232,9 +292,36 @@ void main()
col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
}
vec4 spec = texture2DRect(specularRect, frag.xy);
if (spec.a > 0.0)
{
vec3 npos = -normalize(pos);
dlit *= 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 += dlit*scol*spec.rgb*shadow;
//col += spec.rgb;
}
}
if (envIntensity > 0.0)
{
vec3 ref = reflect(normalize(pos), norm);
@@ -247,13 +334,12 @@ void main()
vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
stc /= stc.w;
if (stc.z > 0.0)
{
stc.xy /= stc.w;
float fatten = clamp(envIntensity*envIntensity+envIntensity*0.25, 0.25, 1.0);
float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0);
stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
if (stc.x < 1.0 &&
@@ -261,13 +347,16 @@ void main()
stc.x > 0.0 &&
stc.y > 0.0)
{
vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb*shadow;
col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod).rgb*shadow*spec.rgb;
}
}
}
}
//not sure why, but this line prevents MATBUG-194
col = max(col, vec3(0.0));
frag_color.rgb = col;
frag_color.a = 0.0;
}

View File

@@ -38,7 +38,6 @@ uniform sampler2DRect lightMap;
uniform sampler2DRect depthMap;
uniform samplerCube environmentMap;
uniform sampler2D lightFunc;
uniform vec3 gi_quad;
uniform float blur_size;
uniform float blur_fidelity;
@@ -60,16 +59,13 @@ uniform float density_multiplier;
uniform float distance_multiplier;
uniform float max_y;
uniform vec4 glow;
uniform float global_gamma;
uniform float scene_light_strength;
uniform mat3 env_mat;
uniform vec4 shadow_clip;
uniform float ssao_effect;
uniform mat4 inv_proj;
uniform vec2 screen_res;
uniform mat3 ssao_effect_mat;
uniform vec3 sun_dir;
VARYING vec2 vary_fragcoord;
vec3 vary_PositionEye;
@@ -79,11 +75,61 @@ vec3 vary_AmblitColor;
vec3 vary_AdditiveColor;
vec3 vary_AtmosAttenuation;
float luminance(vec3 color)
uniform mat4 inv_proj;
uniform vec2 screen_res;
vec3 srgb_to_linear(vec3 cs)
{
/// CALCULATING LUMINANCE (Using NTSC lum weights)
/// http://en.wikipedia.org/wiki/Luma_%28video%29
return dot(color, vec3(0.299, 0.587, 0.114));
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;
}
vec4 getPosition_d(vec2 pos_screen, float depth)
@@ -125,7 +171,6 @@ vec3 getAtmosAttenuation()
return vary_AtmosAttenuation;
}
void setPositionEye(vec3 v)
{
vary_PositionEye = v;
@@ -212,21 +257,78 @@ void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
//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)));
// decrease ambient value for occluded areas
tmpAmbient *= mix(ssao_effect, 1.0, ambFactor);
//brightness of surface both sunlight and ambient
/*setSunlitColor(pow(vec3(sunlight * .5), vec3(global_gamma)) * global_gamma);
setAmblitColor(pow(vec3(tmpAmbient * .25), vec3(global_gamma)) * global_gamma);
setAdditiveColor(pow(getAdditiveColor() * vec3(1.0 - temp1), vec3(global_gamma)) * global_gamma);*/
setSunlitColor(vec3(sunlight * .5));
setAmblitColor(vec3(tmpAmbient * .25));
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;
@@ -239,6 +341,15 @@ vec3 atmosTransport(vec3 light) {
light += getAdditiveColor() * 2.0;
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 atmosGetDiffuseSunlightColor()
{
return getSunlitColor();
@@ -273,18 +384,18 @@ vec3 scaleSoftClip(vec3 light)
return light;
}
vec3 unpack(vec2 tc)
vec3 fullbrightScaleSoftClip(vec3 light)
{
//#define PACK_NORMALS
#ifdef PACK_NORMALS
vec2 enc = texture2DRect(normalMap, tc).xy;
enc = enc*4.0-2.0;
float prod = dot(enc,enc);
return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5);
#else
vec3 norm = texture2DRect(normalMap, tc).xyz;
return norm*2.0-1.0;
#endif
//soft clip effect:
return light;
}
float luminance(vec3 color)
{
/// CALCULATING LUMINANCE (Using NTSC lum weights)
/// http://en.wikipedia.org/wiki/Luma_%28video%29
return dot(color, vec3(0.299, 0.587, 0.114));
}
void main()
@@ -292,61 +403,107 @@ void main()
vec2 tc = vary_fragcoord.xy;
float depth = texture2DRect(depthMap, tc.xy).r;
vec3 pos = getPosition_d(tc, depth).xyz;
vec3 norm = unpack(tc); // unpack norm
vec4 norm = texture2DRect(normalMap, tc);
float envIntensity = norm.z;
norm.xyz = decode_normal(norm.xy); // unpack norm
float da = max(dot(norm.xyz, sun_dir.xyz), 0.0);
vec4 diffuse = texture2DRect(diffuseRect, tc);
vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
float light_gamma = 1.0/1.3;
da = pow(da, light_gamma);
vec4 diffuse = texture2DRect(diffuseRect, tc);
//convert to gamma space
diffuse.rgb = linear_to_srgb(diffuse.rgb);
vec3 col;
float bloom = 0.0;
if (diffuse.a < 0.9)
{
vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
bloom = spec.r*norm.w;
if (norm.w < 0.5)
{
vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg;
scol_ambocc = pow(scol_ambocc, vec2(light_gamma));
float scol = max(scol_ambocc.r, diffuse.a);
float ambocc = scol_ambocc.g;
calcAtmospherics(pos.xyz, ambocc);
col = atmosAmbient(vec3(0));
col += atmosAffectDirectionalLight(max(min(da, scol), diffuse.a));
float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
ambient *= 0.5;
ambient *= ambient;
ambient = (1.0-ambient);
col.rgb *= ambient;
col += atmosAffectDirectionalLight(max(min(da, scol), 0.0));
col *= diffuse.rgb;
vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
if (spec.a > 0.0) // specular reflection
{
// the old infinite-sky shiny reflection
//
vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
float sa = dot(refnormpersp, sun_dir.xyz);
vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*(6 * texture2D(lightFunc, vec2(sa, spec.a)).r);
vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*(texture2D(lightFunc, vec2(sa, spec.a)).r);
// add the two types of shiny together
vec3 spec_contrib = dumbshiny * spec.rgb;
bloom = dot(spec_contrib, spec_contrib) / 4;
bloom = dot(spec_contrib, spec_contrib) / 6;
col += spec_contrib;
//add environmentmap
vec3 env_vec = env_mat * refnormpersp;
vec3 env = textureCube(environmentMap, env_vec).rgb;
bloom = (luminance(env) - .45)*.25;
col = mix(col.rgb, env,
max(spec.a-diffuse.a*2.0, 0.0));
}
col = atmosLighting(col);
col = scaleSoftClip(col);
col = mix(col, diffuse.rgb, diffuse.a);
}
else
{
bloom = spec.r;
col = diffuse.rgb;
}
}
col = mix(col, diffuse.rgb, diffuse.a);
if (envIntensity > 0.0)
{ //add environmentmap
vec3 env_vec = env_mat * refnormpersp;
vec3 refcol = textureCube(environmentMap, env_vec).rgb*scol_ambocc.r;
bloom = (luminance(refcol) - .45)*.25;
col = mix(col.rgb, refcol,
envIntensity);
}
//if (norm.w < 0.5)
{
col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a);
col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);
//bloom += (luminance(col))*.075; //This looks nice, but requires a larger glow rendertarget.
}
#ifdef WATER_FOG
vec4 fogged = applyWaterFogDeferred(pos,vec4(col, bloom));
col = fogged.rgb;
bloom = fogged.a;
#endif
}
else
{
col = diffuse.rgb;
}
col = srgb_to_linear(col);
//col = vec3(1,0,1);
//col.g = envIntensity;
}
frag_color.rgb = col;
frag_color.a = bloom;
}

View File

@@ -24,6 +24,7 @@
*/
#extension GL_ARB_texture_rectangle : enable
#extension GL_ARB_shader_texture_lod : enable
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
@@ -39,6 +40,7 @@ uniform samplerCube environmentMap;
uniform sampler2DRect lightMap;
uniform sampler2D noiseMap;
uniform sampler2D projectionMap;
uniform sampler2D lightFunc;
uniform mat4 proj_mat; //screen space to light space
uniform float proj_near; //near clip for projection
@@ -67,9 +69,69 @@ uniform vec2 screen_res;
uniform mat4 inv_proj;
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 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(srgb_to_linear(col.rgb), col.a);
}
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
ret = correctWithGamma(ret);
vec2 dist = tc-vec2(0.5);
@@ -85,6 +147,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);
vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
@@ -102,6 +165,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);
vec2 dist = tc-vec2(0.5);
@@ -126,20 +190,6 @@ vec4 getPosition(vec2 pos_screen)
return pos;
}
vec3 unpack(vec2 tc)
{
//#define PACK_NORMALS
#ifdef PACK_NORMALS
vec2 enc = texture2DRect(normalMap, tc).xy;
enc = enc*4.0-2.0;
float prod = dot(enc,enc);
return vec3(enc*sqrt(1.0-prod*.25),1.0-prod*.5);
#else
vec3 norm = texture2DRect(normalMap, tc).xyz;
return norm*2.0-1.0;
#endif
}
void main()
{
vec4 frag = vary_fragcoord;
@@ -149,9 +199,9 @@ void main()
vec3 pos = getPosition(frag.xy).xyz;
vec3 lv = trans_center.xyz-pos.xyz;
float dist2 = dot(lv,lv);
dist2 /= size;
if (dist2 > 1.0)
float dist = length(lv);
dist /= size;
if (dist > 1.0)
{
discard;
}
@@ -167,9 +217,11 @@ void main()
shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0);
}
vec3 norm = unpack(frag.xy); // unpack norm
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
float envIntensity = norm.z;
norm = decode_normal(norm.xy);
//norm = normalize(norm); // may be superfluous
norm = normalize(norm);
float l_dist = -dot(lv, proj_n);
vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
@@ -181,7 +233,10 @@ void main()
proj_tc.xyz /= proj_tc.w;
float fa = falloff+1.0;
float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0);
float dist_atten = min(1.0-(dist-1.0*(1.0-fa))/fa, 1.0);
dist_atten *= dist_atten;
dist_atten *= 2.0;
if (dist_atten <= 0.0)
{
discard;
@@ -195,6 +250,10 @@ void main()
vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb;
vec4 spec = texture2DRect(specularRect, frag.xy);
vec3 dlit = vec3(0, 0, 0);
float noise = texture2D(noiseMap, frag.xy/128.0).b;
if (proj_tc.z > 0.0 &&
proj_tc.x < 1.0 &&
@@ -202,21 +261,21 @@ void main()
proj_tc.x > 0.0 &&
proj_tc.y > 0.0)
{
float lit = 0.0;
float amb_da = proj_ambiance;
float lit = 0.0;
if (da > 0.0)
{
lit = da * dist_atten * noise;
float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
float lod = diff * proj_lod;
vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
vec3 lcol = color.rgb * plcol.rgb * plcol.a;
dlit = color.rgb * plcol.rgb * plcol.a;
lit = da * dist_atten * noise;
col = lcol*lit*diff_tex*shadow;
col = dlit*lit*diff_tex*shadow;
amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;
}
@@ -232,9 +291,36 @@ void main()
col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
}
vec4 spec = texture2DRect(specularRect, frag.xy);
if (spec.a > 0.0)
{
dlit *= min(da*6.0, 1.0) * dist_atten;
vec3 npos = -normalize(pos);
//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 += dlit*scol*spec.rgb*shadow;
//col += spec.rgb;
}
}
if (envIntensity > 0.0)
{
vec3 ref = reflect(normalize(pos), norm);
@@ -252,8 +338,9 @@ void main()
{
stc.xy /= stc.w;
float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0);
float fatten = clamp(envIntensity*envIntensity+envIntensity*0.5, 0.25, 1.0);
//stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
if (stc.x < 1.0 &&
@@ -261,13 +348,15 @@ void main()
stc.x > 0.0 &&
stc.y > 0.0)
{
vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb*shadow;
col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod-envIntensity*proj_lod).rgb*shadow*spec.rgb;
}
}
}
}
//not sure why, but this line prevents MATBUG-194
col = max(col, vec3(0.0));
frag_color.rgb = col;
frag_color.a = 0.0;
}

View File

@@ -35,10 +35,10 @@ out vec4 frag_color;
uniform sampler2DRect depthMap;
uniform sampler2DRect normalMap;
uniform sampler2DRectShadow shadowMap0;
uniform sampler2DRectShadow shadowMap1;
uniform sampler2DRectShadow shadowMap2;
uniform sampler2DRectShadow shadowMap3;
uniform sampler2DShadow shadowMap0;
uniform sampler2DShadow shadowMap1;
uniform sampler2DShadow shadowMap2;
uniform sampler2DShadow shadowMap3;
uniform sampler2DShadow shadowMap4;
uniform sampler2DShadow shadowMap5;
@@ -55,16 +55,33 @@ VARYING vec2 vary_fragcoord;
uniform mat4 inv_proj;
uniform vec2 screen_res;
uniform vec2 shadow_res;
uniform vec2 proj_shadow_res;
uniform vec3 sun_dir;
uniform vec2 shadow_res;
uniform float shadow_bias;
uniform float shadow_offset;
uniform float spot_shadow_bias;
uniform float spot_shadow_offset;
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;
}
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2DRect(depthMap, pos_screen.xy).r;
@@ -78,30 +95,31 @@ vec4 getPosition(vec2 pos_screen)
return pos;
}
float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
{
stc.xyz /= stc.w;
stc.z += shadow_bias*scl;
stc.z += shadow_bias;
stc.x = floor(stc.x + fract(pos_screen.y*0.666666666)); // add some jitter to X sample pos according to Y to disguise the snapping going on here
stc.x = floor(stc.x*shadow_res.x + fract(pos_screen.y*0.666666666))/shadow_res.x; // add some jitter to X sample pos according to Y to disguise the snapping going on here
float cs = shadow2D(shadowMap, stc.xyz).x;
float cs = shadow2DRect(shadowMap, stc.xyz).x;
float shadow = cs;
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(2.0, 1.5, 0.0)).x;
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(1.0, -1.5, 0.0)).x;
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-2.0, 1.5, 0.0)).x;
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-1.0, -1.5, 0.0)).x;
shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
return shadow*0.2;
return shadow*0.2;
}
float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
float pcfSpotShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
{
stc.xyz /= stc.w;
stc.z += spot_shadow_bias*scl;
stc.x = floor(proj_shadow_res.x * stc.x + fract(pos_screen.y*0.666666666)) / proj_shadow_res.x; // snap
float cs = shadow2D(shadowMap, stc.xyz).x;
float shadow = cs;
@@ -113,23 +131,7 @@ float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x;
shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x*2.0, -off.y, 0.0)).x;
return shadow*0.2;
}
vec4 unpack(vec2 tc)
{
vec4 norm = texture2DRect(normalMap, tc).xyzw;
//#define PACK_NORMALS
#ifdef PACK_NORMALS
norm.xy = (norm.xy*4.0)-2.0;
float prod = dot(norm.xy,norm.xy);
norm.xy *= sqrt(1.0-prod*.25);
norm.z = 1.0-prod*.5;
#else
norm.xyz = norm.xyz*2.0-1.0;
#endif
norm.w *= norm.z;
return norm;
return shadow*0.2;
}
void main()
@@ -140,10 +142,9 @@ void main()
vec4 pos = getPosition(pos_screen);
vec4 nmap4 = unpack(pos_screen); // unpack norm
float displace = nmap4.w;
vec3 norm = nmap4.xyz;
vec3 norm = texture2DRect(normalMap, pos_screen).xyz;
norm = decode_normal(norm.xy); // unpack norm
/*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL
{
frag_color = vec4(0.0); // doesn't matter
@@ -153,7 +154,7 @@ void main()
float shadow = 0.0;
float dp_directional_light = max(0.0, dot(norm, sun_dir.xyz));
vec3 shadow_pos = pos.xyz + displace*norm;
vec3 shadow_pos = pos.xyz;
vec3 offset = sun_dir.xyz * (1.0-dp_directional_light);
vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0);
@@ -177,8 +178,7 @@ void main()
if (spos.z < near_split.z)
{
lpos = shadow_matrix[3]*spos;
lpos.xy *= shadow_res;
float w = 1.0;
w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
shadow += pcfShadow(shadowMap3, lpos, 0.25, pos_screen)*w;
@@ -189,8 +189,7 @@ void main()
if (spos.z < near_split.y && spos.z > far_split.z)
{
lpos = shadow_matrix[2]*spos;
lpos.xy *= shadow_res;
float w = 1.0;
w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
@@ -201,7 +200,6 @@ void main()
if (spos.z < near_split.x && spos.z > far_split.y)
{
lpos = shadow_matrix[1]*spos;
lpos.xy *= shadow_res;
float w = 1.0;
w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
@@ -213,7 +211,6 @@ void main()
if (spos.z > far_split.x)
{
lpos = shadow_matrix[0]*spos;
lpos.xy *= shadow_res;
float w = 1.0;
w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
@@ -252,11 +249,11 @@ void main()
//spotlight shadow 1
vec4 lpos = shadow_matrix[4]*spos;
frag_color[2] = pcfShadow(shadowMap4, lpos, 0.8, pos_screen);
frag_color[2] = pcfSpotShadow(shadowMap4, lpos, 0.8, pos_screen);
//spotlight shadow 2
lpos = shadow_matrix[5]*spos;
frag_color[3] = pcfShadow(shadowMap5, lpos, 0.8, pos_screen);
frag_color[3] = pcfSpotShadow(shadowMap5, lpos, 0.8, pos_screen);
//frag_color.rgb = pos.xyz;
//frag_color.b = shadow;

View File

@@ -34,10 +34,10 @@ out vec4 frag_color;
uniform sampler2DRect depthMap;
uniform sampler2DRect normalMap;
uniform sampler2DRectShadow shadowMap0;
uniform sampler2DRectShadow shadowMap1;
uniform sampler2DRectShadow shadowMap2;
uniform sampler2DRectShadow shadowMap3;
uniform sampler2DShadow shadowMap0;
uniform sampler2DShadow shadowMap1;
uniform sampler2DShadow shadowMap2;
uniform sampler2DShadow shadowMap3;
uniform sampler2DShadow shadowMap4;
uniform sampler2DShadow shadowMap5;
uniform sampler2D noiseMap;
@@ -55,16 +55,34 @@ VARYING vec2 vary_fragcoord;
uniform mat4 inv_proj;
uniform vec2 screen_res;
uniform vec2 shadow_res;
uniform vec2 proj_shadow_res;
uniform vec3 sun_dir;
uniform vec2 shadow_res;
uniform float shadow_bias;
uniform float shadow_offset;
uniform float spot_shadow_bias;
uniform float spot_shadow_offset;
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;
}
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2DRect(depthMap, pos_screen.xy).r;
@@ -133,25 +151,25 @@ float calcAmbientOcclusion(vec4 pos, vec3 norm)
return (rtn * rtn);
}
float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
{
stc.xyz /= stc.w;
stc.z += shadow_bias*scl;
stc.z += shadow_bias;
stc.x = floor(stc.x + fract(pos_screen.y*0.666666666));
stc.x = floor(stc.x*shadow_res.x + fract(pos_screen.y*0.666666666))/shadow_res.x;
float cs = shadow2D(shadowMap, stc.xyz).x;
float cs = shadow2DRect(shadowMap, stc.xyz).x;
float shadow = cs;
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(2.0, 1.5, 0.0)).x;
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(1.0, -1.5, 0.0)).x;
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-1.0, 1.5, 0.0)).x;
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-2.0, -1.5, 0.0)).x;
shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
return shadow*0.2;
}
float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
float pcfSpotShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
{
stc.xyz /= stc.w;
stc.z += spot_shadow_bias*scl;
@@ -171,22 +189,6 @@ float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
return shadow*0.2;
}
vec4 unpack(vec2 tc)
{
vec4 norm = texture2DRect(normalMap, tc).xyzw;
//#define PACK_NORMALS
#ifdef PACK_NORMALS
norm.xy = (norm.xy*4.0)-2.0;
float prod = dot(norm.xy,norm.xy);
norm.xy *= sqrt(1.0-prod*.25);
norm.z = 1.0-prod*.5;
#else
norm.xyz = norm.xyz*2.0-1.0;
#endif
norm.w *= norm.z;
return norm;
}
void main()
{
vec2 pos_screen = vary_fragcoord.xy;
@@ -195,10 +197,9 @@ void main()
vec4 pos = getPosition(pos_screen);
vec4 nmap4 = unpack(pos_screen); // unpack norm
float displace = nmap4.w;
vec3 norm = nmap4.xyz;
vec3 norm = texture2DRect(normalMap, pos_screen).xyz;
norm = decode_normal(norm.xy); // unpack norm
/*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL
{
frag_color = vec4(0.0); // doesn't matter
@@ -207,8 +208,8 @@ void main()
float shadow = 0.0;
float dp_directional_light = max(0.0, dot(norm, sun_dir.xyz));
vec3 shadow_pos = pos.xyz + displace*norm;
vec3 shadow_pos = pos.xyz;
vec3 offset = sun_dir.xyz * (1.0-dp_directional_light);
vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0);
@@ -232,8 +233,7 @@ void main()
if (spos.z < near_split.z)
{
lpos = shadow_matrix[3]*spos;
lpos.xy *= shadow_res;
float w = 1.0;
w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
shadow += pcfShadow(shadowMap3, lpos, 0.25, pos_screen)*w;
@@ -244,8 +244,7 @@ void main()
if (spos.z < near_split.y && spos.z > far_split.z)
{
lpos = shadow_matrix[2]*spos;
lpos.xy *= shadow_res;
float w = 1.0;
w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
@@ -256,8 +255,7 @@ void main()
if (spos.z < near_split.x && spos.z > far_split.y)
{
lpos = shadow_matrix[1]*spos;
lpos.xy *= shadow_res;
float w = 1.0;
w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
@@ -268,8 +266,7 @@ void main()
if (spos.z > far_split.x)
{
lpos = shadow_matrix[0]*spos;
lpos.xy *= shadow_res;
float w = 1.0;
w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
@@ -307,11 +304,11 @@ void main()
//spotlight shadow 1
vec4 lpos = shadow_matrix[4]*spos;
frag_color[2] = pcfShadow(shadowMap4, lpos, 0.8, pos_screen);
frag_color[2] = pcfSpotShadow(shadowMap4, lpos, 0.8, pos_screen);
//spotlight shadow 2
lpos = shadow_matrix[5]*spos;
frag_color[3] = pcfShadow(shadowMap5, lpos, 0.8, pos_screen);
frag_color[3] = pcfSpotShadow(shadowMap5, lpos, 0.8, pos_screen);
//frag_color.rgb = pos.xyz;
//frag_color.b = shadow;

View File

@@ -304,6 +304,49 @@ LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep)
}
LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp)
{
LLFace *face;
face = new LLFace(this, mVObjp);
face->setTEOffset(mFaces.size());
face->setTexture(texturep);
face->setNormalMap(normalp);
face->setPoolType(gPipeline.getPoolTypeFromTE(te, texturep));
mFaces.push_back(face);
if (isState(UNLIT))
{
face->setState(LLFace::FULLBRIGHT);
}
return face;
}
LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp, LLViewerTexture *specularp)
{
LLFace *face;
face = new LLFace(this, mVObjp);
face->setTEOffset(mFaces.size());
face->setTexture(texturep);
face->setNormalMap(normalp);
face->setSpecularMap(specularp);
face->setPoolType(gPipeline.getPoolTypeFromTE(te, texturep));
mFaces.push_back(face);
if (isState(UNLIT))
{
face->setState(LLFace::FULLBRIGHT);
}
return face;
}
void LLDrawable::setNumFaces(const S32 newFaces, LLFacePool *poolp, LLViewerTexture *texturep)
{
if (newFaces == (S32)mFaces.size())
@@ -565,10 +608,10 @@ F32 LLDrawable::updateXform(BOOL undamped)
mVObjp->dirtySpatialGroup();
}
}
else if (!isRoot() && (
dist_vec_squared(old_pos, target_pos) > 0.f
|| old_rot != target_rot ))
{ //fix for BUG-860, MAINT-2275, MAINT-1742, MAINT-2247
else if (!isRoot() &&
((dist_vec_squared(old_pos, target_pos) > 0.f)
|| (1.f - dot(old_rot, target_rot)) > 0.f))
{ //fix for BUG-840, MAINT-2275, MAINT-1742, MAINT-2247
gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE);
}
else if (!getVOVolume() && !isAvatar())

View File

@@ -151,6 +151,8 @@ public:
//void removeFace(const S32 i); // SJB: Avoid using this, it's slow
LLFace* addFace(LLFacePool *poolp, LLViewerTexture *texturep);
LLFace* addFace(const LLTextureEntry *te, LLViewerTexture *texturep);
LLFace* addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp);
LLFace* addFace(const LLTextureEntry *te, LLViewerTexture *texturep, LLViewerTexture *normalp, LLViewerTexture *specularp);
void deleteFaces(S32 offset, S32 count);
void setNumFaces(const S32 numFaces, LLFacePool *poolp, LLViewerTexture *texturep);
void setNumFacesFast(const S32 numFaces, LLFacePool *poolp, LLViewerTexture *texturep);

View File

@@ -35,6 +35,7 @@
#include "lldrawpoolalpha.h"
#include "lldrawpoolavatar.h"
#include "lldrawpoolbump.h"
#include "lldrawpoolmaterials.h"
#include "lldrawpoolground.h"
#include "lldrawpoolsimple.h"
#include "lldrawpoolsky.h"
@@ -47,6 +48,7 @@
#include "llspatialpartition.h"
#include "llviewercamera.h"
#include "lldrawpoolwlsky.h"
#include "llglslshader.h"
S32 LLDrawPool::sNumDrawPools = 0;
@@ -64,6 +66,12 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0)
case POOL_GRASS:
poolp = new LLDrawPoolGrass();
break;
case POOL_ALPHA_MASK:
poolp = new LLDrawPoolAlphaMask();
break;
case POOL_FULLBRIGHT_ALPHA_MASK:
poolp = new LLDrawPoolFullbrightAlphaMask();
break;
case POOL_FULLBRIGHT:
poolp = new LLDrawPoolFullbright();
break;
@@ -98,6 +106,9 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0)
case POOL_BUMP:
poolp = new LLDrawPoolBump();
break;
case POOL_MATERIALS:
poolp = new LLDrawPoolMaterials();
break;
case POOL_WL_SKY:
poolp = new LLDrawPoolWLSky();
break;
@@ -408,6 +419,27 @@ void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_text
}
}
void LLRenderPass::pushMaskBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)
{
for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
{
LLDrawInfo* pparams = *i;
if (pparams)
{
if (LLGLSLShader::sCurBoundShaderPtr)
{
LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff);
}
else
{
gGL.setAlphaRejectSettings(LLRender::CF_GREATER, pparams->mAlphaMaskCutoff);
}
pushBatch(*pparams, mask, texture, batch_textures);
}
}
}
void LLRenderPass::applyModelMatrix(LLDrawInfo& params)
{
if (params.mModelMatrix != gGLLastMatrix)

View File

@@ -50,8 +50,11 @@ public:
POOL_GROUND,
POOL_FULLBRIGHT,
POOL_BUMP,
POOL_MATERIALS,
POOL_TERRAIN,
POOL_TREE, // Singu Note: Before sky for zcull.
POOL_ALPHA_MASK,
POOL_FULLBRIGHT_ALPHA_MASK,
POOL_SKY,
POOL_WL_SKY,
POOL_GRASS,
@@ -129,6 +132,22 @@ public:
PASS_SHINY,
PASS_BUMP,
PASS_POST_BUMP,
PASS_MATERIAL,
PASS_MATERIAL_ALPHA,
PASS_MATERIAL_ALPHA_MASK,
PASS_MATERIAL_ALPHA_EMISSIVE,
PASS_SPECMAP,
PASS_SPECMAP_BLEND,
PASS_SPECMAP_MASK,
PASS_SPECMAP_EMISSIVE,
PASS_NORMMAP,
PASS_NORMMAP_BLEND,
PASS_NORMMAP_MASK,
PASS_NORMMAP_EMISSIVE,
PASS_NORMSPEC,
PASS_NORMSPEC_BLEND,
PASS_NORMSPEC_MASK,
PASS_NORMSPEC_EMISSIVE,
PASS_GLOW,
PASS_ALPHA,
PASS_ALPHA_MASK,
@@ -147,6 +166,7 @@ public:
static void applyModelMatrix(LLDrawInfo& params);
virtual void pushBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE);
virtual void pushMaskBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE);
virtual void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE);
virtual void renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE);
virtual void renderGroups(U32 type, U32 mask, BOOL texture = TRUE);

View File

@@ -77,33 +77,6 @@ void LLDrawPoolAlpha::prerender()
mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
}
S32 LLDrawPoolAlpha::getNumDeferredPasses()
{
return 1;
}
void LLDrawPoolAlpha::beginDeferredPass(S32 pass)
{
}
void LLDrawPoolAlpha::endDeferredPass(S32 pass)
{
}
void LLDrawPoolAlpha::renderDeferred(S32 pass)
{
LLFastTimer t(FTM_RENDER_GRASS);
gDeferredDiffuseAlphaMaskProgram.bind();
gDeferredDiffuseAlphaMaskProgram.setMinimumAlpha(0.33f);
//render alpha masked objects
LLRenderPass::pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
gDeferredDiffuseAlphaMaskProgram.unbind();
}
S32 LLDrawPoolAlpha::getNumPostDeferredPasses()
{
static const LLCachedControl<bool> render_depth_of_field("RenderDepthOfField");
@@ -127,25 +100,63 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
if (pass == 0)
{
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 = &gObjectFullbrightAlphaMaskProgram;
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();
gPipeline.mDeferredDepth.copyContents(gPipeline.mDeferredScreen, 0, 0, gPipeline.mDeferredScreen.getWidth(), gPipeline.mDeferredScreen.getHeight(),
0, 0, gPipeline.mDeferredDepth.getWidth(), gPipeline.mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
gPipeline.mDeferredDepth.bindTarget();
simple_shader = NULL;
fullbright_shader = NULL;
simple_shader = fullbright_shader = &gObjectFullbrightAlphaMaskProgram;
gObjectFullbrightAlphaMaskProgram.bind();
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)
{
@@ -157,8 +168,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();
@@ -178,16 +188,22 @@ void LLDrawPoolAlpha::beginRenderPass(S32 pass)
{
LLFastTimer t(FTM_RENDER_ALPHA);
if (LLPipeline::sUnderWaterRender)
if (LLPipeline::sImpostorRender)
{
simple_shader = &gObjectSimpleWaterAlphaMaskProgram;
fullbright_shader = &gObjectFullbrightWaterAlphaMaskProgram;
simple_shader = &gObjectSimpleImpostorProgram;
fullbright_shader = &gObjectFullbrightProgram;
emissive_shader = &gObjectEmissiveProgram;
}
else if (LLPipeline::sUnderWaterRender)
{
simple_shader = &gObjectSimpleWaterProgram;
fullbright_shader = &gObjectFullbrightWaterProgram;
emissive_shader = &gObjectEmissiveWaterProgram;
}
else
{
simple_shader = &gObjectSimpleAlphaMaskProgram;
fullbright_shader = &gObjectFullbrightAlphaMaskProgram;
simple_shader = &gObjectSimpleProgram;
fullbright_shader = &gObjectFullbrightProgram;
emissive_shader = &gObjectEmissiveProgram;
}
@@ -205,7 +221,7 @@ void LLDrawPoolAlpha::endRenderPass( S32 pass )
LLFastTimer t(FTM_RENDER_ALPHA);
LLRenderPass::endRenderPass(pass);
if(mVertexShaderLevel > 0)
if(gPipeline.canUseWindLightShaders())
{
LLGLSLShader::bindNoShader();
}
@@ -225,45 +241,14 @@ void LLDrawPoolAlpha::render(S32 pass)
{
gGL.setColorMask(true, true);
}
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;
if (LLPipeline::sAutoMaskAlphaNonDeferred)
{
mColorSFactor = LLRender::BF_ONE; // }
mColorDFactor = LLRender::BF_ZERO; // } these are like disabling blend on the color channels, but we're still blending on the alpha channel so that we can suppress glow
mAlphaSFactor = LLRender::BF_ZERO;
mAlphaDFactor = LLRender::BF_ZERO; // block (zero-out) glow where the alpha test succeeds
gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
if (mVertexShaderLevel > 0)
{
if (!LLPipeline::sRenderDeferred || !deferred_render)
{
simple_shader->bind();
simple_shader->setMinimumAlpha(0.33f);
pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
}
if (fullbright_shader)
{
fullbright_shader->bind();
fullbright_shader->setMinimumAlpha(0.33f);
}
pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
//LLGLSLShader::bindNoShader();
}
else
{
gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.33f); //OK
gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask());
gPipeline.enableLightsDynamic();
pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask());
gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK
}
}
LLGLDepthTest depth(GL_TRUE, (LLDrawPoolWater::sSkipScreenCopy ||
(deferred_render && pass == 1)) ? GL_TRUE : GL_FALSE);
LLGLDepthTest depth(GL_TRUE, write_depth ? GL_TRUE : GL_FALSE);
if (deferred_render && pass == 1)
{
@@ -309,11 +294,11 @@ void LLDrawPoolAlpha::render(S32 pass)
if (mVertexShaderLevel > 0)
{
renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX);
renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, pass);
}
else
{
renderAlpha(getVertexDataMask());
renderAlpha(getVertexDataMask(), pass);
}
gGL.setColorMask(true, false);
@@ -335,7 +320,7 @@ void LLDrawPoolAlpha::render(S32 pass)
gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
}
gGL.diffuseColor4f(0.9,0,0,0.4);
gGL.diffuseColor4f(1,0,0,1);
LLViewerFetchedTexture::sSmokeImagep->addTextureStats(1024.f*1024.f);
gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sSmokeImagep, TRUE) ;
@@ -386,7 +371,7 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
}
}
void LLDrawPoolAlpha::renderAlpha(U32 mask)
void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
{
BOOL initialized_lighting = FALSE;
BOOL light_enabled = TRUE;
@@ -402,13 +387,17 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
if (group->mSpatialPartition->mRenderByGroup &&
!group->isDead())
{
bool draw_glow_for_this_partition = mVertexShaderLevel > 0 && // no shaders = no glow.
// All particle systems seem to come off the wire with texture entries which claim that they glow. This is probably a bug in the data. Suppress.
group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_PARTICLE &&
#if ENABLE_CLASSIC_CLOUDS
group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_CLOUD &&
#endif
group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_HUD_PARTICLE;
bool is_particle_or_hud_particle = group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_PARTICLE
|| group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_CLOUD
|| group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_HUD_PARTICLE;
bool draw_glow_for_this_partition = mVertexShaderLevel > 0; // no shaders = no glow.
static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_GROUP_LOOP("Alpha Group");
LLFastTimer t(FTM_RENDER_ALPHA_GROUP_LOOP);
bool disable_cull = is_particle_or_hud_particle;
LLGLDisable cull(disable_cull ? GL_CULL_FACE : 0);
LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA];
@@ -422,9 +411,32 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
continue;
}
LLRenderPass::applyModelMatrix(params);
// Fix for bug - NORSPEC-271
// If the face is more than 90% transparent, then don't update the Depth buffer for Dof
// We don't want the nearly invisible objects to cause of DoF effects
if(pass == 1 && !LLPipeline::sImpostorRender)
{
LLFace* face = params.mFace;
if(face)
{
const LLTextureEntry* tep = face->getTextureEntry();
if(tep)
{
if(tep->getColor().mV[3] < 0.1f)
continue;
}
}
}
LLRenderPass::applyModelMatrix(params);
LLMaterial* mat = NULL;
if (deferred_render)
{
mat = params.mMaterial;
}
if (params.mFullbright)
{
// Turn off lighting if it hasn't already been so.
@@ -455,13 +467,37 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
gPipeline.enableLightsDynamic();
}
light_enabled = TRUE;
}
if (deferred_render && mat)
{
U32 mask = params.mShaderMask;
llassert(mask < LLMaterial::SHADER_COUNT);
target_shader = &(gDeferredMaterialProgram[mask]);
if (LLPipeline::sUnderWaterRender)
{
target_shader = &(gDeferredMaterialWaterProgram[mask]);
}
// If we need shaders, and we're not ALREADY using the proper shader, then bind it
// (this way we won't rebind shaders unnecessarily).
if(use_shaders && (current_shader != target_shader))
if (current_shader != target_shader)
{
gPipeline.bindDeferredShader(*target_shader);
}
}
else if (!params.mFullbright)
{
llassert(target_shader != NULL);
target_shader = simple_shader;
}
else
{
target_shader = fullbright_shader;
}
if(use_shaders && (current_shader != target_shader))
{// If we need shaders, and we're not ALREADY using the proper shader, then bind it
// (this way we won't rebind shaders unnecessarily).
current_shader = target_shader;
current_shader->bind();
}
@@ -470,6 +506,38 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
LLGLSLShader::bindNoShader();
current_shader = NULL;
}
if (use_shaders && mat)
{
// We have a material. Supply the appropriate data here.
if (LLPipeline::sRenderDeferred)
{
current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, params.mSpecColor.mV[0], params.mSpecColor.mV[1], params.mSpecColor.mV[2], params.mSpecColor.mV[3]);
current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, params.mEnvIntensity);
current_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, params.mFullbright ? 1.f : 0.f);
if (params.mNormalMap)
{
params.mNormalMap->addTextureStats(params.mVSize);
current_shader->bindTexture(LLShaderMgr::BUMP_MAP, params.mNormalMap);
}
if (params.mSpecularMap)
{
params.mSpecularMap->addTextureStats(params.mVSize);
current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, params.mSpecularMap);
}
}
} else if (LLPipeline::sRenderDeferred && current_shader && (current_shader == simple_shader))
{
current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, 1.0f, 1.0f, 1.0f, 1.0f);
current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, 0.0f);
LLViewerFetchedTexture::sFlatNormalImagep->addTextureStats(params.mVSize);
current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep);
LLViewerFetchedTexture::sWhiteImagep->addTextureStats(params.mVSize);
current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep);
}
if (params.mGroup)
{
@@ -493,7 +561,15 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
if (params.mTexture.notNull())
{
params.mTexture->addTextureStats(params.mVSize);
gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ;
if (use_shaders && mat)
{
current_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, params.mTexture);
}
else
{
gGL.getTexUnit(0)->bind(params.mTexture, TRUE);
}
if (params.mTextureMatrix)
{
tex_setup = true;
@@ -509,9 +585,15 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
}
}
params.mVertexBuffer->setBuffer(mask);
static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_PUSH("Alpha Push Verts");
{
LLFastTimer t(FTM_RENDER_ALPHA_PUSH);
gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);
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 &&
@@ -547,6 +629,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
}
}
gGL.setSceneBlendType(LLRender::BT_ALPHA);
LLVertexBuffer::unbind();
if (!light_enabled)

View File

@@ -56,11 +56,6 @@ public:
LLDrawPoolAlpha(U32 type = LLDrawPool::POOL_ALPHA);
/*virtual*/ ~LLDrawPoolAlpha();
/*virtual*/ S32 getNumDeferredPasses();
/*virtual*/ void beginDeferredPass(S32 pass);
/*virtual*/ void endDeferredPass(S32 pass);
/*virtual*/ void renderDeferred(S32 pass);
/*virtual*/ S32 getNumPostDeferredPasses();
/*virtual*/ void beginPostDeferredPass(S32 pass);
/*virtual*/ void endPostDeferredPass(S32 pass);
@@ -74,9 +69,9 @@ public:
/*virtual*/ void prerender();
void renderGroupAlpha(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE);
void renderAlpha(U32 mask);
void renderAlpha(U32 mask, S32 pass);
void renderAlphaHighlight(U32 mask);
static BOOL sShowDebugAlpha;
private:

View File

@@ -55,6 +55,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;
@@ -65,9 +66,11 @@ LLGLSLShader* LLDrawPoolAvatar::sVertexProgram = NULL;
BOOL LLDrawPoolAvatar::sSkipOpaque = FALSE;
BOOL LLDrawPoolAvatar::sSkipTransparent = FALSE;
S32 LLDrawPoolAvatar::sDiffuseChannel = 0;
F32 LLDrawPoolAvatar::sMinimumAlpha = 0.2f;
static bool is_deferred_render = false;
static bool is_post_deferred_render = false;
extern BOOL gUseGLPick;
@@ -197,6 +200,9 @@ void LLDrawPoolAvatar::beginDeferredPass(S32 pass)
case 4:
beginDeferredRiggedBump();
break;
default:
beginDeferredRiggedMaterial(pass-5);
break;
}
}
@@ -229,6 +235,9 @@ void LLDrawPoolAvatar::endDeferredPass(S32 pass)
case 4:
endDeferredRiggedBump();
break;
default:
endDeferredRiggedMaterial(pass-5);
break;
}
}
@@ -239,7 +248,7 @@ void LLDrawPoolAvatar::renderDeferred(S32 pass)
S32 LLDrawPoolAvatar::getNumPostDeferredPasses()
{
return 6;
return 10;
}
void LLDrawPoolAvatar::beginPostDeferredPass(S32 pass)
@@ -261,9 +270,12 @@ void LLDrawPoolAvatar::beginPostDeferredPass(S32 pass)
case 4:
beginRiggedFullbrightAlpha();
break;
case 5:
case 9:
beginRiggedGlow();
break;
default:
beginDeferredRiggedMaterialAlpha(pass-5);
break;
}
}
@@ -276,7 +288,7 @@ void LLDrawPoolAvatar::beginPostDeferredAlpha()
gPipeline.bindDeferredShader(*sVertexProgram);
sVertexProgram->setMinimumAlpha(0.2f);
sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha);
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
}
@@ -289,11 +301,34 @@ void LLDrawPoolAvatar::beginDeferredRiggedAlpha()
gPipeline.enableLightsDynamic();
}
void LLDrawPoolAvatar::beginDeferredRiggedMaterialAlpha(S32 pass)
{
switch (pass)
{
case 0: pass = 1; break;
case 1: pass = 5; break;
case 2: pass = 9; break;
default: pass = 13; break;
}
pass += LLMaterial::SHADER_COUNT;
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);
specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP);
gPipeline.enableLightsDynamic();
}
void LLDrawPoolAvatar::endDeferredRiggedAlpha()
{
LLVertexBuffer::unbind();
gPipeline.unbindDeferredShader(*sVertexProgram);
sDiffuseChannel = 0;
normal_channel = -1;
specular_channel = -1;
sVertexProgram = NULL;
}
@@ -319,6 +354,9 @@ void LLDrawPoolAvatar::endPostDeferredPass(S32 pass)
case 5:
endRiggedGlow();
break;
default:
endDeferredRiggedAlpha();
break;
}
}
@@ -343,16 +381,22 @@ void LLDrawPoolAvatar::renderPostDeferred(S32 pass)
7, //rigged alpha
8, //rigged fullbright alpha
9, //rigged glow
10,//rigged material alpha 2
11,//rigged material alpha 3
12,//rigged material alpha 4
13, //rigged glow
};
pass = actual_pass[pass];
S32 p = actual_pass[pass];
if (LLPipeline::sImpostorRender)
{ //HACK for impostors so actual pass ends up being proper pass
pass -= 2;
p -= 2;
}
render(pass);
is_post_deferred_render = true;
render(p);
is_post_deferred_render = false;
}
@@ -439,12 +483,10 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)
}
else
{
renderRigged(avatarp, RIGGED_SIMPLE);
renderRigged(avatarp, RIGGED_ALPHA);
renderRigged(avatarp, RIGGED_FULLBRIGHT);
renderRigged(avatarp, RIGGED_FULLBRIGHT_SHINY);
renderRigged(avatarp, RIGGED_SHINY);
renderRigged(avatarp, RIGGED_FULLBRIGHT_ALPHA);
for (U32 i = 0; i < NUM_RIGGED_PASSES; ++i)
{
renderRigged(avatarp, i);
}
}
}
@@ -465,11 +507,11 @@ S32 LLDrawPoolAvatar::getNumDeferredPasses()
{
if (LLPipeline::sImpostorRender)
{
return 3;
return 19;
}
else
{
return 5;
return 21;
}
}
@@ -624,7 +666,7 @@ void LLDrawPoolAvatar::beginRigid()
if (sVertexProgram != NULL)
{ //eyeballs render with the specular shader
sVertexProgram->bind();
sVertexProgram->setMinimumAlpha(0.2f);
sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha);
}
}
else
@@ -666,8 +708,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()
@@ -675,7 +718,7 @@ void LLDrawPoolAvatar::beginDeferredRigid()
sVertexProgram = &gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram;
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
sVertexProgram->bind();
sVertexProgram->setMinimumAlpha(0.2f);
sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha);
}
void LLDrawPoolAvatar::endDeferredRigid()
@@ -733,7 +776,7 @@ void LLDrawPoolAvatar::beginSkinned()
if (LLGLSLShader::sNoFixedFunction)
{
sVertexProgram->setMinimumAlpha(0.2f);
sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha);
}
}
@@ -853,6 +896,9 @@ void LLDrawPoolAvatar::beginRiggedGlow()
{
sDiffuseChannel = 0;
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));
}
}
@@ -871,7 +917,14 @@ void LLDrawPoolAvatar::beginRiggedFullbright()
}
else
{
if (LLPipeline::sRenderDeferred)
{
sVertexProgram = &gDeferredSkinnedFullbrightProgram;
}
else
{
sVertexProgram = &gSkinnedObjectFullbrightProgram;
}
}
}
else
@@ -890,6 +943,16 @@ void LLDrawPoolAvatar::beginRiggedFullbright()
{
sDiffuseChannel = 0;
sVertexProgram->bind();
if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred)
{
sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
}
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));
}
}
}
@@ -956,7 +1019,14 @@ void LLDrawPoolAvatar::beginRiggedFullbrightShiny()
}
else
{
if (LLPipeline::sRenderDeferred)
{
sVertexProgram = &gDeferredSkinnedFullbrightShinyProgram;
}
else
{
sVertexProgram = &gSkinnedObjectFullbrightShinyProgram;
}
}
}
else
@@ -976,6 +1046,16 @@ void LLDrawPoolAvatar::beginRiggedFullbrightShiny()
{
sVertexProgram->bind();
LLDrawPoolBump::bindCubeMap(sVertexProgram, 2, sDiffuseChannel, cube_channel, false);
if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred)
{
sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
}
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));
}
}
}
@@ -1024,6 +1104,43 @@ void LLDrawPoolAvatar::endDeferredRiggedBump()
sVertexProgram = NULL;
}
void LLDrawPoolAvatar::beginDeferredRiggedMaterial(S32 pass)
{
if (pass == 1 ||
pass == 5 ||
pass == 9 ||
pass == 13)
{ //skip alpha passes
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);
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
}
void LLDrawPoolAvatar::endDeferredRiggedMaterial(S32 pass)
{
if (pass == 1 ||
pass == 5 ||
pass == 9 ||
pass == 13)
{
return;
}
LLVertexBuffer::unbind();
sVertexProgram->disableTexture(LLViewerShaderMgr::BUMP_MAP);
sVertexProgram->disableTexture(LLViewerShaderMgr::SPECULAR_MAP);
sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
sVertexProgram->unbind();
normal_channel = -1;
sDiffuseChannel = 0;
sVertexProgram = NULL;
}
void LLDrawPoolAvatar::beginDeferredSkinned()
{
sShaderLevel = mVertexShaderLevel;
@@ -1031,7 +1148,7 @@ void LLDrawPoolAvatar::beginDeferredSkinned()
sRenderingSkinned = TRUE;
sVertexProgram->bind();
sVertexProgram->setMinimumAlpha(0.2f);
sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha);
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
gGL.getTexUnit(0)->activate();
@@ -1184,6 +1301,21 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
else
{
renderRiggedSimple(avatarp);
if (LLPipeline::sRenderDeferred)
{ //render "simple" materials
renderRigged(avatarp, RIGGED_MATERIAL);
renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_MASK);
renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_EMISSIVE);
renderRigged(avatarp, RIGGED_NORMMAP);
renderRigged(avatarp, RIGGED_NORMMAP_MASK);
renderRigged(avatarp, RIGGED_NORMMAP_EMISSIVE);
renderRigged(avatarp, RIGGED_SPECMAP);
renderRigged(avatarp, RIGGED_SPECMAP_MASK);
renderRigged(avatarp, RIGGED_SPECMAP_EMISSIVE);
renderRigged(avatarp, RIGGED_NORMSPEC);
renderRigged(avatarp, RIGGED_NORMSPEC_MASK);
renderRigged(avatarp, RIGGED_NORMSPEC_EMISSIVE);
}
}
return;
}
@@ -1202,6 +1334,18 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
return;
}
if (is_deferred_render && pass >= 5 && pass <= 21)
{
S32 p = pass-5;
if (p != 1 &&
p != 5 &&
p != 9 &&
p != 13)
{
renderDeferredRiggedMaterial(avatarp, p);
}
return;
}
if (pass == 5)
{
renderRiggedShinySimple(avatarp);
@@ -1214,11 +1358,26 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
return;
}
if (pass >= 7 && pass < 9)
if (pass >= 7 && pass < 13)
{
if (pass == 7)
{
renderRiggedAlpha(avatarp);
if (LLPipeline::sRenderDeferred && !is_post_deferred_render)
{ //render transparent materials under water
LLGLEnable blend(GL_BLEND);
gGL.setColorMask(true, true);
gGL.blendFunc(LLRender::BF_SOURCE_ALPHA,
LLRender::BF_ONE_MINUS_SOURCE_ALPHA,
LLRender::BF_ZERO,
LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
renderRigged(avatarp, RIGGED_MATERIAL_ALPHA);
renderRigged(avatarp, RIGGED_SPECMAP_BLEND);
renderRigged(avatarp, RIGGED_NORMMAP_BLEND);
renderRigged(avatarp, RIGGED_NORMSPEC_BLEND);
gGL.setSceneBlendType(LLRender::BT_ALPHA);
gGL.setColorMask(true, false);
}
return;
}
@@ -1227,9 +1386,30 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
renderRiggedFullbrightAlpha(avatarp);
return;
}
if (LLPipeline::sRenderDeferred && is_post_deferred_render)
{
S32 p = 0;
switch (pass)
{
case 9: p = 1; break;
case 10: p = 5; break;
case 11: p = 9; break;
case 12: p = 13; break;
}
{
LLGLEnable blend(GL_BLEND);
renderDeferredRiggedMaterial(avatarp, p);
}
return;
}
else if (pass == 9)
{
renderRiggedGlow(avatarp);
return;
}
}
if (pass == 9)
if (pass == 13)
{
renderRiggedGlow(avatarp);
@@ -1267,27 +1447,10 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
}
}
void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* face, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face)
void LLDrawPoolAvatar::getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>& buffer, U32 data_mask, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face)
{
LLVector4a* weight = vol_face.mWeights;
if (!weight)
{
return;
}
LLPointer<LLVertexBuffer> buffer = face->getVertexBuffer();
LLDrawable* drawable = face->getDrawable();
U32 data_mask = face->getRiggedVertexBufferDataMask();
if (buffer.isNull() ||
buffer->getTypeMask() != data_mask ||
buffer->getNumVerts() != vol_face.mNumVertices ||
buffer->getNumIndices() != vol_face.mNumIndices ||
(drawable && drawable->isState(LLDrawable::REBUILD_ALL)))
{
face->setGeomIndex(0);
face->setIndicesIndex(0);
face->setGeomIndex(0);
face->setIndicesIndex(0);
//rigged faces do not batch textures
face->setTextureIndex(255);
@@ -1334,12 +1497,55 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
}
else
{
face->setPoolType(LLDrawPool::POOL_AVATAR);
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);
buffer->flush();
}
void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* face, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face)
{
LLVector4a* weight = vol_face.mWeights;
if (!weight)
{
return;
}
LLPointer<LLVertexBuffer> buffer = face->getVertexBuffer();
LLDrawable* drawable = face->getDrawable();
U32 data_mask = face->getRiggedVertexBufferDataMask();
if (buffer.isNull() ||
buffer->getTypeMask() != data_mask ||
buffer->getNumVerts() != vol_face.mNumVertices ||
buffer->getNumIndices() != vol_face.mNumIndices ||
(drawable && drawable->isState(LLDrawable::REBUILD_ALL)))
{
if (drawable && drawable->isState(LLDrawable::REBUILD_ALL))
{ //rebuild EVERY face in the drawable, not just this one, to avoid missing drawable wide rebuild issues
for (S32 i = 0; i < drawable->getNumFaces(); ++i)
{
LLFace* facep = drawable->getFace(i);
U32 face_data_mask = facep->getRiggedVertexBufferDataMask();
if (face_data_mask)
{
LLPointer<LLVertexBuffer> cur_buffer = facep->getVertexBuffer();
const LLVolumeFace& cur_vol_face = volume->getVolumeFace(i);
getRiggedGeometry(facep, cur_buffer, face_data_mask, skin, volume, cur_vol_face);
}
}
drawable->clearState(LLDrawable::REBUILD_ALL);
buffer = face->getVertexBuffer();
}
else
{ //just rebuild this face
getRiggedGeometry(face, buffer, data_mask, skin, volume, vol_face);
}
face->getGeometryVolume(*volume, face->getTEOffset(), mat_vert, mat_normal, offset, true);
buffer->flush();
}
if (sShaderLevel <= 0 && face->mLastSkinTime < avatar->getLastSkinTime())
@@ -1426,11 +1632,6 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
}
}
}
if (drawable && (face->getTEOffset() == drawable->getNumFaces()-1))
{
drawable->clearState(LLDrawable::REBUILD_ALL);
}
}
void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
@@ -1531,13 +1732,62 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
gGL.diffuseColor4f(0,0,0,face->getTextureEntry()->getGlow());
}*/
gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture());
if (normal_channel > -1)
const LLTextureEntry* te = face->getTextureEntry();
LLMaterial* mat = te->getMaterialParams().get();
if (mat)
{
LLDrawPoolBump::bindBumpMap(face, normal_channel);
gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture(LLRender::DIFFUSE_MAP));
gGL.getTexUnit(normal_channel)->bind(face->getTexture(LLRender::NORMAL_MAP));
gGL.getTexUnit(specular_channel)->bind(face->getTexture(LLRender::SPECULAR_MAP));
LLColor4 col = mat->getSpecularLightColor();
F32 spec = mat->getSpecularLightExponent()/255.f;
F32 env = mat->getEnvironmentIntensity()/255.f;
if (mat->getSpecularID().isNull())
{
env = te->getShiny()*0.25f;
col.set(env,env,env,0);
spec = env;
}
BOOL fullbright = te->getFullbright();
sVertexProgram->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, fullbright ? 1.f : 0.f);
sVertexProgram->uniform4f(LLShaderMgr::SPECULAR_COLOR, col.mV[0], col.mV[1], col.mV[2], spec);
sVertexProgram->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, env);
if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
{
sVertexProgram->setMinimumAlpha(mat->getAlphaMaskCutoff()/255.f);
}
else
{
sVertexProgram->setMinimumAlpha(0.f);
}
for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
{
LLViewerTexture* tex = face->getTexture(i);
if (tex)
{
tex->addTextureStats(avatar->getPixelArea());
}
}
}
else
{
gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture());
sVertexProgram->setMinimumAlpha(0.f);
if (normal_channel > -1)
{
LLDrawPoolBump::bindBumpMap(face, normal_channel);
}
}
if (face->mTextureMatrix)
if (face->mTextureMatrix && vobj->mTexAnimMode)
{
gGL.matrixMode(LLRender::MM_TEXTURE);
gGL.loadMatrix((F32*) face->mTextureMatrix->mMatrix);
@@ -1551,6 +1801,8 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
buff->setBuffer(data_mask);
buff->drawRange(LLRender::TRIANGLES, start, end, count, offset);
}
gPipeline.addTrianglesDrawn(count, LLRender::TRIANGLES);
}
}
}
@@ -1565,6 +1817,11 @@ void LLDrawPoolAvatar::renderDeferredRiggedBump(LLVOAvatar* avatar)
renderRigged(avatar, RIGGED_DEFERRED_BUMP);
}
void LLDrawPoolAvatar::renderDeferredRiggedMaterial(LLVOAvatar* avatar, S32 pass)
{
renderRigged(avatar, pass);
}
static LLFastTimer::DeclareTimer FTM_RIGGED_VBO("Rigged VBO");
void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar)

View File

@@ -119,6 +119,8 @@ public:
void beginRiggedFullbrightAlpha();
void beginRiggedGlow();
void beginDeferredRiggedAlpha();
void beginDeferredRiggedMaterial(S32 pass);
void beginDeferredRiggedMaterialAlpha(S32 pass);
void endRiggedSimple();
void endRiggedFullbright();
@@ -128,6 +130,8 @@ public:
void endRiggedFullbrightAlpha();
void endRiggedGlow();
void endDeferredRiggedAlpha();
void endDeferredRiggedMaterial(S32 pass);
void endDeferredRiggedMaterialAlpha(S32 pass);
void beginDeferredRiggedSimple();
void beginDeferredRiggedBump();
@@ -135,6 +139,7 @@ public:
void endDeferredRiggedSimple();
void endDeferredRiggedBump();
void getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>& buffer, U32 data_mask, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face);
void updateRiggedFaceVertexBuffer(LLVOAvatar* avatar,
LLFace* facep,
const LLMeshSkinInfo* skin,
@@ -152,10 +157,27 @@ public:
void renderRiggedGlow(LLVOAvatar* avatar);
void renderDeferredRiggedSimple(LLVOAvatar* avatar);
void renderDeferredRiggedBump(LLVOAvatar* avatar);
void renderDeferredRiggedMaterial(LLVOAvatar* avatar, S32 pass);
typedef enum
{
RIGGED_SIMPLE = 0,
RIGGED_MATERIAL=0,
RIGGED_MATERIAL_ALPHA,
RIGGED_MATERIAL_ALPHA_MASK,
RIGGED_MATERIAL_ALPHA_EMISSIVE,
RIGGED_SPECMAP,
RIGGED_SPECMAP_BLEND,
RIGGED_SPECMAP_MASK,
RIGGED_SPECMAP_EMISSIVE,
RIGGED_NORMMAP,
RIGGED_NORMMAP_BLEND,
RIGGED_NORMMAP_MASK,
RIGGED_NORMMAP_EMISSIVE,
RIGGED_NORMSPEC,
RIGGED_NORMSPEC_BLEND,
RIGGED_NORMSPEC_MASK,
RIGGED_NORMSPEC_EMISSIVE,
RIGGED_SIMPLE,
RIGGED_FULLBRIGHT,
RIGGED_SHINY,
RIGGED_FULLBRIGHT_SHINY,
@@ -170,6 +192,48 @@ public:
typedef enum
{
RIGGED_MATERIAL_MASK =
LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_NORMAL |
LLVertexBuffer::MAP_TEXCOORD0 |
LLVertexBuffer::MAP_COLOR |
LLVertexBuffer::MAP_WEIGHT4,
RIGGED_MATERIAL_ALPHA_VMASK = RIGGED_MATERIAL_MASK,
RIGGED_MATERIAL_ALPHA_MASK_MASK = RIGGED_MATERIAL_MASK,
RIGGED_MATERIAL_ALPHA_EMISSIVE_MASK = RIGGED_MATERIAL_MASK,
RIGGED_SPECMAP_VMASK =
LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_NORMAL |
LLVertexBuffer::MAP_TEXCOORD0 |
LLVertexBuffer::MAP_TEXCOORD2 |
LLVertexBuffer::MAP_COLOR |
LLVertexBuffer::MAP_WEIGHT4,
RIGGED_SPECMAP_BLEND_MASK = RIGGED_SPECMAP_VMASK,
RIGGED_SPECMAP_MASK_MASK = RIGGED_SPECMAP_VMASK,
RIGGED_SPECMAP_EMISSIVE_MASK = RIGGED_SPECMAP_VMASK,
RIGGED_NORMMAP_VMASK =
LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_NORMAL |
LLVertexBuffer::MAP_TANGENT |
LLVertexBuffer::MAP_TEXCOORD0 |
LLVertexBuffer::MAP_TEXCOORD1 |
LLVertexBuffer::MAP_COLOR |
LLVertexBuffer::MAP_WEIGHT4,
RIGGED_NORMMAP_BLEND_MASK = RIGGED_NORMMAP_VMASK,
RIGGED_NORMMAP_MASK_MASK = RIGGED_NORMMAP_VMASK,
RIGGED_NORMMAP_EMISSIVE_MASK = RIGGED_NORMMAP_VMASK,
RIGGED_NORMSPEC_VMASK =
LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_NORMAL |
LLVertexBuffer::MAP_TANGENT |
LLVertexBuffer::MAP_TEXCOORD0 |
LLVertexBuffer::MAP_TEXCOORD1 |
LLVertexBuffer::MAP_TEXCOORD2 |
LLVertexBuffer::MAP_COLOR |
LLVertexBuffer::MAP_WEIGHT4,
RIGGED_NORMSPEC_BLEND_MASK = RIGGED_NORMSPEC_VMASK,
RIGGED_NORMSPEC_MASK_MASK = RIGGED_NORMSPEC_VMASK,
RIGGED_NORMSPEC_EMISSIVE_MASK = RIGGED_NORMSPEC_VMASK,
RIGGED_SIMPLE_MASK = LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_NORMAL |
LLVertexBuffer::MAP_TEXCOORD0 |
@@ -214,6 +278,7 @@ public:
static BOOL sSkipOpaque;
static BOOL sSkipTransparent;
static S32 sDiffuseChannel;
static F32 sMinimumAlpha;
static LLGLSLShader* sVertexProgram;
};

View File

@@ -456,9 +456,6 @@ void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32&
LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
if( cube_map )
{
cube_map->disable();
cube_map->restoreMatrix();
if (!invisible && shader_level > 1)
{
shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
@@ -471,6 +468,10 @@ void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32&
}
}
}
// Moved below shader->disableTexture call to avoid false alarms from auto-re-enable of textures on stage 0
// MAINT-755
cube_map->disable();
cube_map->restoreMatrix();
}
if (!LLGLSLShader::sNoFixedFunction)
@@ -521,7 +522,14 @@ void LLDrawPoolBump::beginFullbrightShiny()
}
else
{
shader = &gObjectFullbrightShinyProgram;
if (LLPipeline::sRenderDeferred)
{
shader = &gDeferredFullbrightShinyProgram;
}
else
{
shader = &gObjectFullbrightShinyProgram;
}
}
LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
@@ -1381,7 +1389,7 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
gNormalMapGenProgram.uniform1f(sNormScale, gSavedSettings.getF32("RenderNormalMapScale"));
gNormalMapGenProgram.uniform1f(sStepX, 1.f/bump->getWidth());
gNormalMapGenProgram.uniform1f(sStepX, 1.f/bump->getHeight());
gNormalMapGenProgram.uniform1f(sStepY, 1.f/bump->getHeight());
LLVector2 v((F32) bump->getWidth()/gPipeline.mScreen.getWidth(),
(F32) bump->getHeight()/gPipeline.mScreen.getHeight());

View File

@@ -0,0 +1,224 @@
/**
* @file lldrawpool.cpp
* @brief LLDrawPoolMaterials class implementation
* @author Jonathan "Geenz" Goodman
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2013, 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$
*/
#include "llviewerprecompiledheaders.h"
#include "lldrawpoolmaterials.h"
#include "llviewershadermgr.h"
#include "pipeline.h"
S32 diffuse_channel = -1;
LLDrawPoolMaterials::LLDrawPoolMaterials()
: LLRenderPass(LLDrawPool::POOL_MATERIALS)
{
}
void LLDrawPoolMaterials::prerender()
{
mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
}
S32 LLDrawPoolMaterials::getNumDeferredPasses()
{
return 12;
}
void LLDrawPoolMaterials::beginDeferredPass(S32 pass)
{
U32 shader_idx[] =
{
0, //LLRenderPass::PASS_MATERIAL,
//1, //LLRenderPass::PASS_MATERIAL_ALPHA,
2, //LLRenderPass::PASS_MATERIAL_ALPHA_MASK,
3, //LLRenderPass::PASS_MATERIAL_ALPHA_GLOW,
4, //LLRenderPass::PASS_SPECMAP,
//5, //LLRenderPass::PASS_SPECMAP_BLEND,
6, //LLRenderPass::PASS_SPECMAP_MASK,
7, //LLRenderPass::PASS_SPECMAP_GLOW,
8, //LLRenderPass::PASS_NORMMAP,
//9, //LLRenderPass::PASS_NORMMAP_BLEND,
10, //LLRenderPass::PASS_NORMMAP_MASK,
11, //LLRenderPass::PASS_NORMMAP_GLOW,
12, //LLRenderPass::PASS_NORMSPEC,
//13, //LLRenderPass::PASS_NORMSPEC_BLEND,
14, //LLRenderPass::PASS_NORMSPEC_MASK,
15, //LLRenderPass::PASS_NORMSPEC_GLOW,
};
mShader = &(gDeferredMaterialProgram[shader_idx[pass]]);
if (LLPipeline::sUnderWaterRender)
{
mShader = &(gDeferredMaterialWaterProgram[shader_idx[pass]]);
}
mShader->bind();
diffuse_channel = mShader->enableTexture(LLShaderMgr::DIFFUSE_MAP);
LLFastTimer t(FTM_RENDER_MATERIALS);
}
void LLDrawPoolMaterials::endDeferredPass(S32 pass)
{
LLFastTimer t(FTM_RENDER_MATERIALS);
mShader->unbind();
LLRenderPass::endRenderPass(pass);
}
void LLDrawPoolMaterials::renderDeferred(S32 pass)
{
U32 type_list[] =
{
LLRenderPass::PASS_MATERIAL,
//LLRenderPass::PASS_MATERIAL_ALPHA,
LLRenderPass::PASS_MATERIAL_ALPHA_MASK,
LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE,
LLRenderPass::PASS_SPECMAP,
//LLRenderPass::PASS_SPECMAP_BLEND,
LLRenderPass::PASS_SPECMAP_MASK,
LLRenderPass::PASS_SPECMAP_EMISSIVE,
LLRenderPass::PASS_NORMMAP,
//LLRenderPass::PASS_NORMMAP_BLEND,
LLRenderPass::PASS_NORMMAP_MASK,
LLRenderPass::PASS_NORMMAP_EMISSIVE,
LLRenderPass::PASS_NORMSPEC,
//LLRenderPass::PASS_NORMSPEC_BLEND,
LLRenderPass::PASS_NORMSPEC_MASK,
LLRenderPass::PASS_NORMSPEC_EMISSIVE,
};
llassert(pass < sizeof(type_list)/sizeof(U32));
U32 type = type_list[pass];
U32 mask = mShader->mAttributeMask;
LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
{
LLDrawInfo& params = **i;
mShader->uniform4f(LLShaderMgr::SPECULAR_COLOR, params.mSpecColor.mV[0], params.mSpecColor.mV[1], params.mSpecColor.mV[2], params.mSpecColor.mV[3]);
mShader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, params.mEnvIntensity);
if (params.mNormalMap)
{
params.mNormalMap->addTextureStats(params.mVSize);
bindNormalMap(params.mNormalMap);
}
if (params.mSpecularMap)
{
params.mSpecularMap->addTextureStats(params.mVSize);
bindSpecularMap(params.mSpecularMap);
}
mShader->setMinimumAlpha(params.mAlphaMaskCutoff);
mShader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, params.mFullbright ? 1.f : 0.f);
pushBatch(params, mask, TRUE);
}
}
void LLDrawPoolMaterials::bindSpecularMap(LLViewerTexture* tex)
{
mShader->bindTexture(LLShaderMgr::SPECULAR_MAP, tex);
}
void LLDrawPoolMaterials::bindNormalMap(LLViewerTexture* tex)
{
mShader->bindTexture(LLShaderMgr::BUMP_MAP, tex);
}
void LLDrawPoolMaterials::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures)
{
applyModelMatrix(params);
bool tex_setup = false;
if (batch_textures && params.mTextureList.size() > 1)
{
for (U32 i = 0; i < params.mTextureList.size(); ++i)
{
if (params.mTextureList[i].notNull())
{
gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE);
}
}
}
else
{ //not batching textures or batch has only 1 texture -- might need a texture matrix
if (params.mTextureMatrix)
{
//if (mShiny)
{
gGL.getTexUnit(0)->activate();
gGL.matrixMode(LLRender::MM_TEXTURE);
}
gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix);
gPipeline.mTextureMatrixOps++;
tex_setup = true;
}
if (mVertexShaderLevel > 1 && texture)
{
if (params.mTexture.notNull())
{
gGL.getTexUnit(diffuse_channel)->bind(params.mTexture);
params.mTexture->addTextureStats(params.mVSize);
}
else
{
gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE);
}
}
}
if (params.mGroup)
{
params.mGroup->rebuildMesh();
}
params.mVertexBuffer->setBuffer(mask);
params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
if (tex_setup)
{
gGL.getTexUnit(0)->activate();
gGL.loadIdentity();
gGL.matrixMode(LLRender::MM_MODELVIEW);
}
}

View File

@@ -0,0 +1,75 @@
/**
* @file lldrawpoolmaterials.h
* @brief LLDrawPoolMaterials class definition
* @author Jonathan "Geenz" Goodman
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2013, 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$
*/
#ifndef LL_LLDRAWPOOLMATERIALS_H
#define LL_LLDRAWPOOLMATERIALS_H
#include "v4coloru.h"
#include "v2math.h"
#include "v3math.h"
#include "llvertexbuffer.h"
#include "lldrawpool.h"
class LLViewerTexture;
class LLDrawInfo;
class LLGLSLShader;
class LLDrawPoolMaterials : public LLRenderPass
{
LLGLSLShader *mShader;
public:
LLDrawPoolMaterials();
enum
{
VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_NORMAL |
LLVertexBuffer::MAP_TEXCOORD0 |
LLVertexBuffer::MAP_TEXCOORD1 |
LLVertexBuffer::MAP_TEXCOORD2 |
LLVertexBuffer::MAP_COLOR |
LLVertexBuffer::MAP_TANGENT
};
/*virtual*/ U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
/*virtual*/ void render(S32 pass = 0) { }
/*virtual*/ S32 getNumPasses() {return 0;}
/*virtual*/ void prerender();
/*virtual*/ S32 getNumDeferredPasses();
/*virtual*/ void beginDeferredPass(S32 pass);
/*virtual*/ void endDeferredPass(S32 pass);
/*virtual*/ void renderDeferred(S32 pass);
void bindSpecularMap(LLViewerTexture* tex);
void bindNormalMap(LLViewerTexture* tex);
/*virtual*/ void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE);
};
#endif //LL_LLDRAWPOOLMATERIALS_H

View File

@@ -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;
@@ -47,6 +48,7 @@ static LLFastTimer::DeclareTimer FTM_RENDER_GRASS_DEFERRED("Deferred Grass");
void LLDrawPoolGlow::beginPostDeferredPass(S32 pass)
{
gDeferredEmissiveProgram.bind();
gDeferredEmissiveProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
}
static LLFastTimer::DeclareTimer FTM_RENDER_GLOW_PUSH("Glow Push");
@@ -110,6 +112,14 @@ void LLDrawPoolGlow::render(S32 pass)
LLGLSLShader* shader = LLPipeline::sUnderWaterRender ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;
shader->bind();
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);
@@ -146,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;
}
@@ -198,7 +212,11 @@ void LLDrawPoolSimple::render(S32 pass)
if (LLPipeline::sRenderDeferred)
{ //if deferred rendering is enabled, bump faces aren't registered as simple
//render bump faces here as simple so bump faces will appear under water
pushBatches(LLRenderPass::PASS_BUMP, mask, TRUE, TRUE);
pushBatches(LLRenderPass::PASS_BUMP, mask, TRUE, TRUE);
pushBatches(LLRenderPass::PASS_MATERIAL, mask, TRUE, TRUE);
pushBatches(LLRenderPass::PASS_SPECMAP, mask, TRUE, TRUE);
pushBatches(LLRenderPass::PASS_NORMMAP, mask, TRUE, TRUE);
pushBatches(LLRenderPass::PASS_NORMSPEC, mask, TRUE, TRUE);
}
}
else
@@ -210,6 +228,169 @@ void LLDrawPoolSimple::render(S32 pass)
}
}
static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_MASK("Alpha Mask");
LLDrawPoolAlphaMask::LLDrawPoolAlphaMask() :
LLRenderPass(POOL_ALPHA_MASK)
{
}
void LLDrawPoolAlphaMask::prerender()
{
mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
}
void LLDrawPoolAlphaMask::beginRenderPass(S32 pass)
{
LLFastTimer t(FTM_RENDER_ALPHA_MASK);
if (LLPipeline::sUnderWaterRender)
{
simple_shader = &gObjectSimpleWaterAlphaMaskProgram;
}
else
{
simple_shader = &gObjectSimpleAlphaMaskProgram;
}
if (mVertexShaderLevel > 0)
{
simple_shader->bind();
}
else
{
// don't use shaders!
if (gGLManager.mHasShaderObjects)
{
LLGLSLShader::bindNoShader();
}
}
}
void LLDrawPoolAlphaMask::endRenderPass(S32 pass)
{
LLFastTimer t(FTM_RENDER_ALPHA_MASK);
stop_glerror();
LLRenderPass::endRenderPass(pass);
stop_glerror();
if (mVertexShaderLevel > 0)
{
simple_shader->unbind();
}
}
void LLDrawPoolAlphaMask::render(S32 pass)
{
LLGLDisable blend(GL_BLEND);
LLFastTimer t(FTM_RENDER_ALPHA_MASK);
if (mVertexShaderLevel > 0)
{
simple_shader->bind();
simple_shader->setMinimumAlpha(0.33f);
pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
pushMaskBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
pushMaskBatches(LLRenderPass::PASS_SPECMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
pushMaskBatches(LLRenderPass::PASS_NORMMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
pushMaskBatches(LLRenderPass::PASS_NORMSPEC_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
}
else
{
LLGLEnable test(GL_ALPHA_TEST);
pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask(), TRUE, FALSE);
gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK
}
}
LLDrawPoolFullbrightAlphaMask::LLDrawPoolFullbrightAlphaMask() :
LLRenderPass(POOL_FULLBRIGHT_ALPHA_MASK)
{
}
void LLDrawPoolFullbrightAlphaMask::prerender()
{
mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
}
void LLDrawPoolFullbrightAlphaMask::beginRenderPass(S32 pass)
{
LLFastTimer t(FTM_RENDER_ALPHA_MASK);
if (LLPipeline::sUnderWaterRender)
{
simple_shader = &gObjectFullbrightWaterAlphaMaskProgram;
}
else
{
simple_shader = &gObjectFullbrightAlphaMaskProgram;
}
if (mVertexShaderLevel > 0)
{
simple_shader->bind();
}
else
{
// don't use shaders!
if (gGLManager.mHasShaderObjects)
{
LLGLSLShader::bindNoShader();
}
}
}
void LLDrawPoolFullbrightAlphaMask::endRenderPass(S32 pass)
{
LLFastTimer t(FTM_RENDER_ALPHA_MASK);
stop_glerror();
LLRenderPass::endRenderPass(pass);
stop_glerror();
if (mVertexShaderLevel > 0)
{
simple_shader->unbind();
}
}
void LLDrawPoolFullbrightAlphaMask::render(S32 pass)
{
LLFastTimer t(FTM_RENDER_ALPHA_MASK);
if (mVertexShaderLevel > 0)
{
if (simple_shader)
{
simple_shader->bind();
simple_shader->setMinimumAlpha(0.33f);
if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred)
{
simple_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
} else {
simple_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
}
}
pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
//LLGLSLShader::bindNoShader();
}
else
{
LLGLEnable test(GL_ALPHA_TEST);
gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask(), TRUE, FALSE);
gPipeline.enableLightsDynamic();
gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK
}
}
//===============================
//DEFERRED IMPLEMENTATION
//===============================
@@ -239,6 +420,28 @@ void LLDrawPoolSimple::renderDeferred(S32 pass)
}
}
static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_MASK_DEFERRED("Deferred Alpha Mask");
void LLDrawPoolAlphaMask::beginDeferredPass(S32 pass)
{
}
void LLDrawPoolAlphaMask::endDeferredPass(S32 pass)
{
}
void LLDrawPoolAlphaMask::renderDeferred(S32 pass)
{
LLFastTimer t(FTM_RENDER_ALPHA_MASK_DEFERRED);
gDeferredDiffuseAlphaMaskProgram.bind();
gDeferredDiffuseAlphaMaskProgram.setMinimumAlpha(0.33f);
pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
gDeferredDiffuseAlphaMaskProgram.unbind();
}
// grass drawpool
LLDrawPoolGrass::LLDrawPoolGrass() :
LLRenderPass(POOL_GRASS)
@@ -345,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)
@@ -362,9 +573,15 @@ void LLDrawPoolFullbright::renderPostDeferred(S32 pass)
void LLDrawPoolFullbright::endPostDeferredPass(S32 pass)
{
gDeferredFullbrightProgram.unbind();
if (LLPipeline::sUnderWaterRender)
{
gDeferredFullbrightWaterProgram.unbind();
}
else
{
gDeferredFullbrightProgram.unbind();
}
LLRenderPass::endRenderPass(pass);
}
void LLDrawPoolFullbright::beginRenderPass(S32 pass)
@@ -407,14 +624,24 @@ void LLDrawPoolFullbright::render(S32 pass)
{
fullbright_shader->bind();
fullbright_shader->uniform1f(LLViewerShaderMgr::FULLBRIGHT, 1.f);
fullbright_shader->uniform1f(LLViewerShaderMgr::TEXTURE_GAMMA, 1.f);
U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX;
pushBatches(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask, TRUE, TRUE);
pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, fullbright_mask, TRUE, TRUE);
pushBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE, fullbright_mask, TRUE, TRUE);
pushBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE, fullbright_mask, TRUE, TRUE);
pushBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE, fullbright_mask, TRUE, TRUE);
}
else
{
gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR;
renderTexture(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask);
pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, fullbright_mask);
pushBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE, fullbright_mask);
pushBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE, fullbright_mask);
pushBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE, fullbright_mask);
}
stop_glerror();
@@ -425,3 +652,75 @@ S32 LLDrawPoolFullbright::getNumPasses()
return 1;
}
void LLDrawPoolFullbrightAlphaMask::beginPostDeferredPass(S32 pass)
{
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)
{
LLFastTimer t(FTM_RENDER_FULLBRIGHT);
LLGLDisable blend(GL_BLEND);
U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX;
pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, fullbright_mask, TRUE, TRUE);
}
void LLDrawPoolFullbrightAlphaMask::endPostDeferredPass(S32 pass)
{
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);
}

View File

@@ -90,6 +90,59 @@ public:
/*virtual*/ void prerender();
};
class LLDrawPoolAlphaMask : public LLRenderPass
{
public:
enum
{
VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_NORMAL |
LLVertexBuffer::MAP_TEXCOORD0 |
LLVertexBuffer::MAP_COLOR
};
virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
LLDrawPoolAlphaMask();
/*virtual*/ S32 getNumDeferredPasses() { return 1; }
/*virtual*/ void beginDeferredPass(S32 pass);
/*virtual*/ void endDeferredPass(S32 pass);
/*virtual*/ void renderDeferred(S32 pass);
/*virtual*/ S32 getNumPasses() { return 1; }
/*virtual*/ void beginRenderPass(S32 pass);
/*virtual*/ void endRenderPass(S32 pass);
/*virtual*/ void render(S32 pass = 0);
/*virtual*/ void prerender();
};
class LLDrawPoolFullbrightAlphaMask : public LLRenderPass
{
public:
enum
{
VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_TEXCOORD0 |
LLVertexBuffer::MAP_COLOR
};
virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
LLDrawPoolFullbrightAlphaMask();
/*virtual*/ S32 getNumPostDeferredPasses() { return 1; }
/*virtual*/ void beginPostDeferredPass(S32 pass);
/*virtual*/ void endPostDeferredPass(S32 pass);
/*virtual*/ void renderPostDeferred(S32 pass);
/*virtual*/ S32 getNumPasses() { return 1; }
/*virtual*/ void beginRenderPass(S32 pass);
/*virtual*/ void endRenderPass(S32 pass);
/*virtual*/ void render(S32 pass = 0);
/*virtual*/ void prerender();
};
class LLDrawPoolFullbright : public LLRenderPass
{
public:

View File

@@ -564,14 +564,21 @@ void LLDrawPoolWater::shade()
F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - gAgent.getRegion()->getWaterHeight();
if (eyedepth < 0.f && LLPipeline::sWaterReflections)
{
if (deferred_render)
{
shader = &gDeferredWaterProgram;
shader = &gDeferredUnderWaterProgram;
}
else if (eyedepth < 0.f && LLPipeline::sWaterReflections)
else
{
shader = &gUnderWaterProgram;
}
}
else if (deferred_render)
{
shader = &gDeferredWaterProgram;
}
else
{
shader = &gWaterProgram;
@@ -592,7 +599,7 @@ void LLDrawPoolWater::shade()
sTime = (F32)LLFrameTimer::getElapsedSeconds()*0.5f;
}
S32 reftex = shader->enableTexture(LLViewerShaderMgr::WATER_REFTEX);
S32 reftex = shader->enableTexture(LLShaderMgr::WATER_REFTEX);
if (reftex > -1)
{

View File

@@ -57,6 +57,8 @@
#include "llviewerregion.h"
#include "llviewerwindow.h"
#include "llviewershadermgr.h"
#include "llviewertexture.h"
#include "llvoavatar.h"
#define LL_MAX_INDICES_COUNT 1000000
@@ -140,9 +142,13 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)
//special value to indicate uninitialized position
mIndicesIndex = 0xFFFFFFFF;
for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
{
mIndexInTex[i] = 0;
mTexture[i] = NULL;
}
mIndexInTex = 0;
mTexture = NULL;
mTEOffset = -1;
mTextureIndex = 255;
@@ -169,9 +175,12 @@ void LLFace::destroy()
gPipeline.checkReferences(this);
}
if(mTexture.notNull())
for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
{
mTexture->removeFace(this) ;
if(mTexture[i].notNull())
{
mTexture[i]->removeFace(i, this) ;
}
}
if (isState(LLFace::PARTICLE))
@@ -264,47 +273,76 @@ void LLFace::setPool(LLFacePool* new_pool, LLViewerTexture *texturep)
setTexture(texturep) ;
}
void LLFace::setTexture(LLViewerTexture* tex)
void LLFace::setTexture(U32 ch, LLViewerTexture* tex)
{
if(mTexture == tex)
llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
if(mTexture[ch] == tex)
{
return ;
}
if(mTexture.notNull())
if(mTexture[ch].notNull())
{
mTexture->removeFace(this) ;
}
mTexture[ch]->removeFace(ch, this) ;
}
if(tex)
{
tex->addFace(this) ;
tex->addFace(ch, this) ;
}
mTexture = tex ;
mTexture[ch] = tex ;
}
void LLFace::setTexture(LLViewerTexture* tex)
{
setDiffuseMap(tex);
}
void LLFace::setDiffuseMap(LLViewerTexture* tex)
{
setTexture(LLRender::DIFFUSE_MAP, tex);
}
void LLFace::setNormalMap(LLViewerTexture* tex)
{
setTexture(LLRender::NORMAL_MAP, tex);
}
void LLFace::setSpecularMap(LLViewerTexture* tex)
{
setTexture(LLRender::SPECULAR_MAP, tex);
}
void LLFace::dirtyTexture()
{
LLDrawable* drawablep = getDrawable();
if (mVObjp.notNull() && mVObjp->getVolume() &&
mTexture.notNull() && mTexture->getComponents() == 4)
{ //dirty texture on an alpha object should be treated as an LoD update
LLVOVolume* vobj = drawablep->getVOVolume();
if (vobj)
if (mVObjp.notNull() && mVObjp->getVolume())
{
for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
{
vobj->mLODChanged = TRUE;
if (mTexture[ch].notNull() && mTexture[ch]->getComponents() == 4)
{ //dirty texture on an alpha object should be treated as an LoD update
LLVOVolume* vobj = drawablep->getVOVolume();
if (vobj)
{
vobj->mLODChanged = TRUE;
}
gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME, FALSE);
}
}
gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME, FALSE);
}
}
gPipeline.markTextured(drawablep);
}
void LLFace::switchTexture(LLViewerTexture* new_texture)
void LLFace::switchTexture(U32 ch, LLViewerTexture* new_texture)
{
if(mTexture == new_texture)
llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
if(mTexture[ch] == new_texture)
{
return ;
}
@@ -314,10 +352,17 @@ void LLFace::switchTexture(LLViewerTexture* new_texture)
llerrs << "Can not switch to a null texture." << llendl;
return;
}
new_texture->addTextureStats(mTexture->getMaxVirtualSize()) ;
getViewerObject()->changeTEImage(mTEOffset, new_texture) ;
setTexture(new_texture) ;
llassert(mTexture[ch].notNull());
new_texture->addTextureStats(mTexture[ch]->getMaxVirtualSize()) ;
if (ch == LLRender::DIFFUSE_MAP)
{
getViewerObject()->changeTEImage(mTEOffset, new_texture) ;
}
setTexture(ch, new_texture) ;
dirtyTexture();
}
@@ -737,7 +782,7 @@ bool less_than_max_mag(const LLVector4a& vec)
}
BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
const LLMatrix4& mat_vert_in, const LLMatrix3& mat_normal_in, BOOL global_volume)
const LLMatrix4& mat_vert_in, BOOL global_volume)
{
//get bounding box
if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED))
@@ -746,16 +791,6 @@ 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);
//if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME))
//{ //vertex buffer no longer valid
// mVertexBuffer = NULL;
// mLastVertexBuffer = NULL;
//}
//VECTORIZE THIS
LLVector4a min,max;
if (f >= volume.getNumVolumeFaces())
@@ -772,100 +807,68 @@ 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);
llassert(less_than_max_mag(min));
llassert(less_than_max_mag(max));
//get 8 corners of bounding box
LLVector4Logical mask[6];
if (!global_volume)
for (U32 i = 0; i < 6; ++i)
{
//VECTORIZE THIS
LLVector4a scale;
scale.load3(mDrawablep->getVObj()->getScale().mV);
size.mul(scale);
mask[i].clear();
}
// Catch potential badness from normalization before it happens
//
//llassert(mat_normal.mMatrix[0].isFinite3() && (mat_normal.mMatrix[0].dot3(mat_normal.mMatrix[0]).getF32() > F_APPROXIMATELY_ZERO));
//llassert(mat_normal.mMatrix[1].isFinite3() && (mat_normal.mMatrix[1].dot3(mat_normal.mMatrix[1]).getF32() > F_APPROXIMATELY_ZERO));
//llassert(mat_normal.mMatrix[2].isFinite3() && (mat_normal.mMatrix[2].dot3(mat_normal.mMatrix[2]).getF32() > F_APPROXIMATELY_ZERO));
mat_normal.mMatrix[0].normalize3fast();
mat_normal.mMatrix[1].normalize3fast();
mat_normal.mMatrix[2].normalize3fast();
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>();
LLVector4a v[4];
LLVector4a v[8];
//get 4 corners of bounding box
mat_normal.rotate(size,v[0]);
v[6] = min;
v[7] = max;
//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]);
for (U32 i = 0; i < 6; ++i)
{
v[i].setSelectWithMask(mask[i], min, max);
}
LLVector4a tv[8];
//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++)
newMin = newMax = tv[0];
for (U32 i = 1; i < 8; ++i)
{
LLVector4a delta;
delta.setAbs(v[i]);
LLVector4a min;
min.setSub(center, delta);
LLVector4a max;
max.setAdd(center, delta);
newMin.setMin(newMin,min);
newMax.setMax(newMax,max);
llassert(less_than_max_mag(newMin));
llassert(less_than_max_mag(newMax));
newMin.setMin(newMin, tv[i]);
newMax.setMax(newMax, tv[i]);
}
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));
}
t.setAdd(newMin, newMax);
LLVector4a t;
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;
@@ -1273,30 +1276,34 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (tep &&
getPoolType() != LLDrawPool::POOL_ALPHA) // <--- alpha channel MUST contain transparency, not shiny
{
LLMaterial* mat = tep->getMaterialParams().get();
bool shiny_in_alpha = false;
if (LLPipeline::sRenderDeferred)
{ //store shiny in alpha if we don't have a specular map
//if (!mat || mat->getSpecularID().isNull())
if (!mat || mat->getSpecularID().isNull())
{
shiny_in_alpha = true;
}
}
else
{
if(LLPipeline::sRenderBump && tep->getShiny())
if (!mat || mat->getDiffuseAlphaMode() != LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
{
shiny_in_alpha = true;
}
}
if(shiny_in_alpha)
if (shiny_in_alpha)
{
GLfloat alpha[4] =
{
0.00f,
0.25f,
0.5f,
0.75f
0.00f,
0.25f,
0.5f,
0.75f
};
llassert(tep->getShiny() <= 3);
@@ -1555,11 +1562,11 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
break;
case BE_BRIGHTNESS:
case BE_DARKNESS:
if( mTexture.notNull() && mTexture->hasGLTexture())
if( mTexture[LLRender::DIFFUSE_MAP].notNull() && mTexture[LLRender::DIFFUSE_MAP]->hasGLTexture())
{
// Offset by approximately one texel
S32 cur_discard = mTexture->getDiscardLevel();
S32 max_size = llmax( mTexture->getWidth(), mTexture->getHeight() );
S32 cur_discard = mTexture[LLRender::DIFFUSE_MAP]->getDiscardLevel();
S32 max_size = llmax( mTexture[LLRender::DIFFUSE_MAP]->getWidth(), mTexture[LLRender::DIFFUSE_MAP]->getHeight() );
max_size <<= cur_discard;
const F32 ARTIFICIAL_OFFSET = 2.f;
offset_multiple = ARTIFICIAL_OFFSET / (F32)max_size;
@@ -1600,11 +1607,18 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
U8 tex_mode = 0;
bool tex_anim = false;
LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp;
tex_mode = vobj->mTexAnimMode;
if (vobj->mTextureAnimp)
{ //texture animation is in play, override specular and normal map tex coords with diffuse texcoords
tex_anim = true;
}
if (isState(TEXTURE_ANIM))
{
LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp;
tex_mode = vobj->mTexAnimMode;
if (!tex_mode)
{
clearState(TEXTURE_ANIM);
@@ -1629,7 +1643,16 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
LLVector4a scalea;
scalea.load3(scale.mV);
LLMaterial* mat = tep->getMaterialParams().get();
bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1);
if (mat && !do_bump)
{
do_bump = mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1)
|| mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD2);
}
bool do_tex_mat = tex_mode && mTextureMatrix;
if (!do_bump)
@@ -1751,47 +1774,99 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
std::vector<LLVector2> bump_tc;
if (mat && !mat->getNormalID().isNull())
{ //writing out normal and specular texture coordinates, not bump offsets
do_bump = false;
}
LLStrider<LLVector2> dst;
mVertexBuffer->getTexCoord0Strider(dst, mGeomIndex, mGeomCount, map_range);
for (U32 ch = 0; ch < 3; ++ch)
{
switch (ch)
{
case 0:
mVertexBuffer->getTexCoord0Strider(dst, mGeomIndex, mGeomCount, map_range);
break;
case 1:
if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1))
{
mVertexBuffer->getTexCoord1Strider(dst, mGeomIndex, mGeomCount, map_range);
if (mat && !tex_anim)
{
r = mat->getNormalRotation();
mat->getNormalOffset(os, ot);
mat->getNormalRepeat(ms, mt);
for (S32 i = 0; i < num_vertices; i++)
{
LLVector2 tc(vf.mTexCoords[i]);
cos_ang = cos(r);
sin_ang = sin(r);
}
}
else
{
continue;
}
break;
case 2:
if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD2))
{
mVertexBuffer->getTexCoord2Strider(dst, mGeomIndex, mGeomCount, map_range);
if (mat && !tex_anim)
{
r = mat->getSpecularRotation();
mat->getSpecularOffset(os, ot);
mat->getSpecularRepeat(ms, mt);
cos_ang = cos(r);
sin_ang = sin(r);
}
}
else
{
continue;
}
break;
}
for (S32 i = 0; i < num_vertices; i++)
{
LLVector2 tc(vf.mTexCoords[i]);
LLVector4a& norm = vf.mNormals[i];
LLVector4a& norm = vf.mNormals[i];
LLVector4a& center = *(vf.mCenter);
LLVector4a& center = *(vf.mCenter);
if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)
{
LLVector4a vec = vf.mPositions[i];
vec.mul(scalea);
if (texgen == LLTextureEntry::TEX_GEN_PLANAR)
if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)
{
planarProjection(tc, norm, center, vec);
LLVector4a vec = vf.mPositions[i];
vec.mul(scalea);
if (texgen == LLTextureEntry::TEX_GEN_PLANAR)
{
planarProjection(tc, norm, center, vec);
}
}
}
if (tex_mode && mTextureMatrix)
{
LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
tmp = tmp * *mTextureMatrix;
tc.mV[0] = tmp.mV[0];
tc.mV[1] = tmp.mV[1];
}
else
{
xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
}
if (tex_mode && mTextureMatrix)
{
LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
tmp = tmp * *mTextureMatrix;
tc.mV[0] = tmp.mV[0];
tc.mV[1] = tmp.mV[1];
}
else
{
xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
}
*dst++ = tc;
if (do_bump)
{
bump_tc.push_back(tc);
*dst++ = tc;
if (do_bump)
{
bump_tc.push_back(tc);
}
}
}
@@ -1800,7 +1875,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
mVertexBuffer->flush();
}
if (do_bump)
if (!mat && do_bump)
{
mVertexBuffer->getTexCoord1Strider(tex_coords1, mGeomIndex, mGeomCount, map_range);
@@ -1846,20 +1921,31 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (rebuild_pos)
{
LLFastTimer t(FTM_FACE_GEOM_POSITION);
LLVector4a* src = vf.mPositions;
//_mm_prefetch((char*)src, _MM_HINT_T0);
LLVector4a* end = src+num_vertices;
//LLVector4a* end_64 = end-4;
//LLFastTimer t(FTM_FACE_GEOM_POSITION);
llassert(num_vertices > 0);
mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount, map_range);
LLMatrix4a mat_vert;
mat_vert.loadu(mat_vert_in);
LLVector4a* src = vf.mPositions;
volatile F32* dst = (volatile F32*) vert.get();
F32* dst = (F32*) vert.get();
F32* end_f32 = dst+mGeomCount*4;
volatile F32* end = dst+num_vertices*4;
LLVector4a res;
//_mm_prefetch((char*)dst, _MM_HINT_NTA);
//_mm_prefetch((char*)src, _MM_HINT_NTA);
//_mm_prefetch((char*)dst, _MM_HINT_NTA);
LLVector4a res0; //,res1,res2,res3;
LLVector4a texIdx;
@@ -1877,29 +1963,53 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
texIdx.set(0,0,0,val);
{
LLFastTimer t(FTM_FACE_POSITION_STORE);
LLVector4a tmp;
LLVector4a tmp;
do
{
//LLFastTimer t2(FTM_FACE_POSITION_STORE);
/*if (num_vertices > 4)
{ //more than 64 bytes
while (src < end_64)
{
_mm_prefetch((char*)src + 64, _MM_HINT_T0);
_mm_prefetch((char*)dst + 64, _MM_HINT_T0);
mat_vert.affineTransform(*src, res0);
tmp.setSelectWithMask(mask, texIdx, res0);
tmp.store4a((F32*) dst);
mat_vert.affineTransform(*(src+1), res1);
tmp.setSelectWithMask(mask, texIdx, res1);
tmp.store4a((F32*) dst+4);
mat_vert.affineTransform(*(src+2), res2);
tmp.setSelectWithMask(mask, texIdx, res2);
tmp.store4a((F32*) dst+8);
mat_vert.affineTransform(*(src+3), res3);
tmp.setSelectWithMask(mask, texIdx, res3);
tmp.store4a((F32*) dst+12);
dst += 16;
src += 4;
}
}*/
while (src < end)
{
mat_vert.affineTransform(*src++, res);
tmp.setSelectWithMask(mask, texIdx, res);
mat_vert.affineTransform(*src++, res0);
tmp.setSelectWithMask(mask, texIdx, res0);
tmp.store4a((F32*) dst);
dst += 4;
}
while(dst < end);
}
{
LLFastTimer t(FTM_FACE_POSITION_PAD);
S32 aligned_pad_vertices = mGeomCount - num_vertices;
res.set(res[0], res[1], res[2], 0.f);
while (aligned_pad_vertices > 0)
//LLFastTimer t(FTM_FACE_POSITION_PAD);
while (dst < end_f32)
{
--aligned_pad_vertices;
res.store4a((F32*) dst);
res0.store4a((F32*) dst);
dst += 4;
}
}
@@ -1913,14 +2023,16 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (rebuild_normal)
{
LLFastTimer t(FTM_FACE_GEOM_NORMAL);
//LLFastTimer t(FTM_FACE_GEOM_NORMAL);
mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, map_range);
F32* normals = (F32*) norm.get();
for (S32 i = 0; i < num_vertices; i++)
LLVector4a* src = vf.mNormals;
LLVector4a* end = src+num_vertices;
while (src < end)
{
LLVector4a normal;
mat_normal.rotate(vf.mNormals[i], normal);
normal.normalize3fast();
mat_normal.rotate(*src++, normal);
normal.store4a(normals);
normals += 4;
}
@@ -1943,14 +2055,18 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
mask.clear();
mask.setElement<3>();
for (S32 i = 0; i < num_vertices; i++)
LLVector4a* src = vf.mTangents;
LLVector4a* end = vf.mTangents+num_vertices;
while (src < end)
{
LLVector4a tangent_out;
mat_normal.rotate(vf.mTangents[i], tangent_out);
mat_normal.rotate(*src, tangent_out);
tangent_out.normalize3fast();
tangent_out.setSelectWithMask(mask, vf.mTangents[i], tangent_out);
tangent_out.setSelectWithMask(mask, *src, tangent_out);
tangent_out.store4a(tangents);
src++;
tangents += 4;
}
@@ -2070,16 +2186,23 @@ BOOL LLFace::hasMedia() const
{
return TRUE ;
}
if(mTexture.notNull())
if(mTexture[LLRender::DIFFUSE_MAP].notNull())
{
return mTexture->hasParcelMedia() ; //if has a parcel media
return mTexture[LLRender::DIFFUSE_MAP]->hasParcelMedia() ; //if has a parcel media
}
return FALSE ; //no media.
}
const F32 LEAST_IMPORTANCE = 0.05f ;
const F32 LEAST_IMPORTANCE_FOR_LARGE_IMAGE = 0.3f ;
void LLFace::resetVirtualSize()
{
setVirtualSize(0.f);
mImportanceToCamera = 0.f;
}
F32 LLFace::getTextureVirtualSize()
{
F32 radius;
@@ -2115,11 +2238,11 @@ F32 LLFace::getTextureVirtualSize()
}
face_area = LLFace::adjustPixelArea(mImportanceToCamera, face_area);
if (/*mImportanceToCamera < 1.0f && */face_area > LLViewerTexture::sMinLargeImageSize) //if is large image, shrink face_area by considering the partial overlapping.
if(face_area > LLViewerTexture::sMinLargeImageSize) //if is large image, shrink face_area by considering the partial overlapping.
{
if (mImportanceToCamera > LEAST_IMPORTANCE_FOR_LARGE_IMAGE && mTexture.notNull() && mTexture->isLargeImage())
{
face_area *= adjustPartialOverlapPixelArea(cos_angle_to_view_dir, radius);
if(mImportanceToCamera > LEAST_IMPORTANCE_FOR_LARGE_IMAGE && mTexture[LLRender::DIFFUSE_MAP].notNull() && mTexture[LLRender::DIFFUSE_MAP]->isLargeImage())
{
face_area *= adjustPartialOverlapPixelArea(cos_angle_to_view_dir, radius );
}
}
@@ -2145,9 +2268,18 @@ BOOL LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius)
LLVector4a t;
t.load3(camera->getOrigin().mV);
lookAt.setSub(center, t);
F32 dist = lookAt.getLength3().getF32();
dist = llmax(dist-size.getLength3().getF32(), 0.001f);
lookAt.normalize3fast() ;
//ramp down distance for nearby objects
if (dist < 16.f)
{
dist /= 16.f;
dist *= dist;
dist *= 16.f;
}
lookAt.normalize3fast();
//get area of circle around node
F32 app_angle = atanf((F32) sqrt(size_squared) / dist);
@@ -2483,9 +2615,12 @@ LLVector3 LLFace::getPositionAgent() const
return mCenterLocal * getRenderMatrix();
}
}
LLViewerTexture* LLFace::getTexture() const
LLViewerTexture* LLFace::getTexture(U32 ch) const
{
return mTexture ;
llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
return mTexture[ch] ;
}
void LLFace::setVertexBuffer(LLVertexBuffer* buffer)
@@ -2503,6 +2638,22 @@ void LLFace::clearVertexBuffer()
U32 LLFace::getRiggedDataMask(U32 type)
{
static const U32 rigged_data_mask[] = {
LLDrawPoolAvatar::RIGGED_MATERIAL_MASK,
LLDrawPoolAvatar::RIGGED_MATERIAL_ALPHA_VMASK,
LLDrawPoolAvatar::RIGGED_MATERIAL_ALPHA_MASK_MASK,
LLDrawPoolAvatar::RIGGED_MATERIAL_ALPHA_EMISSIVE_MASK,
LLDrawPoolAvatar::RIGGED_SPECMAP_VMASK,
LLDrawPoolAvatar::RIGGED_SPECMAP_BLEND_MASK,
LLDrawPoolAvatar::RIGGED_SPECMAP_MASK_MASK,
LLDrawPoolAvatar::RIGGED_SPECMAP_EMISSIVE_MASK,
LLDrawPoolAvatar::RIGGED_NORMMAP_VMASK,
LLDrawPoolAvatar::RIGGED_NORMMAP_BLEND_MASK,
LLDrawPoolAvatar::RIGGED_NORMMAP_MASK_MASK,
LLDrawPoolAvatar::RIGGED_NORMMAP_EMISSIVE_MASK,
LLDrawPoolAvatar::RIGGED_NORMSPEC_VMASK,
LLDrawPoolAvatar::RIGGED_NORMSPEC_BLEND_MASK,
LLDrawPoolAvatar::RIGGED_NORMSPEC_MASK_MASK,
LLDrawPoolAvatar::RIGGED_NORMSPEC_EMISSIVE_MASK,
LLDrawPoolAvatar::RIGGED_SIMPLE_MASK,
LLDrawPoolAvatar::RIGGED_FULLBRIGHT_MASK,
LLDrawPoolAvatar::RIGGED_SHINY_MASK,

View File

@@ -2,31 +2,25 @@
* @file llface.h
* @brief LLFace class definition
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* Copyright (C) 2010, Linden Research, Inc.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* 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.
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
* 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.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* 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$
*/
@@ -115,8 +109,12 @@ public:
U16 getGeomStart() const { return mGeomIndex; } // index into draw pool
void setTextureIndex(U8 index);
U8 getTextureIndex() const { return mTextureIndex; }
void setTexture(U32 ch, LLViewerTexture* tex);
void setTexture(LLViewerTexture* tex) ;
void switchTexture(LLViewerTexture* new_texture);
void setDiffuseMap(LLViewerTexture* tex);
void setNormalMap(LLViewerTexture* tex);
void setSpecularMap(LLViewerTexture* tex);
void switchTexture(U32 ch, LLViewerTexture* new_texture);
void dirtyTexture();
LLXformMatrix* getXform() const { return mXform; }
BOOL hasGeometry() const { return mGeomCount > 0; }
@@ -135,8 +133,8 @@ public:
F32 getVirtualSize() const { return mVSize; }
F32 getPixelArea() const { return mPixelArea; }
S32 getIndexInTex() const {return mIndexInTex ;}
void setIndexInTex(S32 index) { mIndexInTex = index ;}
S32 getIndexInTex(U32 ch) const {llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); return mIndexInTex[ch];}
void setIndexInTex(U32 ch, S32 index) { llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); mIndexInTex[ch] = index ;}
void renderSetColor() const;
S32 renderElements(const U16 *index_array) const;
@@ -154,7 +152,7 @@ public:
S32 getLOD() const { return mVObjp.notNull() ? mVObjp->getLOD() : 0; }
void setPoolType(U32 type) { mPoolType = type; }
S32 getTEOffset() { return mTEOffset; }
LLViewerTexture* getTexture() const;
LLViewerTexture* getTexture(U32 ch = LLRender::DIFFUSE_MAP) const;
void setViewerObject(LLViewerObject* object);
void setPool(LLFacePool *pool, LLViewerTexture *texturep);
@@ -196,10 +194,9 @@ public:
S32 getColors(LLStrider<LLColor4U> &colors);
S32 getIndices(LLStrider<U16> &indices);
void setSize(S32 numVertices, const S32 num_indices = 0, bool align = false);
void setSize(S32 numVertices, S32 num_indices = 0, bool align = false);
BOOL genVolumeBBoxes(const LLVolume &volume, S32 f,
const LLMatrix4& mat, const LLMatrix3& inv_trans_mat, BOOL global_volume = FALSE);
BOOL genVolumeBBoxes(const LLVolume &volume, S32 f,const LLMatrix4& mat, BOOL global_volume = FALSE);
void init(LLDrawable* drawablep, LLViewerObject* objp);
void destroy();
@@ -224,9 +221,13 @@ public:
F32 getTextureVirtualSize() ;
F32 getImportanceToCamera()const {return mImportanceToCamera ;}
void resetVirtualSize();
void setHasMedia(bool has_media) { mHasMedia = has_media ;}
BOOL hasMedia() const ;
BOOL switchTexture() ;
//vertex buffer tracking
void setVertexBuffer(LLVertexBuffer* buffer);
void clearVertexBuffer(); //sets mVertexBuffer and mLastVertexBuffer to NULL
@@ -258,6 +259,8 @@ public:
F32 mLastSkinTime;
F32 mLastMoveTime;
LLMatrix4* mTextureMatrix;
LLMatrix4* mSpecMapMatrix;
LLMatrix4* mNormalMapMatrix;
LLDrawInfo* mDrawInfo;
private:
@@ -273,10 +276,12 @@ private:
U8 mTextureIndex; // index of texture channel to use for pseudo-atlasing
U32 mIndicesCount;
U32 mIndicesIndex; // index into draw pool for indices (yeah, I know!)
S32 mIndexInTex ;
S32 mIndexInTex[LLRender::NUM_TEXTURE_CHANNELS];
LLXformMatrix* mXform;
LLPointer<LLViewerTexture> mTexture;
LLPointer<LLViewerTexture> mTexture[LLRender::NUM_TEXTURE_CHANNELS];
LLPointer<LLDrawable> mDrawablep;
LLPointer<LLViewerObject> mVObjp;
S32 mTEOffset;

View File

@@ -2,31 +2,25 @@
* @file llface.inl
* @brief Inline functions for LLFace
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* Copyright (C) 2010, Linden Research, Inc.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* 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.
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
* 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.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* 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$
*/

View File

@@ -50,6 +50,7 @@
#define MATERIALS_CAP_MATERIAL_FIELD "Material"
#define MATERIALS_CAP_OBJECT_ID_FIELD "ID"
#define MATERIALS_CAP_MATERIAL_ID_FIELD "MaterialID"
#define SIM_FEATURE_MAX_MATERIALS_PER_TRANSACTION "MaxMaterialsPerTransaction"
#define MATERIALS_GET_MAX_ENTRIES 50
#define MATERIALS_GET_TIMEOUT (60.f * 20)
@@ -339,36 +340,29 @@ const LLMaterialPtr LLMaterialMgr::setMaterial(const LLUUID& region_id, const LL
itMaterial = ret.first;
}
// we may have cleared our queues on leaving a region before we recv'd our
// update for this material...too late now!
//
if (isGetPending(region_id, material_id))
{
TEMaterialPair te_mat_pair;
te_mat_pair.materialID = material_id;
TEMaterialPair te_mat_pair;
te_mat_pair.materialID = material_id;
U32 i = 0;
while (i < LLTEContents::MAX_TES)
U32 i = 0;
while (i < LLTEContents::MAX_TES)
{
te_mat_pair.te = i++;
get_callback_te_map_t::iterator itCallbackTE = mGetTECallbacks.find(te_mat_pair);
if (itCallbackTE != mGetTECallbacks.end())
{
te_mat_pair.te = i++;
get_callback_te_map_t::iterator itCallbackTE = mGetTECallbacks.find(te_mat_pair);
if (itCallbackTE != mGetTECallbacks.end())
{
(*itCallbackTE->second)(material_id, itMaterial->second, te_mat_pair.te);
delete itCallbackTE->second;
mGetTECallbacks.erase(itCallbackTE);
}
(*itCallbackTE->second)(material_id, itMaterial->second, te_mat_pair.te);
delete itCallbackTE->second;
mGetTECallbacks.erase(itCallbackTE);
}
}
get_callback_map_t::iterator itCallback = mGetCallbacks.find(material_id);
if (itCallback != mGetCallbacks.end())
{
(*itCallback->second)(material_id, itMaterial->second);
get_callback_map_t::iterator itCallback = mGetCallbacks.find(material_id);
if (itCallback != mGetCallbacks.end())
{
(*itCallback->second)(material_id, itMaterial->second);
delete itCallback->second;
mGetCallbacks.erase(itCallback);
}
delete itCallback->second;
mGetCallbacks.erase(itCallback);
}
mGetPending.erase(pending_material_t(region_id, material_id));
@@ -555,11 +549,9 @@ void LLMaterialMgr::onIdle(void*)
instancep->processGetAllQueue();
}
static LLFrameTimer mPutTimer;
if ( (!instancep->mPutQueue.empty()) && (mPutTimer.hasExpired()) )
if (!instancep->mPutQueue.empty())
{
instancep->processPutQueue();
mPutTimer.reset(MATERIALS_PUT_THROTTLE_SECS);
}
}
@@ -576,14 +568,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;
}
@@ -606,8 +598,9 @@ void LLMaterialMgr::processGetQueue()
LLSD materialsData = LLSD::emptyArray();
material_queue_t& materials = itRegionQueue->second;
U32 max_entries = regionp->getMaxMaterialsPerTransaction();
material_queue_t::iterator loopMaterial = materials.begin();
while ( (materials.end() != loopMaterial) && (materialsData.size() <= MATERIALS_GET_MAX_ENTRIES) )
while ( (materials.end() != loopMaterial) && (materialsData.size() < (int)max_entries) )
{
material_queue_t::iterator itMaterial = loopMaterial++;
materialsData.append((*itMaterial).asLLSD());
@@ -639,6 +632,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();
}
}
@@ -657,7 +651,7 @@ void LLMaterialMgr::processGetAllQueue()
clearGetQueues(region_id); // Invalidates region_id
continue;
}
else if (!regionp->capabilitiesReceived())
else if (!regionp->capabilitiesReceived() || regionp->materialsCapThrottled())
{
continue;
}
@@ -674,6 +668,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
}
@@ -681,7 +676,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();
@@ -691,25 +686,27 @@ 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())
else
{
continue;
LLViewerRegion* regionp = objectp->getRegion();
if ( !regionp )
{
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() < MATERIALS_GET_MAX_ENTRIES) )
while ( (face_map.end() != itFace) && (facesData.size() < (int)max_entries) )
{
LLSD faceData = LLSD::emptyMap();
faceData[MATERIALS_CAP_FACE_FIELD] = static_cast<LLSD::Integer>(itFace->first);
@@ -726,14 +723,17 @@ void LLMaterialMgr::processPutQueue()
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;
}
@@ -756,6 +756,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
{

View File

@@ -124,6 +124,8 @@ protected:
put_queue_t mPutQueue;
material_map_t mMaterials;
U32 getMaxEntries(const LLViewerRegion* regionp);
};
#endif // LL_LLMATERIALMGR_H

View File

@@ -2386,7 +2386,7 @@ void pushBufferVerts(LLVertexBuffer* buffer, U32 mask)
}
}
void pushBufferVerts(LLSpatialGroup* group, U32 mask)
void pushBufferVerts(LLSpatialGroup* group, U32 mask, bool push_alpha = true)
{
if (group->mSpatialPartition->mRenderByGroup)
{
@@ -2395,7 +2395,10 @@ void pushBufferVerts(LLSpatialGroup* group, U32 mask)
LLDrawInfo* params = *(group->mDrawMap.begin()->second.begin());
LLRenderPass::applyModelMatrix(*params);
pushBufferVerts(group->mVertexBuffer, mask);
if (push_alpha)
{
pushBufferVerts(group->mVertexBuffer, mask);
}
for (LLSpatialGroup::buffer_map_t::iterator i = group->mBufferMap.begin(); i != group->mBufferMap.end(); ++i)
{
@@ -2858,20 +2861,23 @@ void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE)
const LLVector4a* ext;
LLVector4a pos, size;
//render face bounding boxes
for (S32 i = 0; i < drawable->getNumFaces(); i++)
if (drawable->getVOVolume())
{
LLFace* facep = drawable->getFace(i);
if (facep)
//render face bounding boxes
for (S32 i = 0; i < drawable->getNumFaces(); i++)
{
ext = facep->mExtents;
LLFace* facep = drawable->getFace(i);
if (facep)
{
ext = facep->mExtents;
pos.setAdd(ext[0], ext[1]);
pos.mul(0.5f);
size.setSub(ext[1], ext[0]);
size.mul(0.5f);
pos.setAdd(ext[0], ext[1]);
pos.mul(0.5f);
size.setSub(ext[1], ext[0]);
size.mul(0.5f);
drawBoxOutline(pos,size);
drawBoxOutline(pos,size);
}
}
}
@@ -4442,7 +4448,16 @@ LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,
mGroup(NULL),
mFace(NULL),
mDistance(0.f),
mDrawMode(LLRender::TRIANGLES)
mDrawMode(LLRender::TRIANGLES),
mMaterial(NULL),
mShaderMask(0),
mSpecColor(1.0f, 1.0f, 1.0f, 0.5f),
mBlendFuncSrc(LLRender::BF_SOURCE_ALPHA),
mBlendFuncDst(LLRender::BF_ONE_MINUS_SOURCE_ALPHA),
mHasGlow(FALSE),
mEnvIntensity(0.0f),
mAlphaMaskCutoff(0.5f),
mDiffuseAlphaMode(0)
{
mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset);

View File

@@ -117,6 +117,7 @@ public:
U32 mOffset;
BOOL mFullbright;
U8 mBump;
U8 mShiny;
BOOL mParticle;
F32 mPartSize;
F32 mVSize;
@@ -124,6 +125,21 @@ public:
LL_ALIGN_16(LLFace* mFace); //associated face
F32 mDistance;
U32 mDrawMode;
LLMaterialPtr mMaterial; // If this is null, the following parameters are unused.
LLMaterialID mMaterialID;
U32 mShaderMask;
U32 mBlendFuncSrc;
U32 mBlendFuncDst;
BOOL mHasGlow;
LLPointer<LLViewerTexture> mSpecularMap;
const LLMatrix4* mSpecularMapMatrix;
LLPointer<LLViewerTexture> mNormalMap;
const LLMatrix4* mNormalMapMatrix;
LLVector4 mSpecColor; // XYZ = Specular RGB, W = Specular Exponent
F32 mEnvIntensity;
F32 mAlphaMaskCutoff;
U8 mDiffuseAlphaMode;
struct CompareTexture
{

View File

@@ -1158,6 +1158,7 @@ void render_hud_attachments()
if (LLPipeline::sShowHUDAttachments && !gDisconnected && setup_hud_matrices())
{
LLPipeline::sRenderingHUDs = TRUE;
LLCamera hud_cam = *LLViewerCamera::getInstance();
hud_cam.setOrigin(-1.f,0,0);
hud_cam.setAxes(LLVector3(1,0,0), LLVector3(0,1,0), LLVector3(0,0,1));
@@ -1203,10 +1204,13 @@ void render_hud_attachments()
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_SIMPLE);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_VOLUME);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA_MASK);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_FULLBRIGHT);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_BUMP);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_MATERIAL);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY);
@@ -1231,6 +1235,7 @@ void render_hud_attachments()
gPipeline.toggleRenderDebugFeature((void*) LLPipeline::RENDER_DEBUG_FEATURE_UI);
}
LLPipeline::sUseOcclusion = use_occlusion;
LLPipeline::sRenderingHUDs = FALSE;
}
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.popMatrix();

View File

@@ -208,6 +208,8 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
mTotalCRC(0),
mListIndex(-1),
mTEImages(NULL),
mTENormalMaps(NULL),
mTESpecularMaps(NULL),
mGLName(0),
mbCanSelect(TRUE),
mFlags(0),
@@ -336,6 +338,18 @@ void LLViewerObject::deleteTEImages()
{
delete[] mTEImages;
mTEImages = NULL;
if (mTENormalMaps != NULL)
{
delete[] mTENormalMaps;
mTENormalMaps = NULL;
}
if (mTESpecularMaps != NULL)
{
delete[] mTESpecularMaps;
mTESpecularMaps = NULL;
}
}
void LLViewerObject::markDead()
@@ -1600,6 +1614,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
dp->setPassFlags(value);
dp->unpackUUID(owner_id, "Owner");
mOwnerID = owner_id;
if (value & 0x80)
{
dp->unpackVector3(new_angv, "Omega");
@@ -1688,9 +1704,9 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
//
if (value & 0x8)
{
unpackParticleSource(*dp, owner_id);
unpackParticleSource(*dp, owner_id, true);
}
else
else if (!(value & 0x400))
{
deleteParticleSource();
}
@@ -4048,25 +4064,39 @@ void LLViewerObject::setNumTEs(const U8 num_tes)
{
LLPointer<LLViewerTexture> *new_images;
new_images = new LLPointer<LLViewerTexture>[num_tes];
LLPointer<LLViewerTexture> *new_normmaps;
new_normmaps = new LLPointer<LLViewerTexture>[num_tes];
LLPointer<LLViewerTexture> *new_specmaps;
new_specmaps = new LLPointer<LLViewerTexture>[num_tes];
for (i = 0; i < num_tes; i++)
{
if (i < getNumTEs())
{
new_images[i] = mTEImages[i];
new_normmaps[i] = mTENormalMaps[i];
new_specmaps[i] = mTESpecularMaps[i];
}
else if (getNumTEs())
{
new_images[i] = mTEImages[getNumTEs()-1];
new_normmaps[i] = mTENormalMaps[getNumTEs()-1];
new_specmaps[i] = mTESpecularMaps[getNumTEs()-1];
}
else
{
new_images[i] = NULL;
new_normmaps[i] = NULL;
new_specmaps[i] = NULL;
}
}
deleteTEImages();
mTEImages = new_images;
mTENormalMaps = new_normmaps;
mTESpecularMaps = new_specmaps;
}
else
{
@@ -4161,12 +4191,18 @@ void LLViewerObject::sendTEUpdate() const
void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry)
{
LLPrimitive::setTE(te, texture_entry);
// This doesn't work, don't get any textures.
// if (mDrawable.notNull() && mDrawable->isVisible())
// {
const LLUUID& image_id = getTE(te)->getID();
const LLUUID& image_id = getTE(te)->getID();
mTEImages[te] = LLViewerTextureManager::getFetchedTexture(image_id, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
// }
if (getTE(te)->getMaterialParams().notNull())
{
const LLUUID& norm_id = getTE(te)->getMaterialParams()->getNormalID();
mTENormalMaps[te] = LLViewerTextureManager::getFetchedTexture(norm_id, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
const LLUUID& spec_id = getTE(te)->getMaterialParams()->getSpecularID();
mTESpecularMaps[te] = LLViewerTextureManager::getFetchedTexture(spec_id, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
}
}
void LLViewerObject::setTEImage(const U8 te, LLViewerTexture *imagep)
@@ -4201,6 +4237,52 @@ S32 LLViewerObject::setTETextureCore(const U8 te, LLViewerTexture *image)
return retval;
}
S32 LLViewerObject::setTENormalMapCore(const U8 te, LLViewerTexture *image)
{
S32 retval = TEM_CHANGE_TEXTURE;
const LLUUID& uuid = image ? image->getID() : LLUUID::null;
if (uuid != getTE(te)->getID() ||
uuid == LLUUID::null)
{
LLTextureEntry* tep = getTE(te);
LLMaterial* mat = NULL;
if (tep)
{
mat = tep->getMaterialParams();
}
if (mat)
{
mat->setNormalID(uuid);
}
}
changeTENormalMap(te,image);
return retval;
}
S32 LLViewerObject::setTESpecularMapCore(const U8 te, LLViewerTexture *image)
{
S32 retval = TEM_CHANGE_TEXTURE;
const LLUUID& uuid = image ? image->getID() : LLUUID::null;
if (uuid != getTE(te)->getID() ||
uuid == LLUUID::null)
{
LLTextureEntry* tep = getTE(te);
LLMaterial* mat = NULL;
if (tep)
{
mat = tep->getMaterialParams();
}
if (mat)
{
mat->setSpecularID(uuid);
}
}
changeTESpecularMap(te, image);
return retval;
}
//virtual
void LLViewerObject::changeTEImage(S32 index, LLViewerTexture* new_image)
{
@@ -4211,6 +4293,25 @@ void LLViewerObject::changeTEImage(S32 index, LLViewerTexture* new_image)
mTEImages[index] = new_image ;
}
void LLViewerObject::changeTENormalMap(S32 index, LLViewerTexture* new_image)
{
if(index < 0 || index >= getNumTEs())
{
return ;
}
mTENormalMaps[index] = new_image ;
refreshMaterials();
}
void LLViewerObject::changeTESpecularMap(S32 index, LLViewerTexture* new_image)
{
if(index < 0 || index >= getNumTEs())
{
return ;
}
mTESpecularMaps[index] = new_image ;
refreshMaterials();
}
S32 LLViewerObject::setTETexture(const U8 te, const LLUUID& uuid)
{
// Invalid host == get from the agent's sim
@@ -4219,6 +4320,19 @@ S32 LLViewerObject::setTETexture(const U8 te, const LLUUID& uuid)
return setTETextureCore(te,image);
}
S32 LLViewerObject::setTENormalMap(const U8 te, const LLUUID& uuid)
{
LLViewerFetchedTexture *image = (uuid == LLUUID::null) ? NULL : LLViewerTextureManager::getFetchedTexture(
uuid, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost::invalid);
return setTENormalMapCore(te, image);
}
S32 LLViewerObject::setTESpecularMap(const U8 te, const LLUUID& uuid)
{
LLViewerFetchedTexture *image = (uuid == LLUUID::null) ? NULL : LLViewerTextureManager::getFetchedTexture(
uuid, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost::invalid);
return setTESpecularMapCore(te, image);
}
S32 LLViewerObject::setTEColor(const U8 te, const LLColor3& color)
{
@@ -4379,6 +4493,59 @@ S32 LLViewerObject::setTEGlow(const U8 te, const F32 glow)
return retval;
}
S32 LLViewerObject::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID)
{
S32 retval = 0;
const LLTextureEntry *tep = getTE(te);
if (!tep)
{
LL_WARNS("Material") << "No texture entry for te " << (S32)te
<< ", object " << mID
<< ", material " << pMaterialID
<< LL_ENDL;
}
//else if (pMaterialID != tep->getMaterialID())
{
LL_DEBUGS("Material") << "Changing texture entry for te " << (S32)te
<< ", object " << mID
<< ", material " << pMaterialID
<< LL_ENDL;
retval = LLPrimitive::setTEMaterialID(te, pMaterialID);
refreshMaterials();
}
return retval;
}
S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams)
{
S32 retval = 0;
const LLTextureEntry *tep = getTE(te);
if (!tep)
{
llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl;
return 0;
}
retval = LLPrimitive::setTEMaterialParams(te, pMaterialParams);
LL_DEBUGS("Material") << "Changing material params for te " << (S32)te
<< ", object " << mID
<< " (" << retval << ")"
<< LL_ENDL;
setTENormalMap(te, (pMaterialParams) ? pMaterialParams->getNormalID() : LLUUID::null);
setTESpecularMap(te, (pMaterialParams) ? pMaterialParams->getSpecularID() : LLUUID::null);
refreshMaterials();
return retval;
}
void LLViewerObject::refreshMaterials()
{
setChanged(TEXTURE);
if (mDrawable.notNull())
{
gPipeline.markTextured(mDrawable);
}
}
S32 LLViewerObject::setTEScale(const U8 te, const F32 s, const F32 t)
{
@@ -4480,6 +4647,74 @@ 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);
if (face < getNumTEs())
{
LLViewerTexture* image = mTENormalMaps[face];
if (image)
{
return image;
}
else
{
return (LLViewerTexture*)(LLViewerFetchedTexture::sDefaultImagep);
}
}
llerrs << llformat("Requested Image from invalid face: %d/%d",face,getNumTEs()) << llendl;
return NULL;
}
LLViewerTexture *LLViewerObject::getTESpecularMap(const U8 face) const
{
// llassert(mTEImages);
if (face < getNumTEs())
{
LLViewerTexture* image = mTESpecularMaps[face];
if (image)
{
return image;
}
else
{
return (LLViewerTexture*)(LLViewerFetchedTexture::sDefaultImagep);
}
}
llerrs << llformat("Requested Image from invalid face: %d/%d",face,getNumTEs()) << llendl;
return NULL;
}
void LLViewerObject::fitFaceTexture(const U8 face)
{
llinfos << "fitFaceTexture not implemented" << llendl;
@@ -4766,7 +5001,7 @@ void LLViewerObject::unpackParticleSource(const S32 block_num, const LLUUID& own
}
}
void LLViewerObject::unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id)
void LLViewerObject::unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id, bool legacy)
{
if (!mPartSourcep.isNull() && mPartSourcep->isDead())
{
@@ -4775,7 +5010,7 @@ void LLViewerObject::unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_
if (mPartSourcep)
{
// If we've got one already, just update the existing source (or remove it)
if (!LLViewerPartSourceScript::unpackPSS(this, mPartSourcep, dp))
if (!LLViewerPartSourceScript::unpackPSS(this, mPartSourcep, dp, legacy))
{
mPartSourcep->setDead();
mPartSourcep = NULL;
@@ -4783,7 +5018,7 @@ void LLViewerObject::unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_
}
else
{
LLPointer<LLViewerPartSourceScript> pss = LLViewerPartSourceScript::unpackPSS(this, NULL, dp);
LLPointer<LLViewerPartSourceScript> pss = LLViewerPartSourceScript::unpackPSS(this, NULL, dp, legacy);
//If the owner is muted, don't create the system
if(LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagParticles)) return;
// We need to be able to deal with a particle source that hasn't changed, but still got an update!
@@ -5633,6 +5868,11 @@ F32 LLAlphaObject::getPartSize(S32 idx)
return 0.f;
}
void LLAlphaObject::getBlendFunc(S32 face, U32& src, U32& dst)
{
}
// virtual
void LLStaticViewerObject::updateDrawable(BOOL force_damped)
{

View File

@@ -224,6 +224,7 @@ public:
virtual BOOL isFlexible() const { return FALSE; }
virtual BOOL isSculpted() const { return FALSE; }
virtual BOOL isMesh() const { return FALSE; }
virtual BOOL hasLightTexture() const { return FALSE; }
// This method returns true if the object is over land owned by
// the agent, one of its groups, or it encroaches and
@@ -306,7 +307,11 @@ public:
/*virtual*/ void setNumTEs(const U8 num_tes);
/*virtual*/ void setTE(const U8 te, const LLTextureEntry &texture_entry);
/*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid);
S32 setTETextureCore(const U8 te, LLViewerTexture *image);
/*virtual*/ S32 setTENormalMap(const U8 te, const LLUUID &uuid);
/*virtual*/ S32 setTESpecularMap(const U8 te, const LLUUID &uuid);
S32 setTETextureCore(const U8 te, LLViewerTexture *image);
S32 setTENormalMapCore(const U8 te, LLViewerTexture *image);
S32 setTESpecularMapCore(const U8 te, LLViewerTexture *image);
/*virtual*/ S32 setTEColor(const U8 te, const LLColor3 &color);
/*virtual*/ S32 setTEColor(const U8 te, const LLColor4 &color);
/*virtual*/ S32 setTEScale(const U8 te, const F32 s, const F32 t);
@@ -323,11 +328,25 @@ public:
/*virtual*/ S32 setTEFullbright(const U8 te, const U8 fullbright );
/*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags );
/*virtual*/ S32 setTEGlow(const U8 te, const F32 glow);
/*virtual*/ S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID);
/*virtual*/ S32 setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams);
// Used by Materials update functions to properly kick off rebuilds
// of VBs etc when materials updates require changes.
//
void refreshMaterials();
/*virtual*/ BOOL setMaterial(const U8 material);
virtual void setTEImage(const U8 te, LLViewerTexture *imagep); // Not derived from LLPrimitive
virtual void changeTEImage(S32 index, LLViewerTexture* new_image) ;
virtual void changeTEImage(S32 index, LLViewerTexture* new_image) ;
virtual void changeTENormalMap(S32 index, LLViewerTexture* new_image) ;
virtual void changeTESpecularMap(S32 index, LLViewerTexture* new_image) ;
LLViewerTexture *getTEImage(const U8 te) const;
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
@@ -596,6 +615,7 @@ public:
} EPhysicsShapeType;
LLUUID mID;
LLUUID mOwnerID; //null if unknown
// unique within region, not unique across regions
// Local ID = 0 is not used
@@ -608,6 +628,8 @@ public:
S32 mListIndex;
LLPointer<LLViewerTexture> *mTEImages;
LLPointer<LLViewerTexture> *mTENormalMaps;
LLPointer<LLViewerTexture> *mTESpecularMaps;
// Selection, picking and rendering variables
U32 mGLName; // GL "name" used by selection code
@@ -679,7 +701,7 @@ protected:
BOOL isOnMap();
void unpackParticleSource(const S32 block_num, const LLUUID& owner_id);
void unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id);
void unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id, bool legacy);
void deleteParticleSource();
void setParticleSource(const LLPartSysData& particle_parameters, const LLUUID& owner_id);
@@ -847,8 +869,11 @@ public:
LLStrider<LLVector3>& normalsp,
LLStrider<LLVector2>& texcoordsp,
LLStrider<LLColor4U>& colorsp,
LLStrider<LLColor4U>& emissivep,
LLStrider<U16>& indicesp) = 0;
virtual void getBlendFunc(S32 face, U32& src, U32& dst);
F32 mDepth;
};

View File

@@ -86,12 +86,31 @@ LLViewerPart::LLViewerPart() :
mImagep(NULL)
{
mPartSourcep = NULL;
mParent = NULL;
mChild = NULL;
++LLViewerPartSim::sParticleCount2 ;
}
LLViewerPart::~LLViewerPart()
{
if (mPartSourcep.notNull() && mPartSourcep->mLastPart == this)
{
mPartSourcep->mLastPart = NULL;
}
//patch up holes in the ribbon
if (mParent)
{
llassert(mParent->mChild == this);
mParent->mChild = mChild;
}
if (mChild)
{
llassert (mChild->mParent == this);
mChild->mParent = mParent;
}
mPartSourcep = NULL;
--LLViewerPartSim::sParticleCount2 ;
@@ -147,7 +166,11 @@ LLViewerPartGroup::LLViewerPartGroup(const LLVector3 &center_agent, const F32 bo
}
mVOPartGroupp->setViewerPartGroup(this);
mVOPartGroupp->setPositionAgent(getCenterAgent());
mBoxSide = box_side;
F32 scale = box_side * 0.5f;
mVOPartGroupp->setScale(LLVector3(scale,scale,scale));
//gPipeline.addObject(mVOPartGroupp);
@@ -373,6 +396,9 @@ void LLViewerPartGroup::updateParticles(const F32 lastdt)
part->mScale += frac*part->mEndScale;
}
// Do glow interpolation
part->mGlow.mV[3] = (U8) llround(lerp(part->mStartGlow, part->mEndGlow, frac)*255.f);
// Set the last update time to now.
part->mLastUpdateTime = cur_time;
@@ -491,11 +517,16 @@ void LLViewerPartSim::destroyClass()
mViewerPartSources.clear();
}
//static
BOOL LLViewerPartSim::shouldAddPart()
{
if (sParticleCount >= MAX_PART_COUNT)
{
return FALSE;
}
if (sParticleCount > PART_THROTTLE_THRESHOLD*sMaxParticleCount)
{
F32 frac = (F32)sParticleCount/(F32)sMaxParticleCount;
frac -= PART_THROTTLE_THRESHOLD;
frac *= PART_THROTTLE_RESCALE;
@@ -505,7 +536,10 @@ BOOL LLViewerPartSim::shouldAddPart()
return FALSE;
}
}
if (sParticleCount >= MAX_PART_COUNT)
// Check frame rate, and don't add more if the viewer is really slow
const F32 MIN_FRAME_RATE_FOR_NEW_PARTICLES = 4.f;
if (gFPSClamped < MIN_FRAME_RATE_FOR_NEW_PARTICLES)
{
return FALSE;
}
@@ -621,6 +655,9 @@ void LLViewerPartSim::updateSimulation()
{
static LLFrameTimer update_timer;
//reset VBO cursor
LLVOPartGroup::sVBSlotCursor = 0;
const F32 dt = llmin(update_timer.getElapsedTimeAndResetF32(), 0.1f);
if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES)))

View File

@@ -71,15 +71,22 @@ public:
LLVPCallback mVPCallback; // Callback function for more complicated behaviors
LLPointer<LLViewerPartSource> mPartSourcep; // Particle source used for this object
LLViewerPart* mParent; // particle to connect to if this is part of a particle ribbon
LLViewerPart* mChild; // child particle for clean reference destruction
// Current particle state (possibly used for rendering)
LLPointer<LLViewerTexture> mImagep;
LLVector3 mPosAgent;
LLVector3 mVelocity;
LLVector3 mAccel;
LLVector3 mAxis;
LLColor4 mColor;
LLVector2 mScale;
F32 mStartGlow;
F32 mEndGlow;
LLColor4U mGlow;
static U32 sNextPartID;
};
@@ -104,6 +111,9 @@ public:
void shift(const LLVector3 &offset);
F32 getBoxRadius() { return mBoxRadius; }
F32 getBoxSide() { return mBoxSide; }
typedef std::vector<LLViewerPart*> part_list_t;
part_list_t mParticles;
@@ -124,6 +134,7 @@ public:
protected:
LLVector3 mCenterAgent;
F32 mBoxRadius;
F32 mBoxSide;
LLVector3 mMinObjPos;
LLVector3 mMaxObjPos;
@@ -148,7 +159,7 @@ public:
void cleanupRegion(LLViewerRegion *regionp);
BOOL shouldAddPart(); // Just decides whether this particle should be added or not (for particle count capping)
static BOOL shouldAddPart(); // Just decides whether this particle should be added or not (for particle count capping)
F32 maxRate() // Return maximum particle generation rate
{
if (sParticleCount >= MAX_PART_COUNT)

Some files were not shown because too many files have changed in this diff Show More