@ Ramirez, i can chop all the glows & stuff out the shader i've been using recently leaving just the decal and the base diffuse texture map, do you want a version with or without normalmapping?
edit: i had the normalmapped shader handy so i cobbled this together in my coffee break. This will take your 'diffuse' texturemap (the usual skin texture map), a normal map and a decal image and mix them together. this example expects the decal image to be made up of 4 smaller decal images arranged in a horizontal row, the uDecalSelect number then picks a decal from the image and the 'diffuseColor()' function in the shader mixes it into the diffuse texture. the fragment shader checks for Simple shader mode and ignores the decal code if it is switched on
vertex shader:
Code: Select all
#define OO_TANGENT_ATTR 1 // <---- Define OO_TANGENT_ATTR to 1 so that Oolite gives correct tangent data to shader.
#ifdef OO_TANGENT_ATTR
attribute vec3 tangent;
#else
const vec3 tangent = vec3(1.0, 0.0, 0.0);
#endif
varying vec2 vTexCoord;
varying vec3 vEyeVector; // These are all in tangent space
varying vec3 vLight0Vector;
varying vec3 vLight1Vector;
void main()
{
// Build tangent basis
vec3 n = normalize(gl_NormalMatrix * gl_Normal);
vec3 t = normalize(gl_NormalMatrix *tangent);
vec3 b = cross(n, t);
mat3 TBN = mat3(t, b, n);
vec3 eyeVector = -vec3(gl_ModelViewMatrix * gl_Vertex);
vEyeVector = eyeVector * TBN;
#ifdef OO_LIGHT_0_FIX
vec3 light0Vector = gl_LightSource[0].position.xyz + eyeVector;
vLight0Vector = light0Vector * TBN;
#endif
vec3 light1Vector = gl_LightSource[1].position.xyz + eyeVector;
vLight1Vector = light1Vector * TBN;
vTexCoord = gl_MultiTexCoord0.st;
gl_Position = ftransform();
// gl_TexCoord used for the decal function in the fragment
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
}
Fragment Shader
Code: Select all
uniform sampler2D uColorMap;
uniform sampler2D uNormalMap;
uniform sampler2D uDecalMap;
varying vec2 vTexCoord;
varying vec3 vEyeVector; // These are all in tangent space
varying vec3 vLight0Vector;
varying vec3 vLight1Vector;
// Constants
const float KspecExponent = 12.0;
const float kDecalSize = 6.1; // Sets the Decal Size - smaller number is bigger
const float kDecalS = 0.61; // Decal S (U) Co-oord - Tweak to fit your model
const float kDecalT = 0.15; // Decal T (V) Co-oord - Tweak to fit your model
const float kDecalCount = 4.0; //Match the number of Decals in your texture
// Uniforms from Oolite
uniform float uDecalSelect;
/* uDecalSelect is used to decide which decal to select, it works like this - our decal image is split into a 'kDecalCount' number of columns
. In this example kDecalCount = 4.0 so our 128x512 decal image
will be split into 4 columns of 128x128 pixels.
By giving uDecalSelect a value between 0.0 and 0.24 this will select decal 1 from the image, 0.25-0.49 will select decal 2, 0.50-0.74 is decal 3 and 0.74-1.0 we be decal 4 */
void Light(in vec3 lightVector, in vec3 normal, in vec4 lightColor, in vec3 eyeVector,
in float KspecExponent, inout vec4 totalDiffuse, inout vec4 totalSpecular)
{
lightVector = normalize(lightVector);
vec3 reflection = normalize(-reflect(lightVector, normal));
totalDiffuse += gl_FrontMaterial.diffuse * lightColor * max(dot(normal, lightVector), 0.0);
totalSpecular += lightColor * pow(max(dot(reflection, eyeVector), 0.0), KspecExponent);
}
#define LIGHT(idx, vector) Light(vector, normal, gl_LightSource[idx].diffuse, eyeVector, KspecExponent, diffuse, specular)
#ifndef OO_REDUCED_COMPLEXITY
// function to read in the colour map then scale and position the decal map onto it.
vec4 diffuseColor()
{
vec2 baseTexCoord = gl_TexCoord[0].st;
// Calculate decal texture co-ordinates.
vec2 decalTexCoord = baseTexCoord;
decalTexCoord -= vec2(kDecalS, kDecalT - (0.5 / kDecalSize));
decalTexCoord *= vec2(kDecalSize / kDecalCount, kDecalSize);
// Select the desired decal from the set.
float offset = floor(uDecalSelect * kDecalCount) / kDecalCount;
decalTexCoord.s += offset;
// Get texture values.
vec4 baseTex = texture2D(uColorMap, baseTexCoord);
vec4 decalTex = texture2D(uDecalMap, decalTexCoord);
decalTex *= step(offset, decalTexCoord.s) *
step(0.0, decalTexCoord.t) *
step(-1.0 / kDecalCount - offset, -decalTexCoord.s) *
step(-1.0, -decalTexCoord.t);
// Composite decal over base.
return baseTex + decalTex;
}
#endif
void main()
{
vec3 eyeVector = normalize(vEyeVector);
vec2 texCoord = vTexCoord;
vec3 normal = normalize( texture2D(uNormalMap, texCoord).xyz - 0.5);
normal = normalize(normal);
vec4 colorMap = texture2D(uColorMap, texCoord);
vec4 diffuse = vec4(0.0), specular = vec4(0);
float specIntensity = 1.0;
#ifdef OO_LIGHT_0_FIX
LIGHT(0, normalize(vLight0Vector));
#endif
LIGHT(1, normalize(vLight1Vector));
diffuse += gl_FrontMaterial.ambient * gl_LightSource[0].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
gl_FragColor = color;
}
shipdata.plist shaders definition
Code: Select all
shaders =
{
"your_diffuse_texture_map.png" =
{
vertex_shader = "the_vertex_shader.vertex";
fragment_shader = "the_fragment_shader.fragment";
textures =
(
"your_diffuse_texture_map.png",
"your_normalmap_texture.png",
{name = "your_decal_texture"; repeat_s = "yes";}
);
uniforms =
{
uColorMap = { type = texture; value = 0; };
uNormalMap = { type = texture; value = 1; };
uDecalMap = { type = texture; value = 2; };
uDecalSelect = { type = "float"; value = 0.3; };
};
};
};
In the shipdata.plist example above, you can see uDecalSelect is being given the value 0.3, so it's the 2nd decal that is going to get used. to have Oolite choose random decals everytime it spawns a ship use
Code: Select all
uDecalSelect = "entityPersonality";
These are the lines in the fragment shader that control the size and placement of your decal
const float kDecalSize = 6.1; // Sets the Decal Size - smaller number is bigger
const float kDecalS = 0.61; // Decal S (U) Co-oord - Tweak to fit your model
const float kDecalT = 0.15; // Decal T (V) Co-oord - Tweak to fit your model
This line needs to match how many decals your are placing in a horizontal row in your decal, have a look at ahrumans post where he explains the shader for an example of a decal image
const float kDecalCount = 4.0; //Match the number of Decals in your texture
other important lines you might need to tweak:
const float KspecExponent = 12.0; - the glossyness of the surface (highlight size basically - higher numbers make the surface more plastic/wet looking
float specIntensity = 1.0; - the shinyness of the surface, higher numbers make brighter highlights, you can also use numbers lower than 1.0 (eg float
specIntensity = 0.5; or float specIntensity = 0.005;
Make sure you change all the referenced png's and shader filenames in the shipdata.plist example above to match what your textures and shader files are called.