Re: Griff's normalmapped ship remakes
Posted: Wed Nov 25, 2020 12:21 pm
Sweet!
For information and discussion about Oolite.
https://bb.oolite.space/
Code: Select all
#define SUN_RADIANCE 3.0
const vec3 PRIMARY_COLOR[12] = vec3[](vec3(1.0, 0.2176, 0.1889),
vec3(0.6090, 0.0484, 0.0),
vec3(1.0, 0.4109, 0.0),
vec3(0.8271, 0.6382, 0.0),
vec3(0.1880, 0.5414, 0.3770),
vec3(0.0, 0.2707, 0.0557),
vec3(0.2133, 0.5105, 0.6617),
vec3(0.1662, 0.0, 0.6617),
vec3(0.5392, 0.1448, 0.6617),
vec3(0.0, 0.0889, 0.2707),
vec3(0.8571, 0.8150, 0.6510),
vec3(0.2588,0.3083,0.2193));
const vec3 SECONDARY_COLOR[12] = vec3[](vec3(0.5176, 0.0069, 0.0),
vec3(0.1805, 0.0, 0.0053),
vec3(0.3910, 0.0260, 0.0),
vec3(0.8, 0.1846, 0.2315),
vec3(0.0484, 0.1486, 0.3083),
vec3(0.0, 0.0016, 0.3233),
vec3(0.1974, 0.2537, 0.5113),
vec3(0.0, 0.0333, 0.3233),
vec3(0.0, 0.0637, 0.5113),
vec3(0.0, 0.3097, 0.3233),
vec3(0.2331, 0.2242, 0.2282),
vec3(0.0, 0.1265, 0.2331));
// Information from vertex shader
varying vec2 vTexCoord, scrollvTexCoord;
varying vec3 vEyeVector, vLight1Vector;
uniform int uAlertLevel;
uniform int uDamageAmount;
uniform int uTradeFactor;
uniform float uDecal1_Rotation; // rotation settings for decal 1
uniform float uDecal2_Rotation; // rotation settings for decal
uniform float uEnginePower;
uniform float uGloss;
uniform float uHullHeatLevel;
uniform float uLaserHeatLevel;
uniform float uPaintColScheme;
uniform float uTime;
uniform vec4 uDecal1_Scale_Position; // position & scale settings for decal 1
uniform vec4 uDecal2_Scale_Position; // position & scale settings for decal 2
uniform vec4 uExhaustCoreCol;
uniform vec4 uExhaustPlumeCol;
uniform vec4 uFogColor;
// Texture Uniforms
uniform sampler2D uDiffuseMap;
uniform sampler2D uNormalMap;
uniform sampler2D uEffectsMap;
uniform sampler2D uDecalMap;
// Glow color constants
const vec4 kRedExhaustGlow = vec4(2.0, 0.4, 0.0, 1.0);
const float kDecalCount = 16.0;
const vec4 kLampColorNoAlert = vec4(0.0);
const vec4 kLampColorYellowAlert = vec4(0.9926, 0.9686, 0.7325, 1.0);
const vec4 kLampColorRedAlert = vec4(1.0, 0.1, 0.0, 1.0);
// Weathering effect constants
const float kChipFactor = 4.5;
const float kSmallChipFactor = 4.0;
const vec4 kDustColor = vec4(0.3, 0.3, 0.3, 1.0);
const vec4 kBareMetalColor = vec4(0.2, 0.2, 0.2, 1.0); // a dark grey
const vec4 kPaintUndercoatColor = vec4(0.0724, 0.1105, 0.1407, 1.0); // a dark grey/blue colour
// Function - Increase contrast level on supplied texturemap
float contrast(vec4 inputsettings, float inputmap)
{
float Tempresult = min(max(inputmap - inputsettings.r, 0.0) / (inputsettings.g - inputsettings.r), 1.0);
float result = mix(inputsettings.b, inputsettings.a,Tempresult);
return result;
}
// Function - Calculate diffuse lighting
vec4 CalcDiffuseLight(in vec3 lightVector, in vec3 normal, in vec4 lightColor)
{
float intensity = dot(normal, lightVector);
intensity = max(intensity, 0.0);
return lightColor * intensity;
}
// Fuction - Irregular flickering effect
float Pulse(float value, float timeScale)
{
float t = uTime * timeScale;
float s0 = t;
s0 -= floor(s0);
float sum = abs( s0 - 0.5);
float s1 = t * 0.7 - 0.05;
s1 -= floor(s1);
sum += abs(s1 - 0.5) - 0.25;
float s2 = t * 1.3 - 0.3;
s2 -= floor(s2);
sum += abs(s2 - 0.5) - 0.25;
float s3 = t * 5.09 - 0.6;
s3 -= floor(s3);
sum += abs(s3 - 0.5) - 0.25;
return (sum * 0.1 + 0.9) * value;
}
// Function - Calculate hull temperature effect
vec4 TemperatureGlow(float level)
{
vec4 result = vec4(0);
result.r = level;
result.g = level * level * level;
result.b = max(level - 0.6, 0.0);
result.a = 1.0;
return result * 2.0;
}
// Function - return 'On' or 'Off' (used for damage effect on lights and engine glow)
float Blink_on_off(float stepcutoff, float timeScale)
{
float result = step(stepcutoff, sin(uTime * timeScale));
return result;
}
// Function - Calculate weapon temperature effect
vec4 WeaponGlow(float level)
{
vec4 result;
result.rgb = vec3(1.38, 0.35, 0.20) * level;
result.a = 1.0;
return result;
}
// Fuction - 'fizzy' noise effect
float rand(vec2 co)
{
float noise = 0.5 + fract(sin(dot(co.xy, vec2(12.9898, 78.233)))* 43758.5453);
float clampednoise = step(noise, 0.9);
return 2.0 + clampednoise;
}
// Function - recolor engine glow when using 'Torus Drive'
vec4 InjectorColGlow(vec4 ExhaustPlumeCol, float level)
{
vec4 result = ExhaustPlumeCol;
float TorusDimmer = smoothstep(0.0, 32.0, level);
if (level > 1.0) // if > 1.0 ship is using afterburners, modify the glow rgb values
{
result.r += level;
result.g -= level;
result.b *= level;
result.a = 1.0;
vec4 moddedglow = vec4(0.0);
moddedglow.r = min(result.r, 1.5);
moddedglow.g = max(result.g, 0.0);
moddedglow.b = min(result.b, 1.0);
moddedglow.a = 1.0;
result = moddedglow;
result.rg += max(3.5 - level, 0.0); // add a brief flash of glow intensity when engpow>1.0 < 3.5
}
else
{
result * level;
}
if (level > 8.0) // if > 8.0 ship is using Torus, dim the glow
{
result = mix(result, result * 0.3, TorusDimmer);
}
return result;
}
/*
Fuction - Part of new GGX lighting model. More physically accurate specular lighting models
This is based on the GLSL code from FS2 SCP ( https://github.com/scp-fs2open )
*/
vec3 FresnelSchlick(vec3 specColor, vec3 light, vec3 halfVec)
{
return specColor + (vec3(1.0) - specColor) * pow(1.0 - clamp(dot(light, halfVec), 0.0, 1.0), 5.0);
}
vec3 CalcSpecularGGX(vec3 light, vec3 normal, vec3 halfVec, vec3 view, float gloss, vec3 fresnel)
{
float NdotL = clamp(dot(normal, light), 0.0, 1.0);
float roughness = clamp(1.0 - gloss, 0.0, 1.0);
float alpha = roughness * roughness;
float NdotH = clamp(dot(normal, halfVec), 0.0, 1.0);
float NdotV = clamp(dot(normal, view), 0.0, 1.0);
float alphaSqr = alpha * alpha;
float pi = 3.14159;
float denom = NdotH * NdotH * (alphaSqr - 1.0) + 1.0;
float distribution = alphaSqr / (pi * denom * denom);
// fresnel comes in pre-calculated
float alphaPrime = roughness + 1.0;
float k = alphaPrime * alphaPrime / 8.0;
float g1vNL = NdotL / (NdotL * (1.0 - k) + k);
float g1vNV = NdotV / (NdotV * (1.0 - k) + k);
float visibility = g1vNL * g1vNV;
return distribution * fresnel * visibility * NdotL / max(4.0 * NdotL * NdotV, 0.001);
}
// Function - Calculate position, scale and rotatation for the supplied decal texture
vec4 the_decaliser(vec4 Your_Decal_Settings, float Your_decal_Rotation)
{
// Setup the basic texture co-ords for the decals
vec2 decal_TexCoord = vTexCoord;
// Position the decal
decal_TexCoord -= vec2(Your_Decal_Settings.s, Your_Decal_Settings.t - (0.5 / Your_Decal_Settings.p));
// Orientate & scale the decal
float decal_s = sin(Your_decal_Rotation);
float decal_c = cos(Your_decal_Rotation);
// Nvidia Driver Workaround:
vec2 DecalRotTemp = decal_TexCoord * mat2(decal_c, decal_s, -decal_s, decal_c);
decal_TexCoord = DecalRotTemp;
decal_TexCoord += vec2(0.5 / Your_Decal_Settings.p);
decal_TexCoord *= vec2(Your_Decal_Settings.p, Your_Decal_Settings.p);
// Get texture values.
vec4 decal_Tex = texture2D(uDecalMap, decal_TexCoord);
decal_Tex.rgb = pow(decal_Tex.rgb, vec3(2.2));
// Modify the Decals texture co-oords
decal_TexCoord.s += 1.0;
decal_Tex *= step(1.0, decal_TexCoord.s) *
step(0.0, decal_TexCoord.t) *
step(-2.0, -decal_TexCoord.s) *
step(-1.0, -decal_TexCoord.t);
// Use the Alpha in the decal as a transparency mask so you can 'cutout' your decal from it's background
float alpha = decal_Tex.a + 0.2; // strengthen the alpha a bit as otherwise the decals are too transparent
// Return the scaled, position & rotated decal, it's mixed into the colour texture further on in the shader .
return alpha * decal_Tex;
}
// Main loop
void main(void)
{
vec4 totalColor = vec4(0.0);
vec3 eyeVector = normalize(vEyeVector);
vec2 texCoord = vTexCoord;
// Free up the blue channel from the normal map so we can use if for the weathering map
vec2 normalRG = texture2D(uNormalMap, vTexCoord).rg * 2.0 - 1.0;
float normalB = sqrt(1.0 - normalRG.r * normalRG.r - normalRG.g * normalRG.g);
vec3 normal = vec3(normalRG, normalB);
vec4 diffuseMapColor = texture2D(uDiffuseMap, texCoord); // alpha channel is paintmask
vec4 effectsMap = texture2D(uEffectsMap, texCoord); // alpha channel is glossyness
diffuseMapColor.rgb = pow(diffuseMapColor.rgb, vec3(2.2));
effectsMap.rgb = pow(effectsMap.rgb, vec3(2.2));
float glossMap = effectsMap.a;
float glowMap = texture2D(uNormalMap, texCoord).a;
float wearMap = texture2D(uNormalMap, vTexCoord).b; // weathering map in b channel
vec4 LampColor = diffuseMapColor; // light colour now baked into the colour map
// Trade Factor 'weathering' - do this early as we need the results to modify the gloss texture a but further down in the code
float dustamount = (float(uTradeFactor) - 75.0) / 25.0;
float chipamount = (float(uTradeFactor) - 10.0) / 90.0;
float chipamountsmaller = (float(uTradeFactor) - 2.0) / 98.0;
float EngMisFireLV = 1.0 - dustamount;
// Get light vectors
vec3 lightVector = normalize(vLight1Vector);
vec3 halfVector = normalize(lightVector + eyeVector);
// Get ambient colour
vec4 ambientLight = gl_LightModel.ambient;
// Calculate diffuse lighting level
vec4 diffuseLight = vec4(0);
diffuseLight += CalcDiffuseLight(lightVector, normal, gl_LightSource[1].diffuse * SUN_RADIANCE);
// Calculate the decal texture, position, scale and rotation
vec4 decals = the_decaliser(uDecal1_Scale_Position, uDecal1_Rotation) + the_decaliser(uDecal2_Scale_Position, uDecal2_Rotation);
// Darken the glossmap with the decal tex so decals appear less shiny that the metal they are painted on
glossMap =mix(glossMap, min(decals.a, 0.2), decals.a); // darken the Glossmap with the decal so it appears more matte
glossMap -= max(mix(diffuseMapColor.a, 0.0, dustamount), 0.0); // darken the glossmap by the paintmap. the paintmap areas are the most glossy, this dulls that
// Darken the glossmap by the dust amount so the ship appears more dull and less shiny in dusty areas
float DustLayer = smoothstep(dustamount, 1.0, contrast(vec4(0.5, 0.9, 0.0, 1.0), wearMap));
glossMap =mix(glossMap, min(DustLayer, 0.0), DustLayer);
// Add the 'PaintChip' layer, we'll edge the chips with a slightly lighter version of the shape, to do this we need two copies of the chip shape, one slightly smaller than the other
float PaintChip = step(chipamount, wearMap); // try glossMap, it's the same texture but with some manipulation by now
// This is the smaller chip shape, subtracted from the large chip shape to find the chip edges later on in the shader...
float PaintChipsmaller = step(chipamountsmaller, wearMap);
// Subtract the smaller PaintChip from the bigger one to leave just the very edge of the shape
float PaintChipEdge = PaintChip - PaintChipsmaller;
// Darken the glossmap by the larger paint chip, so that these areas are less glossy
glossMap =mix(glossMap, min(PaintChipsmaller, 0.0), PaintChipsmaller); // note: change the 0.0 to 1.0 and the chipped areas are made shiny
// Get specular parameters
float specularExponentLevel = pow(glossMap, 2.0) + 0.001;
#define APPLY_MAPPED_EXPONENT exponent = (exponent - 1.0) * specularExponentLevel + 1.0
vec4 specularColor = gl_FrontMaterial.specular;
vec3 fresnel = vec3(0.0);
// Calculate specular light
vec4 specularLight = vec4(0);
float exponent = gl_FrontMaterial.shininess;
APPLY_MAPPED_EXPONENT;
fresnel = FresnelSchlick(specularColor.rgb, lightVector, halfVector);
float gloss = uGloss;
gloss *= glossMap * 1.5;
vec4 ambientColor = gl_FrontMaterial.ambient;
vec4 diffuseColor = gl_FrontMaterial.diffuse;
// Begin repaint the colour texture - Select the paint scheme from the two arrays
int PaintIndex = int(uPaintColScheme);
vec4 PaintPrimaryCol = vec4(vec3(PRIMARY_COLOR[PaintIndex]), 1.0);
vec4 PaintSecondaryCol = vec4(vec3(SECONDARY_COLOR[PaintIndex]), 1.0);
// Calculate the mixing effect for the two paint colours, we'll run the paintMap (diffuseMapColor A) texture through the increse contrast function to get a map we can use to control the mix
float paintmixmap = contrast(vec4(0.5, 0.8, 0.2, 1.0), diffuseMapColor.a);
vec4 paintmix = mix(PaintSecondaryCol, PaintPrimaryCol, paintmixmap);
vec4 painteddiffuseMap = mix(diffuseMapColor, paintmix, diffuseMapColor.a);
// Mix the colour for the decal back into the main colour texture
vec4 decalTex = mix(painteddiffuseMap, decals, decals.a); // change diffuseMapColor to vec4(0.0) if you want to place the decal on a black background
vec4 decalpainteddiffuseMapcolor = mix(painteddiffuseMap, decalTex, decals.a);
// Dull the paint by mixing between a colour and a greyscale version
float GreyMixLevel = max(0.65, dustamount); // set the amount to mix between colour & greyscale versions of the texture, cap it a 65% color, 35% greyscale
float average = (decalpainteddiffuseMapcolor.r + decalpainteddiffuseMapcolor.g + decalpainteddiffuseMapcolor.b) / 3.0;
vec4 greyscaleversion = vec4(average, average, average, 1.0) ;
vec4 greycolor = mix(greyscaleversion, decalpainteddiffuseMapcolor, GreyMixLevel); // mix between the greyscale & colour versions of the texture, use the dulllevel to control the mix
// Add the dust layer
vec4 dustaddedcolor = mix(greycolor, kDustColor, DustLayer);
// Colour then mix in the PaintChip layers
vec4 PaintChipLayer = PaintChip * kBareMetalColor;
PaintChipLayer += PaintChipEdge * kPaintUndercoatColor;
vec4 chippedpaint = mix(dustaddedcolor, PaintChipLayer, PaintChip);
// Put everything created so far back into the color texture
diffuseMapColor = chippedpaint;
// Calculate the lighting color
diffuseColor *= diffuseMapColor;
ambientColor *= diffuseMapColor;
// specularColor *= diffuseMapColor; // We're not using a specular colour map, so colour the spec with the colour texturemap
specularLight = vec4(CalcSpecularGGX(lightVector, normal, halfVector, eyeVector, gloss * (1.0 - decals.a), fresnel), 0.0);
specularLight.a = 1.0;
// light energy conservation here
vec4 kD = vec4(vec3(1.0) - fresnel, 1.0);
totalColor += (diffuseColor * diffuseLight * kD) + (ambientColor * ambientLight);
// Apply Specular
totalColor += specularLight * gl_LightSource[1].specular * SUN_RADIANCE;
// calculate the hull lights
vec4 Lamp_pass = mix(vec4(0.0), diffuseMapColor, glowMap);
// Engine glow animation effect
vec2 scrolloffset = vec2(vTexCoord.s + effectsMap.r, vTexCoord.t + effectsMap.b);
float scrollingheatMap = texture2D(uDiffuseMap, scrollvTexCoord + scrolloffset).a * effectsMap.r;
// Call the function to modify the engine glow colour depending on current ship speed
vec4 PlumeColGLow = InjectorColGlow(uExhaustPlumeCol, uEnginePower);
// Calculate random engine flicker
vec2 twmp = vec2(vTexCoord * uTime);
float engnoise = rand(twmp);
float engineburp = max(0.8, sin(Pulse(uTime, 0.2))); // calculate small 'blip' for engine core glow level
// Check if ship is hostile, adjust lampColor accordingly
if (uAlertLevel > 0)
{
totalColor -= glowMap;
LampColor = (uAlertLevel > 2) ? kLampColorRedAlert * max(mod(uTime, 1.0), 0.5): kLampColorYellowAlert;
}
else
{
LampColor = kLampColorNoAlert;
}
// Calculate the amount to ship damage to apply
float tempvar = float(uDamageAmount);
float DamageAmount = mod(tempvar, 100.0) / 100.0;
// Calculate the engine and lamp glows
float LowLevelCoreGlow = smoothstep(0.0, 1.0, uEnginePower);
vec4 Lampglow = Lamp_pass * LampColor * Pulse(2.0, 1.0) * (1.0 - DamageAmount);
vec4 PlumeGlow = PlumeColGLow * effectsMap.b * Pulse(min(uEnginePower, 1.0), 1.0);
// Add a very low speed core glow colour, fade it out as speed increases
if (uEnginePower > 0.001)
{
totalColor += uExhaustCoreCol * effectsMap.b * max(0.0, 1.0 - LowLevelCoreGlow) * 0.2;
}
vec4 CoreGlow = uExhaustCoreCol * effectsMap.r * Pulse(min(uEnginePower, 1.0), 1.0) ;
CoreGlow += uExhaustCoreCol * engineburp * effectsMap.r * step(0.001, uEnginePower); // add in core glow level 'jitter'
CoreGlow *= engnoise;
vec4 FinalCoreGlow = mix(CoreGlow, CoreGlow * scrollingheatMap, min(uEnginePower, 0.8));
// Calculate a red glow for the engine core to simulate heated metal. This glow stays visible whilst the rest of the engine effect flickers from shipdamage
vec4 ConstCoreGlow = kRedExhaustGlow * effectsMap.r * Pulse(min(uEnginePower, 1.0), 1.0) * Blink_on_off(0.5, Pulse(1.0, 0.6));
ConstCoreGlow += kRedExhaustGlow * effectsMap.r * Pulse(min(uEnginePower, 1.0), 1.0) * Blink_on_off(0.5, Pulse(1.0, 0.7));
// Apply the engine and lamp glows
totalColor += mix(Lampglow + PlumeGlow + FinalCoreGlow,
ConstCoreGlow +
Lampglow * Blink_on_off(0.5, Pulse(1.0, 0.4)) * 4.0 +
PlumeGlow * Blink_on_off(0.5, Pulse(1.0, 1.0)), max(0.0, DamageAmount - 0.4));
// Apply the lasergun heat glow
totalColor += WeaponGlow(effectsMap.g * Pulse(min(uLaserHeatLevel, 1.0), 1.0));
// Calculate an engine misfire flicker, this only kick in when Tradefactor pases 80%
float EngineMisFire = effectsMap.b * uEnginePower * max(0.0, EngMisFireLV - 0.8);
totalColor += kRedExhaustGlow * Blink_on_off(0.9, Pulse(0.5, 0.9)) * EngineMisFire; // use vec4(5.0) to get a really strong white flash
// Apply the hull temperature glow
float hullHeat = max(uHullHeatLevel - 0.5, 0.0) * 2.0;
hullHeat = Pulse(hullHeat * hullHeat, 0.1);
totalColor += TemperatureGlow(hullHeat);
vec3 x = max(vec3(0.0), totalColor.rgb - 0.004);
totalColor.rgb = (x * (6.2 * x + 0.5)) / (x * (6.2 * x + 1.7) + 0.06);
gl_FragColor = mix(totalColor, vec4(uFogColor.xyz, 1.0), 0.0); // change 0.0 to uFogColor.w for oolite
}
Code: Select all
"griff_HP_CobraIII_player" =
{
like_ship = "oolite_template_cobra3";
aft_eject_position = "0.0 -7.7913 -15.047";
exhaust = (
"5.6 0.0 -12.3 3.0 2.0 1.5",
"-5.6 0.0 -12.3 3.0 2.0 1.5",
"15.8 0.05 -12.3 1.0 1.0 1.5",
"-15.8 0.05 -12.3 1.0 1.0 1.5"
);
materials =
{
"Hull" =
{
diffuse_map = "griff_HP_CobraIII_diffuse.png";
specular_color = ( 0.04, 0.04, 0.04 ); // Applies when specular map is not used (no shaders)
shininess = 35;
gloss = 0.72;
emission_map = { name = "griff_HP_CobraIII_normal.png"; extract_channel = "a"; };
emission_modulate_color = (0.9926, 0.9686, 0.7325);
};
};
missile_launch_position = "0.0 -2.7316 10.1303";
model = "griff_HP_CobraIII.dat";
scoop_position = "0.0 -3.0757 6.61";
roles = "player";
shaders =
{
"Hull" =
{
specular_color = (0.72, 0.72, 0.72);
vertex_shader = "griff_normalmap_ships_withScroll.vertex";
// fragment_shader = "NoEnergyConservation_PLAYERShader.fragment"; // hardcoded SpecCol, no EnergyConservation
fragment_shader = "griff_HP_CobraIII_PLAYER.fragment"; // more similar to Oolite Default Shader
textures =
(
{name = "griff_HP_CobraIII_diffuse.png"; repeat_s = "yes"; repeat_t = "yes";},
"griff_HP_CobraIII_normal.png",
"griff_HP_CobraIII_effects.png",
"griff_HP_cobraIII_playerdecal.png"
);
uniforms =
{
uDiffuseMap = { type = texture; value = 0; };
uNormalMap = { type = texture; value = 1; };
uEffectsMap = { type = texture; value = 2; };
uDecalMap = { type = texture; value = 3; };
uAlertLevel = "alertCondition";
uDamageAmount = "damage";
uTradeFactor = "tradeInFactor";
uDecal1_Rotation = { type = "float"; value = 0.75; };
uDecal2_Rotation = { type = "float"; value = -1.0; };
uEnginePower = "speedFactor";
uGloss = { type = "float"; value = 1.0; };
uHullHeatLevel = "hullHeatLevel";
uLaserHeatLevel = "laserHeatLevel";
uPaintColScheme = { type = "randomFloat"; scale = 11.0;};
uTime = "universalTime";
uDecal1_Scale_Position = { type = vector; value = "0.18 0.22 12.0"; };
uDecal2_Scale_Position = { type = vector; value = "0.59 0.34 20.0"; };
uExhaustCoreCol = {type = vector; value = "0.4549 0.8062 0.8431";};
uExhaustPlumeCol = {type = vector; value = "0.0 0.3471 1.0";};
uFogColor = "fogUniform";
};
};
};
view_position_aft = "0.0 2.4489 -12.3025";
view_position_forward = "0.0 1.2416 8.1737";
view_position_port = "-18.4308 -0.19 -2.2775";
view_position_starboard = "18.4308 -0.19 -2.2775";
weapon_position_forward = "0.0 0.1997 13.2055";
weapon_position_aft = "0.0 1.7538 -12.3025";
weapon_position_port = "-18.4308 -0.5321 -2.2775";
weapon_position_starboard = "18.4308 -0.5321 -2.2775";
custom_views =
(
{
view_description = "Rear View";
view_orientation = "1.0 0.0 0.0 0.0";
view_position = "0.0 6.0 -55.00";
weapon_facing = "FORWARD";
},
{
view_description = "Rear Right View";
view_orientation = "0.9239 0.0 0.3827 0.0";
view_position = "38.8909 6.0 -38.8909";
weapon_facing = "FORWARD";
},
{
view_description = "Right View";
view_orientation = "0.7071 0.0 0.7071 0.0";
view_position = "55.0 6.0 0.0 ";
weapon_facing = "FORWARD";
},
{
view_description = "Front Right View";
view_orientation = "0.3827 0.0 0.9239 0.0";
view_position = "38.8909 6.0 38.8909";
weapon_facing = "FORWARD";
},
{
view_description = "Front View";
view_orientation = "0.0 0.0 1.0 0.0";
view_position = "0.0 6.0 55.0";
weapon_facing = "FORWARD";
},
{
view_description = "Front Left View";
view_orientation = "0.3827 0.0 -0.9239 0.0";
view_position = "-38.8909 6.0 38.8909";
weapon_facing = "FORWARD";
},
{
view_description = "Left View";
view_orientation = "0.7071 0.0 -0.7071 0.0";
view_position = "-55.0 6.0 0.0";
weapon_facing = "FORWARD";
},
{
view_description = "Rear Left View";
view_orientation = "0.9239 0.0 -0.3827 0.0";
view_position = "-38.8909 6.0 -38.8909";
weapon_facing = "FORWARD";
},
{
view_description = "Top View";
view_orientation = "-0.7071 0.7071 0.0 0.0";
view_position = "0.0 65.0 0.0";
weapon_facing = "FORWARD";
},
{
view_description = "Bottom View";
view_orientation = "0.0 0.0 0.7071 0.7071";
view_position = "0.0 -85.0 0.0";
weapon_facing = "FORWARD";
}
);
};
Code: Select all
#define SUN_RADIANCE 3.0
const vec3 PRIMARY_COLOR[12] = vec3[](vec3(1.0, 0.2176, 0.1889),
vec3(0.6090, 0.0484, 0.0),
vec3(1.0, 0.4109, 0.0),
vec3(0.8271, 0.6382, 0.0),
vec3(0.1880, 0.5414, 0.3770),
vec3(0.0, 0.2707, 0.0557),
vec3(0.2133, 0.5105, 0.6617),
vec3(0.1662, 0.0, 0.6617),
vec3(0.5392, 0.1448, 0.6617),
vec3(0.0, 0.0889, 0.2707),
vec3(0.8571, 0.8150, 0.6510),
vec3(0.2588,0.3083,0.2193));
const vec3 SECONDARY_COLOR[12] = vec3[](vec3(0.5176, 0.0069, 0.0),
vec3(0.1805, 0.0, 0.0053),
vec3(0.3910, 0.0260, 0.0),
vec3(0.8, 0.1846, 0.2315),
vec3(0.0484, 0.1486, 0.3083),
vec3(0.0, 0.0016, 0.3233),
vec3(0.1974, 0.2537, 0.5113),
vec3(0.0, 0.0333, 0.3233),
vec3(0.0, 0.0637, 0.5113),
vec3(0.0, 0.3097, 0.3233),
vec3(0.2331, 0.2242, 0.2282),
vec3(0.0, 0.1265, 0.2331));
// Information from vertex shader
varying vec2 vTexCoord, scrollvTexCoord;
varying vec3 vEyeVector, vLight1Vector;
uniform int uAlertLevel;
uniform int uDamageAmount;
uniform int uTradeFactor;
uniform float uDecal1_Rotation; // rotation settings for decal 1
uniform float uDecal2_Rotation; // rotation settings for decal
uniform float uEnginePower;
uniform float uGloss;
uniform float uHullHeatLevel;
uniform float uLaserHeatLevel;
uniform float uPaintColScheme;
uniform float uTime;
uniform vec4 uDecal1_Scale_Position; // position & scale settings for decal 1
uniform vec4 uDecal2_Scale_Position; // position & scale settings for decal 2
uniform vec4 uExhaustCoreCol;
uniform vec4 uExhaustPlumeCol;
uniform vec4 uFogColor;
// Texture Uniforms
uniform sampler2D uDiffuseMap;
uniform sampler2D uNormalMap;
uniform sampler2D uEffectsMap;
uniform sampler2D uDecalMap;
// Glow color constants
const vec4 kRedExhaustGlow = vec4(2.0, 0.4, 0.0, 1.0);
const float kDecalCount = 16.0;
const vec4 kLampColorNoAlert = vec4(0.0);
const vec4 kLampColorYellowAlert = vec4(0.9926, 0.9686, 0.7325, 1.0);
const vec4 kLampColorRedAlert = vec4(1.0, 0.1, 0.0, 1.0);
// Weathering effect constants
const float kChipFactor = 4.5;
const float kSmallChipFactor = 4.0;
const vec4 kDustColor = vec4(0.3, 0.3, 0.3, 1.0);
const vec4 kBareMetalColor = vec4(0.2, 0.2, 0.2, 1.0); // a dark grey
const vec4 kPaintUndercoatColor = vec4(0.0724, 0.1105, 0.1407, 1.0); // a dark grey/blue colour
// Function - Increase contrast level on supplied texturemap
float contrast(vec4 inputsettings, float inputmap)
{
float Tempresult = min(max(inputmap - inputsettings.r, 0.0) / (inputsettings.g - inputsettings.r), 1.0);
float result = mix(inputsettings.b, inputsettings.a,Tempresult);
return result;
}
// Function - Calculate diffuse lighting
vec4 CalcDiffuseLight(in vec3 lightVector, in vec3 normal, in vec4 lightColor)
{
float intensity = dot(normal, lightVector);
intensity = max(intensity, 0.0);
return lightColor * intensity;
}
// Fuction - Irregular flickering effect
float Pulse(float value, float timeScale)
{
float t = uTime * timeScale;
float s0 = t;
s0 -= floor(s0);
float sum = abs( s0 - 0.5);
float s1 = t * 0.7 - 0.05;
s1 -= floor(s1);
sum += abs(s1 - 0.5) - 0.25;
float s2 = t * 1.3 - 0.3;
s2 -= floor(s2);
sum += abs(s2 - 0.5) - 0.25;
float s3 = t * 5.09 - 0.6;
s3 -= floor(s3);
sum += abs(s3 - 0.5) - 0.25;
return (sum * 0.1 + 0.9) * value;
}
// Function - Calculate hull temperature effect
vec4 TemperatureGlow(float level)
{
vec4 result = vec4(0);
result.r = level;
result.g = level * level * level;
result.b = max(level - 0.6, 0.0);
result.a = 1.0;
return result * 2.0;
}
// Function - return 'On' or 'Off' (used for damage effect on lights and engine glow)
float Blink_on_off(float stepcutoff, float timeScale)
{
float result = step(stepcutoff, sin(uTime * timeScale));
return result;
}
// Function - Calculate weapon temperature effect
vec4 WeaponGlow(float level)
{
vec4 result;
result.rgb = vec3(1.38, 0.35, 0.20) * level;
result.a = 1.0;
return result;
}
// Fuction - 'fizzy' noise effect
float rand(vec2 co)
{
float noise = 0.5 + fract(sin(dot(co.xy, vec2(12.9898, 78.233)))* 43758.5453);
float clampednoise = step(noise, 0.9);
return 2.0 + clampednoise;
}
// Function - recolor engine glow when using 'Torus Drive'
vec4 InjectorColGlow(vec4 ExhaustPlumeCol, float level)
{
vec4 result = ExhaustPlumeCol;
float TorusDimmer = smoothstep(0.0, 32.0, level);
if (level > 1.0) // if > 1.0 ship is using afterburners, modify the glow rgb values
{
result.r += level;
result.g -= level;
result.b *= level;
result.a = 1.0;
vec4 moddedglow = vec4(0.0);
moddedglow.r = min(result.r, 1.5);
moddedglow.g = max(result.g, 0.0);
moddedglow.b = min(result.b, 1.0);
moddedglow.a = 1.0;
result = moddedglow;
result.rg += max(3.5 - level, 0.0); // add a brief flash of glow intensity when engpow>1.0 < 3.5
}
else
{
result * level;
}
if (level > 8.0) // if > 8.0 ship is using Torus, dim the glow
{
result = mix(result, result * 0.3, TorusDimmer);
}
return result;
}
/*
Function - Part of new GGX lighting model. More physically accurate specular lighting models
This is based on the GLSL code from FS2 SCP ( https://github.com/scp-fs2open )
*/
vec3 FresnelSchlick(vec3 specColor, vec3 light, vec3 halfVec)
{
return specColor + (vec3(1.0) - specColor) * pow(1.0 - clamp(dot(light, halfVec), 0.0, 1.0), 5.0);
}
vec3 CalcSpecularGGX(vec3 light, vec3 normal, vec3 halfVec, vec3 view, float gloss, vec3 fresnel)
{
float NdotL = clamp(dot(normal, light), 0.0, 1.0);
float roughness = clamp(1.0 - gloss, 0.0, 1.0);
float alpha = roughness * roughness;
float NdotH = clamp(dot(normal, halfVec), 0.0, 1.0);
float NdotV = clamp(dot(normal, view), 0.0, 1.0);
float alphaSqr = alpha * alpha;
float pi = 3.14159;
float denom = NdotH * NdotH * (alphaSqr - 1.0) + 1.0;
float distribution = alphaSqr / (pi * denom * denom);
// fresnel comes in pre-calculated
float alphaPrime = roughness + 1.0;
float k = alphaPrime * alphaPrime / 8.0;
float g1vNL = NdotL / (NdotL * (1.0 - k) + k);
float g1vNV = NdotV / (NdotV * (1.0 - k) + k);
float visibility = g1vNL * g1vNV;
return distribution * fresnel * visibility * NdotL / max(4.0 * NdotL * NdotV, 0.001);
}
// Function - Calculate position, scale and rotatation for the supplied decal texture
vec4 the_decaliser(vec4 Your_Decal_Settings, float Your_decal_Rotation)
{
// Setup the basic texture co-ords for the decals
vec2 decal_TexCoord = vTexCoord;
// Position the decal
decal_TexCoord -= vec2(Your_Decal_Settings.s, Your_Decal_Settings.t - (0.5 / Your_Decal_Settings.p));
// Orientate & scale the decal
float decal_s = sin(Your_decal_Rotation);
float decal_c = cos(Your_decal_Rotation);
// Nvidia Driver Workaround:
vec2 DecalRotTemp = decal_TexCoord * mat2(decal_c, decal_s, -decal_s, decal_c);
decal_TexCoord = DecalRotTemp;
decal_TexCoord += vec2(0.5 / Your_Decal_Settings.p);
decal_TexCoord *= vec2(Your_Decal_Settings.p, Your_Decal_Settings.p);
// Get texture values.
vec4 decal_Tex = texture2D(uDecalMap, decal_TexCoord);
// Remove gamma correction from the texture - we're going to do math on the color values so we need them
// to be in linear colorspace
decal_Tex.rgb = pow(decal_Tex.rgb, vec3(2.2));
// Modify the Decals texture co-oords
decal_TexCoord.s += 1.0;
decal_Tex *= step(1.0, decal_TexCoord.s) *
step(0.0, decal_TexCoord.t) *
step(-2.0, -decal_TexCoord.s) *
step(-1.0, -decal_TexCoord.t);
// Use the Alpha in the decal as a transparency mask so you can 'cutout' your decal from it's background
float alpha = decal_Tex.a + 0.2; // strengthen the alpha a bit as otherwise the decals are too transparent
// Return the scaled, position & rotated decal, it's mixed into the colour texture further on in the shader .
return alpha * decal_Tex;
}
// Main loop
void main(void)
{
vec4 totalColor = vec4(0.0);
vec3 eyeVector = normalize(vEyeVector);
vec2 texCoord = vTexCoord;
// Free up the blue channel from the normal map so we can use if for the weathering map
vec2 normalRG = texture2D(uNormalMap, vTexCoord).rg * 2.0 - 1.0;
float normalB = sqrt(1.0 - normalRG.r * normalRG.r - normalRG.g * normalRG.g);
vec3 normal = vec3(normalRG, normalB);
vec4 diffuseMapColor = texture2D(uDiffuseMap, texCoord); // alpha channel is paintmask
vec4 effectsMap = texture2D(uEffectsMap, texCoord); // alpha channel is glossyness
// Remove gamma correction and get the required texture colors in linear color space - we're
// going to do math on them
diffuseMapColor.rgb = pow(diffuseMapColor.rgb, vec3(2.2));
effectsMap.rgb = pow(effectsMap.rgb, vec3(2.2));
float glossMap = effectsMap.a;
float glowMap = texture2D(uNormalMap, texCoord).a;
float wearMap = texture2D(uNormalMap, vTexCoord).b; // weathering map in b channel
vec4 LampColor = diffuseMapColor; // light colour now baked into the colour map
// Trade Factor 'weathering' - do this early as we need the results to modify the gloss texture a but further down in the code
float dustamount = (float(uTradeFactor) - 75.0) / 25.0;
float chipamount = (float(uTradeFactor) - 10.0) / 90.0;
float chipamountsmaller = (float(uTradeFactor) - 2.0) / 98.0;
float EngMisFireLV = 1.0 - dustamount;
// Get light vectors
vec3 lightVector = normalize(vLight1Vector);
vec3 halfVector = normalize(lightVector + eyeVector);
// Get ambient colour
vec4 ambientLight = gl_LightModel.ambient;
// Calculate diffuse lighting level
vec4 diffuseLight = vec4(0);
diffuseLight += CalcDiffuseLight(lightVector, normal, gl_LightSource[1].diffuse * SUN_RADIANCE);
// Calculate the decal texture, position, scale and rotation
vec4 decals = the_decaliser(uDecal1_Scale_Position, uDecal1_Rotation) + the_decaliser(uDecal2_Scale_Position, uDecal2_Rotation);
// Darken the glossmap with the decal tex so decals appear less shiny that the metal they are painted on
glossMap =mix(glossMap, min(decals.a, 0.2), decals.a); // darken the Glossmap with the decal so it appears more matte
glossMap -= max(mix(diffuseMapColor.a, 0.0, dustamount), 0.0); // darken the glossmap by the paintmap. the paintmap areas are the most glossy, this dulls that
// Darken the glossmap by the dust amount so the ship appears more dull and less shiny in dusty areas
float DustLayer = smoothstep(dustamount, 1.0, contrast(vec4(0.5, 0.9, 0.0, 1.0), wearMap));
glossMap =mix(glossMap, min(DustLayer, 0.0), DustLayer);
// Add the 'PaintChip' layer, we'll edge the chips with a slightly lighter version of the shape, to do this we need two copies of the chip shape, one slightly smaller than the other
float PaintChip = step(chipamount, wearMap); // try glossMap, it's the same texture but with some manipulation by now
// This is the smaller chip shape, subtracted from the large chip shape to find the chip edges later on in the shader...
float PaintChipsmaller = step(chipamountsmaller, wearMap);
// Subtract the smaller PaintChip from the bigger one to leave just the very edge of the shape
float PaintChipEdge = PaintChip - PaintChipsmaller;
// Darken the glossmap by the larger paint chip, so that these areas are less glossy
glossMap =mix(glossMap, min(PaintChipsmaller, 0.0), PaintChipsmaller); // note: change the 0.0 to 1.0 and the chipped areas are made shiny
// Get specular parameters
vec4 specularColor = gl_FrontMaterial.specular;
vec3 fresnel = vec3(0.0);
// Calculate specular light
vec4 specularLight = vec4(0);
fresnel = FresnelSchlick(specularColor.rgb, lightVector, halfVector);
float gloss = uGloss;
gloss *= glossMap;
vec4 ambientColor = gl_FrontMaterial.ambient;
vec4 diffuseColor = gl_FrontMaterial.diffuse;
// Begin repaint the colour texture - Select the paint scheme from the two arrays
int PaintIndex = int(uPaintColScheme);
vec4 PaintPrimaryCol = vec4(vec3(PRIMARY_COLOR[PaintIndex]), 1.0);
vec4 PaintSecondaryCol = vec4(vec3(SECONDARY_COLOR[PaintIndex]), 1.0);
// Calculate the mixing effect for the two paint colours, we'll run the paintMap (diffuseMapColor A) texture through the increse contrast function to get a map we can use to control the mix
float paintmixmap = contrast(vec4(0.5, 0.8, 0.2, 1.0), diffuseMapColor.a);
vec4 paintmix = mix(PaintSecondaryCol, PaintPrimaryCol, paintmixmap);
vec4 painteddiffuseMap = mix(diffuseMapColor, paintmix, diffuseMapColor.a);
// Mix the colour for the decal back into the main colour texture
vec4 decalTex = mix(painteddiffuseMap, decals, decals.a); // change diffuseMapColor to vec4(0.0) if you want to place the decal on a black background
vec4 decalpainteddiffuseMapcolor = mix(painteddiffuseMap, decalTex, decals.a);
// Dull the paint by mixing between a colour and a greyscale version
float GreyMixLevel = max(0.65, dustamount); // set the amount to mix between colour & greyscale versions of the texture, cap it a 65% color, 35% greyscale
float average = (decalpainteddiffuseMapcolor.r + decalpainteddiffuseMapcolor.g + decalpainteddiffuseMapcolor.b) / 3.0;
vec4 greyscaleversion = vec4(average, average, average, 1.0) ;
vec4 greycolor = mix(greyscaleversion, decalpainteddiffuseMapcolor, GreyMixLevel); // mix between the greyscale & colour versions of the texture, use the dulllevel to control the mix
// Add the dust layer
vec4 dustaddedcolor = mix(greycolor, kDustColor, DustLayer);
// Colour then mix in the PaintChip layers
vec4 PaintChipLayer = PaintChip * kBareMetalColor;
PaintChipLayer += PaintChipEdge * kPaintUndercoatColor;
vec4 chippedpaint = mix(dustaddedcolor, PaintChipLayer, PaintChip);
// Put everything created so far back into the color texture
diffuseMapColor = chippedpaint;
// Calculate the lighting color
diffuseColor *= diffuseMapColor;
ambientColor *= diffuseMapColor;
specularLight = vec4(CalcSpecularGGX(lightVector, normal, halfVector, eyeVector, gloss * (1.0 - decals.a), fresnel), 0.0);
specularLight.a = 1.0;
// light energy conservation here
vec4 kD = vec4(vec3(1.0) - fresnel, 1.0);
// Apply diffuse + ambient
totalColor += (diffuseColor * diffuseLight * kD) + (ambientColor * ambientLight);
// Apply Specular
totalColor += specularLight * gl_LightSource[1].specular * SUN_RADIANCE;
// calculate the hull lights
vec4 Lamp_pass = mix(vec4(0.0), diffuseMapColor, glowMap);
// Engine glow animation effect
vec2 scrolloffset = vec2(vTexCoord.s + effectsMap.r, vTexCoord.t + effectsMap.b);
float scrollingheatMap = texture2D(uDiffuseMap, scrollvTexCoord + scrolloffset).a * effectsMap.r;
// Call the function to modify the engine glow colour depending on current ship speed
vec4 PlumeColGLow = InjectorColGlow(uExhaustPlumeCol, uEnginePower);
// Calculate random engine flicker
vec2 twmp = vec2(vTexCoord * uTime);
float engnoise = rand(twmp);
float engineburp = max(0.8, sin(Pulse(uTime, 0.2))); // calculate small 'blip' for engine core glow level
// Check if ship is hostile, adjust lampColor accordingly
if (uAlertLevel > 0)
{
totalColor -= glowMap;
LampColor = (uAlertLevel > 2) ? kLampColorRedAlert * max(mod(uTime, 1.0), 0.5): kLampColorYellowAlert;
}
else
{
LampColor = kLampColorNoAlert;
}
// Calculate the amount to ship damage to apply
float tempvar = float(uDamageAmount);
float DamageAmount = mod(tempvar, 100.0) / 100.0;
// Calculate the engine and lamp glows
float LowLevelCoreGlow = smoothstep(0.0, 1.0, uEnginePower);
vec4 Lampglow = Lamp_pass * LampColor * Pulse(2.0, 1.0) * (1.0 - DamageAmount);
vec4 PlumeGlow = PlumeColGLow * effectsMap.b * Pulse(min(uEnginePower, 1.0), 1.0);
// Add a very low speed core glow colour, fade it out as speed increases
if (uEnginePower > 0.001)
{
totalColor += uExhaustCoreCol * effectsMap.b * max(0.0, 1.0 - LowLevelCoreGlow) * 0.2;
}
vec4 CoreGlow = uExhaustCoreCol * effectsMap.r * Pulse(min(uEnginePower, 1.0), 1.0) ;
CoreGlow += uExhaustCoreCol * engineburp * effectsMap.r * step(0.001, uEnginePower); // add in core glow level 'jitter'
CoreGlow *= engnoise;
vec4 FinalCoreGlow = mix(CoreGlow, CoreGlow * scrollingheatMap, min(uEnginePower, 0.8));
// Calculate a red glow for the engine core to simulate heated metal. This glow stays visible whilst the rest of the engine effect flickers from shipdamage
vec4 ConstCoreGlow = kRedExhaustGlow * effectsMap.r * Pulse(min(uEnginePower, 1.0), 1.0) * Blink_on_off(0.5, Pulse(1.0, 0.6));
ConstCoreGlow += kRedExhaustGlow * effectsMap.r * Pulse(min(uEnginePower, 1.0), 1.0) * Blink_on_off(0.5, Pulse(1.0, 0.7));
// Apply the engine and lamp glows
totalColor += mix(Lampglow + PlumeGlow + FinalCoreGlow,
ConstCoreGlow +
Lampglow * Blink_on_off(0.5, Pulse(1.0, 0.4)) * 4.0 +
PlumeGlow * Blink_on_off(0.5, Pulse(1.0, 1.0)), max(0.0, DamageAmount - 0.4));
// Apply the lasergun heat glow
totalColor += WeaponGlow(effectsMap.g * Pulse(min(uLaserHeatLevel, 1.0), 1.0));
// Calculate an engine misfire flicker, this only kick in when Tradefactor pases 80%
float EngineMisFire = effectsMap.b * uEnginePower * max(0.0, EngMisFireLV - 0.8);
totalColor += kRedExhaustGlow * Blink_on_off(0.9, Pulse(0.5, 0.9)) * EngineMisFire; // use vec4(5.0) to get a really strong white flash
// Apply the hull temperature glow
float hullHeat = max(uHullHeatLevel - 0.5, 0.0) * 2.0;
hullHeat = Pulse(hullHeat * hullHeat, 0.1);
totalColor += TemperatureGlow(hullHeat);
// Apply gamma correction to return to sRGB colorpsace and apply tone mapping. This should be the very last thing
// we do before sending the output to display.
// Using the J. Hejl & R. Burgess-Dawson forumla
vec3 x = max(vec3(0.0), totalColor.rgb - 0.004);
totalColor.rgb = (x * (6.2 * x + 0.5)) / (x * (6.2 * x + 1.7) + 0.06);
gl_FragColor = mix(totalColor, vec4(uFogColor.xyz, 1.0), 0.0); // change 0.0 to uFogColor.w for oolite
}
Code: Select all
vec4 specularColor = vec4(0.9,0.4,0.1,1.0); // forcing the spec color to a warm yellow
Exactly this. The spec map is RGB and for most non-metallic materials it should consist of various shades of gray depending on the reflectivity you want to achieve (although most non metals should have a specular of (0.04, 0.04, 0.04) but on the net you can find specific values for specific materials like here). When it is colored, it would normally refer to metallic surfaces and the diffuse of these surfaces would be black.
Ooooh, momma! Not to mention there are 4 of themanother_commander wrote: ↑Wed Nov 25, 2020 2:57 pm[...]
I really dig the blue light emitted from the engines.