diff options
Diffstat (limited to 'libs/preview_nif/data/shaders/sk_msn.frag')
| -rw-r--r-- | libs/preview_nif/data/shaders/sk_msn.frag | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/libs/preview_nif/data/shaders/sk_msn.frag b/libs/preview_nif/data/shaders/sk_msn.frag new file mode 100644 index 0000000..3ebbf93 --- /dev/null +++ b/libs/preview_nif/data/shaders/sk_msn.frag @@ -0,0 +1,194 @@ +#version 120 + +uniform sampler2D BaseMap; +uniform sampler2D NormalMap; +uniform sampler2D SpecularMap; +uniform sampler2D LightMask; +uniform sampler2D TintMask; +uniform sampler2D DetailMask; +uniform sampler2D BacklightMap; + +uniform vec3 specColor; +uniform float specStrength; +uniform float specGlossiness; + +uniform vec3 glowColor; +uniform float glowMult; + +uniform float alpha; + +uniform vec3 tintColor; + +uniform vec2 uvScale; +uniform vec2 uvOffset; + +uniform bool hasEmit; +uniform bool hasSoftlight; +uniform bool hasBacklight; +uniform bool hasRimlight; +uniform bool hasSpecularMap; +uniform bool hasDetailMask; +uniform bool hasTintMask; +uniform bool hasTintColor; + +uniform float softlight; +uniform float rimPower; + +uniform mat4 viewMatrix; + +varying vec3 v; + +varying vec2 TexCoord; +varying vec3 LightDir; +varying vec3 ViewDir; + +varying vec4 A; +varying vec4 C; +varying vec4 D; + + +vec3 tonemap(vec3 x) +{ + float _A = 0.15; + float _B = 0.50; + float _C = 0.10; + float _D = 0.20; + float _E = 0.02; + float _F = 0.30; + + return ((x*(_A*x+_C*_B)+_D*_E)/(x*(_A*x+_B)+_D*_F))-_E/_F; +} + +vec3 toGrayscale(vec3 color) +{ + return vec3(dot(vec3(0.3, 0.59, 0.11), color)); +} + +float overlay( float base, float blend ) +{ + float result; + if ( base < 0.5 ) { + result = 2.0 * base * blend; + } else { + result = 1.0 - 2.0 * (1.0 - blend) * (1.0 - base); + } + return result; +} + +vec3 overlay( vec3 ba, vec3 bl ) +{ + return vec3( overlay(ba.r, bl.r), overlay(ba.g, bl.g), overlay( ba.b, bl.b ) ); +} + +void main( void ) +{ + vec2 offset = TexCoord.st * uvScale + uvOffset; + + vec4 baseMap = texture2D( BaseMap, offset ); + vec4 normalMap = texture2D( NormalMap, offset ); + + vec3 normal = normalMap.rgb * 2.0 - 1.0; + + // Convert model space to view space + // Swizzled G/B values! + normal = normalize( vec3( viewMatrix * vec4( normal.rbg, 0.0 ))); + + // Face Normals + //vec3 X = dFdx(v); + //vec3 Y = dFdy(v); + //vec3 constructedNormal = normalize(cross(X,Y)); + + + vec3 L = normalize(LightDir); + vec3 E = normalize(ViewDir); + vec3 R = reflect(-L, normal); + vec3 H = normalize( L + E ); + + float NdotL = max( dot(normal, L), 0.0 ); + float NdotH = max( dot(normal, H), 0.0 ); + float EdotN = max( dot(normal, E), 0.0 ); + float NdotNegL = max( dot(normal, -L), 0.0 ); + + + vec4 color; + vec3 albedo = baseMap.rgb * C.rgb; + vec3 diffuse = A.rgb + (D.rgb * NdotL); + + + // Emissive + vec3 emissive = vec3(0.0); + if ( hasEmit ) { + emissive += glowColor * glowMult; + } + + // Specular + + float s = texture2D( SpecularMap, offset ).r; + if ( !hasSpecularMap || hasBacklight ) { + s = normalMap.a; + } + + vec3 spec = clamp( specColor * specStrength * s * pow(NdotH, specGlossiness), 0.0, 1.0 ); + spec *= D.rgb; + + + vec3 backlight = vec3(0.0); + if ( hasBacklight ) { + backlight = texture2D( BacklightMap, offset ).rgb; + backlight *= NdotNegL; + + emissive += backlight * D.rgb; + } + + vec4 mask = vec4(0.0); + if ( hasRimlight || hasSoftlight ) { + mask = texture2D( LightMask, offset ); + } + + vec3 rim = vec3(0.0); + if ( hasRimlight ) { + rim = mask.rgb * pow(vec3((1.0 - EdotN)), vec3(rimPower)); + rim *= smoothstep( -0.2, 1.0, dot(-L, E) ); + + emissive += rim * D.rgb; + } + + vec3 soft = vec3(0.0); + if ( hasSoftlight ) { + float wrap = (dot(normal, L) + softlight) / (1.0 + softlight); + + soft = max( wrap, 0.0 ) * mask.rgb * smoothstep( 1.0, 0.0, NdotL ); + soft *= sqrt( clamp( softlight, 0.0, 1.0 ) ); + + emissive += soft * D.rgb; + } + + vec3 detail = vec3(0.0); + if ( hasDetailMask ) { + detail = texture2D( DetailMask, offset ).rgb; + + albedo = overlay( albedo, detail ); + } + + vec3 tint = vec3(0.0); + if ( hasTintMask ) { + tint = texture2D( TintMask, offset ).rgb; + + albedo = overlay( albedo, tint ); + } + + if ( hasDetailMask ) { + albedo += albedo; + } + + if ( hasTintColor ) { + albedo *= tintColor; + } + + color.rgb = albedo * (diffuse + emissive) + spec; + color.rgb = tonemap( color.rgb ) / tonemap( vec3(1.0) ); + color.a = C.a * baseMap.a; + + gl_FragColor = color; + gl_FragColor.a *= alpha; +} |
