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