armory/Shaders/deferred_light/deferred_light.frag.glsl

277 lines
7.5 KiB
Plaintext
Raw Normal View History

2016-01-28 00:58:00 +01:00
#version 450
2016-01-03 19:41:00 +01:00
#ifdef GL_ES
precision mediump float;
#endif
2016-07-10 00:51:39 +02:00
#include "../compiled.glsl"
2016-10-17 17:39:40 +02:00
#include "../std/brdf.glsl"
2016-11-05 20:57:04 +01:00
#include "../std/math.glsl"
2016-11-06 15:07:13 +01:00
// #ifdef _PolyLight
#include "../std/ltc.glsl"
// #endif
2016-10-17 17:39:40 +02:00
// ...
#ifndef _NoShadows
#ifdef _PCSS
#include "../std/shadows_pcss.glsl"
// PCSS()
#else
#include "../std/shadows.glsl"
// PCF()
#endif
#endif
#include "../std/gbuffer.glsl"
// octahedronWrap()
// unpackFloat()
2016-07-10 00:51:39 +02:00
2016-05-13 00:08:11 +02:00
uniform sampler2D gbufferD;
2016-03-20 18:44:11 +01:00
uniform sampler2D gbuffer0;
2016-06-07 09:38:49 +02:00
uniform sampler2D gbuffer1;
2016-01-03 19:41:00 +01:00
2016-07-17 20:29:53 +02:00
#ifndef _NoShadows
2016-10-17 17:39:40 +02:00
//!uniform sampler2D shadowMap;
2016-09-08 14:08:31 +02:00
#ifdef _PCSS
2016-10-17 17:39:40 +02:00
//!uniform sampler2D snoise;
//!uniform float lampSizeUV;
//!uniform float lampNear;
2016-09-08 14:08:31 +02:00
#endif
2016-07-17 20:29:53 +02:00
#endif
2016-06-07 09:38:49 +02:00
2016-10-09 16:06:18 +02:00
#ifdef _VoxelGI
uniform sampler2D ssaotex;
uniform sampler2D senvmapBrdf;
2016-10-17 17:39:40 +02:00
//!uniform sampler3D voxels;
2016-10-09 16:06:18 +02:00
#endif
2016-11-06 15:07:13 +01:00
// #ifdef _PolyLight
//! uniform sampler2D sltcMat;
//! uniform sampler2D sltcMag;
// #endif
2016-08-09 23:51:40 +02:00
uniform mat4 invVP;
2016-08-25 00:26:01 +02:00
uniform mat4 LWVP;
2016-06-26 12:11:51 +02:00
uniform vec3 lightPos;
uniform vec3 lightDir;
uniform int lightType;
2016-08-09 23:51:40 +02:00
// uniform int lightIndex;
2016-05-16 12:01:12 +02:00
uniform float lightStrength;
2016-08-12 13:48:04 +02:00
uniform float shadowsBias;
2016-06-26 12:11:51 +02:00
uniform float spotlightCutoff;
uniform float spotlightExponent;
2016-11-06 15:07:13 +01:00
// #ifdef _PolyLight
uniform vec3 lampArea0;
uniform vec3 lampArea1;
uniform vec3 lampArea2;
uniform vec3 lampArea3;
// #endif
2016-03-20 18:44:11 +01:00
uniform vec3 eye;
2016-08-09 23:51:40 +02:00
// uniform vec3 eyeLook;
2016-09-08 14:08:31 +02:00
// uniform vec2 screenSize;
2016-05-10 12:11:31 +02:00
2016-11-06 15:07:13 +01:00
#ifdef _LampColTex
2016-11-05 20:57:04 +01:00
uniform sampler2D texlampcolor;
#else
uniform vec3 lightColor;
#endif
2016-08-09 23:51:40 +02:00
// in vec2 texCoord;
2016-08-25 00:26:01 +02:00
in vec4 wvpposition;
2016-08-09 23:51:40 +02:00
// in vec3 viewRay;
2016-10-12 17:52:27 +02:00
out vec4 fragColor;
2016-06-26 12:11:51 +02:00
2016-05-01 00:56:40 +02:00
// Separable SSS Transmittance Function, ref to sss_pass
2016-07-17 20:29:53 +02:00
#ifdef _SSS
2016-05-01 00:56:40 +02:00
vec3 SSSSTransmittance(float translucency, float sssWidth, vec3 worldPosition, vec3 worldNormal, vec3 lightDir) {
float scale = 8.25 * (1.0 - translucency) / sssWidth;
2016-06-30 13:22:05 +02:00
vec4 shrinkedPos = vec4(worldPosition - 0.005 * worldNormal, 1.0);
2016-08-25 00:26:01 +02:00
vec4 shadowPosition = LWVP * shrinkedPos;
2016-06-30 13:22:05 +02:00
float d1 = texture(shadowMap, shadowPosition.xy / shadowPosition.w).r; // 'd1' has a range of 0..1
float d2 = shadowPosition.z; // 'd2' has a range of 0..'lightFarPlane'
const float lightFarPlane = 120 / 3.5;
2016-05-01 00:56:40 +02:00
d1 *= lightFarPlane; // So we scale 'd1' accordingly:
2016-06-30 13:22:05 +02:00
float d = scale * abs(d1 - d2);
float dd = -d * d;
vec3 profile = vec3(0.233, 0.455, 0.649) * exp(dd / 0.0064) +
2016-08-07 23:12:14 +02:00
vec3(0.1, 0.336, 0.344) * exp(dd / 0.0484) +
vec3(0.118, 0.198, 0.0) * exp(dd / 0.187) +
vec3(0.113, 0.007, 0.007) * exp(dd / 0.567) +
vec3(0.358, 0.004, 0.0) * exp(dd / 1.99) +
vec3(0.078, 0.0, 0.0) * exp(dd / 7.41);
2016-06-30 13:22:05 +02:00
return profile * clamp(0.3 + dot(lightDir, -worldNormal), 0.0, 1.0);
2016-05-01 00:56:40 +02:00
}
2016-07-17 20:29:53 +02:00
#endif
2016-05-01 00:56:40 +02:00
2016-07-17 20:29:53 +02:00
#ifndef _NoShadows
2016-03-22 23:35:54 +01:00
float shadowTest(vec4 lPos) {
2016-10-15 12:17:33 +02:00
lPos.xyz /= lPos.w;
lPos.xy = lPos.xy * 0.5 + 0.5;
2016-11-07 16:11:35 +01:00
#ifdef _Clampstc
2016-11-07 16:11:35 +01:00
// Filtering out of bounds, remove
2016-11-07 17:01:21 +01:00
// const vec2 border = vec2(1.0 / shadowmapSize[0], 1.0 / shadowmapSize[1]) * 2.0;
// lPos.xy = clamp(lPos.xy, border[0], 1.0 - border[1]);
2016-11-07 16:11:35 +01:00
if (lPos.x < 0.0) return 1.0;
if (lPos.y < 0.0) return 1.0;
if (lPos.x > 1.0) return 1.0;
if (lPos.y > 1.0) return 1.0;
#endif
2016-11-07 16:11:35 +01:00
2016-09-08 14:08:31 +02:00
#ifdef _PCSS
2016-10-15 12:17:33 +02:00
return PCSS(lPos.xy, lPos.z - shadowsBias);
2016-09-08 14:08:31 +02:00
#else
2016-10-15 12:17:33 +02:00
return PCF(lPos.xy, lPos.z - shadowsBias);
2016-09-08 14:08:31 +02:00
#endif
2016-03-22 23:35:54 +01:00
}
2016-07-17 20:29:53 +02:00
#endif
2016-01-24 22:32:51 +01:00
void main() {
2016-08-25 00:26:01 +02:00
vec2 screenPosition = wvpposition.xy / wvpposition.w;
2016-08-09 23:51:40 +02:00
vec2 texCoord = screenPosition * 0.5 + 0.5;
// texCoord += vec2(0.5 / screenSize); // Half pixel offset
2016-08-09 23:51:40 +02:00
2016-08-29 09:56:34 +02:00
vec4 g0 = texture(gbuffer0, texCoord); // Normal.xy, metallic/roughness, mask
2016-08-07 23:12:14 +02:00
vec4 g1 = texture(gbuffer1, texCoord); // Basecolor.rgb, occlusion
2016-10-26 13:50:17 +02:00
// 0 - 1 => -1 - 1
// float depth = texture(gbufferD, texCoord).r * 2.0 - 1.0;
2016-10-26 14:23:42 +02:00
// TODO: Can not read and test depth buffer at once, fetch depth from g0
2016-10-26 13:50:17 +02:00
float depth = (1.0 - g0.a) * 2.0 - 1.0;
2016-03-20 18:44:11 +01:00
2016-06-30 13:22:05 +02:00
vec3 n;
2016-08-07 23:12:14 +02:00
n.z = 1.0 - abs(g0.x) - abs(g0.y);
n.xy = n.z >= 0.0 ? g0.xy : octahedronWrap(g0.xy);
2016-06-30 13:22:05 +02:00
n = normalize(n);
2016-04-16 13:19:03 +02:00
2016-10-17 17:39:40 +02:00
vec3 p = getPos2(invVP, depth, texCoord);
2016-08-29 09:56:34 +02:00
vec2 metrough = unpackFloat(g0.b);
2016-03-20 18:44:11 +01:00
2016-10-25 16:15:07 +02:00
vec3 v = normalize(eye - p);
2016-09-08 14:08:31 +02:00
float dotNV = dot(n, v);
2016-06-30 13:22:05 +02:00
2016-08-29 09:56:34 +02:00
vec3 albedo = surfaceAlbedo(g1.rgb, metrough.x); // g1.rgb - basecolor
vec3 f0 = surfaceF0(g1.rgb, metrough.x);
2016-06-30 13:22:05 +02:00
// Per-light
vec3 l;
if (lightType == 0) { // Sun
l = lightDir;
}
else { // Point, spot
2016-10-25 16:15:07 +02:00
l = normalize(lightPos - p);
2016-06-30 13:22:05 +02:00
}
vec3 h = normalize(v + l);
2016-09-08 14:08:31 +02:00
float dotNH = dot(n, h);
float dotVH = dot(v, h);
float dotNL = dot(n, l);
// float dotLV = dot(l, v);
// float dotLH = dot(l, h);
2016-06-30 13:22:05 +02:00
2016-03-20 18:44:11 +01:00
float visibility = 1.0;
2016-07-17 20:29:53 +02:00
#ifndef _NoShadows
2016-10-15 12:17:33 +02:00
vec4 lampPos = LWVP * vec4(p, 1.0);
if (lampPos.w > 0.0) {
visibility = shadowTest(lampPos);
2016-03-22 23:35:54 +01:00
}
2016-07-17 20:29:53 +02:00
#endif
2016-06-30 13:22:05 +02:00
2016-03-20 18:44:11 +01:00
// Direct
2016-11-06 15:07:13 +01:00
vec3 direct;
// #ifdef _PolyLight
if (lightType == 3) { // Area
float theta = acos(dotNV);
vec2 tuv = vec2(metrough.y, theta / (0.5 * PI));
tuv = tuv * LUT_SCALE + LUT_BIAS;
vec4 t = texture(sltcMat, tuv);
mat3 Minv = mat3(
vec3(1.0, 0.0, t.y),
vec3(0.0, t.z, 0.0),
vec3(t.w, 0.0, t.x));
vec3 ltcspec = ltcEvaluate(n, v, dotNV, p, Minv, lampArea0, lampArea1, lampArea2, lampArea3, false);
ltcspec *= texture(sltcMag, tuv).a;
vec3 ltcdiff = ltcEvaluate(n, v, dotNV, p, mat3(1.0), lampArea0, lampArea1, lampArea2, lampArea3, false);
direct = ltcdiff * albedo;// + ltcspec;
}
else {
// #endif
2016-09-08 14:08:31 +02:00
#ifdef _OrenNayar
2016-11-06 15:07:13 +01:00
direct = orenNayarDiffuseBRDF(albedo, metrough.y, dotNV, dotNL, dotVH) + specularBRDF(f0, metrough.y, dotNL, dotNH, dotNV, dotVH);
2016-09-08 14:08:31 +02:00
#else
2016-11-06 15:07:13 +01:00
direct = lambertDiffuseBRDF(albedo, dotNL) + specularBRDF(f0, metrough.y, dotNL, dotNH, dotNV, dotVH);
2016-09-08 14:08:31 +02:00
#endif
2016-08-29 09:56:34 +02:00
2016-11-06 15:07:13 +01:00
if (lightType == 2) { // Spot
float spotEffect = dot(lightDir, l);
if (spotEffect < spotlightCutoff) {
float spotEffect = smoothstep(spotlightCutoff - spotlightExponent, spotlightCutoff, spotEffect);
direct *= spotEffect;
}
2016-06-30 13:22:05 +02:00
}
2016-11-06 15:07:13 +01:00
2016-06-30 13:22:05 +02:00
}
// Aniso spec
2016-10-17 17:39:40 +02:00
// #ifdef _Aniso
2016-08-29 09:56:34 +02:00
// float shinyParallel = metrough.y;
2016-06-30 13:22:05 +02:00
// float shinyPerpendicular = 0.08;
// vec3 fiberDirection = vec3(0.0, 1.0, 8.0);
2016-08-29 09:56:34 +02:00
// vec3 direct = diffuseBRDF(albedo, metrough.y, dotNV, dotNL, dotVH, dotLV) + wardSpecular(n, h, dotNL, dotNV, dotNH, fiberDirection, shinyParallel, shinyPerpendicular);
2016-10-17 17:39:40 +02:00
// #endif
2016-11-05 20:57:04 +01:00
2016-11-06 15:07:13 +01:00
direct *= lightStrength;
#ifdef _LampColTex
// direct *= texture(texlampcolor, envMapEquirect(l)).rgb;
direct *= pow(texture(texlampcolor, l.xy).rgb, vec3(2.2));
2016-11-05 20:57:04 +01:00
#else
direct *= lightColor;
#endif
2016-06-30 13:22:05 +02:00
2016-06-26 12:11:51 +02:00
#ifdef _SSS
2016-06-30 13:22:05 +02:00
float mask = g0.a;
2016-06-07 09:38:49 +02:00
if (mask == 2.0) {
2016-08-09 23:51:40 +02:00
direct *= SSSSTransmittance(1.0, 0.005, p, n, l);
2016-05-01 00:56:40 +02:00
}
2016-06-26 12:11:51 +02:00
#endif
2016-03-20 18:44:11 +01:00
2016-08-07 23:12:14 +02:00
// Direct
2016-10-12 17:52:27 +02:00
fragColor = vec4(vec3(direct * visibility), 1.0);
2016-08-07 23:12:14 +02:00
2016-10-09 16:06:18 +02:00
// Voxels test..
#ifdef _VoxelGI
vec4 g1a = texture(gbuffer1, texCoord); // Basecolor.rgb, occlusion
vec3 albedoa = surfaceAlbedo(g1a.rgb, metrough.x); // g1a.rgb - basecolor
2016-06-07 09:38:49 +02:00
2016-10-09 16:06:18 +02:00
vec3 tangent = normalize(cross(n, vec3(0.0, 1.0, 0.0)));
if (length(tangent) == 0.0) {
tangent = normalize(cross(n, vec3(0.0, 0.0, 1.0)));
}
vec3 bitangent = normalize(cross(n, tangent));
mat3 tanToWorld = inverse(transpose(mat3(tangent, bitangent, n)));
float diffOcclusion = 0.0;
2016-10-17 17:39:40 +02:00
vec3 indirectDiffusea = coneTraceIndirect(p, tanToWorld, n, diffOcclusion).rgb * 4.0;
2016-10-09 16:06:18 +02:00
indirectDiffusea *= albedoa;
diffOcclusion = min(1.0, 1.5 * diffOcclusion);
vec3 reflectWorld = reflect(-v, n);
float specularOcclusion;
2016-10-17 17:39:40 +02:00
float lodOffset = 0.0;//getMipFromRoughness(roughness, numMips);
2016-10-09 16:06:18 +02:00
vec3 indirectSpecular = coneTrace(p, reflectWorld, n, 0.07 + lodOffset, specularOcclusion).rgb;
if (metrough.y > 0.0) { // Temp..
float dotNVa = max(dot(n, v), 0.0);
vec3 f0a = surfaceF0(g1a.rgb, metrough.x);
vec2 envBRDFa = texture(senvmapBrdf, vec2(metrough.y, 1.0 - dotNVa)).xy;
indirectSpecular *= (f0a * envBRDFa.x + envBRDFa.y);
}
vec3 indirect1 = indirectDiffusea * diffOcclusion + indirectSpecular;
indirect1 *= texture(ssaotex, texCoord).r;
2016-10-12 17:52:27 +02:00
fragColor.rgb += indirect1;
2016-10-09 16:06:18 +02:00
#endif
2016-01-03 19:41:00 +01:00
}