Page Menu
Home
Phabricator (Chris)
Search
Configure Global Search
Log In
Files
F629658
pbr_ship_ps.txt
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Authored By
Unknown
Size
12 KB
Referenced Files
None
Subscribers
None
pbr_ship_ps.txt
View Options
#version 120
const int nLightCount = 2;
const float pi = 3.14159265358;
uniform sampler2D diffuse, normalAOlights, shield, masks;
uniform samplerCube skybox;
uniform vec4 ownerColor;
uniform vec3 glowColor;
uniform float thrust;
uniform float camDist;
uniform float time, nodeScale;
float teamNumber = 5;
//varying vec4 shadowCoord[nLightCount];
varying vec3 forward, right;
varying vec3 normal, binormal, tangent;
varying vec3 npos;
varying vec2 uv, uv2, uv3;
varying vec4 vertPaint;
vec3 light[nLightCount];
float dist[nLightCount];
/*
//Skybox sampling call
vec2 skyboxSample(vec3 dir) {
float x = dot(dir, forward);
float z = dot(dir, right);
float y = dot(dir, cross(forward,right));
return vec2(atan(-x,z) / 6.28318530718, (y + 1.0) * 0.5);
}
*/
//Engine heat color call
float mixRange(float x, float low, float hi) {
return clamp((x - low) / (hi - low), 0.0, 1.0);
}
vec3 blackBody(float temp) {
vec3 c;
c.r = mix(1.0, 0.6234, mixRange(temp, 6400.0, 29800.0));
c.b = mix(0.0, 1.0, mixRange(temp, 2800.0, 7600.0));
if(temp < 6600.0)
c.g = mix(0.22, 0.976, mixRange(temp, 1000.0, 6600.0));
else
c.g = mix(0.976, 0.75, mixRange(temp, 6600.0, 29800.0));
return c;
}
float D_GGX(float HdotN, float Roughness)
{
float m = Roughness * Roughness;
float m2 = m * m;
float denominator = HdotN * HdotN * (m2 - 1.0) + 1.0;
float D = m2 /( pi * denominator * denominator);
return D;
}
// Schlick GGX approximation
float V_SchlickforGGX(float Roughness, float NdotV, float NdotL)
{
float k = Roughness * Roughness * 0.5f;
float G1V = NdotV * (1.0 - k) + k;
float G1L = NdotL * (1.0 - k) + k;
return 0.25f / (G1V * G1L);
}
vec3 Fresnel(vec3 substance, vec3 l, vec3 h)
{
return substance + (1.0 - substance) * pow(1.0 - clamp((dot(l, h)), 0.0, 1.0), 5.0);
}
vec3 Fresnel2(vec3 substance, float dotProduct, float roughness)
{
return substance + (1.0 - substance) * pow((1.0 - dotProduct), 5.0) / (6.0 - 5.0 * roughness);
}
float RoughToSPow(float fRoughness)
{
return (2.0 / (fRoughness * fRoughness)) - 2.0;
}
const float k0 = 0.00098f, k1 = 0.9921f;
const float g_fMaxT = (exp2(-10.0 / sqrt((2.0 / (0.0014f * 0.0014f)) - 2.0)) - 0.00098f) / 0.9921f;
float GetSpecPowToMip(float fSpecPow, int nMips)
{
float fSmulMaxT = (exp2( -10.0 / sqrt(fSpecPow)) - k0) / k1;
return float(nMips - 1) * (1.0 - clamp(fSmulMaxT / g_fMaxT, 0.0, 1.0 ));
}
void main() {
vec4 diffuse = texture2D(diffuse, uv.xy);
vec4 normAO = texture2D(normalAOlights, uv.xy);
vec3 maskSamp = texture2D(masks, uv.xy).rgb;
float paintSamp = texture2D(masks, uv2.xy).w;
float flagSamp = texture2D(masks, uv2.xy + vec2((1.0/32.0) * teamNumber, 0.0)).w;
vec3 vertMasksPrimary = vertPaint.rgb; // .a unused
//float texSamp7 = texture2D(shield, uv2.xy * 10);
//float texSamp8 = texture2D(shield, uv2.xy - time * 80.0);
float texSamp5 = texture2D(shield, uv2.xy - 8.0 * 24.0).r;
float texSamp6 = texture2D(shield, uv2.xy + time * 24.0).g;
// Normal map setup
vec3 normMap = normAO.xyz * 2.0 - vec3(1.0);
// Vertex masks setup
vec3 vertMasksSecondary = (clamp(vertMasksPrimary, 0.5, 1.0) - 0.5) * 2.0; // shield r, windows g, engine b
vertMasksPrimary = clamp(((1.0 - vertMasksPrimary) - 0.5)* 2.0, 0.0, 1.0); // flags g, warp b, transparency on r
// Texture masks setup
float paintMask = (flagSamp * vertMasksPrimary.g + paintSamp * (1.0-vertMasksPrimary.g)) * maskSamp.b;
float plateMask = maskSamp.b * (1.0-paintMask);
float roughnessTweakMask = plateMask * (1.0-paintMask);
float lightsOne = (clamp(1.0 - normAO.w, 0.5, 1.0) - 0.5) * 2.0;
float lightsTwo = (clamp(normAO.w, 0.5, 1.0) - 0.5) * 2.0;
// Emissive lights setup
vec3 lights = vec3(0.0);
float lightMask = 1.0 - vertMasksSecondary.r - vertMasksSecondary.g - vertMasksSecondary.b - vertMasksPrimary.b; // filter for no-special lights
// Primary and secondary lights are added - should be selectable, as owner and inverted owner is not always nice
lights += vec3(lightsOne * lightMask * ownerColor.rgb * 2.0);
lights += vec3(lightsTwo * lightMask * (1.0 - ownerColor.rgb) * 2.0);
// Warp drive is added - currently no models contains the mask.
float engineGlow = texSamp5 * texSamp6;
// lights += vec3(2.0, 0.0, 2.0) * (1.0 + engineGlow) * lightsTwo * vertMasksPrimary.b;
// Windows are added
lights += glowColor * vertMasksSecondary.g * lightsOne;
// Engine animation is created
engineGlow = lightsOne * (/*lightsOne * 2.0 + */engineGlow * 2.0) * vertMasksSecondary.b;
// Gives nice intensity and falloff transitions.
lights = pow(lights + (lightsOne + lightsTwo) * 1.0, vec3(1.5)) * (1.0 - vertMasksPrimary.r);
// Transparency setup
float transparency = min(clamp((clamp(diffuse.w,0.25, 0.5) - 0.25), 0.0, 0.25) * 4 + 0.25, 1.0-vertMasksPrimary.r);
// Transparency and ao extractionsetup
float ao = (1.0-((1.0-transparency) * 0.5 + diffuse.w))*2.0;
// Engine setup
float thrustIntensity = pow(thrust * 1.0, 2.0) * engineGlow;
lights += (blackBody(1000.0 + 5000.0 * thrustIntensity) * thrustIntensity);
// Player color setup - move the PBR values to external source!
// float playerMetal = 0.01; //PBR gold
// vec3 playerMetalCol = vec3(1.0, 0.77, 0.33); //PBR gold
// float playerMetal = 0.25; //PBR bronze
// vec3 playerMetalCol = vec3(0.99, 0.64, 0.34); //PBR bronze
// float playerMetal = 0.13; //PBR brass
// vec3 playerMetalCol = vec3(0.98, 0.87, 0.41); //PBR brass
// float playerMetal = 0.35; //PBR Copper
// vec3 playerMetalCol = vec3(0.98, 0.60, 0.52); //PBR Copper
// float playerMetal = 0.10; //PBR Silver
// vec3 playerMetalCol = vec3(0.97, 0.96, 0.91); //PBR Silver
// float playerMetal = 0.01; //PBR Chrome
// vec3 playerMetalCol = vec3(0.91, 0.95, 0.97); //PBR Chrome
// float playerMetal = 0.45; //PBR Titanium
// vec3 playerMetalCol = vec3(0.54, 0.49, 0.46); //PBR Titanium
// float playerMetal = 0.15; //PBR Bright Steel
// vec3 playerMetalCol = vec3(0.84, 0.85, 0.90); //PBR Bright Steel
// float playerMetal = 0.75; //PBR Dull Steel
// vec3 playerMetalCol = vec3(0.56, 0.57, 0.58); //PBR Dull Steel
// float playerMetal = 0.25; //PBR Dark Steel
// vec3 playerMetalCol = vec3(0.48, 0.45, 0.42) ; //PBR Dark Steel
// float playerMetal = 0.27; //PBR Gallium
// vec3 playerMetalCol = vec3(0.88, 0.93, 0.56); //PBR Gallium
// float playerMetal = 0.35; //PBR Molybdenum
// vec3 playerMetalCol = vec3(0.16, 0.22, 0.15); //PBR Molybdenum
// float playerMetal = 0.33; //PBR Niobium
// vec3 playerMetalCol = vec3(0.38, 0.34, 0.62); //PBR Niobium
// float playerMetal = 0.35; //PBR Vanadium
// vec3 playerMetalCol = vec3(0.08, 0.10, 0.09); //PBR Vanadium
// float playerMetal = 0.25; //PBR Adamantium
// vec3 playerMetalCol = vec3(0.26, 0.18, 0.25); //PBR Adamantium
// float playerMetal = 0.07; //PBR Tritinium
// vec3 playerMetalCol = vec3(0.54, 0.49, 0.62); //PBR Tritinium
// float playerMetal = 0.03; //PBR Zentronium
// vec3 playerMetalCol = vec3(0.96, 0.48, 0.43); //PBR Zentronium
// float playerMetal = 0.16; //PBR Xintinium
// vec3 playerMetalCol = vec3(0.48, 0.96, 0.96); //PBR Xintinium
// float playerMetal = 0.15; //PBR Duranium
// vec3 playerMetalCol = vec3(0.94, 0.24, 0.02); //PBR Duranium
// float playerMetal = 1.0; //PBR Carbon Fibre Complimentary
// vec3 playerMetalCol = vec3(1.0 - ownerColor) * 0.25; //PBR Carbon Fibre Complimentary
// float playerMetal = 0.9; //PBR Ceramic Complimentary
// vec3 playerMetalCol = vec3(1.0 - ownerColor) * 0.64 + vec3(0.32); //PBR Ceramic Complimentary
// float playerMetal = 1.0; //PBR Paint Complimentary
// vec3 playerMetalCol = vec3(1.0 - ownerColor); //PBR Paint Complimentary
float playerMetal = 0.15; //PBR Metal Complimentary
vec3 playerMetalCol = vec3(1.0 - ownerColor) * 0.5 + vec3(0.5); //PBR Metal Complimentary
vec4 playerPlateProfile = vec4(playerMetalCol, playerMetal);
// PBR mixer
playerMetal = clamp(playerMetal, 0.001, 1.0) * plateMask;
vec3 paintColor = ownerColor.rgb * (1.0-paintMask);
float metalness = clamp(maskSamp.g * max(0.5, 1.0-paintMask), 0.0, 1.0);
// Roughness setup
float orgRoughness = maskSamp.r * (1.0-plateMask) + plateMask * (plateMask * playerPlateProfile.w);
// Albedo setup
vec3 albedo = mix(diffuse.rgb * plateMask * playerMetalCol, ownerColor.rgb * diffuse.rgb, paintMask);
albedo = mix(diffuse.rgb, albedo, maskSamp.b);
// Shield setup.
lights *= (1.0 - vertMasksSecondary.r);
//vertMasksSecondary.r * (1.0 - abs(texSamp5 * texSamp6 * 2.0 - 1.0)) * vec3(0.33, 0.99, 2.0);
// transparency *= vertMasksSecondary.r * (1.0 - abs(texSamp5 * texSamp6 * 2.0 - 1.0)) * 0.66;
transparency *= clamp(1.0 - vertMasksSecondary.r * 0.5, 0.0, 1.0);
transparency += (texSamp5 * texSamp6);// * vertMasksSecondary.r;
lights += transparency * vec3(0.33, 0.99, 2.0) * vertMasksSecondary.r;
//Adjust all other PBR textures accordingly
ao *= 1.0 - vertMasksSecondary.r;
orgRoughness *= 1.0 - vertMasksSecondary.r;
metalness *= 1.0 - vertMasksSecondary.r;
albedo *= 1.0-vertMasksSecondary.r;
normMap = normalize(mix(normMap, vec3(0.0,0.0,1.0), vertMasksSecondary.r));
// Normal setup
vec3 n = normalize(normal) * normMap.z;
n += normalize(binormal) * normMap.y;
n += normalize(tangent) * normMap.x;
n = normalize(n);
vec3 v = normalize(npos);
vec3 r = normalize(reflect(-v, n));
// Substance setup and Albedo adjust
vec3 substance = clamp((0.04 - 0.04 * metalness) + albedo * metalness,0.0, 1.0);
albedo -= substance;
// Light model specials setup
float NdotV = clamp(dot(n, v), 0.0, 1.0);
float roughnessV = (orgRoughness + 1.0)/2.0; // roughness remapping
if(nLightCount > 0) {
const int i = 0;
light[i] = gl_LightSource[i].position.xyz + npos;
dist[i] = length(light[i]);
light[i] = light[i] / dist[i];
}
if(nLightCount > 1) {
const int i = 1;
light[i] = gl_LightSource[i].position.xyz + npos;
dist[i] = length(light[i]);
light[i] = light[i] / dist[i];
}
//Zoom-out highlight setup
float highlight = 0.0;
if(camDist > 1.0)
highlight += smoothstep(0.0, 500.0, camDist / sqrt(nodeScale)) * 0.2;
vec3 color = vec3(highlight);
// Ambient reflections
float fakeLysSpecularPower=RoughToSPow(orgRoughness);
float lysMipMap = GetSpecPowToMip(fakeLysSpecularPower,8);
color += textureCube(skybox, r, lysMipMap).rgb * Fresnel2(substance,NdotV,orgRoughness);
// use this if you want a cheaper reflection cubemap calculation. If so, remember to remove the GetSpecPowToMip() and RoughToSPow()
// color += textureCube(skybox, r,8.0 - (8.0*(1.0-orgRoughness))).rgb * reflectionFresnel;
// Ambient light
color += textureCube(skybox, n, 7.0).rgb * albedo * (1.0 - Fresnel2(substance,NdotV,orgRoughness));
if(nLightCount > 0) {
//light
const int i = 0;
// float falloff = 1.0 / (1.0 + (gl_LightSource[i].quadraticAttenuation * dist[i] * dist[i]));
// float NdotL = clamp(dot(n,light[i]) + 0.2,0.0, 1.0);
// fakes disc lights up close to a star.
float falloff = 1.0 / (0.25 + (gl_LightSource[i].quadraticAttenuation * dist[i] * dist[i]));
float NdotL = clamp(dot(n,light[i]) + 0.2,0.0, 1.0);
float intensity = falloff * NdotL;
vec3 L=light[i];
L = normalize(L);
vec3 VplusL = L + v;
vec3 halfVec = normalize(VplusL);
float HdotN = clamp(dot(halfVec,n), 0.0, 0.98);
vec3 F = Fresnel(substance, L, halfVec);
float D = D_GGX(HdotN, roughnessV);
float V = V_SchlickforGGX(roughnessV, NdotV, NdotL);
color += ao * ((D * V * F) + (1.0 - F) * NdotL * albedo) * gl_LightSource[i].diffuse.rgb * intensity;
}
if(nLightCount > 1) {
//light
const int i = 1;
// float falloff = 1.0 / (1.0 + (gl_LightSource[i].quadraticAttenuation * dist[i] * dist[i]));
// float NdotL = clamp(dot(n,light[i]) + 0.2,0.0, 1.0);
// fakes disc lights up close to a star.
float falloff = 1.0 / (0.25 + (gl_LightSource[i].quadraticAttenuation * dist[i] * dist[i]));
float NdotL = clamp(dot(n,light[i]) + 0.2,0.0, 1.0);
float intensity = falloff * NdotL;
vec3 L=light[i];
L = normalize(L);
vec3 VplusL = L + v;
vec3 halfVec = normalize(VplusL);
float HdotN = clamp(dot(halfVec,n), 0.0, 1.0);
vec3 F = Fresnel(substance, L, halfVec);
float D = D_GGX(HdotN, roughnessV);
float V = V_SchlickforGGX(roughnessV, NdotV, NdotL);
color += ao * ((D * V * F) + (1.0 - F) * NdotL * albedo) * gl_LightSource[i].diffuse.rgb * intensity;
}
gl_FragColor.rgb = color + lights;
gl_FragColor.a = transparency + 1.0;
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Sun, Nov 15, 7:28 AM (34 m, 49 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
127390
Default Alt Text
pbr_ship_ps.txt (12 KB)
Attached To
Mode
R80 StarRuler2-Source
Attached
Detach File
Event Timeline