• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#import "Common/ShaderLib/Parallax.glsllib"
2#import "Common/ShaderLib/Optics.glsllib"
3#define ATTENUATION
4//#define HQ_ATTENUATION
5
6varying vec2 texCoord;
7#ifdef SEPARATE_TEXCOORD
8  varying vec2 texCoord2;
9#endif
10
11varying vec3 AmbientSum;
12varying vec4 DiffuseSum;
13varying vec3 SpecularSum;
14
15#ifndef VERTEX_LIGHTING
16  uniform vec4 g_LightDirection;
17  //varying vec3 vPosition;
18  varying vec3 vViewDir;
19  varying vec4 vLightDir;
20  varying vec3 lightVec;
21#else
22  varying vec2 vertexLightValues;
23#endif
24
25#ifdef DIFFUSEMAP
26  uniform sampler2D m_DiffuseMap;
27#endif
28
29#ifdef SPECULARMAP
30  uniform sampler2D m_SpecularMap;
31#endif
32
33#ifdef PARALLAXMAP
34  uniform sampler2D m_ParallaxMap;
35#endif
36#if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP))) && !defined(VERTEX_LIGHTING)
37    uniform float m_ParallaxHeight;
38#endif
39
40#ifdef LIGHTMAP
41  uniform sampler2D m_LightMap;
42#endif
43
44#ifdef NORMALMAP
45  uniform sampler2D m_NormalMap;
46#else
47  varying vec3 vNormal;
48#endif
49
50#ifdef ALPHAMAP
51  uniform sampler2D m_AlphaMap;
52#endif
53
54#ifdef COLORRAMP
55  uniform sampler2D m_ColorRamp;
56#endif
57
58uniform float m_AlphaDiscardThreshold;
59
60#ifndef VERTEX_LIGHTING
61uniform float m_Shininess;
62
63#ifdef HQ_ATTENUATION
64uniform vec4 g_LightPosition;
65#endif
66
67#ifdef USE_REFLECTION
68    uniform float m_ReflectionPower;
69    uniform float m_ReflectionIntensity;
70    varying vec4 refVec;
71
72    uniform ENVMAP m_EnvMap;
73#endif
74
75float tangDot(in vec3 v1, in vec3 v2){
76    float d = dot(v1,v2);
77    #ifdef V_TANGENT
78        d = 1.0 - d*d;
79        return step(0.0, d) * sqrt(d);
80    #else
81        return d;
82    #endif
83}
84
85float lightComputeDiffuse(in vec3 norm, in vec3 lightdir, in vec3 viewdir){
86    #ifdef MINNAERT
87        float NdotL = max(0.0, dot(norm, lightdir));
88        float NdotV = max(0.0, dot(norm, viewdir));
89        return NdotL * pow(max(NdotL * NdotV, 0.1), -1.0) * 0.5;
90    #else
91        return max(0.0, dot(norm, lightdir));
92    #endif
93}
94
95float lightComputeSpecular(in vec3 norm, in vec3 viewdir, in vec3 lightdir, in float shiny){
96    // NOTE: check for shiny <= 1 removed since shininess is now
97    // 1.0 by default (uses matdefs default vals)
98    #ifdef LOW_QUALITY
99       // Blinn-Phong
100       // Note: preferably, H should be computed in the vertex shader
101       vec3 H = (viewdir + lightdir) * vec3(0.5);
102       return pow(max(tangDot(H, norm), 0.0), shiny);
103    #elif defined(WARDISO)
104        // Isotropic Ward
105        vec3 halfVec = normalize(viewdir + lightdir);
106        float NdotH  = max(0.001, tangDot(norm, halfVec));
107        float NdotV  = max(0.001, tangDot(norm, viewdir));
108        float NdotL  = max(0.001, tangDot(norm, lightdir));
109        float a      = tan(acos(NdotH));
110        float p      = max(shiny/128.0, 0.001);
111        return NdotL * (1.0 / (4.0*3.14159265*p*p)) * (exp(-(a*a)/(p*p)) / (sqrt(NdotV * NdotL)));
112    #else
113       // Standard Phong
114       vec3 R = reflect(-lightdir, norm);
115       return pow(max(tangDot(R, viewdir), 0.0), shiny);
116    #endif
117}
118
119vec2 computeLighting(in vec3 wvNorm, in vec3 wvViewDir, in vec3 wvLightDir){
120   float diffuseFactor = lightComputeDiffuse(wvNorm, wvLightDir, wvViewDir);
121   float specularFactor = lightComputeSpecular(wvNorm, wvViewDir, wvLightDir, m_Shininess);
122
123   #ifdef HQ_ATTENUATION
124    float att = clamp(1.0 - g_LightPosition.w * length(lightVec), 0.0, 1.0);
125   #else
126    float att = vLightDir.w;
127   #endif
128
129   if (m_Shininess <= 1.0) {
130       specularFactor = 0.0; // should be one instruction on most cards ..
131   }
132
133   specularFactor *= diffuseFactor;
134
135   return vec2(diffuseFactor, specularFactor) * vec2(att);
136}
137#endif
138
139void main(){
140    vec2 newTexCoord;
141
142    #if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP))) && !defined(VERTEX_LIGHTING)
143
144       #ifdef STEEP_PARALLAX
145           #ifdef NORMALMAP_PARALLAX
146               //parallax map is stored in the alpha channel of the normal map
147               newTexCoord = steepParallaxOffset(m_NormalMap, vViewDir, texCoord, m_ParallaxHeight);
148           #else
149               //parallax map is a texture
150               newTexCoord = steepParallaxOffset(m_ParallaxMap, vViewDir, texCoord, m_ParallaxHeight);
151           #endif
152       #else
153           #ifdef NORMALMAP_PARALLAX
154               //parallax map is stored in the alpha channel of the normal map
155               newTexCoord = classicParallaxOffset(m_NormalMap, vViewDir, texCoord, m_ParallaxHeight);
156           #else
157               //parallax map is a texture
158               newTexCoord = classicParallaxOffset(m_ParallaxMap, vViewDir, texCoord, m_ParallaxHeight);
159           #endif
160       #endif
161    #else
162       newTexCoord = texCoord;
163    #endif
164
165   #ifdef DIFFUSEMAP
166      vec4 diffuseColor = texture2D(m_DiffuseMap, newTexCoord);
167    #else
168      vec4 diffuseColor = vec4(1.0);
169    #endif
170
171    float alpha = DiffuseSum.a * diffuseColor.a;
172    #ifdef ALPHAMAP
173       alpha = alpha * texture2D(m_AlphaMap, newTexCoord).r;
174    #endif
175    if(alpha < m_AlphaDiscardThreshold){
176        discard;
177    }
178
179    #ifndef VERTEX_LIGHTING
180        float spotFallOff = 1.0;
181
182        #if __VERSION__ >= 110
183          // allow use of control flow
184          if(g_LightDirection.w != 0.0){
185        #endif
186
187          vec3 L       = normalize(lightVec.xyz);
188          vec3 spotdir = normalize(g_LightDirection.xyz);
189          float curAngleCos = dot(-L, spotdir);
190          float innerAngleCos = floor(g_LightDirection.w) * 0.001;
191          float outerAngleCos = fract(g_LightDirection.w);
192          float innerMinusOuter = innerAngleCos - outerAngleCos;
193          spotFallOff = (curAngleCos - outerAngleCos) / innerMinusOuter;
194
195          #if __VERSION__ >= 110
196              if(spotFallOff <= 0.0){
197                  gl_FragColor.rgb = AmbientSum * diffuseColor.rgb;
198                  gl_FragColor.a   = alpha;
199                  return;
200              }else{
201                  spotFallOff = clamp(spotFallOff, 0.0, 1.0);
202              }
203             }
204          #else
205             spotFallOff = clamp(spotFallOff, step(g_LightDirection.w, 0.001), 1.0);
206          #endif
207     #endif
208
209    // ***********************
210    // Read from textures
211    // ***********************
212    #if defined(NORMALMAP) && !defined(VERTEX_LIGHTING)
213      vec4 normalHeight = texture2D(m_NormalMap, newTexCoord);
214      vec3 normal = (normalHeight.xyz * vec3(2.0) - vec3(1.0));
215      #ifdef LATC
216        normal.z = sqrt(1.0 - (normal.x * normal.x) - (normal.y * normal.y));
217      #endif
218      //normal.y = -normal.y;
219    #elif !defined(VERTEX_LIGHTING)
220      vec3 normal = vNormal;
221      #if !defined(LOW_QUALITY) && !defined(V_TANGENT)
222         normal = normalize(normal);
223      #endif
224    #endif
225
226    #ifdef SPECULARMAP
227      vec4 specularColor = texture2D(m_SpecularMap, newTexCoord);
228    #else
229      vec4 specularColor = vec4(1.0);
230    #endif
231
232    #ifdef LIGHTMAP
233       vec3 lightMapColor;
234       #ifdef SEPARATE_TEXCOORD
235          lightMapColor = texture2D(m_LightMap, texCoord2).rgb;
236       #else
237          lightMapColor = texture2D(m_LightMap, texCoord).rgb;
238       #endif
239       specularColor.rgb *= lightMapColor;
240       diffuseColor.rgb  *= lightMapColor;
241    #endif
242
243    #ifdef VERTEX_LIGHTING
244       vec2 light = vertexLightValues.xy;
245       #ifdef COLORRAMP
246           light.x = texture2D(m_ColorRamp, vec2(light.x, 0.0)).r;
247           light.y = texture2D(m_ColorRamp, vec2(light.y, 0.0)).r;
248       #endif
249
250       gl_FragColor.rgb =  AmbientSum     * diffuseColor.rgb +
251                           DiffuseSum.rgb * diffuseColor.rgb  * vec3(light.x) +
252                           SpecularSum    * specularColor.rgb * vec3(light.y);
253    #else
254       vec4 lightDir = vLightDir;
255       lightDir.xyz = normalize(lightDir.xyz);
256       vec3 viewDir = normalize(vViewDir);
257
258       vec2   light = computeLighting(normal, viewDir, lightDir.xyz) * spotFallOff;
259       #ifdef COLORRAMP
260           diffuseColor.rgb  *= texture2D(m_ColorRamp, vec2(light.x, 0.0)).rgb;
261           specularColor.rgb *= texture2D(m_ColorRamp, vec2(light.y, 0.0)).rgb;
262       #endif
263
264       // Workaround, since it is not possible to modify varying variables
265       vec4 SpecularSum2 = vec4(SpecularSum, 1.0);
266       #ifdef USE_REFLECTION
267            vec4 refColor = Optics_GetEnvColor(m_EnvMap, refVec.xyz);
268
269            // Interpolate light specularity toward reflection color
270            // Multiply result by specular map
271            specularColor = mix(SpecularSum2 * light.y, refColor, refVec.w) * specularColor;
272
273            SpecularSum2 = vec4(1.0);
274            light.y = 1.0;
275       #endif
276
277       gl_FragColor.rgb =  AmbientSum       * diffuseColor.rgb  +
278                           DiffuseSum.rgb   * diffuseColor.rgb  * vec3(light.x) +
279                           SpecularSum2.rgb * specularColor.rgb * vec3(light.y);
280    #endif
281    gl_FragColor.a = alpha;
282}
283