Hard Light Productions Forums

Modding, Mission Design, and Coding => The Modding Workshop => Topic started by: Bobboau on August 22, 2011, 03:12:45 am

Title: Totaly Metal
Post by: Bobboau on August 22, 2011, 03:12:45 am
ok, so this isn't particularly great, but I just made a quick and dirty unoptimized, buggy, hack implementation of anisotropic reflection, it's parameters are sort of hack-grabed from the spec map, but it should be good enough to give you an idea of how it works.

attached file goes in the effects directory, rename the extension from txt to sdr.

if you wish to tinker with it the _AlphaX/Y variables are a good place to mess with it, right now if there is a spec map it pulls those from the red and green components of the spec map, a more interesting place to potentially pull values from would be the unused red and blue channels of the normal map, or you could just set them to a constant so you get an idea what they do.

[attachment deleted by ninja]
Title: Re: Totaly Metal
Post by: MetalDestroyer on August 22, 2011, 04:42:09 am
It's definitly very good, but is there a way to know if you have also in the main-f.sdr modification from Valathill about cloak effect or shader effect ?

Here some comparison screenshots:
With previous main-f:
(http://cloud.steampowered.com/ugc/576679876823041518/E3AFDC6D5C6AAEBC04EF087B8CEF6AAB1A26941C/)

With your modified main-f:
(http://cloud.steampowered.com/ugc/576679876823025745/2619ABDC09BACFB816AD7A8B915F28A1A82AE8E2/)
Title: Re: Totaly Metal
Post by: Zacam on August 22, 2011, 04:45:08 am

Hmmm. This is actually a really cool feature.

Though, you have an undefined dotNL in the shader, did you perhaps mean to use dotHN instead? (around line 153)

It's also not good to call to the same uniform multiple times directly, and I see you didn't do that, so definitely excellent work on that regard.

I'll play around with this some and get back to here if there are any significant changes.

MetalDestroyer: I'm currently merging the suggested modifications into a current shader, so watch the following spaces for an update.

Edit: Update
Code: (main-f.sdr) [Select]
#ifdef FLAG_LIGHT
uniform int n_lights;
#endif

#ifdef FLAG_DIFFUSE_MAP
uniform sampler2D sBasemap;
#endif

#ifdef FLAG_GLOW_MAP
uniform sampler2D sGlowmap;
#endif

#ifdef FLAG_SPEC_MAP
uniform sampler2D sSpecmap;
#endif

#ifdef FLAG_ENV_MAP
uniform samplerCube sEnvmap;
uniform bool alpha_spec;
varying vec3 envReflect;
#endif

#ifdef FLAG_NORMAL_MAP
uniform sampler2D sNormalmap;
varying mat3 tbnMatrix;
#endif

#ifdef FLAG_FOG
varying float fogDist;
#endif

#ifdef FLAG_ANIMATED
uniform sampler2D sFramebuffer;
uniform int effect_num;
uniform float anim_timer;
uniform float vpwidth;
uniform float vpheight;
#endif

varying vec4 position;
varying vec3 lNormal;

#if SHADER_MODEL == 2
  #define MAX_LIGHTS 2
#else
  #define MAX_LIGHTS 8
#endif

#define SPEC_INTENSITY_POINT 5.3 // Point light
#define SPEC_INTENSITY_DIRECTIONAL 3.0 // Directional light
#define SPECULAR_FACTOR 1.75
#define SPECULAR_ALPHA 0.1
#define SPEC_FACTOR_NO_SPEC_MAP 0.6
#define ENV_ALPHA_FACTOR 0.3
#define GLOW_MAP_INTENSITY 1.5
#define AMBIENT_LIGHT_BOOST 1.0

void main()
{
vec3 eyeDir = vec3(normalize(-position).xyz); // Camera is at (0,0,0) in ModelView space
vec4 lightAmbientDiffuse = vec4(0.0, 0.0, 0.0, 1.0);
vec4 lightDiffuse = vec4(0.0, 0.0, 0.0, 1.0);
vec4 lightAmbient = vec4(0.0, 0.0, 0.0, 1.0);
vec4 lightSpecular = vec4(0.0, 0.0, 0.0, 1.0);
vec2 texCoord = gl_TexCoord[0].xy;
 #ifdef FLAG_SPEC_MAP
vec4 specColour = texture2D(sSpecmap, texCoord);
 #endif

 #ifdef FLAG_LIGHT
  #ifdef FLAG_NORMAL_MAP
// Normal map - convert from DXT5nm
vec3 normal;
normal.rg = (texture2D(sNormalmap, texCoord).ag * 2.0) - 1.0;
   #ifdef FLAG_ENV_MAP
vec3 envOffset = vec3(0.0);
envOffset.xy = normal.xy;
vec3 envReflectNM = envReflect + envOffset;
vec4 envColour = textureCube(sEnvmap, envReflectNM);
lightDiffuse = envColour * ENV_ALPHA_FACTOR;
   #endif
normal.b = sqrt(1.0 - dot(normal.rg, normal.rg));
normal = tbnMatrix * normal;
float norm = length(normal);
// prevent breaking of normal maps
if (length(normal) > 0.0)
normal /= norm ;
else
normal = tbnMatrix * vec3(0.0, 0.0, 1.0);
  #else
vec3 normal = lNormal;
   #ifdef FLAG_ENV_MAP
vec4 envColour = textureCube(sEnvmap, envReflect);
lightDiffuse = envColour * ENV_ALPHA_FACTOR;
   #endif
  #endif

vec3 lightDir;
lightAmbient = gl_FrontMaterial.emission + (gl_LightModel.ambient * gl_FrontMaterial.ambient);
float dist;

#pragma optionNV unroll all
for (int i = 0; i < MAX_LIGHTS; ++i) {
  #if SHADER_MODEL > 2
if (i > n_lights)
break;
  #endif

float specularIntensity = 1.0;
float attenuation = 1.0;

// Attenuation and light direction
  #if SHADER_MODEL > 2
if (gl_LightSource[i].position.w == 1.0) {
  #else
if (gl_LightSource[i].position.w == 1.0 && i != 0) {
  #endif
// Positional light source
dist = distance(gl_LightSource[i].position.xyz, position.xyz);
lightDir = (gl_LightSource[i].position.xyz - position.xyz);

  #if SHADER_MODEL > 2
if (gl_LightSource[i].spotCutoff < 91.0) {  // Tube light
float beamlength = length(gl_LightSource[i].spotDirection);
vec3 beamDir = normalize(gl_LightSource[i].spotDirection);
// Get nearest point on line
float neardist = dot(position.xyz - gl_LightSource[i].position.xyz , beamDir);
// Move back from the endpoint of the beam along the beam by the distance we calculated
vec3 nearest = gl_LightSource[i].position.xyz - beamDir * abs(neardist);
lightDir = nearest - position.xyz;
dist = length(lightDir);
}
  #endif

lightDir = normalize(lightDir);
attenuation = 1.0 / (gl_LightSource[i].constantAttenuation + (gl_LightSource[i].linearAttenuation * dist) + (gl_LightSource[i].quadraticAttenuation * dist * dist));
specularIntensity = SPEC_INTENSITY_POINT;

} else {
// Directional light source
lightDir = normalize(gl_LightSource[i].position.xyz);
specularIntensity = SPEC_INTENSITY_DIRECTIONAL;
}

// Ambient and Diffuse
lightAmbient += (gl_FrontLightProduct[i].ambient * attenuation);
lightDiffuse += (gl_FrontLightProduct[i].diffuse * (max(dot(normal, lightDir), 0.0)) * attenuation);

  #ifdef FLAG_NORMAL_MAP
// Specular
vec3 half_vec = normalize(lightDir + eyeDir);
mat3 tan_mat = mat3(tbnMatrix[2], tbnMatrix[1], tbnMatrix[0]);
vec3 tan = normalize(tan_mat * normal);
mat3 bin_mat = mat3(tbnMatrix[2], tbnMatrix[0], tbnMatrix[1]);
vec3 bin = normalize(bin_mat * normal);

   #ifdef FLAG_SPEC_MAP
float _AlphaX = specColour.r;
float _AlphaY = specColour.g;
   #else
float _AlphaX = 0.5;
float _AlphaY = 0.01;
   #endif
float dotHN = clamp(dot(normal, half_vec), 0.0, 1.0);
float dotVN = clamp(dot(normal, eyeDir), 0.0001, 1.0);
float dotHTAlphaX = dot(half_vec, tan) / _AlphaX;
float dotHBAlphaY = dot(half_vec, bin) / _AlphaY;

lightSpecular += 0.5 * max(dotHN, 0.0) * exp((-2.0 * ((dotHTAlphaX * dotHTAlphaX) + (dotHBAlphaY * dotHBAlphaY))) / (1.0 + dotHN)) * gl_FrontLightProduct[i].specular * attenuation * specularIntensity;
lightSpecular += 0.5 * ((gl_FrontLightProduct[i].specular * pow(max(0.0, dotHN), gl_FrontMaterial.shininess)) * attenuation) * specularIntensity;
  #else
// Specular
float NdotHV = clamp(dot(normal, normalize(eyeDir + lightDir)), 0.0, 1.0);
lightSpecular += ((gl_FrontLightProduct[i].specular * pow(NdotHV, gl_FrontMaterial.shininess)) * attenuation) * specularIntensity;
  #endif
}

lightAmbientDiffuse = lightAmbient + lightDiffuse;
 #else
lightAmbientDiffuse = gl_Color;
lightSpecular = gl_SecondaryColor;
 #endif

 #ifdef FLAG_ANIMATED
vec2 distort = vec2(cos(position.x*position.w*0.005+anim_timer*20.0)*sin(position.y*position.w*0.005),sin(position.x*position.w*0.005+anim_timer*20.0)*cos(position.y*position.w*0.005))*0.03;
 #endif

 #ifdef FLAG_DIFFUSE_MAP
 // Base color
  #ifdef FLAG_ANIMATED
vec4 baseColor;
if (effect_num == 2) {
baseColor = texture2D(sBasemap, texCoord + distort*(1.0-anim_timer));
} else {
baseColor = texture2D(sBasemap, texCoord);
}
  #else
vec4 baseColor = texture2D(sBasemap, texCoord);
  #endif
 #else
vec4 baseColor = gl_Color;
 #endif

vec4 fragmentColor;
fragmentColor.rgb = baseColor.rgb * max(lightAmbientDiffuse.rgb * AMBIENT_LIGHT_BOOST, gl_LightModel.ambient.rgb - 0.425);
fragmentColor.a = baseColor.a;

 #ifdef FLAG_SPEC_MAP
 // Spec color
fragmentColor.rgb += lightSpecular.rgb * (specColour.rgb * SPECULAR_FACTOR);
fragmentColor.a += (dot(lightSpecular.a, lightSpecular.a) * SPECULAR_ALPHA);
 #else
fragmentColor.rgb += lightSpecular.rgb * (baseColor.rgb * SPEC_FACTOR_NO_SPEC_MAP);
 #endif

 #ifdef FLAG_ENV_MAP
 // Env color
vec3 envIntensity = (alpha_spec) ? vec3(specColour.a) : specColour.rgb;
fragmentColor.a += (dot(envColour.rgb, envColour.rgb) * ENV_ALPHA_FACTOR);
fragmentColor.rgb += envColour.rgb * envIntensity;
 #endif

 #ifdef FLAG_GLOW_MAP
 // Glow color
fragmentColor.rgb += texture2D(sGlowmap, texCoord).rgb * GLOW_MAP_INTENSITY;
 #endif

 #ifdef FLAG_FOG
fragmentColor.rgb = mix(fragmentColor.rgb, gl_Fog.color.rgb, fogDist);
 #endif

fragmentColor.a = clamp(fragmentColor.a ,0.0,1.0);

 #ifdef FLAG_ANIMATED
if (effect_num == 0) {
float shinefactor = 1.0/(1.0 + pow((fract(abs(gl_TexCoord[0].x))-anim_timer) * 1000.0, 2.0)) * 1000.0;
gl_FragColor.rgb = fragmentColor.rgb + vec3(shinefactor);
gl_FragColor.a = fragmentColor.a * clamp(shinefactor * (fract(abs(gl_TexCoord[0].x))-anim_timer) * -10000.0,0.0,1.0);
}
if (effect_num == 1) {
float shinefactor = 1.0/(1.0 + pow((position.y-anim_timer), 2.0));
gl_FragColor.rgb = fragmentColor.rgb + vec3(shinefactor);
#ifdef FLAG_LIGHT
gl_FragColor.a = fragmentColor.a;
#else
// ATI Wireframe fix *grumble*
gl_FragColor.a = clamp((position.y-anim_timer) * 10000.0,0.0,1.0);
#endif
}
if (effect_num == 2) {
vec2 screenPos = gl_FragCoord.xy * vec2(vpwidth,vpheight);
gl_FragColor.a = fragmentColor.a;
float cloak_interp = (sin(position.x*position.w*0.005+anim_timer*20.0)*sin(position.y*position.w*0.005)*0.5)-0.5;
#ifdef FLAG_LIGHT
gl_FragColor.rgb = mix(texture2D(sFramebuffer, screenPos + distort*anim_timer + anim_timer*0.1*normal.xy).rgb,fragmentColor.rgb,clamp(cloak_interp+anim_timer*2.0,0.0,1.0));
#else
gl_FragColor.rgb = mix(texture2D(sFramebuffer, screenPos + distort*anim_timer + anim_timer*0.1*lNormal.xy).rgb,fragmentColor.rgb,clamp(cloak_interp+anim_timer*2.0,0.0,1.0));
#endif
}
 #else
gl_FragColor = fragmentColor;
 #endif
}
Title: Re: Totaly Metal
Post by: Zacam on August 22, 2011, 05:38:35 am
*bump*
Title: Re: Totaly Metal
Post by: Bobboau on August 22, 2011, 06:29:05 am
yeah, as I said, this was very very quick and dirty, less than an hour's worth of work, so it was very sloppily done, but it got the point across, it looks less plastic.
Title: Re: Totaly Metal
Post by: Zacam on August 22, 2011, 06:50:55 am

Alternatively, the ENV (in the normal map function) can be altered from lightDiffuse to lightSpecular with a pretty easy change.

Code: [Select]
lightDiffuse = envColour * ENV_ALPHA_FACTOR;

Change to:
Code: [Select]
lightSpecular = envColour * ENV_ALPHA_FACTOR;
Title: Re: Totaly Metal
Post by: Woolie Wool on August 22, 2011, 08:36:53 am
There is way, way too much ENV now, even on ships that never had it before, and lights are now really bright.
Title: Re: Totaly Metal
Post by: The E on August 22, 2011, 08:42:53 am
In the shader, lower the ENV_ALPHA_COLOUR constant, or set it to 0.0.
Title: Re: Totaly Metal
Post by: Zacam on August 22, 2011, 01:16:38 pm

Also, don't go by just what the LAB shows you. Srsly. It does work out pretty well in-game.
Title: Re: Totaly Metal
Post by: Reprobator on August 22, 2011, 03:39:12 pm
I don't know why but this has the effect to turn all my ships to something absolutely and totally black except glows.
Yet another ati issue?
Title: Re: Totaly Metal
Post by: Bobboau on August 22, 2011, 03:45:21 pm
I made it on an ATI machine, more likely too many instructions, as I have a high level ATI card, and I would not notice if lower level cards couldn't handle this poorly completely not optimized shader.
Title: Re: Totaly Metal
Post by: Commander Zane on August 22, 2011, 04:00:13 pm
Depends exactly on how high-level it is. :nervous:
Title: Re: Totaly Metal
Post by: Bobboau on August 22, 2011, 04:25:01 pm
Radeon 5770
Title: Re: Totaly Metal
Post by: Reprobator on August 23, 2011, 12:26:53 am
Well my radeon is a 6970 so i don't think it comes frome there :p
i'm using 11.7 driver personally.
Title: Re: Totaly Metal
Post by: The E on August 23, 2011, 02:14:20 am
I don't know why but this has the effect to turn all my ships to something absolutely and totally black except glows.
Yet another ati issue?

No, it's an issue with you not using the right shaders. You not only need the main-f.sdr posted here, but also this main-v.sdr:

Code: [Select]
#ifdef FLAG_ENV_MAP
uniform mat4 envMatrix;
varying vec3 envReflect;
#endif

#ifdef FLAG_NORMAL_MAP
varying mat3 tbnMatrix;
#endif

#ifdef FLAG_FOG
varying float fogDist;
#endif

varying vec4 position;
varying vec3 lNormal;

void main()
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;
gl_FrontColor = gl_Color;
gl_FrontSecondaryColor = vec4(0.0, 0.0, 0.0, 1.0);

 // Transform the normal into eye space and normalize the result.
position = gl_ModelViewMatrix * gl_Vertex;
vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
lNormal = normal;

 #ifdef FLAG_NORMAL_MAP
 // Setup stuff for normal maps
vec3 t = normalize(gl_NormalMatrix * gl_MultiTexCoord1.xyz);
vec3 b = cross(normal, t) * gl_MultiTexCoord1.w;
tbnMatrix = mat3(t, b, normal);
 #endif

 #ifdef FLAG_ENV_MAP
 // Environment mapping reflection vector.
envReflect = reflect(position.xyz, normal);
envReflect = vec3(envMatrix * vec4(envReflect, 0.0));
envReflect = normalize(envReflect);
 #endif

 #ifdef FLAG_FOG
fogDist = clamp((gl_Position.z - gl_Fog.start) * 0.75 * gl_Fog.scale, 0.0, 1.0);
 #endif

 #ifdef __GLSL_CG_DATA_TYPES
 // Check necessary for ATI specific behavior
gl_ClipVertex = (gl_ModelViewMatrix * gl_Vertex);
 #endif
}
Title: Re: Totaly Metal
Post by: Bobboau on August 23, 2011, 07:16:30 am
No, it's an issue with you not using the right shaders. You not only need the main-f.sdr posted here, but also this main-v.sdr:

[derp]I probably should have posted that

also, before this thread gets any further, this is based on this (http://en.wikibooks.org/wiki/GLSL_Programming/Unity/Brushed_Metal)
Title: Re: Totaly Metal
Post by: Reprobator on August 23, 2011, 05:05:13 pm
Yup now cloacking and this effect work far better, thank you!
and it's pretty awesome!
Title: Re: Totaly Metal
Post by: JGZinv on August 23, 2011, 05:24:11 pm
New pic of it working properly?
Title: Re: Totaly Metal
Post by: Bobboau on August 23, 2011, 06:39:55 pm
unfortunately it has more to do with how the highlight moves so it's very hard to capture the effect in a static image.

also, I did a little tweaking with it today, I added a 'ratio' variable, so you can go between the old specular model and this by tweaking that variable between 0 and 1. I have it defaulted to the new effect being totally on.

Code: [Select]
#ifdef FLAG_LIGHT
uniform int n_lights;
#endif

#ifdef FLAG_DIFFUSE_MAP
uniform sampler2D sBasemap;
#endif

#ifdef FLAG_GLOW_MAP
uniform sampler2D sGlowmap;
#endif

#ifdef FLAG_SPEC_MAP
uniform sampler2D sSpecmap;
#endif

#ifdef FLAG_ENV_MAP
uniform samplerCube sEnvmap;
uniform bool alpha_spec;
varying vec3 envReflect;
#endif

#ifdef FLAG_NORMAL_MAP
uniform sampler2D sNormalmap;
varying mat3 tbnMatrix;
#endif

#ifdef FLAG_FOG
varying float fogDist;
#endif

varying vec4 position;
varying vec3 lNormal;

#if SHADER_MODEL == 2
  #define MAX_LIGHTS 2
#else
  #define MAX_LIGHTS 8
#endif

#define SPEC_INTENSITY_POINT 5.3 // Point light
#define SPEC_INTENSITY_DIRECTIONAL 3.0 // Directional light
#define SPECULAR_FACTOR 1.75
#define SPECULAR_ALPHA 0.1
#define SPEC_FACTOR_NO_SPEC_MAP 0.6
#define ENV_ALPHA_FACTOR 0.3
#define GLOW_MAP_INTENSITY 1.5
#define AMBIENT_LIGHT_BOOST 1.0

void main()
{
vec3 eyeDir = vec3(normalize(-position).xyz); // Camera is at (0,0,0) in ModelView space
vec4 lightAmbientDiffuse = vec4(0.0, 0.0, 0.0, 1.0);
vec4 lightDiffuse = vec4(0.0, 0.0, 0.0, 1.0);
vec4 lightAmbient = vec4(0.0, 0.0, 0.0, 1.0);
vec4 lightSpecular = vec4(0.0, 0.0, 0.0, 1.0);
vec2 texCoord = gl_TexCoord[0].xy;
 #ifdef FLAG_SPEC_MAP
 // Spec color
vec4 spec_tex = texture2D(sSpecmap, texCoord);
#endif

 #ifdef FLAG_LIGHT
  #ifdef FLAG_NORMAL_MAP
// Normal map - convert from DXT5nm
vec3 normal;

normal.rg = (texture2D(sNormalmap, texCoord).ag * 2.0) - 1.0;
  #ifdef FLAG_ENV_MAP
vec3 envOffset;
envOffset = normal;
  #endif
normal.b = sqrt(1.0 - dot(normal.rg, normal.rg));

mat3 tan_mat = mat3(tbnMatrix[2], tbnMatrix[1], tbnMatrix[0]);
mat3 bin_mat = mat3(tbnMatrix[2], tbnMatrix[0], tbnMatrix[1]);

vec3 tan = normalize(tan_mat * normal);
vec3 bin = normalize(bin_mat * normal);

normal = normalize(tbnMatrix * normal);
  #else
vec3 normal = lNormal;
  #endif

vec3 lightDir;
lightAmbient = gl_FrontMaterial.emission + (gl_LightModel.ambient * gl_FrontMaterial.ambient);

#pragma optionNV unroll all
for (int i = 0; i < MAX_LIGHTS; ++i) {
  #if SHADER_MODEL > 2
if (i > n_lights)
break;
  #endif
float specularIntensity = 1.0;
float attenuation = 1.0;

// Attenuation and light direction
  #if SHADER_MODEL > 2
if (gl_LightSource[i].position.w == 1.0) {
  #else
if (gl_LightSource[i].position.w == 1.0 && i != 0) {
  #endif
// Positional light source
float dist = distance(gl_LightSource[i].position.xyz, position.xyz);

float spotEffect = 1.0;

  #if SHADER_MODEL > 2
if (gl_LightSource[i].spotCutoff < 91.0) {
spotEffect = dot(normalize(gl_LightSource[i].spotDirection), normalize(-position.xyz));

if (spotEffect < gl_LightSource[i].spotCosCutoff) {
spotEffect = 0.0;
}
}
  #endif

attenuation = spotEffect / (gl_LightSource[i].constantAttenuation + (gl_LightSource[i].linearAttenuation * dist) + (gl_LightSource[i].quadraticAttenuation * dist * dist));

lightDir = normalize(gl_LightSource[i].position.xyz - position.xyz);

specularIntensity = SPEC_INTENSITY_POINT; // Point light
} else {
// Directional light source
lightDir = normalize(gl_LightSource[i].position.xyz);

specularIntensity = SPEC_INTENSITY_DIRECTIONAL; // Directional light
}

float dotLN = dot(lightDir, normal); // compute this dot product only once

// Ambient and Diffuse
lightAmbient += (gl_FrontLightProduct[i].ambient * attenuation);
lightDiffuse += ((gl_FrontLightProduct[i].diffuse * max(dotLN, 0.0)) * attenuation);

 #ifdef FLAG_NORMAL_MAP
// Specular
vec3 half_vec = normalize(lightDir + eyeDir);


  float _AlphaX = 0.3;
float _AlphaY = 0.1;

float dotHN = clamp(dot(normal, half_vec), 0.0, 1.0);
float dotVN = clamp(dot(normal, eyeDir), 0.0001, 1.0);
float dotHTAlphaX = dot(half_vec, tan) / _AlphaX;
float dotHBAlphaY = dot(half_vec, bin) / _AlphaY;

float ratio = 1.0;

lightSpecular += ratio * 2.0*dotVN * sqrt(max(0.0, dotLN / dotVN)) * exp(-2.0 * (dotHTAlphaX * dotHTAlphaX + dotHBAlphaY * dotHBAlphaY) / (1.0 + dotHN)) * gl_FrontLightProduct[i].specular * attenuation * specularIntensity;

lightSpecular += (1.0-ratio) * ((gl_FrontLightProduct[i].specular * pow(max(0.0, dotHN), gl_FrontMaterial.shininess)) * attenuation) * specularIntensity;

#else
// Specular
float NdotHV = clamp(dot(normal, normalize(eyeDir + lightDir)), 0.0, 1.0);
lightSpecular += ((gl_FrontLightProduct[i].specular * pow(max(0.0, NdotHV), gl_FrontMaterial.shininess)) * attenuation) * specularIntensity;
#endif
}

lightAmbientDiffuse = lightAmbient + lightDiffuse;
 #else
lightAmbientDiffuse = gl_Color;
lightSpecular = gl_SecondaryColor;
 #endif

 #ifdef FLAG_DIFFUSE_MAP
 // Base color
vec4 baseColor = texture2D(sBasemap, texCoord);
 #else
vec4 baseColor = gl_Color;
 #endif
 
vec4 fragmentColor;
fragmentColor.rgb = baseColor.rgb * max(lightAmbientDiffuse.rgb * AMBIENT_LIGHT_BOOST, gl_LightModel.ambient.rgb - 0.425);
fragmentColor.a = baseColor.a;

 #ifdef FLAG_SPEC_MAP
 // Spec color
fragmentColor.rgb += lightSpecular.rgb * (spec_tex.rgb * SPECULAR_FACTOR);
fragmentColor.a += (dot(lightSpecular.a, lightSpecular.a) * SPECULAR_ALPHA);
 #else
fragmentColor.rgb += lightSpecular.rgb * (baseColor.rgb * SPEC_FACTOR_NO_SPEC_MAP);
 #endif

 #ifdef FLAG_ENV_MAP
 // Env color
  #ifdef FLAG_NORMAL_MAP
vec3 envReflectNM = envReflect + envOffset;
vec3 envIntensity = (alpha_spec) ? vec3(texture2D(sSpecmap, texCoord).a) : texture2D(sSpecmap, texCoord).rgb;
fragmentColor.a += (dot(textureCube(sEnvmap, envReflectNM).rgb, textureCube(sEnvmap, envReflectNM).rgb) * ENV_ALPHA_FACTOR);
fragmentColor.rgb += textureCube(sEnvmap, envReflectNM).rgb * envIntensity;
  #else
vec3 envIntensity = (alpha_spec) ? vec3(texture2D(sSpecmap, texCoord).a) : texture2D(sSpecmap, texCoord).rgb;
fragmentColor.a += (dot(textureCube(sEnvmap, envReflect).rgb, textureCube(sEnvmap, envReflect).rgb) * ENV_ALPHA_FACTOR);
fragmentColor.rgb += textureCube(sEnvmap, envReflect).rgb * envIntensity;
  #endif
 #endif

 #ifdef FLAG_GLOW_MAP
 // Glow color
fragmentColor.rgb += texture2D(sGlowmap, texCoord).rgb * GLOW_MAP_INTENSITY;
 #endif

 #ifdef FLAG_FOG
fragmentColor.rgb = mix(fragmentColor.rgb, gl_Fog.color.rgb, fogDist);
 #endif

gl_FragColor = fragmentColor;
}
these tweaks don't have the changes others have made

this lighting model seems to like congruent and smoothly rounded surfaces.
Title: Re: Totaly Metal
Post by: Lucika on August 23, 2011, 07:11:10 pm
unfortunately it has more to do with how the highlight moves so it's very hard to capture the effect in a static image.

Could you upload a video maybe? :)
Title: Re: Totaly Metal
Post by: Bobboau on August 23, 2011, 09:00:38 pm
I never bothered installing, yet alone, learning to use fraps (etc), so someone else will have to do it.
Title: Re: Totaly Metal
Post by: Zacam on August 25, 2011, 02:53:02 am

So, I've been playing about back and forth between the versions. I think I like the first one better. The second one picks up too much noise from the normal map and does weird things with it. So, barring any other adjustments, v1 will probably be the version going into the MediaVPs.

Since there were complaints about there being too much ENV contribution to the last version I posted, here is a version with no additional ENV contributions (though, I think in a slightly less-powerful form, they add quite a good bit of atmosphere to the apperance, but it's still an experimental concept), I left the bit in for allowing a modified version, but it's also been commented out (just remove the two '//' to activate it):

Code: (main-f.sdr) [Select]
#ifdef FLAG_LIGHT
uniform int n_lights;
#endif

#ifdef FLAG_DIFFUSE_MAP
uniform sampler2D sBasemap;
#endif

#ifdef FLAG_GLOW_MAP
uniform sampler2D sGlowmap;
#endif

#ifdef FLAG_SPEC_MAP
uniform sampler2D sSpecmap;
#endif

#ifdef FLAG_ENV_MAP
uniform samplerCube sEnvmap;
uniform bool alpha_spec;
varying vec3 envReflect;
#endif

#ifdef FLAG_NORMAL_MAP
uniform sampler2D sNormalmap;
varying mat3 tbnMatrix;
#endif

#ifdef FLAG_FOG
varying float fogDist;
#endif

#ifdef FLAG_ANIMATED
uniform sampler2D sFramebuffer;
uniform int effect_num;
uniform float anim_timer;
uniform float vpwidth;
uniform float vpheight;
#endif

varying vec4 position;
varying vec3 lNormal;

#if SHADER_MODEL == 2
  #define MAX_LIGHTS 2
#else
  #define MAX_LIGHTS 8
#endif

#define SPEC_INTENSITY_POINT 5.3 // Point light
#define SPEC_INTENSITY_DIRECTIONAL 3.0 // Directional light
#define SPECULAR_FACTOR 1.75
#define SPECULAR_ALPHA 0.1
#define SPEC_FACTOR_NO_SPEC_MAP 0.6
#define ENV_ALPHA_FACTOR 0.3
#define GLOW_MAP_INTENSITY 1.5
#define AMBIENT_LIGHT_BOOST 1.0

void main()
{
vec3 eyeDir = vec3(normalize(-position).xyz); // Camera is at (0,0,0) in ModelView space
vec4 lightAmbientDiffuse = vec4(0.0, 0.0, 0.0, 1.0);
vec4 lightDiffuse = vec4(0.0, 0.0, 0.0, 1.0);
vec4 lightAmbient = vec4(0.0, 0.0, 0.0, 1.0);
vec4 lightSpecular = vec4(0.0, 0.0, 0.0, 1.0);
vec2 texCoord = gl_TexCoord[0].xy;

 #ifdef FLAG_SPEC_MAP
vec4 specColour = texture2D(sSpecmap, texCoord);
 #endif

 #ifdef FLAG_LIGHT
  #ifdef FLAG_NORMAL_MAP
// Normal map - convert from DXT5nm
vec3 normal;
normal.rg = (texture2D(sNormalmap, texCoord).ag * 2.0) - 1.0;
   #ifdef FLAG_ENV_MAP
vec3 envOffset = vec3(0.0);
envOffset.xy = normal.xy;
vec3 envReflectNM = envReflect + envOffset;
vec4 envColour = textureCube(sEnvmap, envReflectNM);
// Uncomment the following line for ENV Contribution to the model lighting
//lightSpecular = (envColour * ENV_ALPHA_FACTOR) - specColour.a;
   #endif
normal.b = sqrt(1.0 - dot(normal.rg, normal.rg));
normal = tbnMatrix * normal;
float norm = length(normal);
// prevent breaking of normal maps
if (length(normal) > 0.0)
normal /= norm ;
else
normal = tbnMatrix * vec3(0.0, 0.0, 1.0);
  #else
vec3 normal = lNormal;
   #ifdef FLAG_ENV_MAP
vec4 envColour = textureCube(sEnvmap, envReflect);
// Uncomment the following line for ENV Contribution to the model lighting
//lightSpecular = (envColour * ENV_ALPHA_FACTOR) - specColour.a;
   #endif
  #endif

vec3 lightDir;
lightAmbient = gl_FrontMaterial.emission + (gl_LightModel.ambient * gl_FrontMaterial.ambient);
float dist;

#pragma optionNV unroll all
for (int i = 0; i < MAX_LIGHTS; ++i) {
  #if SHADER_MODEL > 2
if (i > n_lights)
break;
  #endif

float specularIntensity = 1.0;
float attenuation = 1.0;

// Attenuation and light direction
  #if SHADER_MODEL > 2
if (gl_LightSource[i].position.w == 1.0) {
  #else
if (gl_LightSource[i].position.w == 1.0 && i != 0) {
  #endif
// Positional light source
dist = distance(gl_LightSource[i].position.xyz, position.xyz);
lightDir = (gl_LightSource[i].position.xyz - position.xyz);

  #if SHADER_MODEL > 2
if (gl_LightSource[i].spotCutoff < 91.0) {  // Tube light
float beamlength = length(gl_LightSource[i].spotDirection);
vec3 beamDir = normalize(gl_LightSource[i].spotDirection);
// Get nearest point on line
float neardist = dot(position.xyz - gl_LightSource[i].position.xyz , beamDir);
// Move back from the endpoint of the beam along the beam by the distance we calculated
vec3 nearest = gl_LightSource[i].position.xyz - beamDir * abs(neardist);
lightDir = nearest - position.xyz;
dist = length(lightDir);
}
  #endif

lightDir = normalize(lightDir);
attenuation = 1.0 / (gl_LightSource[i].constantAttenuation + (gl_LightSource[i].linearAttenuation * dist) + (gl_LightSource[i].quadraticAttenuation * dist * dist));
specularIntensity = SPEC_INTENSITY_POINT;

} else {
// Directional light source
lightDir = normalize(gl_LightSource[i].position.xyz);
specularIntensity = SPEC_INTENSITY_DIRECTIONAL;
}
vec3 half_vec = normalize(lightDir + eyeDir);

// Ambient and Diffuse
lightAmbient += (gl_FrontLightProduct[i].ambient * attenuation);
lightDiffuse += (gl_FrontLightProduct[i].diffuse * (max(dot(normal, lightDir), 0.0)) * attenuation);

// Specular
  #ifdef FLAG_NORMAL_MAP
mat3 tan_mat = mat3(tbnMatrix[2], tbnMatrix[1], tbnMatrix[0]);
mat3 bin_mat = mat3(tbnMatrix[2], tbnMatrix[0], tbnMatrix[1]);
vec3 tan = normalize(tan_mat * normal);
vec3 bin = normalize(bin_mat * normal);
   #ifdef FLAG_SPEC_MAP
float _AlphaX = specColour.r;
float _AlphaY = specColour.g;
   #else
float _AlphaX = 0.5;
float _AlphaY = 0.01;
   #endif
float dotHN = clamp(dot(normal, half_vec), 0.0, 1.0);
float dotVN = clamp(dot(normal, eyeDir), 0.0001, 1.0);
float dotHTAlphaX = dot(half_vec, tan) / _AlphaX;
float dotHBAlphaY = dot(half_vec, bin) / _AlphaY;

lightSpecular += 0.5 * max(dotHN, 0.0) * exp((-2.0 * ((dotHTAlphaX * dotHTAlphaX) + (dotHBAlphaY * dotHBAlphaY))) / (1.0 + dotHN)) * gl_FrontLightProduct[i].specular * attenuation * specularIntensity;
lightSpecular += 0.5 * ((gl_FrontLightProduct[i].specular * pow(max(0.0, dotHN), gl_FrontMaterial.shininess)) * attenuation) * specularIntensity;
  #else
float NdotHV = clamp(dot(normal, half_vec), 0.0, 1.0);
lightSpecular += ((gl_FrontLightProduct[i].specular * pow(NdotHV, gl_FrontMaterial.shininess)) * attenuation) * specularIntensity;
  #endif
}

lightAmbientDiffuse = lightAmbient + lightDiffuse;
 #else
lightAmbientDiffuse = gl_Color;
lightSpecular = gl_SecondaryColor;
 #endif

 #ifdef FLAG_ANIMATED
vec2 distort = vec2(cos(position.x*position.w*0.005+anim_timer*20.0)*sin(position.y*position.w*0.005),sin(position.x*position.w*0.005+anim_timer*20.0)*cos(position.y*position.w*0.005))*0.03;
 #endif

 // Base color
 #ifdef FLAG_DIFFUSE_MAP
  #ifdef FLAG_ANIMATED
vec4 baseColor;
if (effect_num == 2) {
baseColor = texture2D(sBasemap, texCoord + distort*(1.0-anim_timer));
} else {
baseColor = texture2D(sBasemap, texCoord);
}
  #else
vec4 baseColor = texture2D(sBasemap, texCoord);
  #endif
 #else
vec4 baseColor = gl_Color;
 #endif

vec4 fragmentColor;
fragmentColor.rgb = baseColor.rgb * max(lightAmbientDiffuse.rgb * AMBIENT_LIGHT_BOOST, gl_LightModel.ambient.rgb - 0.425);
fragmentColor.a = baseColor.a;

 // Spec color
 #ifdef FLAG_SPEC_MAP
fragmentColor.rgb += lightSpecular.rgb * (specColour.rgb * SPECULAR_FACTOR);
fragmentColor.a += (dot(lightSpecular.a, lightSpecular.a) * SPECULAR_ALPHA);
 #else
fragmentColor.rgb += lightSpecular.rgb * (baseColor.rgb * SPEC_FACTOR_NO_SPEC_MAP);
 #endif

 // Env color
 #ifdef FLAG_ENV_MAP
vec3 envIntensity = (alpha_spec) ? vec3(specColour.a) : specColour.rgb;
fragmentColor.a += (dot(envColour.rgb, envColour.rgb) * ENV_ALPHA_FACTOR);
fragmentColor.rgb += envColour.rgb * envIntensity;
 #endif

 // Glow color
 #ifdef FLAG_GLOW_MAP
fragmentColor.rgb += texture2D(sGlowmap, texCoord).rgb * GLOW_MAP_INTENSITY;
 #endif

 #ifdef FLAG_FOG
fragmentColor.rgb = mix(fragmentColor.rgb, gl_Fog.color.rgb, fogDist);
 #endif

//Commented out. If HDR makes a comeback, we may need this.
//fragmentColor.a = clamp(fragmentColor.a ,0.0,1.0);

 #ifdef FLAG_ANIMATED
if (effect_num == 0) {
float shinefactor = 1.0/(1.0 + pow((fract(abs(gl_TexCoord[0].x))-anim_timer) * 1000.0, 2.0)) * 1000.0;
gl_FragColor.rgb = fragmentColor.rgb + vec3(shinefactor);
gl_FragColor.a = fragmentColor.a * clamp(shinefactor * (fract(abs(gl_TexCoord[0].x))-anim_timer) * -10000.0,0.0,1.0);
}
if (effect_num == 1) {
float shinefactor = 1.0/(1.0 + pow((position.y-anim_timer), 2.0));
gl_FragColor.rgb = fragmentColor.rgb + vec3(shinefactor);
#ifdef FLAG_LIGHT
gl_FragColor.a = fragmentColor.a;
#else
// ATI Wireframe fix *grumble*
gl_FragColor.a = clamp((position.y-anim_timer) * 10000.0,0.0,1.0);
#endif
}
if (effect_num == 2) {
vec2 screenPos = gl_FragCoord.xy * vec2(vpwidth,vpheight);
gl_FragColor.a = fragmentColor.a;
float cloak_interp = (sin(position.x*position.w*0.005+anim_timer*20.0)*sin(position.y*position.w*0.005)*0.5)-0.5;
#ifdef FLAG_LIGHT
gl_FragColor.rgb = mix(texture2D(sFramebuffer, screenPos + distort*anim_timer + anim_timer*0.1*normal.xy).rgb,fragmentColor.rgb,clamp(cloak_interp+anim_timer*2.0,0.0,1.0));
#else
gl_FragColor.rgb = mix(texture2D(sFramebuffer, screenPos + distort*anim_timer + anim_timer*0.1*lNormal.xy).rgb,fragmentColor.rgb,clamp(cloak_interp+anim_timer*2.0,0.0,1.0));
#endif
}
 #else
gl_FragColor = fragmentColor;
 #endif
}
Title: Re: Totaly Metal
Post by: Bobboau on August 25, 2011, 07:37:07 am
I wouldn't put it in exactly like how it is, the chunk that looks like
Code: [Select]
   #ifdef FLAG_SPEC_MAP
float _AlphaX = specColour.r;
float _AlphaY = specColour.g;
   #else
float _AlphaX = 0.5;
float _AlphaY = 0.01;
   #endif
is pure hack, either set alpha to something constant (what ever you pick it will look great on some models and horrible on others) or map it to the unused portions of the normal map, and then start modifying the normal maps to have some value basically on the red and blue components, you need to make flat patches of color, these will determine the orientation of the shine.
Title: Re: Totaly Metal
Post by: Zacam on August 26, 2011, 12:04:35 am

Perhaps, but at the current moment, the fixed values are only there for if -spec isn't enabled.
Otherwise, it uses an already existing data from the -shine map, which may not be entirely optimal, perhaps, but it results in the quickest results that are still usable and specific to the model in question.

Especially if the -shine map is actually made properly.

Later on branching that into using the current unused portions of the normal map can be added in later while still allowing the existing use of the -shine map which will allow for the content to be created for those maps for the shaders to implement.

Given that there is some talk of potentially adding in a gloss-map as well, it may even go into an entirely separate direction of using another file all together. Or a materials system that makes it all a moot point to begin with and the shader function becomes deprecated.

But right now, setting it to the normal unused channels which currently have no content to them (or may have copies of the G channel data in them) would lead to even WORSE looking results than it currently stands. And the "fixed" values idea leaves no flexibility for those models that they may not work on, again requiring the remake of content to adapt.