Moderator: Mod Contributor
klauss wrote:Take a peek at the previous post, I've added the right formula
chuck_starchaser wrote:EDIT:
HECK! Shininess itself needs to be limited for light spots!!! Stars are not point light sources!
Higher shininesses than some 20 or 30 should ONLY apply to env mapping.
Got it. Not sure how, though; I'll have to pass star distance from the vp to the fp.klauss wrote:If you do limit shininess, please, make it distance-to-light-dependant?
float limited_shininessMap(float shininess, float specmap)
{
float limit = 50; //fixed for now
float shine = shininessMap(shininess,specmap);
return shine*limit/(shine+limit);
}
specular = 0.6*(1+shininess/10)^1.7
float limited_shininessMap(float shininess, float specmap)
{
float limit = 20; //20^1.7 is 162. 162*0.0117 = 1.9 --enough risk of saturation!
float shine = shininessMap(shininess,specmap);
return shine*limit/(shine+limit);
}
float shininess_to_brightness(float shininess)
{
//specular = 1.0 / (1.7/(1+shininess/10))^1.7;
//specular = 0.588*(1+shininess/10)^1.7
//but the 1+ term is dubious. If we get rid of it, we get
//specular = 0.588*(shininess/10)^1.7 which simplifies to
//specular = 0.011736837 * shininess^1.7
return 0.011736837 * pow( shininess, 1.7 );
}
float limited_shininessMap(float shininess, float specmap)
{
float limit = 30; //30^1.7 is 324. 324*0.005 = 1.62 --enough risk of saturation!
float shine = shininessMap(shininess,specmap);
return shine*limit/(shine+limit);
}
float shininess_to_brightness(float shininess)
{
//specular = 1.0 / (1.7/(1+shininess/10))^1.7;
//specular = 0.588*(1+shininess/10)^1.7
//but the 1+ term is dubious. If we get rid of it, we get
//specular = 0.588*(shininess/10)^1.7 which simplifies to
//specular = 0.011736837 * shininess^1.7 but make that .005...
return 0.005 * pow( shininess, 1.7 );
}
float lightspot_brightness( float shininess, float specmap )
{
return limited_shininessMap( shininess, specmap ) * shininess_to_brightness( shininess );
}
void lightingLight(
in vec3 light, in vec3 normal, in vec3 vnormal, in vec3 eye, in vec3 reflection,
in vec4 lightDiffuse, in float lightAtt,
in vec4 diffusemap, in vec4 specmap, in float shininess,
in vec4 ambientProduct,
inout vec3 diffuse, inout vec3 specular)
{
float NdotL = dot(normal,light);
float VNdotL= dot(vnormal,light);
float RdotL = dot(reflection,light);
float selfshadow = selfshadowStep(VNdotL);
diffuse += selfshadow * clamp(NdotL,0.0,1.0) * lightDiffuse.rgb * lightAtt ;
specular += pow(clamp(RdotL,0.0,1.0), lightspot_brightness(shininess,specmap)) * lightDiffuse.rgb * lightAtt;
}
//float selfshadowStep(float VNdotL) { return step(0.0,VNdotL); } // fast but hard selfshadow function
float selfshadowStep(float VNdotL) { return smoothstep(0.0,0.25,VNdotL); } // costly but soft and nice selfshadow function
float VNdotL= dot(vnormal,light);
vec3 vnormal=iNormal;
// Retrieve normals
vec3 iNormal=gl_TexCoord[1].xyz;
vec3 iTangent=gl_TexCoord[2].xyz;
vec3 iBinormal=gl_TexCoord[3].xyz;
chuck_starchaser wrote:If we wanted to make it be a paint, we'd probably want even lower specularity, but much higher shininess...
...plus fresnel...
Next shader will be able to do that.
uniform int light_enabled[gl_MaxLights];
uniform int max_light_enabled;
uniform sampler2D diffuseMap;
uniform sampler2D envMap;
uniform sampler2D specMap;
uniform sampler2D glowMap;
uniform sampler2D normalMap;
uniform sampler2D damageMap;
uniform sampler2D detail0Map;
uniform sampler2D detail1Map;
uniform vec4 cloaking;
uniform vec4 damage;
uniform vec4 envColor;
vec3 matmul(vec3 tangent, vec3 binormal, vec3 normal,vec3 lightVec) {
return vec3(dot(lightVec,tangent),dot(lightVec,binormal),dot(lightVec,normal));
}
vec3 imatmul(vec3 tangent, vec3 binormal, vec3 normal,vec3 lightVec) {
return lightVec.xxx*tangent+lightVec.yyy*binormal+lightVec.zzz*normal;
}
vec2 EnvMapGen(vec3 f) {
float fzp1=f.z+1.0;
float m=2.0*sqrt(f.x*f.x+f.y*f.y+(fzp1)*(fzp1));
return vec2(f.x/m+.5,f.y/m+.5);
}
float bias(float f){ return f*0.5+0.5; }
vec2 bias(vec2 f) { return f*0.5+vec2(0.5); }
vec3 bias(vec3 f) { return f*0.5+vec3(0.5); }
vec4 bias(vec4 f) { return f*0.5+vec4(0.5); }
float expand(float f){ return f*2.0-1.0; }
vec2 expand(vec2 f) { return f*2.0-vec2(1.0); }
vec3 expand(vec3 f) { return f*2.0-vec3(1.0); }
vec4 expand(vec4 f) { return f*2.0-vec4(1.0); }
float lerp(float f, float a, float b){return (1.0-f)*a+f*b; }
vec2 lerp(float f, vec2 a, vec2 b) { return (1.0-f)*a+f*b; }
vec3 lerp(float f, vec3 a, vec3 b) { return (1.0-f)*a+f*b; }
vec4 lerp(float f, vec4 a, vec4 b) { return (1.0-f)*a+f*b; }
//float selfshadowStep(float VNdotL) { return step(0.0,VNdotL); } // fast but hard selfshadow function
//float selfshadowStep(float VNdotL) { return smoothstep(0.0,0.25,VNdotL); } // costly but soft and nice selfshadow function
//float shininessMap(float shininess, vec4 specmap) { return clamp(specmap.a*shininess,1.0,255.0); } // alpha-based shininess modulation
float shininessMap(float shininess, vec4 specmap) // luma-based shininess modulation
{
float3 temp = specmap.rgb;
temp *= specmap.rgb;
temp *= specmap.rgb;
temp.b = (temp.r+temp.g)*0.75;
return clamp( temp.b*shininess, 1.0, 255.0 );
}
float shininess2Lod(float shininess) { return max(0.0,7.0-log2(shininess+1.0))+3.0*(1.0+envColor.a); }
float limited_shininessMap(float shininess, float specmap)
{
float limit = 30; //30^1.7 is 324. 324*0.005 = 1.62 --enough risk of saturation!
float shine = shininessMap(shininess,specmap);
return (shine*limit)/(shine+limit);
}
float shininess_to_brightness(float shininess)
{
return 0.0025 * shininess * shininess;
}
float lightspot_brightness( float shininess, float specmap )
{
return limited_shininessMap( shininess, specmap ) * shininess_to_brightness( shininess );
}
void lightingLight(
in vec3 light, in vec3 normal, in vec3 vnormal, in vec3 eye, in vec3 reflection,
in vec4 lightDiffuse, in float lightAtt,
in vec4 diffusemap, in vec4 specmap, in float shininess,
in vec4 ambientProduct,
inout vec3 diffuse, inout vec3 specular)
{
float NdotL = dot(normal,light);
float VNdotL= dot(vnormal,light);
float RdotL = dot(reflection,light);
//float selfshadow = selfshadowStep(VNdotL);
diffuse += clamp(NdotL,0.0,1.0) * lightDiffuse.rgb * lightAtt ;
specular += pow(clamp(RdotL,0.0,1.0), lightspot_brightness(shininess,specmap)) * lightDiffuse.rgb * lightAtt;
}
#define lighting(name, lightno_gl, lightno_tex) \
void name( \
in vec3 normal, in vec3 vnormal, in vec3 eye, in vec3 reflection, \
in vec4 diffusemap, in vec4 specmap, \
inout vec3 diffuse, inout vec3 specular) \
{ \
lightingLight( \
normalize(gl_TexCoord[lightno_tex].xyz), normal, vnormal, eye, reflection, \
gl_FrontLightProduct[lightno_gl].diffuse, \
gl_TexCoord[lightno_tex].w, \
diffusemap, specmap, gl_FrontMaterial.shininess, \
gl_FrontLightProduct[lightno_gl].ambient, \
diffuse, specular); \
}
lighting(lighting0, 0, 5)
lighting(lighting1, 1, 6)
vec3 lightingClose(in vec3 diffuse, in vec3 specular, in vec3 ambient, in vec4 diffusemap, in vec4 specmap)
{
return (diffuse + ambient) * diffusemap.rgb + specular * specmap.rgb;
}
vec3 envMapping(in vec3 reflection, in float gloss, in vec4 specmap)
{
float envLod = shininess2Lod(gloss);//shininessMap(shininess,specmap));
return texture2DLod(envMap, EnvMapGen(reflection), envLod).rgb * specmap.rgb * vec3(2.0);
}
void main()
{
// Retrieve normals
vec3 iNormal=gl_TexCoord[1].xyz;
vec3 iTangent=gl_TexCoord[2].xyz;
vec3 iBinormal=gl_TexCoord[3].xyz;
vec3 vnormal=iNormal;
//vec3 normal=normalize(imatmul(iTangent,iBinormal,iNormal,expand(texture2D(normalMap,gl_TexCoord[0].xy).yxz)*vec3(-1.0,1.0,1.0)));
vec3 normal=normalize(imatmul(iTangent,iBinormal,iNormal,expand(texture2D(normalMap,gl_TexCoord[0].xy).wyz)));
// Other vectors
vec3 eye = gl_TexCoord[4].xyz;
vec3 reflection = -reflect(eye,normal);
// Init lighting accumulators
vec3 diffuse = vec3(0.0);
vec3 specular= vec3(0.0);
vec3 ambient = vec3(0.0);
// Sample textures
vec4 damagecolor = texture2D(damageMap , gl_TexCoord[0].xy);
vec4 diffusecolor= texture2D(diffuseMap, gl_TexCoord[0].xy);
vec4 speccolor = texture2D(specMap , gl_TexCoord[0].xy);
vec4 glowcolor = texture2D(glowMap , gl_TexCoord[0].xy);
//sanity enforcement:
float temp = 1.0 - max( diffusecolor.r, max( diffusecolor.g, diffusecolor.b ) );
speccolor.r = min( speccolor.r, temp );
speccolor.g = min( speccolor.g, temp );
speccolor.b = min( speccolor.b, temp );
vec4 diffusemap = lerp(damage.x, diffusecolor, damagecolor);
vec4 specmap = speccolor;
float specdamage = clamp(1.0 - dot(damagecolor.xyz,vec3(1.0/3.0)) * damage.x * 2.0, 0.0, 1.0);
specmap.rgb *= specdamage;
specmap.a *= bias(specdamage);
float gloss = shininessMap(gl_FrontMaterial.shininess,specmap);
// Do lighting for every active light
if (light_enabled[0] != 0)
lighting0(normal, vnormal, eye, reflection, diffusemap, specmap, diffuse, specular);
if (light_enabled[1] != 0)
lighting1(normal, vnormal, eye, reflection, diffusemap, specmap, diffuse, specular);
vec4 result;
result.rgb = lightingClose(diffuse, specular, ambient, diffusemap, specmap)
+ glowcolor.rgb
+ envMapping(reflection,gloss,specmap);
result.a = diffusemap.a;
result *= cloaking.rrrg;
gl_FragColor = result;
}
klauss wrote:Chuck, don't change the 1.7, it was a hand-picked fit for the mathematically correct function. Doing so would sacrifice the correctness of lower shininess values. Rather, I believe you want to raise the limit on shininess.
Clamping is non-linear, and would look absolutely horrible. My function is a very smooth function yielding "lower of two numbers", namely "product over sum". The formula comes from electronics. If you have two resistors in parallel, total resistance is the product over the sum of their resistances. If the two are equal, you get half --e.g. 7x7 / (7+7) = 3.5; so when the input shininess is 30 the output shininess is 15.BTW: I don't get how that limiting function you use works. I would have expected something like clamp().
The selfshadow term is intended to black out specularity when the geometry is facing away from the light. Right now, there are two things that control the normals (and thus specular highlights): vertex normals, and the normalmap.
Normal mapping is supposed to model small features on the surface that change normal direction. They're not supposed to be big enough to shadow anything. Vertex normal captures big, gross geometry features. When vertex normals face away from the light, it's not supposed that normalmapped features will change the fact that they're in the shadowed side of the model. So, the term does that: when a pixel is in the shadowed side of a model (vertex normal pointing away from the light). no amount of normalmapping can create any lighting. So, selfshadow darkens everything. The function just does that smoothly, because doing it hardly (ie: (VNdotL > 0) ? 1 : 0 ) simply looks weird.
Perhaps it's too soft. Try making it harder, decreasing the 0.25.
I've no idea what that is.BTW: Beware of misim(ex)ported vertex normals. Weird lighting tends to be the result of that.
float selfshadowStep(float VNdotL) { return smoothstep(-0.0625,0.0625,VNdotL); }
float selfshadowStep(float VNdotL) { return smoothstep(-0.0625,0.0625,VNdotL); }
uniform int light_enabled[gl_MaxLights];
uniform int max_light_enabled;
uniform sampler2D diffuseMap;
uniform sampler2D envMap;
uniform sampler2D specMap;
uniform sampler2D glowMap;
uniform sampler2D normalMap;
uniform sampler2D damageMap;
uniform sampler2D detail0Map;
uniform sampler2D detail1Map;
uniform vec4 cloaking;
uniform vec4 damage;
uniform vec4 envColor;
vec3 matmul(vec3 tangent, vec3 binormal, vec3 normal,vec3 lightVec) {
return vec3(dot(lightVec,tangent),dot(lightVec,binormal),dot(lightVec,normal));
}
vec3 imatmul(vec3 tangent, vec3 binormal, vec3 normal,vec3 lightVec) {
return lightVec.xxx*tangent+lightVec.yyy*binormal+lightVec.zzz*normal;
}
vec2 EnvMapGen(vec3 f) {
float fzp1=f.z+1.0;
float m=2.0*sqrt(f.x*f.x+f.y*f.y+(fzp1)*(fzp1));
return vec2(f.x/m+.5,f.y/m+.5);
}
float bias(float f){ return f*0.5+0.5; }
vec2 bias(vec2 f) { return f*0.5+vec2(0.5); }
vec3 bias(vec3 f) { return f*0.5+vec3(0.5); }
vec4 bias(vec4 f) { return f*0.5+vec4(0.5); }
float expand(float f){ return f*2.0-1.0; }
vec2 expand(vec2 f) { return f*2.0-vec2(1.0); }
vec3 expand(vec3 f) { return f*2.0-vec3(1.0); }
vec4 expand(vec4 f) { return f*2.0-vec4(1.0); }
float lerp(float f, float a, float b){return (1.0-f)*a+f*b; }
vec2 lerp(float f, vec2 a, vec2 b) { return (1.0-f)*a+f*b; }
vec3 lerp(float f, vec3 a, vec3 b) { return (1.0-f)*a+f*b; }
vec4 lerp(float f, vec4 a, vec4 b) { return (1.0-f)*a+f*b; }
//float selfshadowStep(float VNdotL) { return step(0.0,VNdotL); } // fast but hard selfshadow function
float selfshadowStep(float VNdotL) { return smoothstep(-0.0625,0.125,VNdotL); } // costly but soft and nice selfshadow function
//float shininessMap(float shininess, vec4 specmap) { return clamp(specmap.a*shininess,1.0,255.0); } // alpha-based shininess modulation
float shininessMap(float shininess, vec4 specmap) // luma-based shininess modulation
{
float3 temp = specmap.rgb;
temp *= specmap.rgb;
temp *= specmap.rgb;
temp.b = (temp.r+temp.g)*0.75;
return clamp( temp.b*shininess, 1.0, 255.0 );
}
float shininess2Lod(float shininess) { return max(0.0,7.0-log2(shininess+1.0))+3.0*(1.0+envColor.a); }
float limited_shininessMap(float shininess, float specmap)
{
float limit = 50; //50^2 is 2500. 2500*0.001 = 2.5 --enough risk of saturation!
float shine = shininessMap(shininess,specmap);
return (shine*limit)/(shine+limit);
}
float shininess_to_brightness(float shininess)
{
return 0.001 * shininess * shininess;
}
float lightspot_brightness( float shininess, float specmap )
{
return limited_shininessMap( shininess, specmap ) * shininess_to_brightness( shininess );
}
void lightingLight(
in vec3 light, in vec3 normal, in vec3 vnormal, in vec3 eye, in vec3 reflection,
in vec4 lightDiffuse, in float lightAtt,
in vec4 diffusemap, in vec4 specmap, in float shininess,
in vec4 ambientProduct,
inout vec3 diffuse, inout vec3 specular)
{
float NdotL = dot(normal,light);
float VNdotL= dot(vnormal,light);
float RdotL = dot(reflection,light);
float selfshadow = selfshadowStep(VNdotL);
diffuse += selfshadow * clamp(NdotL,0.0,1.0) * lightDiffuse.rgb * lightAtt ;
specular += selfshadow * pow(clamp(RdotL,0.0,1.0), lightspot_brightness(shininess,specmap)) * lightDiffuse.rgb * lightAtt;
}
#define lighting(name, lightno_gl, lightno_tex) \
void name( \
in vec3 normal, in vec3 vnormal, in vec3 eye, in vec3 reflection, \
in vec4 diffusemap, in vec4 specmap, \
inout vec3 diffuse, inout vec3 specular) \
{ \
lightingLight( \
normalize(gl_TexCoord[lightno_tex].xyz), normal, vnormal, eye, reflection, \
gl_FrontLightProduct[lightno_gl].diffuse, \
gl_TexCoord[lightno_tex].w, \
diffusemap, specmap, gl_FrontMaterial.shininess, \
gl_FrontLightProduct[lightno_gl].ambient, \
diffuse, specular); \
}
lighting(lighting0, 0, 5)
lighting(lighting1, 1, 6)
vec3 lightingClose(in vec3 diffuse, in vec3 specular, in vec3 ambient, in vec4 diffusemap, in vec4 specmap)
{
return (diffuse + ambient) * diffusemap.rgb + specular * specmap.rgb;
}
vec3 envMapping(in vec3 reflection, in float gloss, in vec4 specmap)
{
float envLod = shininess2Lod(gloss);//shininessMap(shininess,specmap));
return texture2DLod(envMap, EnvMapGen(reflection), envLod).rgb * specmap.rgb * vec3(2.0);
}
void main()
{
// Retrieve normals
vec3 iNormal=gl_TexCoord[1].xyz;
vec3 iTangent=gl_TexCoord[2].xyz;
vec3 iBinormal=gl_TexCoord[3].xyz;
vec3 vnormal=iNormal;
//vec3 normal=normalize(imatmul(iTangent,iBinormal,iNormal,expand(texture2D(normalMap,gl_TexCoord[0].xy).yxz)*vec3(-1.0,1.0,1.0)));
vec3 normal=normalize(imatmul(iTangent,iBinormal,iNormal,expand(texture2D(normalMap,gl_TexCoord[0].xy).wyz)));
// Other vectors
vec3 eye = gl_TexCoord[4].xyz;
vec3 reflection = -reflect(eye,normal);
// Init lighting accumulators
vec3 diffuse = vec3(0.0);
vec3 specular= vec3(0.0);
vec3 ambient = vec3(0.0);
// Sample textures
vec4 damagecolor = texture2D(damageMap , gl_TexCoord[0].xy);
vec4 diffusecolor= texture2D(diffuseMap, gl_TexCoord[0].xy);
vec4 speccolor = texture2D(specMap , gl_TexCoord[0].xy);
vec4 glowcolor = texture2D(glowMap , gl_TexCoord[0].xy);
//sanity enforcement:
float temp = 1.0 - max( diffusecolor.r, max( diffusecolor.g, diffusecolor.b ) );
speccolor.r = min( speccolor.r, temp );
speccolor.g = min( speccolor.g, temp );
speccolor.b = min( speccolor.b, temp );
vec4 diffusemap = lerp(damage.x, diffusecolor, damagecolor);
vec4 specmap = speccolor;
float specdamage = clamp(1.0 - dot(damagecolor.xyz,vec3(1.0/3.0)) * damage.x * 2.0, 0.0, 1.0);
specmap.rgb *= specdamage;
specmap.a *= bias(specdamage);
float gloss = shininessMap(gl_FrontMaterial.shininess,specmap);
// Do lighting for every active light
if (light_enabled[0] != 0)
lighting0(normal, vnormal, eye, reflection, diffusemap, specmap, diffuse, specular);
if (light_enabled[1] != 0)
lighting1(normal, vnormal, eye, reflection, diffusemap, specmap, diffuse, specular);
vec4 result;
result.rgb = lightingClose(diffuse, specular, ambient, diffusemap, specmap)
+ glowcolor.rgb
+ envMapping(reflection,gloss,specmap);
result.a = diffusemap.a;
result *= cloaking.rrrg;
gl_FragColor = result;
}
float NdotL = dot( N * L );
float temp = 1 - NdotL*NdotL
//temp is now a sine wave twice the frequency of NdotL, shifted positive
temp = temp * temp;
temp = temp * temp;
temp = temp * temp;
//now temp shows a narrower pulse at each zero-crossing of NdotL
temp *= NdotL;
//This caused the pulses to be turned into wavelets with zero-crossings
//in phase with NdotL
float smootherNdotL = NdotL - (K * temp);
//With the right value for K, we got zero-cross distortions on NdotL that
//make its zero-crossings shallower.
void lightingLight(
in vec3 light, in vec3 normal, in vec3 vnormal, in vec3 eye, in vec3 reflection,
in vec4 lightDiffuse, in float lightAtt,
in vec4 diffusemap, in vec4 specmap, in float shininess,
in vec4 ambientProduct,
inout vec3 diffuse, inout vec3 specular)
{
float NdotL = dot(normal,light);
float VNdotL= dot(vnormal,light);
float s = 1.0 - (NdotL*NdotL);
float RdotL = dot(reflection,light);
float selfshadow = selfshadowStep(VNdotL);
float temp = clamp( NdotL - (0.94 * s * s * s * s * NdotL) + 0.005, 0.0, 1.01 );
specular += ( selfshadow * pow(clamp(RdotL,0.0,1.0), lightspot_brightness(shininess,specmap)) * lightDiffuse.rgb * lightAtt );
diffuse += ( selfshadow * temp * lightDiffuse.rgb * lightAtt );
}
void lightingLight(
in vec3 light, in vec3 normal, in vec3 vnormal, in vec3 eye, in vec3 reflection,
in vec4 lightDiffuse, in float lightAtt,
in vec4 diffusemap, in vec4 specmap, in float shininess,
in vec4 ambientProduct,
inout vec3 diffuse, inout vec3 specular)
{
float VNdotLx4= clamp( 4.0 * dot(vnormal,light), 0.0, 1.0 ); // <-***** modified
float NdotL = clamp( dot(normal,light), -1.0, VNdotLx4 ); // <-***** modified
float RdotL = clamp( dot(reflection,light), 0.0, VNdotLx4 ); // <-***** modified
float s = 1.0 - (NdotL*NdotL); //soft penumbra stuff
//float selfshadow = selfshadowStep(VNdotL); // <-***** removed
float temp = clamp( NdotL - (0.94 * s * s * s * s * NdotL) + 0.005, 0.0, 1.01 ); //soft penumbra stuff
specular += ( pow( RdotL, lightspot_brightness(shininess,specmap)) * lightDiffuse.rgb * lightAtt ); // <-***** modified
diffuse += ( temp * lightDiffuse.rgb * lightAtt );
}
uniform int light_enabled[gl_MaxLights];
uniform int max_light_enabled;
uniform sampler2D diffuseMap;
uniform sampler2D envMap;
uniform sampler2D specMap;
uniform sampler2D glowMap;
uniform sampler2D normalMap;
uniform sampler2D damageMap;
uniform sampler2D detail0Map;
uniform sampler2D detail1Map;
uniform vec4 cloaking;
uniform vec4 damage;
uniform vec4 envColor;
vec3 matmul(vec3 tangent, vec3 binormal, vec3 normal,vec3 lightVec) {
return vec3(dot(lightVec,tangent),dot(lightVec,binormal),dot(lightVec,normal));
}
vec3 imatmul(vec3 tangent, vec3 binormal, vec3 normal,vec3 lightVec) {
return lightVec.xxx*tangent+lightVec.yyy*binormal+lightVec.zzz*normal;
}
vec2 EnvMapGen(vec3 f) {
float fzp1=f.z+1.0;
float m=2.0*sqrt(f.x*f.x+f.y*f.y+(fzp1)*(fzp1));
return vec2(f.x/m+.5,f.y/m+.5);
}
float bias(float f){ return f*0.5+0.5; }
vec2 bias(vec2 f) { return f*0.5+vec2(0.5); }
vec3 bias(vec3 f) { return f*0.5+vec3(0.5); }
vec4 bias(vec4 f) { return f*0.5+vec4(0.5); }
float expand(float f){ return f*2.0-1.0; }
vec2 expand(vec2 f) { return f*2.0-vec2(1.0); }
vec3 expand(vec3 f) { return f*2.0-vec3(1.0); }
vec4 expand(vec4 f) { return f*2.0-vec4(1.0); }
float lerp(float f, float a, float b){return (1.0-f)*a+f*b; }
vec2 lerp(float f, vec2 a, vec2 b) { return (1.0-f)*a+f*b; }
vec3 lerp(float f, vec3 a, vec3 b) { return (1.0-f)*a+f*b; }
vec4 lerp(float f, vec4 a, vec4 b) { return (1.0-f)*a+f*b; }
//float shininessMap(float shininess, vec4 specmap) { return clamp(specmap.a*shininess,1.0,255.0); } // alpha-based shininess modulation
float shininessMap(float shininess, vec4 specmap) // luma-based shininess modulation
{
float3 temp = specmap.rgb;
temp *= specmap.rgb;
temp *= specmap.rgb;
temp.b = (temp.r+temp.g)*0.75;
return clamp( temp.b*shininess, 1.0, 255.0 );
}
float shininess2Lod(float shininess) { return max(0.0,7.0-log2(shininess+1.0))+3.0*(1.0+envColor.a); }
float limited_shininessMap(float shininess, float specmap)
{
float limit = 50; //50^2 is 2500. 2500*0.001 = 2.5 --enough risk of saturation!
float shine = shininessMap(shininess,specmap);
return (shine*limit)/(shine+limit);
}
float shininess_to_brightness(float shininess)
{
return 0.001 * shininess * shininess;
}
float lightspot_brightness( float shininess, float specmap )
{
return limited_shininessMap( shininess, specmap ) * shininess_to_brightness( shininess );
}
void lightingLight(
in vec3 light, in vec3 normal, in vec3 vnormal, in vec3 eye, in vec3 reflection,
in vec4 lightDiffuse, in float lightAtt,
in vec4 diffusemap, in vec4 specmap, in float shininess,
in vec4 ambientProduct,
inout vec3 diffuse, inout vec3 specular)
{
float VNdotLx4= clamp( 4.0 * dot(vnormal,light), 0.0, 1.0 ); // <-***** modified
float NdotL = clamp( dot(normal,light), -1.0, VNdotLx4 ); // <-***** modified
float RdotL = clamp( dot(reflection,light), 0.0, VNdotLx4 ); // <-***** modified
float s = 1.0 - (NdotL*NdotL); //soft penumbra stuff
//float selfshadow = selfshadowStep(VNdotL); // <-***** removed
float temp = clamp( NdotL - (0.94 * s * s * s * s * NdotL) + 0.005, 0.0, 1.01 ); //soft penumbra stuff
specular += ( pow( RdotL, lightspot_brightness(shininess,specmap)) * lightDiffuse.rgb * lightAtt ); // <-***** modified
diffuse += ( temp * lightDiffuse.rgb * lightAtt );
}
#define lighting(name, lightno_gl, lightno_tex) \
void name( \
in vec3 normal, in vec3 vnormal, in vec3 eye, in vec3 reflection, \
in vec4 diffusemap, in vec4 specmap, \
inout vec3 diffuse, inout vec3 specular) \
{ \
lightingLight( \
normalize(gl_TexCoord[lightno_tex].xyz), normal, vnormal, eye, reflection, \
gl_FrontLightProduct[lightno_gl].diffuse, \
gl_TexCoord[lightno_tex].w, \
diffusemap, specmap, gl_FrontMaterial.shininess, \
gl_FrontLightProduct[lightno_gl].ambient, \
diffuse, specular); \
}
lighting(lighting0, 0, 5)
lighting(lighting1, 1, 6)
vec3 lightingClose(in vec3 diffuse, in vec3 specular, in vec3 ambient, in vec4 diffusemap, in vec4 specmap)
{
return (diffuse + ambient) * diffusemap.rgb + specular * specmap.rgb;
}
vec3 envMapping(in vec3 reflection, in float gloss, in vec4 specmap)
{
float envLod = shininess2Lod(gloss);//shininessMap(shininess,specmap));
return texture2DLod(envMap, EnvMapGen(reflection), envLod).rgb * specmap.rgb * vec3(2.0);
}
void main()
{
// Retrieve normals
vec3 iNormal=gl_TexCoord[1].xyz;
vec3 iTangent=gl_TexCoord[2].xyz;
vec3 iBinormal=gl_TexCoord[3].xyz;
vec3 vnormal=iNormal;
//vec3 normal=normalize(imatmul(iTangent,iBinormal,iNormal,expand(texture2D(normalMap,gl_TexCoord[0].xy).yxz)*vec3(-1.0,1.0,1.0)));
vec3 normal=normalize(imatmul(iTangent,iBinormal,iNormal,expand(texture2D(normalMap,gl_TexCoord[0].xy).wyz)));
// Other vectors
vec3 eye = gl_TexCoord[4].xyz;
vec3 reflection = -reflect(eye,normal);
// Init lighting accumulators
vec3 diffuse = vec3(0.0);
vec3 specular= vec3(0.0);
vec3 ambient = vec3(0.0);
// Sample textures
vec4 damagecolor = texture2D(damageMap , gl_TexCoord[0].xy);
vec4 diffusecolor= texture2D(diffuseMap, gl_TexCoord[0].xy);
vec4 speccolor = texture2D(specMap , gl_TexCoord[0].xy);
vec4 glowcolor = texture2D(glowMap , gl_TexCoord[0].xy);
//sanity enforcement:
float temp = 1.0 - max( diffusecolor.r, max( diffusecolor.g, diffusecolor.b ) );
speccolor.r = min( speccolor.r, temp );
speccolor.g = min( speccolor.g, temp );
speccolor.b = min( speccolor.b, temp );
vec4 diffusemap = lerp(damage.x, diffusecolor, damagecolor);
vec4 specmap = speccolor;
float specdamage = clamp(1.0 - dot(damagecolor.xyz,vec3(1.0/3.0)) * damage.x * 2.0, 0.0, 1.0);
specmap.rgb *= specdamage;
specmap.a *= bias(specdamage);
float gloss = shininessMap(gl_FrontMaterial.shininess,specmap);
// Do lighting for every active light
if (light_enabled[0] != 0)
lighting0(normal, vnormal, eye, reflection, diffusemap, specmap, diffuse, specular);
if (light_enabled[1] != 0)
lighting1(normal, vnormal, eye, reflection, diffusemap, specmap, diffuse, specular);
vec4 result;
result.rgb = lightingClose(diffuse, specular, ambient, diffusemap, specmap)
+ glowcolor.rgb
+ envMapping(reflection,gloss,specmap);
result.a = diffusemap.a;
result *= cloaking.rrrg;
gl_FragColor = result;
}
Users browsing this forum: No registered users and 1 guest