Merge branch 'master' of git://github.com/Shyotl/SingularityViewer
This commit is contained in:
@@ -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));
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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....
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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++ )
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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..
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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++)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
46
indra/newview/app_settings/shaders/class1/deferred/srgb.glsl
Normal file
46
indra/newview/app_settings/shaders/class1/deferred/srgb.glsl
Normal 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);
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -31,8 +31,6 @@ out vec4 frag_color;
|
||||
|
||||
uniform sampler2D depthMap;
|
||||
|
||||
uniform float delta;
|
||||
|
||||
VARYING vec2 tc0;
|
||||
VARYING vec2 tc1;
|
||||
VARYING vec2 tc2;
|
||||
|
||||
@@ -33,8 +33,6 @@ out vec4 frag_color;
|
||||
|
||||
uniform sampler2DRect depthMap;
|
||||
|
||||
uniform float delta;
|
||||
|
||||
VARYING vec2 tc0;
|
||||
VARYING vec2 tc1;
|
||||
VARYING vec2 tc2;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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());
|
||||
|
||||
224
indra/newview/lldrawpoolmaterials.cpp
Normal file
224
indra/newview/lldrawpoolmaterials.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
75
indra/newview/lldrawpoolmaterials.h
Normal file
75
indra/newview/lldrawpoolmaterials.h
Normal 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
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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$
|
||||
*/
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -124,6 +124,8 @@ protected:
|
||||
put_queue_t mPutQueue;
|
||||
|
||||
material_map_t mMaterials;
|
||||
|
||||
U32 getMaxEntries(const LLViewerRegion* regionp);
|
||||
};
|
||||
|
||||
#endif // LL_LLMATERIALMGR_H
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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 ¢er_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)))
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user