summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorGeenz <geenz@geenzo.com>2013-01-30 12:17:04 -0500
committerGeenz <geenz@geenzo.com>2013-01-30 12:17:04 -0500
commitaa1befd689703d9fea50399201911e0f8fca6ac6 (patch)
treec60457d1762d8b1c28a9d40130ba2988f532cd27 /indra/newview
parent66a01ba4c581d79227b0e67f5f75dc248fcaf7ab (diff)
Specular map support. This is the vast majority of the material parameters implemented at this point for opaque geometry.
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl21
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl6
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl6
-rw-r--r--indra/newview/lldrawpoolbump.cpp19
-rw-r--r--indra/newview/lldrawpoolbump.h5
-rwxr-xr-xindra/newview/llface.cpp6
-rw-r--r--indra/newview/llspatialpartition.cpp7
-rw-r--r--indra/newview/llviewerobject.cpp11
-rw-r--r--indra/newview/llvovolume.cpp18
-rw-r--r--indra/newview/pipeline.cpp25
10 files changed, 76 insertions, 48 deletions
diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
index 23c4ea2fff..6e5cc69e39 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
@@ -31,6 +31,9 @@ out vec4 frag_data[3];
uniform sampler2D diffuseMap;
uniform sampler2D bumpMap;
+uniform sampler2D specularMap;
+uniform float env_intensity;
+uniform vec4 specular_color;
VARYING vec3 vary_mat0;
VARYING vec3 vary_mat1;
@@ -42,15 +45,17 @@ VARYING vec2 vary_texcoord0;
void main()
{
vec3 col = vertex_color.rgb * texture2D(diffuseMap, vary_texcoord0.xy).rgb;
- vec3 norm = texture2D(bumpMap, vary_texcoord0.xy).rgb * 2.0 - 1.0;
+ vec4 spec = texture2D(specularMap, vary_texcoord0.xy);
+ vec4 norm = texture2D(bumpMap, vary_texcoord0.xy);
+ norm.xyz = norm.xyz * 2 - 1;
- vec3 tnorm = vec3(dot(norm,vary_mat0),
- dot(norm,vary_mat1),
- dot(norm,vary_mat2));
-
- frag_data[0] = vec4(col, 0.0);
- frag_data[1] = vertex_color.aaaa; // spec
+ vec3 tnorm = vec3(dot(norm.xyz,vary_mat0),
+ dot(norm.xyz,vary_mat1),
+ dot(norm.xyz,vary_mat2));
+
+ frag_data[0] = vec4(col * (1 - spec.a * env_intensity), 0);
+ frag_data[1] = vec4(spec.xyz * specular_color.xyz, specular_color.a * norm.a); // 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(nvn.xyz * 0.5 + 0.5, 0.0);
+ frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, spec.a * env_intensity);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
index 87cdf1026f..2ec3fe4a52 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
@@ -280,8 +280,8 @@ void main()
vec2 tc = vary_fragcoord.xy;
float depth = texture2DRect(depthMap, tc.xy).r;
vec3 pos = getPosition_d(tc, depth).xyz;
- vec3 norm = texture2DRect(normalMap, tc).xyz;
- norm = (norm.xyz-0.5)*2.0; // unpack norm
+ vec4 norm = texture2DRect(normalMap, tc);
+ norm.xyz = (norm.xyz-0.5)*2.0; // unpack norm
float da = max(dot(norm.xyz, sun_dir.xyz), 0.0);
@@ -315,7 +315,7 @@ void main()
//add environmentmap
vec3 env_vec = env_mat * refnormpersp;
col = mix(col.rgb, samplesRGB(textureCube(environmentMap, env_vec).rgb) * 2.2,
- max(spec.a-diffuse.a*2.0, 0.0));
+ max(norm.a-diffuse.a*2.0, 0.0));
}
col = atmosLighting(col);
diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
index bf4c476138..e95991a635 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
@@ -283,8 +283,8 @@ void main()
vec2 tc = vary_fragcoord.xy;
float depth = texture2DRect(depthMap, tc.xy).r;
vec3 pos = getPosition_d(tc, depth).xyz;
- vec3 norm = texture2DRect(normalMap, tc).xyz;
- norm = (norm.xyz-0.5)*2.0; // unpack norm
+ vec4 norm = texture2DRect(normalMap, tc);
+ norm.xyz = (norm.xyz-0.5)*2.0; // unpack norm
float da = max(dot(norm.xyz, sun_dir.xyz), 0.0);
@@ -324,7 +324,7 @@ void main()
//add environmentmap
vec3 env_vec = env_mat * refnormpersp;
col = mix(col.rgb, samplesRGB(textureCube(environmentMap, env_vec).rgb) * 2.2,
- max(spec.a-diffuse.a*2.0, 0.0));
+ max(norm.a-diffuse.a*2.0, 0.0));
}
col = atmosLighting(col);
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index fcc81dc723..07384a136a 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -72,7 +72,7 @@ static LLGLSLShader* shader = NULL;
static S32 cube_channel = -1;
static S32 diffuse_channel = -1;
static S32 bump_channel = -1;
-
+static S32 spec_channel = -1;
// static
void LLStandardBumpmap::init()
{
@@ -634,7 +634,7 @@ BOOL LLDrawPoolBump::bindBumpMap(LLDrawInfo& params, S32 channel)
U8 bump_code = params.mBump;
if (params.mNormalMap.notNull())
{
- bump_code = BE_CUSTOM;
+ bump_code = 99;
return bindBumpMap(bump_code, params.mNormalMap, params.mVSize, channel);
}
@@ -675,7 +675,7 @@ BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, F32 vsi
case BE_DARKNESS:
bump = gBumpImageList.getBrightnessDarknessImage( tex, bump_code );
break;
- case BE_CUSTOM:
+ case 99:
bump = tex;
bump->addTextureStats(vsize);
break;
@@ -828,6 +828,7 @@ void LLDrawPoolBump::beginDeferredPass(S32 pass)
gDeferredBumpProgram.bind();
diffuse_channel = gDeferredBumpProgram.enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
bump_channel = gDeferredBumpProgram.enableTexture(LLViewerShaderMgr::BUMP_MAP);
+ spec_channel = gDeferredBumpProgram.enableTexture(LLViewerShaderMgr::SPECULAR_MAP);
gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(bump_channel)->unbind(LLTexUnit::TT_TEXTURE);
}
@@ -842,6 +843,7 @@ void LLDrawPoolBump::endDeferredPass(S32 pass)
mShiny = FALSE;
gDeferredBumpProgram.disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
gDeferredBumpProgram.disableTexture(LLViewerShaderMgr::BUMP_MAP);
+ gDeferredBumpProgram.disableTexture(LLViewerShaderMgr::SPECULAR_MAP);
gDeferredBumpProgram.unbind();
gGL.getTexUnit(0)->activate();
}
@@ -864,7 +866,16 @@ void LLDrawPoolBump::renderDeferred(S32 pass)
{
LLDrawInfo& params = **i;
- gDeferredBumpProgram.uniform4fv(LLShaderMgr::SPECULAR_COLOR, 4, (GLfloat*)params.mSpecColor.mV);
+ gDeferredBumpProgram.uniform4f(LLShaderMgr::SPECULAR_COLOR, params.mSpecColor.mV[0], params.mSpecColor.mV[1], params.mSpecColor.mV[2], params.mSpecColor.mV[3]);
+ gDeferredBumpProgram.uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, params.mEnvIntensity);
+
+ if (params.mSpecularMap)
+ {
+ params.mSpecularMap->addTextureStats(params.mVSize);
+ gGL.getTexUnit(spec_channel)->bind(params.mSpecularMap);
+ } else {
+ gGL.getTexUnit(spec_channel)->bind(LLViewerFetchedTexture::sWhiteImagep);
+ }
LLDrawPoolBump::bindBumpMap(params, bump_channel);
pushBatch(params, mask, TRUE);
diff --git a/indra/newview/lldrawpoolbump.h b/indra/newview/lldrawpoolbump.h
index aaf0bdf36f..476b1d41b7 100644
--- a/indra/newview/lldrawpoolbump.h
+++ b/indra/newview/lldrawpoolbump.h
@@ -100,9 +100,8 @@ enum EBumpEffect
BE_NO_BUMP = 0,
BE_BRIGHTNESS = 1,
BE_DARKNESS = 2,
- BE_CUSTOM = 3,
- BE_STANDARD_0 = 4, // Standard must always be the last one
- BE_COUNT = 5
+ BE_STANDARD_0 = 3, // Standard must always be the last one
+ BE_COUNT = 4
};
////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 01cbfafe16..cd84815295 100755
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -2077,9 +2077,11 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
LLFastTimer t(FTM_FACE_GEOM_BINORMAL);
mVertexBuffer->getBinormalStrider(binorm, mGeomIndex, mGeomCount, map_range);
F32* binormals = (F32*) binorm.get();
-
+
+ mVObjp->getVolume()->genBinormals(f);
+
for (S32 i = 0; i < num_vertices; i++)
- {
+ {
LLVector4a binormal;
mat_normal.rotate(vf.mBinormals[i], binormal);
binormal.normalize3fast();
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 2083afdcf5..8a62f22985 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -4672,7 +4672,12 @@ LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,
mGroup(NULL),
mFace(NULL),
mDistance(0.f),
- mDrawMode(LLRender::TRIANGLES)
+ mDrawMode(LLRender::TRIANGLES),
+ mSpecColor(1.0f, 1.0f, 1.0f, 0.5f),
+ mEnvIntensity(0.0f),
+ mAlphaMaskCutoff(0.5f),
+ mDiffuseAlphaMode(0),
+ mMaterialID(NULL)
{
mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset);
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 78c5b3ac53..b8de345a9a 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -4108,12 +4108,10 @@ S32 LLViewerObject::setTETextureCore(const U8 te, const LLUUID& uuid, LLHost hos
S32 LLViewerObject::setTENormalMapCore(const U8 te, const LLUUID& uuid, LLHost host)
{
- LL_INFOS("Materials") << "Maybe normal maps! " << uuid << LL_ENDL;
S32 retval = 0;
//if (uuid != getTE(te)->getMaterialParams()->getNormalID() ||
- //uuid == LLUUID::null)
+ // uuid == LLUUID::null)
{
- LL_INFOS("Materials") << "Normal maps! " << uuid << LL_ENDL;
retval = TEM_CHANGE_TEXTURE;
getTE(te)->getMaterialParams()->setNormalID(uuid);
mTENormalMaps[te] = LLViewerTextureManager::getFetchedTexture(uuid, TRUE, LLViewerTexture::BOOST_BUMP, LLViewerTexture::LOD_TEXTURE, 0, 0, host);
@@ -4128,12 +4126,10 @@ S32 LLViewerObject::setTENormalMapCore(const U8 te, const LLUUID& uuid, LLHost h
S32 LLViewerObject::setTESpecularMapCore(const U8 te, const LLUUID& uuid, LLHost host)
{
- LL_INFOS("Materials") << "Maybe specular maps! " << uuid << LL_ENDL;
S32 retval = 0;
- if (uuid != getTE(te)->getMaterialParams()->getSpecularID() ||
- uuid == LLUUID::null)
+ //if (uuid != getTE(te)->getMaterialParams()->getSpecularID() ||
+ // uuid == LLUUID::null)
{
- LL_INFOS("Materials") << "Specular maps! " << uuid << LL_ENDL;
retval = TEM_CHANGE_TEXTURE;
getTE(te)->getMaterialParams()->setSpecularID(uuid);
mTESpecularMaps[te] = LLViewerTextureManager::getFetchedTexture(uuid, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host);
@@ -4381,6 +4377,7 @@ S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMateri
{
retval = LLPrimitive::setTEMaterialParams(te, pMaterialParams);
setTENormalMap(te, tep->getMaterialParams()->getNormalID());
+ setTESpecularMap(te, tep->getMaterialParams()->getSpecularID());
setChanged(TEXTURE);
if (mDrawable.notNull() && retval)
{
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 8cf22d9808..c9d6a34b8a 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -4172,12 +4172,26 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
specColor.mV[2] = facep->getTextureEntry()->getMaterialParams()->getSpecularLightColor().mV[2] * (1.0 / 255);
specColor.mV[3] = facep->getTextureEntry()->getMaterialParams()->getSpecularLightExponent() * (1.0 / 255);
draw_info->mSpecColor = specColor;
+ LL_INFOS("Materials") << "Specular Color: " << specColor << LL_ENDL;
draw_info->mEnvIntensity = facep->getTextureEntry()->getMaterialParams()->getEnvironmentIntensity() * (1.0 / 255);
draw_info->mAlphaMaskCutoff = facep->getTextureEntry()->getMaterialParams()->getAlphaMaskCutoff() * (1.0 / 255);
draw_info->mDiffuseAlphaMode = facep->getTextureEntry()->getMaterialParams()->getDiffuseAlphaMode();
draw_info->mNormalMap = facep->getViewerObject()->getTENormalMap(facep->getTextureIndex());
draw_info->mSpecularMap = facep->getViewerObject()->getTESpecularMap(facep->getTextureIndex());
}
+ } else {
+ U8 shiny = facep->getTextureEntry()->getShiny();
+ float alpha[4] =
+ {
+ 0.00f,
+ 0.25f,
+ 0.5f,
+ 0.75f
+ };
+ float spec = alpha[shiny];
+ LLVector4 specColor(spec, spec, spec, spec);
+ draw_info->mSpecColor = specColor;
+ draw_info->mEnvIntensity = spec;
}
if (type == LLRenderPass::PASS_ALPHA)
@@ -4631,7 +4645,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
if (gPipeline.canUseWindLightShadersOnObjects()
&& LLPipeline::sRenderBump)
{
- if (te->getBumpmap())
+ if (te->getBumpmap() || te->getMaterialParams() != NULL)
{ //needs normal + binormal
bump_faces.push_back(facep);
}
@@ -5237,7 +5251,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
}
else
{
- if (LLPipeline::sRenderDeferred && LLPipeline::sRenderBump && (te->getBumpmap() || te->getMaterialParams() != NULL))
+ if (LLPipeline::sRenderDeferred && LLPipeline::sRenderBump && (te->getBumpmap() || te->getMaterialParams()))
{ //non-shiny or fullbright deferred bump
registerFace(group, facep, LLRenderPass::PASS_BUMP);
}
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 07246391e3..ea7de6f399 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -1262,31 +1262,26 @@ void LLPipeline::createLUTBuffers()
U32 lightResY = gSavedSettings.getU32("RenderSpecularResY");
F32* ls = new F32[lightResX*lightResY];
//F32 specExp = gSavedSettings.getF32("RenderSpecularExponent"); // Note: only use this when creating new specular lighting functions.
- // Calculate the (normalized) Gaussian specular lookup texture. (with a few tweaks)
+ // Calculate the (normalized) blinn-phong specular lookup texture. (with a few tweaks)
for (U32 y = 0; y < lightResY; ++y)
{
for (U32 x = 0; x < lightResX; ++x)
{
ls[y*lightResX+x] = 0;
F32 sa = (F32) x/(lightResX-1);
- F32 spec = (F32) y/(lightResY);
- F32 n = spec;
+ F32 spec = (F32) y/(lightResY-1);
+ F32 n = spec * spec * 368;
- float angleNormalHalf = acosf(sa);
- float exponent = angleNormalHalf / ((1 - n));
- exponent = -(exponent * exponent);
- spec = expf(exponent);
+ // Nothing special here. Just your typical blinn-phong term.
+ spec = powf(sa, n);
// Apply our normalization function.
- // This is based around the phong normalization function, trading n+2 for n+1 instead.
- // Since we're using a gaussian model here, we actually don't really need as large of an exponent as blinn-phong shading.
- // Instead, we assume that the correct exponent is 8 here.
- // This was achieved through much tweaking to find a decent "middleground" with our specular highlights with the gaussian term.
- // Bigger highlights don't look too soft, smaller highlights don't look too bright, and everything in the middle seems to have a well maintained highlight curvature.
- // There isn't really much theory behind this one. This was done purely to produce a nice and mostly customizable BRDF.
-
- spec = lerpf(spec, spec * (n * 8 + 1) / 4.5, n);
+ // Note: This is the full equation that applies the full normalization curve, not an approximation.
+ // This is fine, given we only need to create our LUT once per buffer initialization.
+ spec *= (((n + 2) * (n + 4)) / (8 * F_PI * (powf(2, -n/2) + n)));
+ // Since we use R16F, we no longer have a dynamic range issue we need to work around here.
+ // Though some older drivers may not like this, newer drivers shouldn't have this problem.
ls[y*lightResX+x] = spec;
}
}