// (C)2009 S2 Games // simple_color_flat.psh // // ... //============================================================================= //============================================================================= // Uniform variables //============================================================================= uniform vec3 vSunPositionWorld; uniform vec3 vAmbient; uniform vec3 vSunColor; uniform float fFogStart; uniform float fFogEnd; uniform float fFogScale; uniform vec3 vFogColor; uniform float fFogDensity; uniform vec3 vFog; #if (NUM_POINT_LIGHTS > 0) uniform vec3 vPointLightPositionOffset[NUM_POINT_LIGHTS]; uniform vec3 vPointLightColor[NUM_POINT_LIGHTS]; uniform vec2 vPointLightFalloff[NUM_POINT_LIGHTS]; #endif //============================================================================= // Varying variables //============================================================================= varying vec4 v_vColor; #if (LIGHTING_QUALITY == 0 || LIGHTING_QUALITY == 1) varying vec3 v_vNormal; #elif (LIGHTING_QUALITY == 2) #ifdef GROUND_AMBIENT varying vec4 v_vDiffLight; #else varying vec3 v_vDiffLight; #endif #endif #if (LIGHTING_QUALITY == 0 || FALLOFF_QUALITY == 0) varying vec3 v_vPositionOffset; #endif #if (SHADOWS == 1) varying vec4 v_vTexcoordLight; #endif #ifdef CLOUDS varying vec2 v_vClouds; #endif #if ((FOG_QUALITY == 1 && FOG_TYPE != 0) || (FALLOFF_QUALITY == 1 && (FOG_TYPE != 0 || SHADOWS == 1)) || FOG_OF_WAR == 1) varying vec4 v_vData0; #endif //============================================================================= // Samplers //============================================================================= #ifdef CLOUDS uniform sampler2D clouds; #endif #if (FOG_OF_WAR == 1) uniform sampler2D fogofwar; #endif //============================================================================= // Shadow //============================================================================= #if (SHADOWS == 1) uniform vec2 vShadowLeak; uniform vec2 vShadowFalloff; #if (SHADOWMAP_TYPE == 0) // SHADOWMAP_R32F uniform float fShadowmapSize; uniform float fShadowmapSizeInv; uniform sampler2D shadowmap; //==================== // shadow_r32f //==================== float shadow_r32f() { #if (SHADOWMAP_FILTER_WIDTH > 0) // Project shadow texture coord vec2 vShadowTexcoord = (v_vTexcoordLight.xy / v_vTexcoordLight.w) - fShadowmapSizeInv * 0.5; // Determine the lerp amounts vec2 vLerps = fract(fShadowmapSize * vShadowTexcoord); float fDepth = v_vTexcoordLight.z / v_vTexcoordLight.w; // Read shadow samples vec4 vSamples; vSamples.x = texture2D(shadowmap, vShadowTexcoord).r; vSamples.y = texture2D(shadowmap, vShadowTexcoord + vec2(fShadowmapSizeInv, 0.0)).r; vSamples.z = texture2D(shadowmap, vShadowTexcoord + vec2(0.0, fShadowmapSizeInv)).r; vSamples.w = texture2D(shadowmap, vShadowTexcoord + vec2(fShadowmapSizeInv , fShadowmapSizeInv)).r; vec4 vShadow = step(fDepth, vSamples); // Percentage-closer filtering float fSample = mix(mix(vShadow.x, vShadow.y, vLerps.x), mix(vShadow.z, vShadow.w, vLerps.x), vLerps.y); #else vec3 vShadowTexcoord = v_vTexcoordLight.xyz / v_vTexcoordLight.w; float fSample = (texture2D(shadowmap, vShadowTexcoord.xy).r < vShadowTexcoord.z) ? 0.0 : 1.0; #endif return clamp(fSample * vShadowLeak.x + vShadowLeak.y, 0.0, 1.0); } #else // SHADOWMAP_DEPTH uniform sampler2DShadow shadowmap; //==================== // shadow_depth //==================== float shadow_depth() { return clamp(shadow2DProj(shadowmap, v_vTexcoordLight).r * vShadowLeak.x + vShadowLeak.y, 0.0, 1.0); } #endif //==================== // shadow //==================== float shadow(float fCamDistance) { #ifdef SHADOW_FALLOFF float fFade = clamp(fCamDistance * vShadowFalloff.x + vShadowFalloff.y, 0.0, 1.0); #else float fFade = 0.0; #endif #if (SHADOWMAP_TYPE == 0) // SHADOWMAP_R32F float fShadowmap = shadow_r32f(); #else // SHADOWMAP_DEPTH float fShadowmap = shadow_depth(); #endif return clamp(fShadowmap + fFade, 0.0, 1.0); } #endif //============================================================================= // Pixel Shader //============================================================================= void main() { vec4 cDiffuseColor = v_vColor; #if (LIGHTING_QUALITY == 0) vec3 vCamDirection = -normalize(v_vPositionOffset); #endif #if (FOG_TYPE != 0 || SHADOWS == 1) #if (FALLOFF_QUALITY == 1) float fCamDistance = v_vData0.z; #else float fCamDistance = length(v_vPositionOffset); #endif #endif // // Shadowing // #if (SHADOWS == 1) float fShadow = shadow(fCamDistance); #else float fShadow = 1.0; #endif // // Lighting // #if (LIGHTING != 0) vec3 vDiffuse = vAmbient; #if (LIGHTING_QUALITY == 2) #ifdef GROUND_AMBIENT vDiffuse *= v_vDiffLight.w; #endif #elif (LIGHTING_QUALITY == 0 || LIGHTING_QUALITY == 1) vec3 vNormal = normalize(v_vNormal); #ifdef GROUND_AMBIENT vDiffuse *= dot(vNormal, vec3(0.0, 0.0, 1.0)) * 0.375 + 0.625; #endif #endif #if (LIGHTING_QUALITY == 2) vDiffuse += v_vDiffLight.xyz * fShadow; #else // 0 or 1 vec3 vLight = vSunPositionWorld; float fLit = clamp(dot(vNormal, vLight), 0.0, 1.0) * fShadow; #ifdef CLOUDS vec3 cCloudColor = texture2D(clouds, v_vClouds).rgb; vDiffuse += vSunColor * fLit * cCloudColor; #else vDiffuse += vSunColor * fLit; #endif #if (NUM_POINT_LIGHTS > 0 && LIGHTING_QUALITY == 0) // Point Lights for (int i = 0; i < NUM_POINT_LIGHTS; ++i) { vec3 vDeltaPosition = vPointLightPositionOffset[i] - v_vPositionOffset; float fDistance = length(vDeltaPosition); vec3 vLight = normalize(vDeltaPosition); vec3 vHalfAngle = normalize(vLight + vCamDirection); float fAttenuation = 1.0 - clamp(fDistance * vPointLightFalloff[i].x + vPointLightFalloff[i].y, 0.0, 1.0); float fLit = clamp(dot(vNormal, vLight), 0.0, 1.0) * fAttenuation; vDiffuse += vPointLightColor[i] * fLit; } #endif #endif // LIGHTING_QUALITY #else // LIGHTING == 0 vec3 vDiffuse = vec3(1.0, 1.0, 1.0); #endif // // Fog // #if (FOG_TYPE != 0) // FOG_NONE #if (FOG_QUALITY == 1) float fFog = v_vData0.w; #else #if (FOG_TYPE == 0) // FOG_NONE float fFog = 0.0; #elif (FOG_TYPE == 1) // FOG_LINEAR float fFog = clamp(fCamDistance * vFog.x + vFog.y, 0.0, 1.0) * vFog.z; #elif (FOG_TYPE == 2) // FOG_EXP2 float fFog = 1.0 - exp2(-fCamDistance * fFogDensity); #elif (FOG_TYPE == 3) // FOG_EXP float fFog = 1.0 - exp(-fCamDistance * fFogDensity); #elif (FOG_TYPE == 4) // FOG_HERMITE float fFog = smoothstep(fFogStart, fFogEnd, fCamDistance) * fFogScale; #endif #endif #else float fFog = 0.0; #endif // // Final // vec3 vFinalColor = cDiffuseColor.rgb * vDiffuse; #if (FOG_OF_WAR == 1) vFinalColor *= texture2D(fogofwar, v_vData0.xy).a; #endif gl_FragColor.rgb = mix(vFinalColor, vFogColor, fFog); gl_FragColor.a = cDiffuseColor.a; }