armory/Shaders/forward/mesh.frag.glsl
2016-12-13 01:09:17 +01:00

424 lines
9.8 KiB
GLSL

#version 450
#ifdef GL_ES
precision mediump float;
#endif
#include "../compiled.glsl"
#include "../std/brdf.glsl"
#ifdef _PolyLight
#include "../std/ltc.glsl"
#endif
#ifdef _Rad
#include "../std/math.glsl"
#endif
#ifndef _NoShadows
#ifdef _PCSS
#include "../std/shadows_pcss.glsl"
// PCSS()
#else
#include "../std/shadows.glsl"
// PCF()
#endif
#endif
#include "../std/shirr.glsl"
// shIrradiance()
//!uniform float shirr[27];
#ifdef _PolyLight
//!uniform sampler2D sltcMat;
//!uniform sampler2D sltcMag;
#endif
#ifdef _BaseTex
uniform sampler2D sbase;
#endif
#ifndef _NoShadows
//!uniform sampler2D shadowMap;
#ifdef _PCSS
//!uniform sampler2D snoise;
//!uniform float lampSizeUV;
#endif
#endif
#ifdef _Rad
uniform sampler2D senvmapRadiance;
uniform sampler2D senvmapBrdf;
uniform int envmapNumMipmaps;
#endif
#ifdef _NorTex
uniform sampler2D snormal;
#endif
#ifdef _NorStr
uniform float normalStrength;
#endif
#ifdef _OccTex
uniform sampler2D socclusion;
#else
uniform float occlusion;
#endif
#ifdef _RoughTex
uniform sampler2D srough;
#else
uniform float roughness;
#endif
#ifdef _RoughStr
uniform float roughnessStrength;
#endif
#ifdef _MetTex
uniform sampler2D smetal;
#else
uniform float metalness;
#endif
uniform float envmapStrength;
uniform bool receiveShadow;
uniform vec3 lightPos;
uniform vec3 lightDir;
uniform int lightType;
uniform vec3 lightColor;
uniform float spotlightCutoff;
uniform float spotlightExponent;
uniform float shadowsBias;
uniform vec3 eye;
#ifdef _PolyLight
uniform vec3 lampArea0;
uniform vec3 lampArea1;
uniform vec3 lampArea2;
uniform vec3 lampArea3;
#endif
#ifdef _VoxelGI
uniform sampler2D ssaotex;
uniform sampler2D senvmapBrdf;
//!uniform sampler3D voxels;
#endif
in vec3 position;
#ifdef _Tex
in vec2 texCoord;
#endif
#ifdef _Tex1
in vec2 texCoord1;
#endif
#ifndef _NoShadows
in vec4 lampPos;
#endif
in vec4 matColor;
in vec3 eyeDir;
#ifdef _NorTex
in mat3 TBN;
#else
in vec3 normal;
#endif
out vec4 fragColor;
#ifndef _NoShadows
float shadowTest(vec4 lPos) {
lPos.xyz /= lPos.w;
lPos.xy = lPos.xy * 0.5 + 0.5;
#ifdef _PCSS
return PCSS(lPos.xy, lPos.z - shadowsBias);
#else
return PCF(lPos.xy, lPos.z - shadowsBias);
#endif
// return VSM(lPos.xy, lPos.z);
// float distanceFromLight = texture(shadowMap, lPos.xy).r * 2.0 - 1.0;
// return float(distanceFromLight > lPos.z - shadowsBias);
}
#endif
// #ifdef _Toon
// float stepmix(float edge0, float edge1, float E, float x) {
// float T = clamp(0.5 * (x - edge0 + E) / E, 0.0, 1.0);
// return mix(edge0, edge1, T);
// }
// #endif
void main() {
#ifdef _NorTex
#ifdef _NorTex1
vec3 n = texture(snormal, texCoord1).rgb * 2.0 - 1.0;
#else
vec3 n = texture(snormal, texCoord).rgb * 2.0 - 1.0;
#endif
n = normalize(TBN * normalize(n));
// vec3 normal = texture(snormal, texCoord).rgb * 2.0 - 1.0;
// vec3 nn = normalize(normal);
// vec3 dp1 = dFdx(position);
// vec3 dp2 = dFdy(position);
// vec2 duv1 = dFdx(texCoord);
// vec2 duv2 = dFdy(texCoord);
// vec3 dp2perp = cross(dp2, nn);
// vec3 dp1perp = cross(nn, dp1);
// vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;
// vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;
// float invmax = inversesqrt(max(dot(T,T), dot(B,B)));
// mat3 TBN = mat3(T * invmax, B * invmax, nn);
// vec3 n = (TBN * nn);
#else
vec3 n = normalize(normal);
#endif
#ifdef _NorStr
n *= normalStrength;
#endif
// Move out
vec3 l;
if (lightType == 0) { // Sun
l = lightDir;
}
else { // Point, spot
l = normalize(lightPos - position.xyz);
}
float visibility = 1.0;
#ifndef _NoShadows
if (receiveShadow) {
if (lampPos.w > 0.0) {
visibility = shadowTest(lampPos);
}
}
#endif
vec3 baseColor = matColor.rgb;
#ifdef _BaseTex
#ifdef _BaseTex1
vec4 texel = texture(sbase, texCoord1);
#else
vec4 texel = texture(sbase, texCoord);
#endif
#ifdef _AlphaTest
if (texel.a < 0.4)
discard;
#endif
texel.rgb = pow(texel.rgb, vec3(2.2));
baseColor *= texel.rgb;
#endif
vec3 v = normalize(eyeDir);
vec3 h = normalize(v + l);
float dotNL = dot(n, l);
float dotNV = dot(n, v);
float dotNH = dot(n, h);
float dotVH = dot(v, h);
#ifdef _MetTex
#ifdef _MetTex1
float metalness = texture(smetal, texCoord1).r;
#else
float metalness = texture(smetal, texCoord).r;
#endif
#endif
vec3 albedo = surfaceAlbedo(baseColor, metalness);
vec3 f0 = surfaceF0(baseColor, metalness);
#ifdef _RoughTex
#ifdef _RoughTex1
float roughness = texture(srough, texCoord1).r;
#else
float roughness = texture(srough, texCoord).r;
#endif
#endif
#ifdef _RoughStr
roughness *= roughnessStrength;
#endif
// #ifdef _Toon
// vec3 v = normalize(eyeDir);
// vec3 h = normalize(v + l);
// const vec3 ambientMaterial = baseColor * vec3(0.35, 0.35, 0.35) + vec3(0.15);
// const vec3 diffuseMaterial = baseColor;
// const vec3 specularMaterial = vec3(0.45, 0.35, 0.35);
// const float shininess = 0.5;
// float df = max(0.0, dotNL);
// float sf = max(0.0, dot(n, h));
// sf = pow(sf, shininess);
// const float A = 0.1;
// const float B = 0.3;
// const float C = 0.6;
// const float D = 1.0;
// float E = fwidth(df);
// bool f = false;
// if (df > A - E) if (df < A + E) {
// f = true;
// df = stepmix(A, B, E, df);
// }
// /*else*/if (!f) if (df > B - E) if(df < B + E) {
// f = true;
// df = stepmix(B, C, E, df);
// }
// /*else*/if (!f) if (df > C - E) if (df < C + E) {
// f = true;
// df = stepmix(C, D, E, df);
// }
// /*else*/if (!f) if (df < A) {
// df = 0.0;
// }
// else if (df < B) {
// df = B;
// }
// else if (df < C) {
// df = C;
// }
// else df = D;
// E = fwidth(sf);
// if (sf > 0.5 - E && sf < 0.5 + E) {
// sf = smoothstep(0.5 - E, 0.5 + E, sf);
// }
// else {
// sf = step(0.5, sf);
// }
// fragColor.rgb = ambientMaterial + (df * diffuseMaterial + sf * specularMaterial) * visibility;
// float edgeDetection = (dot(v, n) < 0.1) ? 0.0 : 1.0;
// fragColor.rgb *= edgeDetection;
// // const int levels = 4;
// // const float scaleFactor = 1.0 / levels;
// // float diffuse = max(0, dotNL);
// // const float material_kd = 0.8;
// // const float material_ks = 0.3;
// // vec3 diffuseColor = vec3(0.40, 0.60, 0.70);
// // diffuseColor = diffuseColor * material_kd * floor(diffuse * levels) * scaleFactor;
// // float specular = 0.0;
// // if(dotNL > 0.0) {
// // specular = material_ks * pow( max(0, dot( h, n)), shininess);
// // }
// // // Limit specular
// // float specMask = (pow(dot(h, n), shininess) > 0.4) ? 1.0 : 0.0;
// // float edgeDetection = (dot(v, n) > 0.3) ? 1.0 : 0.0;
// // fragColor.rgb = edgeDetection * ((diffuseColor + specular * specMask) * visibility + ambientMaterial);
// #endif
// Direct
vec3 direct;
#ifdef _PolyLight
if (lightType == 3) { // Area
float theta = acos(dotNV);
vec2 tuv = vec2(roughness, theta / (0.5 * PI));
tuv = tuv * LUT_SCALE + LUT_BIAS;
// vec4 t = texture(sltcMat, tuv);
vec4 t = clamp(texture(sltcMat, tuv), 0.0, 1.0);
mat3 invM = 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, position, invM, lampArea0, lampArea1, lampArea2, lampArea3, false);
ltcspec *= texture(sltcMag, tuv).a;
vec3 ltcdiff = ltcEvaluate(n, v, dotNV, position, mat3(1.0), lampArea0, lampArea1, lampArea2, lampArea3, false);
direct = ltcdiff * albedo + ltcspec;
}
else {
#endif
// Direct
#ifdef _OrenNayar
direct = orenNayarDiffuseBRDF(albedo, roughness, dotNV, dotNL, dotVH) + specularBRDF(f0, roughness, dotNL, dotNH, dotNV, dotVH);
#else
direct = lambertDiffuseBRDF(albedo, dotNL) + specularBRDF(f0, roughness, dotNL, dotNH, dotNV, dotVH);
#endif
if (lightType == 2) { // Spot
float spotEffect = dot(lightDir, l);
if (spotEffect < spotlightCutoff) {
spotEffect = smoothstep(spotlightCutoff - spotlightExponent, spotlightCutoff, spotEffect);
direct *= spotEffect;
}
}
#ifdef _PolyLight
}
#endif
direct = direct * lightColor;
#ifdef _VoxelGI
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;
vec3 indirectDiffuse = indirectLight(tanToWorld, n, diffOcclusion).rgb * 4.0;
indirectDiffuse *= albedo;
diffOcclusion = min(1.0, 1.5 * diffOcclusion);
vec3 reflectWorld = reflect(-v, n);
float specularOcclusion;
float lodOffset = 0.0;//getMipFromRoughness(roughness, numMips);
vec3 indirectSpecular = coneTrace(reflectWorld, n, 0.07 + lodOffset, specularOcclusion).rgb;
if (roughness > 0.0) { // Temp..
vec2 envBRDF = texture(senvmapBrdf, vec2(roughness, 1.0 - dotNV)).xy;
indirectSpecular *= (f0 * envBRDF.x + envBRDF.y);
}
vec3 indirect = indirectDiffuse * diffOcclusion + indirectSpecular;
#else
// Indirect
vec3 indirectDiffuse = shIrradiance(n, 2.2) / PI;
#ifdef _EnvLDR
indirectDiffuse = pow(indirectDiffuse, vec3(2.2));
#endif
indirectDiffuse *= albedo;
vec3 indirect = indirectDiffuse;
#ifdef _Rad
vec3 reflectionWorld = reflect(-v, n);
float lod = getMipFromRoughness(roughness, envmapNumMipmaps);
vec3 prefilteredColor = textureLod(senvmapRadiance, envMapEquirect(reflectionWorld), lod).rgb;
#ifdef _EnvLDR
prefilteredColor = pow(prefilteredColor, vec3(2.2));
#endif
vec2 envBRDF = texture(senvmapBrdf, vec2(roughness, 1.0 - dotNV)).xy;
vec3 indirectSpecular = prefilteredColor * (f0 * envBRDF.x + envBRDF.y);
indirect += indirectSpecular;
#endif
indirect = indirect * envmapStrength;// * lightColor;
#endif
fragColor = vec4(vec3(direct * visibility + indirect), 1.0);
#ifdef _OccTex
#ifdef _OccTex1
float occ = texture(socclusion, texCoord1).r;
#else
float occ = texture(socclusion, texCoord).r;
#endif
fragColor.rgb *= occ;
#else
fragColor.rgb *= occlusion;
#endif
#ifdef _LDR
fragColor = vec4(pow(fragColor.rgb, vec3(1.0 / 2.2)), fragColor.a);
#endif
}