Code: Select all
// Texture Information from Oolite.
uniform sampler2D tex0; // Difuse and Illumination map
uniform sampler2D tex1; // Decal Texture
// Uniforms from Oolite
uniform float uDecalSelect; // used to decide which decal to select
// Information from vertex shader.
varying vec3 v_normal; // Surface normal
varying vec3 v_pos; // Vertex/fragment position in eye space
// Constants
const float specExponent = 12.0;
const float kDecal1Size = 5.0; // Sets the Decal Size - smaller number is bigger
const float kDecal1S = 0.50;
const float kDecal1T = 0.30;
const float kDecal2Size = 12.0; // Sets the Decal Size - smaller number is bigger
const float kDecal2S = 0.10;
const float kDecal2T = 0.60;
const float kDecalCount = 4.0; //Match the number of Decals in your texture
const float kOrientation1 = 1.57079633; // pi / 2
const float kOrientation2 = 3.6651914; // 210 degrees
// the diffuseColor function takes your diffuse map and your decal map, selects,
// scales & positions the decal image then adds it into the diffuse texturemap
vec4 diffuseColor()
{
vec2 baseTexCoord = gl_TexCoord[0].st;
// Calculate decal texture co-ordinates.
vec2 decal1TexCoord = baseTexCoord;
decal1TexCoord -= vec2(kDecal1S, kDecal1T - (0.5 / kDecal1Size));
float 1s = sin(kOrientation1);
float 1c = cos(kOrientation1);
decal1TexCoord *= mat2(1c, 1s, -1s, 1c);
decal1TexCoord += vec2(0.5 / kDecal1Size);
decal1TexCoord *= vec2(kDecal1Size / kDecalCount, kDecal1Size);
vec2 decal2TexCoord = baseTexCoord;
decal2TexCoord -= vec2(kDecal2S, kDecal2T - (0.5 / kDecal2Size));
float 2s = sin(kOrientation2);
float 2c = cos(kOrientation2);
decal2TexCoord *= mat2(2c, 2s, -2s, 2c);
decal2TexCoord += vec2(0.5 / kDecal2Size);
decal2TexCoord *= vec2(kDecal2Size / kDecalCount, kDecal2Size);
// Select the desired decal from the set.
float offset = floor(uDecalSelect * kDecalCount) / kDecalCount;
decal1TexCoord.s += offset;
decal2TexCoord.s += offset;
// Get texture values.
vec4 baseTex = texture2D(tex0, baseTexCoord);
vec4 decal1Tex = texture2D(tex1, decal1TexCoord);
decal1Tex *= step(offset, decal1TexCoord.s) *
step(0.0, decal1TexCoord.t) *
step(-1.0 / kDecalCount - offset, -decal1TexCoord.s) *
step(-1.0, -decal1TexCoord.t);
vec4 decal2Tex = texture2D(tex1, decal2TexCoord);
decal2Tex *= step(offset, decal2TexCoord.s) *
step(0.0, decal2TexCoord.t) *
step(-1.0 / kDecalCount - offset, -decal2TexCoord.s) *
step(-1.0, -decal2TexCoord.t);
// Composite decal over base.
return baseTex + decal1Tex + decal2Tex;
}
// Calculate the contribution of a single light. Ought to be a function, but OS X's GLSlang implementation isn't sufficiently clever.
#define LIGHT(idx) \
{ \
vec3 lightVector = normalize(gl_LightSource[idx].position.xyz); \
vec3 reflection = normalize(-reflect(lightVector, v_normal)); \
diffuse += gl_FrontMaterial.diffuse * gl_LightSource[idx].diffuse * max(dot(v_normal, lightVector), 0.0); \
specular += gl_LightSource[idx].diffuse * pow(max(dot(reflection, eyeVector), 0.0), specExponent); \
}
void main(void)
{
vec4 diffuse = vec4(0.0), specular = vec4(0.0);
vec3 eyeVector = normalize(-v_pos);
// Load texture data
vec2 texCoord = gl_TexCoord[0].st;
vec4 colorMap = texture2D(tex0, texCoord);
// calculate specular effects
float specIntensity = 0.5;
/* Light 0 is the "showroom" light, used in the demo screen and shipyard.
Light 1 is the sun.
*/
#ifdef OO_LIGHT_0_FIX
LIGHT(0);
#endif
LIGHT(1);
diffuse += gl_FrontMaterial.ambient * gl_LightModel.ambient;
// Calculate the lighting for full shader mode
#ifndef OO_REDUCED_COMPLEXITY
vec4 color = diffuse * diffuseColor() + specular * specIntensity;
#endif
// Calculate the lighting for simple shader mode
#ifdef OO_REDUCED_COMPLEXITY
vec4 color = diffuse * colorMap + specular * specIntensity;
#endif
// Output final color
gl_FragColor = vec4(color.rgb, 1.0);
}