aboutsummaryrefslogtreecommitdiff
path: root/libs/preview_nif/data/shaders/sk_msn.frag
blob: 3ebbf9325e1fde0918fb61f6394ff4352928760c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
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;
}