Posted: Wed Jan 13, 2010 5:25 pm
from https://bb.oolite.space/viewtopic.php?t=4494&start=1662
I've been doing the recolouring as follows, there's probably much more sophisticated ways of doing it that don't lead to such muddy colours in the lower range of tones
The re-painting can be thought of as simply taking a greyscale 'paintmask' image, recolouring it and mixing it into the underlying texturemap (the paint mask is used
to control the effect and limit it to only certain areas of the ship - black areas in the paintmask won't be recoloured, white areas will get the maximum amount of
re-colouring).
Taking the griff_normalmapped cobraIII as an example:
The cobra has 2 paintmasks, these are stored are the green channel and the alpha channel in the 'Griff_cobra_mk3_cleaner_mainhull_effects.png' image.
In the fragment shader (Griff_Cobra_mk3_Mainhull_Cleaner.fragment) the re-painting effect is included in the same function that creates the decal, the function is
called diffuseColor and is found at lines 120-146:
the lines we are interested in here are:
this line creates a 2 component vector and stores the green and alpha channels from the 'uEffectsMap' texture - (see the cobras shipdata.plist and line 3 in the shader
to see the lines that link the Griff_cobra_mk3_cleaner_mainhull_effects.png to the shader as an 'uniform' called uEffectsMap)
aargh, i just realise i've started in the wrong place with the explanation, so skip back up the fragment shader to lines 25 & 26
Here we're reading in the paint colours from the cobraIII's shipdata.plist and storing them in the shader as 2 '4 component vectors' (that's too many components
really, the 4th one isn't really going to be used - bad shader writing on my part, we could have used a vec3 for Red, Green, and Blue)
next, skip down the fragment shader to line 134
here we're reading in the cobras basic texture 'skin' image and storing it in a vec4 called baseTex, see the shipdata.plist and line 1 in the shader for the setting up
of the uniform to link 'Griff_cobra_mk3_cleaner_mainhull_diffuse_spec.png' to the uniform binding 'uColorMap'
now we just need to mix our 2 paintmask images with our 2 paintColors and add them into the basetexture,this is done in lines 137 & 138
then line 145 outputs the final texture (as a vec4) from the function where it is used in line 170 onwards
the random paint colours are generated by oolite using the following info in the shipdata.plist
the scale is used as an upper limit for the values generated, anything more vivid that 0.4 gets a bit lurid in the game, notice how the player ship has it's paint
colours set to black:
we can't use random colours for the player as the ship would change it's paint job every game session. As the paint effects are added into the underlying texturemap,
setting the paint colour to black has no effect on the under lying texture as your basically just adding a 0.0 to whatever the current colour value is.
edit: as suggested by Zieman in the post below, 'baseTexCoord' wasn't actually needed it was just a duplicate of the vTexCoord vec2, i've ammended the example above to remove it and also the problematic references to gl_TexCoord[0].st
I've been doing the recolouring as follows, there's probably much more sophisticated ways of doing it that don't lead to such muddy colours in the lower range of tones
The re-painting can be thought of as simply taking a greyscale 'paintmask' image, recolouring it and mixing it into the underlying texturemap (the paint mask is used
to control the effect and limit it to only certain areas of the ship - black areas in the paintmask won't be recoloured, white areas will get the maximum amount of
re-colouring).
Taking the griff_normalmapped cobraIII as an example:
The cobra has 2 paintmasks, these are stored are the green channel and the alpha channel in the 'Griff_cobra_mk3_cleaner_mainhull_effects.png' image.
In the fragment shader (Griff_Cobra_mk3_Mainhull_Cleaner.fragment) the re-painting effect is included in the same function that creates the decal, the function is
called diffuseColor and is found at lines 120-146:
Code: Select all
vec4 diffuseColor()
{
// Calculate decal texture co-ordinates.
vec2 decalTexCoord = vTexCoord;
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, vTexCoord);
vec2 PaintMap = texture2D(uEffectsMap, vTexCoord).ga;
float decalTex = texture2D(uDecalMap, decalTexCoord).b;
baseTex += PaintMap.x * PaintColor1;
baseTex += PaintMap.y * PaintColor2;
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 * DecalColor;
}
Code: Select all
vec2 PaintMap = texture2D(uEffectsMap, vTexCoord).ga;
to see the lines that link the Griff_cobra_mk3_cleaner_mainhull_effects.png to the shader as an 'uniform' called uEffectsMap)
aargh, i just realise i've started in the wrong place with the explanation, so skip back up the fragment shader to lines 25 & 26
Code: Select all
uniform vec4 PaintColor1; // used with paintmask map to tint diffuse texture
uniform vec4 PaintColor2; // used with paintmask map to tint diffuse texture
really, the 4th one isn't really going to be used - bad shader writing on my part, we could have used a vec3 for Red, Green, and Blue)
next, skip down the fragment shader to line 134
Code: Select all
vec4 baseTex = texture2D(uColorMap, vTexCoord);
of the uniform to link 'Griff_cobra_mk3_cleaner_mainhull_diffuse_spec.png' to the uniform binding 'uColorMap'
now we just need to mix our 2 paintmask images with our 2 paintColors and add them into the basetexture,this is done in lines 137 & 138
Code: Select all
baseTex += PaintMap.x * PaintColor1;
baseTex += PaintMap.y * PaintColor2;
the random paint colours are generated by oolite using the following info in the shipdata.plist
Code: Select all
PaintColor1 = {type = "randomUnitVector"; scale = 0.4;};
PaintColor2 = {type = "randomUnitVector"; scale = 0.4;};
colours set to black:
Code: Select all
PaintColor1 = { type = vector; value = "0.0 0.0 0.0"; };
PaintColor2 = { type = vector; value = "0.0 0.0 0.0"; };
setting the paint colour to black has no effect on the under lying texture as your basically just adding a 0.0 to whatever the current colour value is.
edit: as suggested by Zieman in the post below, 'baseTexCoord' wasn't actually needed it was just a duplicate of the vTexCoord vec2, i've ammended the example above to remove it and also the problematic references to gl_TexCoord[0].st