aboutsummaryrefslogtreecommitdiff
path: root/engine/src/core-data/Common/MatDefs/Light/Deferred.frag
diff options
context:
space:
mode:
Diffstat (limited to 'engine/src/core-data/Common/MatDefs/Light/Deferred.frag')
-rw-r--r--engine/src/core-data/Common/MatDefs/Light/Deferred.frag146
1 files changed, 146 insertions, 0 deletions
diff --git a/engine/src/core-data/Common/MatDefs/Light/Deferred.frag b/engine/src/core-data/Common/MatDefs/Light/Deferred.frag
new file mode 100644
index 0000000..9fc7ebb
--- /dev/null
+++ b/engine/src/core-data/Common/MatDefs/Light/Deferred.frag
@@ -0,0 +1,146 @@
+#define ATTENUATION
+//#define HQ_ATTENUATION
+
+varying vec2 texCoord;
+
+uniform sampler2D m_DiffuseData;
+uniform sampler2D m_SpecularData;
+uniform sampler2D m_NormalData;
+uniform sampler2D m_DepthData;
+
+uniform vec3 m_FrustumCorner;
+uniform vec2 m_FrustumNearFar;
+
+uniform vec4 g_LightColor;
+uniform vec4 g_LightPosition;
+uniform vec3 g_CameraPosition;
+
+uniform mat4 m_ViewProjectionMatrixInverse;
+
+#ifdef COLORRAMP
+ uniform sampler2D m_ColorRamp;
+#endif
+
+float lightComputeDiffuse(in vec3 norm, in vec3 lightdir, in vec3 viewdir){
+ #ifdef MINNAERT
+ float NdotL = max(0.0, dot(norm, lightdir));
+ float NdotV = max(0.0, dot(norm, viewdir));
+ return NdotL * pow(max(NdotL * NdotV, 0.1), -1.0) * 0.5;
+ #else
+ return max(0.0, dot(norm, lightdir));
+ #endif
+}
+
+float lightComputeSpecular(in vec3 norm, in vec3 viewdir, in vec3 lightdir, in float shiny){
+//#ifdef LOW_QUALITY
+ // Blinn-Phong
+ // Note: preferably, H should be computed in the vertex shader
+ vec3 H = (viewdir + lightdir) * vec3(0.5);
+ return pow(max(dot(H, norm), 0.0), shiny);
+/*
+ #elif defined(WARDISO)
+ // Isotropic Ward
+ vec3 halfVec = normalize(viewdir + lightdir);
+ float NdotH = max(0.001, tangDot(norm, halfVec));
+ float NdotV = max(0.001, tangDot(norm, viewdir));
+ float NdotL = max(0.001, tangDot(norm, lightdir));
+ float a = tan(acos(NdotH));
+ float p = max(shiny/128.0, 0.001);
+ return NdotL * (1.0 / (4.0*3.14159265*p*p)) * (exp(-(a*a)/(p*p)) / (sqrt(NdotV * NdotL)));
+ #else
+ // Standard Phong
+ vec3 R = reflect(-lightdir, norm);
+ return pow(max(tangDot(R, viewdir), 0.0), shiny);
+ #endif
+*/
+}
+
+vec2 computeLighting(in vec3 wvPos, in vec3 wvNorm, in vec3 wvViewDir, in vec4 wvLightDir, in float shiny){
+ float diffuseFactor = lightComputeDiffuse(wvNorm, wvLightDir.xyz, wvViewDir);
+ float specularFactor = lightComputeSpecular(wvNorm, wvViewDir, wvLightDir.xyz, shiny);
+ return vec2(diffuseFactor, specularFactor) * vec2(wvLightDir.w);
+}
+
+vec3 decodeNormal(in vec4 enc){
+ vec4 nn = enc * vec4(2.0,2.0,0.0,0.0) + vec4(-1.0,-1.0,1.0,-1.0);
+ float l = dot(nn.xyz, -nn.xyw);
+ nn.z = l;
+ nn.xy *= sqrt(l);
+ return nn.xyz * vec3(2.0) + vec3(0.0,0.0,-1.0);
+}
+
+vec3 getPosition(in vec2 newTexCoord){
+ //Reconstruction from depth
+ float depth = texture2D(m_DepthData, newTexCoord).r;
+ //if (depth == 1.0)
+ // return vec3(0.0, 0.0, 2.0);
+ //depth = (2.0 * m_FrustumNearFar.x)
+ /// (m_FrustumNearFar.y + m_FrustumNearFar.x - depth * (m_FrustumNearFar.y-m_FrustumNearFar.x));
+
+ //one frustum corner method
+ //float x = mix(-m_FrustumCorner.x, m_FrustumCorner.x, newTexCoord.x);
+ //float y = mix(-m_FrustumCorner.y, m_FrustumCorner.y, newTexCoord.y);
+
+ //return depth * vec3(x, y, m_FrustumCorner.z);
+ vec4 pos;
+ pos.xy = (newTexCoord * vec2(2.0)) - vec2(1.0);
+ pos.z = depth;
+ pos.w = 1.0;
+ pos = m_ViewProjectionMatrixInverse * pos;
+ //pos /= pos.w;
+ return pos.xyz;
+}
+
+// JME3 lights in world space
+void lightComputeDir(in vec3 worldPos, in vec4 color, in vec4 position, out vec4 lightDir){
+ #ifdef DIR_LIGHT
+ lightDir.xyz = -position.xyz;
+ #else
+ lightDir.xyz = position.xyz - worldPos.xyz;
+ float dist = length(lightDir.xyz);
+ lightDir.w = clamp(1.0 - position.w * dist, 0.0, 1.0);
+ lightDir.xyz /= dist;
+ #endif
+
+/*
+ float posLight = step(0.5, color.w);
+ vec3 tempVec = position.xyz * sign(posLight - 0.5) - (worldPos * posLight);
+ #ifdef ATTENUATION
+ float dist = length(tempVec);
+ lightDir.w = clamp(1.0 - position.w * dist * posLight, 0.0, 1.0);
+ lightDir.xyz = tempVec / vec3(dist);
+ #ifdef HQ_ATTENUATION
+ lightVec = tempVec;
+ #endif
+ #else
+ lightDir = vec4(normalize(tempVec), 1.0);
+ #endif
+*/
+}
+
+void main(){
+ vec2 newTexCoord = texCoord;
+ vec4 diffuseColor = texture2D(m_DiffuseData, newTexCoord);
+ if (diffuseColor.a == 0.0)
+ discard;
+
+ vec4 specularColor = texture2D(m_SpecularData, newTexCoord);
+ vec3 worldPosition = getPosition(newTexCoord);
+ vec3 viewDir = normalize(g_CameraPosition - worldPosition);
+
+ vec4 normalInfo = vec4(texture2D(m_NormalData, newTexCoord).rg, 0.0, 0.0);
+ vec3 normal = decodeNormal(normalInfo);
+
+ vec4 lightDir;
+ lightComputeDir(worldPosition, g_LightColor, g_LightPosition, lightDir);
+
+ vec2 light = computeLighting(worldPosition, normal, viewDir, lightDir, specularColor.w*128.0);
+
+ #ifdef COLORRAMP
+ diffuseColor.rgb *= texture2D(m_ColorRamp, vec2(light.x, 0.0)).rgb;
+ specularColor.rgb *= texture2D(m_ColorRamp, vec2(light.y, 0.0)).rgb;
+ #endif
+
+ gl_FragColor = vec4(light.x * diffuseColor.xyz + light.y * specularColor.xyz, 1.0);
+ gl_FragColor.xyz *= g_LightColor.xyz;
+}