Griff's normalmapped ship remakes
Moderators: winston, another_commander
- Cody
- Sharp Shooter Spam Assassin
- Posts: 16081
- Joined: Sat Jul 04, 2009 9:31 pm
- Location: The Lizard's Claw
- Contact:
Re: Griff's normalmapped ship remakes
Sweet!
I would advise stilts for the quagmires, and camels for the snowy hills
And any survivors, their debts I will certainly pay. There's always a way!
And any survivors, their debts I will certainly pay. There's always a way!
- montana05
- ---- E L I T E ----
- Posts: 1166
- Joined: Mon May 30, 2016 3:54 am
- Location: lurking in The Devils Triangle (G1)
Re: Griff's normalmapped ship remakes
The master of graphics is back, a very warm welcome
Scars remind us where we've been. They don't have to dictate where we're going.
- Griff
- Oolite 2 Art Director
- Posts: 2483
- Joined: Fri Jul 14, 2006 12:29 pm
- Location: Probably hugging his Air Fryer
Re: Griff's normalmapped ship remakes
i definately need to read the pbr guide again, i'm certain i'm probaby using an incorrect material
heh, i edit shaders by just trying to copy as much as i can from oolite's default shader before rendermonkey breaks, the ones n the oxp "griff_HP_CobraIII_NPC" and "griff_HP_CobraIII_PLAYER" are the ones i've tried to get as close to what oolite is doing, they just send everything a deep blue in rendermonkey and a bit blueish (i think) in oolte - rendermonkey i think might be doing that as it probabky doesn't set up lights the same as oolite does, so stuff like .ambient might not have a proper value in it inside rendermonkey
it's this line i think
// light energy conservation here
vec4 kD = vec4(vec3(1.0) - fresnel, 1.0);
had to do this to stop the blueness
vec4 kD = vec4(1.0);
plus i also set a fixed specular colour to a warm yellow/orange
heh, i edit shaders by just trying to copy as much as i can from oolite's default shader before rendermonkey breaks, the ones n the oxp "griff_HP_CobraIII_NPC" and "griff_HP_CobraIII_PLAYER" are the ones i've tried to get as close to what oolite is doing, they just send everything a deep blue in rendermonkey and a bit blueish (i think) in oolte - rendermonkey i think might be doing that as it probabky doesn't set up lights the same as oolite does, so stuff like .ambient might not have a proper value in it inside rendermonkey
it's this line i think
// light energy conservation here
vec4 kD = vec4(vec3(1.0) - fresnel, 1.0);
had to do this to stop the blueness
vec4 kD = vec4(1.0);
plus i also set a fixed specular colour to a warm yellow/orange
Wiki homepage for my OXP: http://wiki.alioth.net/index.php/Griff_Industries
-
- Quite Grand Sub-Admiral
- Posts: 6683
- Joined: Wed Feb 28, 2007 7:54 am
Re: Griff's normalmapped ship remakes
Here it is, with some basic shader treatment. Includes energy conservation, gamma correction and tone mapping.
The modified shader, based on griff_HP_CobraIII_PLAYER, is this:
and the modification to the player shipdata entry:
I really dig the blue light emitted from the engines.
The modified shader, based on griff_HP_CobraIII_PLAYER, is this:
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";
}
);
};
- Cholmondely
- Archivist
- Posts: 5365
- Joined: Tue Jul 07, 2020 11:00 am
- Location: The Delightful Domains of His Most Britannic Majesty (industrial? agricultural? mainly anything?)
- Contact:
Re: Griff's normalmapped ship remakes
Inspiring!
I'd really rather like one...
Not too sure where I'd keep it ... our coach-house is a tad on the small side ...
I'd really rather like one...
Not too sure where I'd keep it ... our coach-house is a tad on the small side ...
Comments wanted:
•Missing OXPs? What do you think is missing?
•Lore: The economics of ship building How many built for Aronar?
•Lore: The Space Traders Flight Training Manual: Cowell & MgRath Do you agree with Redspear?
•Missing OXPs? What do you think is missing?
•Lore: The economics of ship building How many built for Aronar?
•Lore: The Space Traders Flight Training Manual: Cowell & MgRath Do you agree with Redspear?
- Griff
- Oolite 2 Art Director
- Posts: 2483
- Joined: Fri Jul 14, 2006 12:29 pm
- Location: Probably hugging his Air Fryer
Re: Griff's normalmapped ship remakes
wow that looks great, thanks for fixing the shader A_C, i'll copy the fixes and update the oxp, i'll set t player version to use multiple decals too
Wiki homepage for my OXP: http://wiki.alioth.net/index.php/Griff_Industries
- Redspear
- ---- E L I T E ----
- Posts: 2687
- Joined: Thu Jun 20, 2013 10:22 pm
- Location: On the moon Thought, orbiting the planet Ignorance.
Re: Griff's normalmapped ship remakes
Love it!
That near equilateral triangle at the nose really brings the flavour of the original elite model... while the detailing takes it to another level entirely.
Good job Griff! (and nicely fixed a_c)
That near equilateral triangle at the nose really brings the flavour of the original elite model... while the detailing takes it to another level entirely.
Good job Griff! (and nicely fixed a_c)
- Cody
- Sharp Shooter Spam Assassin
- Posts: 16081
- Joined: Sat Jul 04, 2009 9:31 pm
- Location: The Lizard's Claw
- Contact:
Re: Griff's normalmapped ship remakes
Music to my ears, amigo!
I would advise stilts for the quagmires, and camels for the snowy hills
And any survivors, their debts I will certainly pay. There's always a way!
And any survivors, their debts I will certainly pay. There's always a way!
-
- Quite Grand Sub-Admiral
- Posts: 6683
- Joined: Wed Feb 28, 2007 7:54 am
Re: Griff's normalmapped ship remakes
I have made a few more edits on the Cobra shader in order to comment a bit better the things I changed and also because I found that some of the calculations done were not actually used and could be omitted. Also reduced slightly the overall gloss applied by the shader, so that we get back the nice cockpit reflection present in the original shader. Here is the modified griff_HP_CobraIII_PLAYER.fragment shader in its current form:
Edit: Griff, regarding your blue tinting issue, it was because of this line:
This enables colored specular on a material that emits diffuse color. This is in violation of natural laws and creates an impossible material. Because of light energy conservation, the shader is trying to paint the non-reflective areas with the color that is complementary to yellow, i.e. blue, thus tinting whatever diffuse color is emitted at those areas. The only materials that can have colorized specular are metals and those do not emit diffuse (or, in other words, diffuse color for metals is black in the specular-gloss PBR workflow that we use).
As a final note, we don't seem to have a specular map. This leaves room for further improvement on this otherwise excellent model, by allowing multiple reflectivities across the surface of the ship. Combined with the existing gloss map, there is a lot of potential to be exploited here if you want to.
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
As a final note, we don't seem to have a specular map. This leaves room for further improvement on this otherwise excellent model, by allowing multiple reflectivities across the surface of the ship. Combined with the existing gloss map, there is a lot of potential to be exploited here if you want to.
- Griff
- Oolite 2 Art Director
- Posts: 2483
- Joined: Fri Jul 14, 2006 12:29 pm
- Location: Probably hugging his Air Fryer
Re: Griff's normalmapped ship remakes
Thanks for picking through all this and fixing stuff A_C, i was just having a read of the lighting guide, https://bb.oolite.space/viewtopic.ph ... c4427c452e - the lightbulb floating above my head is very dim but slowly starting to brighten
it's not the guide's fault, it's excellent but i'm struggling a bit, i think i might have confused gloss and spec intensity in my textures
I'm totally up for adding a specular map, is that just a greyscale 'intensity' texture, or do i need the rgb channels for specular_color and the alpha channel for the intensity? and if i do use rgb for specular colour, then that's just to have color on the pure metal parts and not on the 'painted metal' parts like the top of the hull (they'd be black in the spec colour map?)
it's not the guide's fault, it's excellent but i'm struggling a bit, i think i might have confused gloss and spec intensity in my textures
I'm totally up for adding a specular map, is that just a greyscale 'intensity' texture, or do i need the rgb channels for specular_color and the alpha channel for the intensity? and if i do use rgb for specular colour, then that's just to have color on the pure metal parts and not on the 'painted metal' parts like the top of the hull (they'd be black in the spec colour map?)
Wiki homepage for my OXP: http://wiki.alioth.net/index.php/Griff_Industries
-
- Quite Grand Sub-Admiral
- Posts: 6683
- Joined: Wed Feb 28, 2007 7:54 am
Re: Griff's normalmapped ship remakes
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.
In the core shaders the alpha of the specmap is used for gloss, but I see that you are handling it differently on your shader. That's fine and you can use the alpha of your specular for something else, although the spec intensity is basically already determined by how white or black the spec rgb texture is. You may want to experiment with different combinations of gloss and specular to fully understand what each of them does, I know it's a bit tricky getting one's head around all this.
-
- ---- E L I T E ----
- Posts: 675
- Joined: Sat Aug 09, 2014 4:16 pm
Re: Griff's normalmapped ship remakes
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.
- Cody
- Sharp Shooter Spam Assassin
- Posts: 16081
- Joined: Sat Jul 04, 2009 9:31 pm
- Location: The Lizard's Claw
- Contact:
Re: Griff's normalmapped ship remakes
Griff - I'm having problems downloading from this link: https://drive.google.com/drive/folders/ ... sp=sharing (updated today, yes?)
I would advise stilts for the quagmires, and camels for the snowy hills
And any survivors, their debts I will certainly pay. There's always a way!
And any survivors, their debts I will certainly pay. There's always a way!
- Griff
- Oolite 2 Art Director
- Posts: 2483
- Joined: Fri Jul 14, 2006 12:29 pm
- Location: Probably hugging his Air Fryer
Re: Griff's normalmapped ship remakes
hmm, it does look like it's picky about the browser, just tried in Internet Explorer and i got a page saying the website wasn't compatible
Just in case i've done something wrong trying to share the folder earlier i think this is a direct link to the multidecal player version of the oxp
https://drive.google.com/file/d/1NEpm7a ... sp=sharing
it's a bit weird, i follow that link and then i get a page that seems to let me explore inside the .zip file and see all the sub folders instead of downloading the file, but there's a small download arrow up in the top right of the page that does seem to allow downloading the whole zip
If this still doesn't work i think my box.com login account still works, i could put it up on there
Just in case i've done something wrong trying to share the folder earlier i think this is a direct link to the multidecal player version of the oxp
https://drive.google.com/file/d/1NEpm7a ... sp=sharing
it's a bit weird, i follow that link and then i get a page that seems to let me explore inside the .zip file and see all the sub folders instead of downloading the file, but there's a small download arrow up in the top right of the page that does seem to allow downloading the whole zip
If this still doesn't work i think my box.com login account still works, i could put it up on there
Wiki homepage for my OXP: http://wiki.alioth.net/index.php/Griff_Industries
- Cody
- Sharp Shooter Spam Assassin
- Posts: 16081
- Joined: Sat Jul 04, 2009 9:31 pm
- Location: The Lizard's Claw
- Contact:
Re: Griff's normalmapped ship remakes
That got it - thanks! Have you still got access to your folder in my Box, btw?
I would advise stilts for the quagmires, and camels for the snowy hills
And any survivors, their debts I will certainly pay. There's always a way!
And any survivors, their debts I will certainly pay. There's always a way!