armory/Shaders/deferred_light/deferred_light.frag.glsl

257 lines
6.3 KiB
Plaintext
Raw Normal View History

2016-01-28 00:58:00 +01:00
#version 450
#include "compiled.inc"
2017-12-13 14:21:42 +01:00
#include "std/brdf.glsl"
#include "std/math.glsl"
#ifdef _LightIES
2017-12-13 14:21:42 +01:00
#include "std/ies.glsl"
2017-08-17 14:37:04 +02:00
#endif
2017-08-13 20:28:06 +02:00
#ifdef _VoxelGIDirect
2017-12-13 14:21:42 +01:00
#include "std/conetrace.glsl"
2017-08-13 20:28:06 +02:00
#endif
2017-11-27 14:29:21 +01:00
#ifdef _LTC
2017-12-13 14:21:42 +01:00
#include "std/ltc.glsl"
2017-03-12 17:29:22 +01:00
#endif
2016-10-17 17:39:40 +02:00
#ifndef _NoShadows
2017-12-13 14:21:42 +01:00
#include "std/shadows.glsl"
2016-10-17 17:39:40 +02:00
#endif
2017-05-23 15:01:56 +02:00
#ifdef _SSS
2017-12-13 14:21:42 +01:00
#include "std/sss.glsl"
2017-05-23 15:01:56 +02:00
#endif
2017-07-05 23:26:13 +02:00
#ifdef _SSRS
2017-12-13 14:21:42 +01:00
#include "std/ssrs.glsl"
2017-07-05 23:26:13 +02:00
#endif
2017-12-13 14:21:42 +01:00
#include "std/gbuffer.glsl"
2016-07-10 00:51:39 +02:00
2017-08-13 20:28:06 +02:00
#ifdef _VoxelGIDirect
2018-01-29 23:52:42 +01:00
uniform sampler3D voxels;
2017-08-13 20:28:06 +02:00
#endif
2017-10-23 16:24:57 +02:00
#ifdef _VoxelGICam
uniform vec3 eyeSnap;
#endif
2017-02-22 15:50:19 +01:00
2018-01-29 23:52:42 +01: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;
2018-05-19 19:29:14 +02:00
#ifdef _gbuffer2direct
uniform sampler2D gbuffer2;
#endif
2016-01-03 19:41:00 +01:00
2017-03-17 18:34:03 +01:00
// TODO: separate shaders
2016-07-17 20:29:53 +02:00
#ifndef _NoShadows
2017-12-04 19:49:06 +01:00
#ifdef _SoftShadows
uniform sampler2D svisibility;
#else
2018-01-29 23:52:42 +01:00
uniform sampler2D shadowMap;
uniform samplerCube shadowMapCube;
2017-12-04 19:49:06 +01:00
#endif
#endif
#ifdef _LightIES
2017-08-17 14:37:04 +02:00
//!uniform sampler2D texIES;
#endif
2018-11-07 13:11:38 +01:00
#ifdef _SMSizeUniform
uniform vec2 smSizeUniform;
#endif
2016-06-07 09:38:49 +02:00
2017-11-17 16:15:35 +01:00
#ifdef _SSS
vec2 lightPlane;
#endif
2016-08-09 23:51:40 +02:00
uniform mat4 invVP;
2016-08-25 00:26:01 +02:00
uniform mat4 LWVP;
2017-03-12 17:29:22 +01:00
uniform vec3 lightColor;
2016-06-26 12:11:51 +02:00
uniform vec3 lightDir;
2017-03-12 17:29:22 +01:00
uniform vec3 lightPos;
2017-11-15 16:43:46 +01:00
uniform vec2 lightProj;
2016-06-26 12:11:51 +02:00
uniform int lightType;
2017-03-11 01:50:47 +01:00
uniform int lightShadow;
2016-08-12 13:48:04 +02:00
uniform float shadowsBias;
2017-03-11 01:50:47 +01:00
uniform vec2 spotlightData;
2017-11-27 14:29:21 +01:00
#ifdef _LTC
uniform vec3 lightArea0;
uniform vec3 lightArea1;
uniform vec3 lightArea2;
uniform vec3 lightArea3;
2017-03-11 01:50:47 +01:00
uniform sampler2D sltcMat;
uniform sampler2D sltcMag;
2016-11-08 15:14:56 +01:00
#endif
2016-03-20 18:44:11 +01:00
uniform vec3 eye;
2017-01-17 14:48:47 +01:00
#ifdef _SSRS
2017-07-05 23:26:13 +02:00
//!uniform mat4 VP;
2017-01-17 14:48:47 +01:00
#endif
2016-05-10 12:11:31 +02:00
#ifdef _LightColTex
uniform sampler2D texlightcolor;
2016-11-05 20:57:04 +01:00
#endif
2016-08-25 00:26:01 +02:00
in vec4 wvpposition;
2016-10-12 17:52:27 +02:00
out vec4 fragColor;
2016-06-26 12:11:51 +02:00
2016-01-24 22:32:51 +01:00
void main() {
2017-03-03 14:36:01 +01:00
vec2 texCoord = wvpposition.xy / wvpposition.w;
texCoord = texCoord * 0.5 + 0.5;
2017-06-23 15:47:51 +02:00
#ifdef _InvY
texCoord.y = 1.0 - texCoord.y;
#endif
2016-08-09 23:51:40 +02:00
2018-05-19 19:29:14 +02:00
vec4 g0 = texture(gbuffer0, texCoord); // Normal.xy, metallic/roughness, depth
vec4 g1 = texture(gbuffer1, texCoord); // Basecolor.rgb, spec/occ
2018-05-26 16:39:10 +02:00
float spec = unpackFloat2(g1.a).g;
2017-06-23 15:47:51 +02:00
// #ifdef _InvY // D3D
2017-03-28 14:30:51 +02:00
// float depth = texture(gbufferD, texCoord).r * 2.0 - 1.0; // 0 - 1 => -1 - 1
2017-06-23 15:47:51 +02:00
// #else
2017-03-11 01:50:47 +01:00
// TODO: store_depth
2017-03-28 14:30:51 +02:00
float depth = (1.0 - g0.a) * 2.0 - 1.0;
2017-06-23 15:47:51 +02:00
// #endif
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
2017-03-18 18:44:21 +01:00
vec3 lp = lightPos - p;
vec3 l = normalize(lp);
2017-08-13 20:28:06 +02:00
vec3 h = normalize(v + l);
float dotNH = dot(n, h);
float dotVH = dot(v, h);
float dotNL = dot(n, l);
2017-03-17 18:34:03 +01:00
2017-02-22 15:50:19 +01:00
float visibility = 1.0;
2017-02-22 15:50:19 +01:00
#ifndef _NoShadows
#ifdef _SoftShadows
visibility = texture(svisibility, texCoord).r;
#else
2017-03-11 01:50:47 +01:00
if (lightShadow == 1) {
2018-01-23 22:40:09 +01:00
vec4 lPos = LWVP * vec4(p + n * shadowsBias * 10, 1.0);
2017-11-15 13:34:51 +01:00
if (lPos.w > 0.0) {
2018-11-07 13:11:38 +01:00
#ifdef _SMSizeUniform
visibility = shadowTest(shadowMap, lPos.xyz / lPos.w, shadowsBias, smSizeUniform);
#else
2018-01-29 23:52:42 +01:00
visibility = shadowTest(shadowMap, lPos.xyz / lPos.w, shadowsBias, shadowmapSize);
2018-11-07 13:11:38 +01:00
#endif
2017-11-15 13:34:51 +01:00
}
2017-03-17 18:34:03 +01:00
}
else if (lightShadow == 2) { // Cube
2018-01-29 23:52:42 +01:00
visibility = PCFCube(shadowMapCube, lp, -l, shadowsBias, lightProj, n);
2017-02-22 15:50:19 +01:00
}
#endif
2017-02-22 15:50:19 +01:00
#endif
2017-08-13 20:28:06 +02:00
#ifdef _VoxelGIShadow // #else
2017-10-12 23:57:12 +02:00
#ifdef _VoxelGICam
vec3 voxpos = (p - eyeSnap) / voxelgiHalfExtents;
#else
vec3 voxpos = p / voxelgiHalfExtents;
#endif
2018-03-26 00:30:24 +02:00
if (dotNL > 0.0) visibility = max(0, 1.0 - traceShadow(voxels, voxpos, l, 0.1, length(lp), n));
2017-08-13 20:28:06 +02:00
#endif
2017-03-15 15:49:13 +01:00
visibility *= attenuate(distance(p, lightPos));
2017-08-19 03:08:42 +02:00
#ifdef _LightIES
2017-08-17 14:37:04 +02:00
visibility *= iesAttenuation(-l);
2017-03-15 15:49:13 +01:00
#endif
if (lightType == 2) { // Spot
2017-03-11 01:50:47 +01:00
float spotEffect = dot(lightDir, l);
// x - cutoff, y - cutoff - exponent
if (spotEffect < spotlightData.x) {
visibility *= smoothstep(spotlightData.y, spotlightData.x, spotEffect);
}
}
2017-10-17 01:27:07 +02:00
2017-11-27 14:29:21 +01:00
#ifdef _LTC
2016-11-06 15:07:13 +01:00
if (lightType == 3) { // Area
float theta = acos(dotNV);
vec2 tuv = vec2(metrough.y, theta / (0.5 * PI));
tuv = tuv * LUT_SCALE + LUT_BIAS;
2017-03-03 14:36:01 +01:00
vec4 t = texture(sltcMat, tuv);
2016-11-08 15:14:56 +01:00
mat3 invM = mat3(
2016-11-06 15:07:13 +01:00
vec3(1.0, 0.0, t.y),
vec3(0.0, t.z, 0.0),
vec3(t.w, 0.0, t.x));
float ltcspec = ltcEvaluate(n, v, dotNV, p, invM, lightArea0, lightArea1, lightArea2, lightArea3);
2016-11-06 15:07:13 +01:00
ltcspec *= texture(sltcMag, tuv).a;
float ltcdiff = ltcEvaluate(n, v, dotNV, p, mat3(1.0), lightArea0, lightArea1, lightArea2, lightArea3);
2018-05-19 19:29:14 +02:00
fragColor.rgb = albedo * ltcdiff + ltcspec * spec;
2016-11-06 15:07:13 +01:00
}
else {
2016-11-08 15:14:56 +01:00
#endif
2016-11-06 15:07:13 +01:00
2017-11-25 20:09:55 +01:00
#ifdef _Hair // Aniso
2018-05-19 19:29:14 +02:00
if (texture(gbuffer2, texCoord).a == 2) {
2017-11-25 20:09:55 +01:00
const float shinyParallel = metrough.y;
const float shinyPerpendicular = 0.1;
const vec3 v = vec3(0.99146, 0.11664, 0.05832);
vec3 T = abs(dot(n, v)) > 0.99999 ? cross(n, vec3(0.0, 1.0, 0.0)) : cross(n, v);
2018-05-21 17:55:26 +02:00
fragColor.rgb = orenNayarDiffuseBRDF(albedo, metrough.y, dotNV, dotNL, dotVH) + wardSpecular(n, h, dotNL, dotNV, dotNH, T, shinyParallel, shinyPerpendicular) * spec;
2017-11-25 20:09:55 +01:00
}
2018-05-19 19:29:14 +02:00
else fragColor.rgb = lambertDiffuseBRDF(albedo, dotNL) + specularBRDF(f0, metrough.y, dotNL, dotNH, dotNV, dotVH) * spec;
2017-11-25 20:09:55 +01:00
#else
2017-10-02 00:00:52 +02:00
#ifdef _OrenNayar
2018-05-19 19:29:14 +02:00
fragColor.rgb = orenNayarDiffuseBRDF(albedo, metrough.y, dotNV, dotNL, dotVH) + specularBRDF(f0, metrough.y, dotNL, dotNH, dotNV, dotVH) * spec;
2016-09-08 14:08:31 +02:00
#else
2018-05-19 19:29:14 +02:00
fragColor.rgb = lambertDiffuseBRDF(albedo, dotNL) + specularBRDF(f0, metrough.y, dotNL, dotNH, dotNV, dotVH) * spec;
2016-09-08 14:08:31 +02:00
#endif
2017-11-25 20:09:55 +01:00
#endif
2016-08-29 09:56:34 +02:00
2017-11-27 14:29:21 +01:00
#ifdef _LTC
2016-06-30 13:22:05 +02:00
}
2016-11-08 15:14:56 +01:00
#endif
2016-06-30 13:22:05 +02:00
2017-11-25 20:09:55 +01:00
#ifdef _Hair // Aniso
#endif
2016-11-05 20:57:04 +01:00
2017-03-11 01:50:47 +01:00
fragColor.rgb *= lightColor;
2016-11-06 15:07:13 +01:00
#ifdef _LightColTex
// fragColor.rgb *= texture(texlightcolor, envMapEquirect(l)).rgb;
fragColor.rgb *= pow(texture(texlightcolor, l.xy).rgb, vec3(2.2));
2016-11-05 20:57:04 +01:00
#endif
2016-06-30 13:22:05 +02:00
2016-06-26 12:11:51 +02:00
#ifdef _SSS
2018-05-19 19:29:14 +02:00
if (texture(gbuffer2, texCoord).a == 2) {
2017-11-17 16:15:35 +01:00
if (lightShadow == 1) fragColor.rgb += fragColor.rgb * SSSSTransmittance(LWVP, p, n, l, lightPlane.y, shadowMap);
// else fragColor.rgb += fragColor.rgb * SSSSTransmittanceCube();
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
2017-01-17 14:48:47 +01:00
#ifdef _SSRS
2017-08-13 20:28:06 +02:00
float tvis = traceShadowSS(-l, p, gbuffer0, invVP, eye);
2017-01-17 14:48:47 +01:00
// vec2 coords = getProjectedCoord(hitCoord);
// vec2 deltaCoords = abs(vec2(0.5, 0.5) - coords.xy);
// float screenEdgeFactor = clamp(1.0 - (deltaCoords.x + deltaCoords.y), 0.0, 1.0);
// tvis *= screenEdgeFactor;
visibility *= tvis;
#endif
2017-03-11 01:50:47 +01:00
fragColor.rgb *= visibility;
2017-08-13 20:28:06 +02:00
#ifdef _VoxelGIRefract
2017-10-16 09:25:18 +02:00
#ifdef _VoxelGICam
vec3 voxposr = (p - eyeSnap) / voxelgiHalfExtents;
#else
vec3 voxposr = p / voxelgiHalfExtents;
#endif
2018-05-19 19:29:14 +02:00
float opac = texture(gbuffer2, texCoord).b;
fragColor.rgb = mix(traceRefraction(voxels, voxposr, n, -v, metrough.y), fragColor.rgb, opac);
2017-08-13 20:28:06 +02:00
#endif
2016-01-03 19:41:00 +01:00
}