Specular map support. This is the vast majority of the material parameters implemented at this point for opaque geometry.
parent
66a01ba4c5
commit
aa1befd689
|
|
@ -1126,6 +1126,7 @@ void LLShaderMgr::initAttribsAndUniforms()
|
|||
mReservedUniforms.push_back("texture_gamma");
|
||||
|
||||
mReservedUniforms.push_back("specular_color");
|
||||
mReservedUniforms.push_back("env_intensity");
|
||||
|
||||
llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS);
|
||||
|
||||
|
|
|
|||
|
|
@ -169,6 +169,7 @@ public:
|
|||
TEXTURE_GAMMA,
|
||||
|
||||
SPECULAR_COLOR,
|
||||
ENVIRONMENT_INTENSITY,
|
||||
|
||||
END_RESERVED_UNIFORMS
|
||||
} eGLSLReservedUniforms;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue