1#define ATTENUATION 2//#define HQ_ATTENUATION 3 4varying vec2 texCoord; 5 6uniform sampler2D m_DiffuseData; 7uniform sampler2D m_SpecularData; 8uniform sampler2D m_NormalData; 9uniform sampler2D m_DepthData; 10 11uniform vec3 m_FrustumCorner; 12uniform vec2 m_FrustumNearFar; 13 14uniform vec4 g_LightColor; 15uniform vec4 g_LightPosition; 16uniform vec3 g_CameraPosition; 17 18uniform mat4 m_ViewProjectionMatrixInverse; 19 20#ifdef COLORRAMP 21 uniform sampler2D m_ColorRamp; 22#endif 23 24float lightComputeDiffuse(in vec3 norm, in vec3 lightdir, in vec3 viewdir){ 25 #ifdef MINNAERT 26 float NdotL = max(0.0, dot(norm, lightdir)); 27 float NdotV = max(0.0, dot(norm, viewdir)); 28 return NdotL * pow(max(NdotL * NdotV, 0.1), -1.0) * 0.5; 29 #else 30 return max(0.0, dot(norm, lightdir)); 31 #endif 32} 33 34float lightComputeSpecular(in vec3 norm, in vec3 viewdir, in vec3 lightdir, in float shiny){ 35//#ifdef LOW_QUALITY 36 // Blinn-Phong 37 // Note: preferably, H should be computed in the vertex shader 38 vec3 H = (viewdir + lightdir) * vec3(0.5); 39 return pow(max(dot(H, norm), 0.0), shiny); 40/* 41 #elif defined(WARDISO) 42 // Isotropic Ward 43 vec3 halfVec = normalize(viewdir + lightdir); 44 float NdotH = max(0.001, tangDot(norm, halfVec)); 45 float NdotV = max(0.001, tangDot(norm, viewdir)); 46 float NdotL = max(0.001, tangDot(norm, lightdir)); 47 float a = tan(acos(NdotH)); 48 float p = max(shiny/128.0, 0.001); 49 return NdotL * (1.0 / (4.0*3.14159265*p*p)) * (exp(-(a*a)/(p*p)) / (sqrt(NdotV * NdotL))); 50 #else 51 // Standard Phong 52 vec3 R = reflect(-lightdir, norm); 53 return pow(max(tangDot(R, viewdir), 0.0), shiny); 54 #endif 55*/ 56} 57 58vec2 computeLighting(in vec3 wvPos, in vec3 wvNorm, in vec3 wvViewDir, in vec4 wvLightDir, in float shiny){ 59 float diffuseFactor = lightComputeDiffuse(wvNorm, wvLightDir.xyz, wvViewDir); 60 float specularFactor = lightComputeSpecular(wvNorm, wvViewDir, wvLightDir.xyz, shiny); 61 return vec2(diffuseFactor, specularFactor) * vec2(wvLightDir.w); 62} 63 64vec3 decodeNormal(in vec4 enc){ 65 vec4 nn = enc * vec4(2.0,2.0,0.0,0.0) + vec4(-1.0,-1.0,1.0,-1.0); 66 float l = dot(nn.xyz, -nn.xyw); 67 nn.z = l; 68 nn.xy *= sqrt(l); 69 return nn.xyz * vec3(2.0) + vec3(0.0,0.0,-1.0); 70} 71 72vec3 getPosition(in vec2 newTexCoord){ 73 //Reconstruction from depth 74 float depth = texture2D(m_DepthData, newTexCoord).r; 75 //if (depth == 1.0) 76 // return vec3(0.0, 0.0, 2.0); 77 //depth = (2.0 * m_FrustumNearFar.x) 78 /// (m_FrustumNearFar.y + m_FrustumNearFar.x - depth * (m_FrustumNearFar.y-m_FrustumNearFar.x)); 79 80 //one frustum corner method 81 //float x = mix(-m_FrustumCorner.x, m_FrustumCorner.x, newTexCoord.x); 82 //float y = mix(-m_FrustumCorner.y, m_FrustumCorner.y, newTexCoord.y); 83 84 //return depth * vec3(x, y, m_FrustumCorner.z); 85 vec4 pos; 86 pos.xy = (newTexCoord * vec2(2.0)) - vec2(1.0); 87 pos.z = depth; 88 pos.w = 1.0; 89 pos = m_ViewProjectionMatrixInverse * pos; 90 //pos /= pos.w; 91 return pos.xyz; 92} 93 94// JME3 lights in world space 95void lightComputeDir(in vec3 worldPos, in vec4 color, in vec4 position, out vec4 lightDir){ 96 #ifdef DIR_LIGHT 97 lightDir.xyz = -position.xyz; 98 #else 99 lightDir.xyz = position.xyz - worldPos.xyz; 100 float dist = length(lightDir.xyz); 101 lightDir.w = clamp(1.0 - position.w * dist, 0.0, 1.0); 102 lightDir.xyz /= dist; 103 #endif 104 105/* 106 float posLight = step(0.5, color.w); 107 vec3 tempVec = position.xyz * sign(posLight - 0.5) - (worldPos * posLight); 108 #ifdef ATTENUATION 109 float dist = length(tempVec); 110 lightDir.w = clamp(1.0 - position.w * dist * posLight, 0.0, 1.0); 111 lightDir.xyz = tempVec / vec3(dist); 112 #ifdef HQ_ATTENUATION 113 lightVec = tempVec; 114 #endif 115 #else 116 lightDir = vec4(normalize(tempVec), 1.0); 117 #endif 118*/ 119} 120 121void main(){ 122 vec2 newTexCoord = texCoord; 123 vec4 diffuseColor = texture2D(m_DiffuseData, newTexCoord); 124 if (diffuseColor.a == 0.0) 125 discard; 126 127 vec4 specularColor = texture2D(m_SpecularData, newTexCoord); 128 vec3 worldPosition = getPosition(newTexCoord); 129 vec3 viewDir = normalize(g_CameraPosition - worldPosition); 130 131 vec4 normalInfo = vec4(texture2D(m_NormalData, newTexCoord).rg, 0.0, 0.0); 132 vec3 normal = decodeNormal(normalInfo); 133 134 vec4 lightDir; 135 lightComputeDir(worldPosition, g_LightColor, g_LightPosition, lightDir); 136 137 vec2 light = computeLighting(worldPosition, normal, viewDir, lightDir, specularColor.w*128.0); 138 139 #ifdef COLORRAMP 140 diffuseColor.rgb *= texture2D(m_ColorRamp, vec2(light.x, 0.0)).rgb; 141 specularColor.rgb *= texture2D(m_ColorRamp, vec2(light.y, 0.0)).rgb; 142 #endif 143 144 gl_FragColor = vec4(light.x * diffuseColor.xyz + light.y * specularColor.xyz, 1.0); 145 gl_FragColor.xyz *= g_LightColor.xyz; 146} 147