armory/raw/deferred/mesh.frag.glsl

274 lines
9.1 KiB
Plaintext
Raw Normal View History

2016-03-18 23:02:00 +01:00
#version 450
#ifdef GL_ES
precision mediump float;
#endif
2016-08-25 00:26:01 +02:00
#ifdef _HeightTex
#define _NorTex
2016-06-18 13:58:12 +02:00
#endif
2016-08-25 00:26:01 +02:00
// #ifdef _NorTex
2016-06-21 13:29:27 +02:00
// #define _Tex
// #endif
2016-03-18 23:02:00 +01:00
2016-08-07 23:12:14 +02:00
uniform float mask;
2016-08-25 00:26:01 +02:00
#ifdef _BaseTex
uniform sampler2D sbase;
2016-03-18 23:02:00 +01:00
#endif
2016-08-25 00:26:01 +02:00
#ifdef _NorTex
2016-06-18 13:58:12 +02:00
uniform sampler2D snormal;
2016-03-18 23:02:00 +01:00
#endif
2016-08-25 00:26:01 +02:00
#ifdef _NorStr
2016-08-04 22:38:56 +02:00
uniform float normalStrength;
#endif
2016-08-25 00:26:01 +02:00
#ifdef _OccTex
uniform sampler2D socclusion;
2016-06-21 13:29:27 +02:00
#else
uniform float occlusion;
2016-03-18 23:02:00 +01:00
#endif
2016-08-25 00:26:01 +02:00
#ifdef _RoughTex
uniform sampler2D srough;
2016-03-18 23:02:00 +01:00
#else
2016-06-18 13:58:12 +02:00
uniform float roughness;
2016-03-18 23:02:00 +01:00
#endif
2016-08-25 00:26:01 +02:00
#ifdef _RoughStr
2016-08-04 22:38:56 +02:00
uniform float roughnessStrength;
#endif
2016-08-25 00:26:01 +02:00
#ifdef _MetTex
uniform sampler2D smetal;
2016-03-18 23:02:00 +01:00
#else
2016-06-18 13:58:12 +02:00
uniform float metalness;
#endif
2016-08-25 00:26:01 +02:00
#ifdef _HeightTex
uniform sampler2D sheight;
2016-06-18 13:58:12 +02:00
uniform float heightStrength;
2016-03-18 23:02:00 +01:00
#endif
#ifdef _Probes
2016-06-18 13:58:12 +02:00
uniform int probeID;
uniform vec3 probeVolumeCenter;
uniform vec3 probeVolumeSize;
2016-06-07 09:38:49 +02:00
#endif
2016-08-07 23:12:14 +02:00
in vec4 matColor;
2016-06-21 13:29:27 +02:00
#ifdef _Tex
2016-06-18 13:58:12 +02:00
in vec2 texCoord;
2016-03-18 23:02:00 +01:00
#endif
2016-08-25 00:26:01 +02:00
#ifdef _NorTex
2016-06-18 13:58:12 +02:00
in mat3 TBN;
2016-03-18 23:02:00 +01:00
#else
2016-06-18 13:58:12 +02:00
in vec3 normal;
#endif
2016-08-25 00:26:01 +02:00
#ifdef _HeightTex
2016-06-18 13:58:12 +02:00
in vec3 tanLightDir;
in vec3 tanEyeDir;
2016-03-18 23:02:00 +01:00
#endif
#ifdef _Probes
2016-08-25 00:26:01 +02:00
in vec4 wpos;
2016-06-07 09:38:49 +02:00
#endif
2016-07-31 23:25:33 +02:00
#ifdef _Veloc
2016-08-25 00:26:01 +02:00
in vec4 wvppos;
in vec4 prevwvppos;
2016-07-31 23:25:33 +02:00
#endif
2016-06-07 09:38:49 +02:00
2016-08-13 20:38:45 +02:00
#ifdef _Veloc
out vec4[3] outColor;
#else
out vec4[2] outColor;
#endif
float packFloat(float f1, float f2) {
2016-08-29 09:56:34 +02:00
float index = floor(f1 * 1000.0); // Temporary
float alpha = clamp(f2, 0.0, 1.0 - 0.001);
2016-08-07 23:12:14 +02:00
return index + alpha;
}
2016-04-16 13:19:03 +02:00
vec2 octahedronWrap(vec2 v) {
return (1.0 - abs(v.yx)) * (vec2(v.x >= 0.0 ? 1.0 : -1.0, v.y >= 0.0 ? 1.0 : -1.0));
}
#ifdef _Probes
2016-06-07 09:38:49 +02:00
float distanceBox(vec3 point, vec3 center, vec3 halfExtents) {
vec3 d = abs(point - center) - halfExtents * 0.75;
2016-06-07 09:38:49 +02:00
return min(max(d.x, max(d.y, d.z)), 0.0) + length(max(d, 0.0));
}
#endif
2016-08-25 00:26:01 +02:00
#ifdef _HeightTex
2016-06-18 13:58:12 +02:00
float parallaxHeight;
const float minLayers = 20;
const float maxLayers = 30;
vec2 parallaxMapping(vec3 V, vec2 T) {
float parallaxScale = -0.06 * heightStrength;
// PM
2016-08-25 00:26:01 +02:00
// float initialHeight = texture(sheight, texCoord).r;
2016-06-18 13:58:12 +02:00
// vec2 texCoordOffset = 0.03 * V.xy / V.z * initialHeight;
// vec2 texCoordOffset = 0.03 * V.xy * initialHeight;
// return texCoord + texCoordOffset;
// POM
float numLayers = mix(maxLayers, minLayers, abs(dot(vec3(0, 0, 1), V)));
float layerHeight = 1.0 / numLayers;
float curLayerHeight = 0;
vec2 dtex = parallaxScale * V.xy / V.z / numLayers;
vec2 currentTextureCoords = T;
2016-08-25 00:26:01 +02:00
float heightFromTexture = texture(sheight, currentTextureCoords).r;
2016-06-18 13:58:12 +02:00
// while (heightFromTexture > curLayerHeight) {
// curLayerHeight += layerHeight;
// currentTextureCoords -= dtex;
2016-08-25 00:26:01 +02:00
// heightFromTexture = texture(sheight, currentTextureCoords).r;
2016-06-18 13:58:12 +02:00
// Waiting for loops
2016-08-25 00:26:01 +02:00
if (heightFromTexture > curLayerHeight) { curLayerHeight += layerHeight; currentTextureCoords -= dtex; heightFromTexture = texture(sheight, currentTextureCoords).r; }
if (heightFromTexture > curLayerHeight) { curLayerHeight += layerHeight; currentTextureCoords -= dtex; heightFromTexture = texture(sheight, currentTextureCoords).r; }
if (heightFromTexture > curLayerHeight) { curLayerHeight += layerHeight; currentTextureCoords -= dtex; heightFromTexture = texture(sheight, currentTextureCoords).r; }
if (heightFromTexture > curLayerHeight) { curLayerHeight += layerHeight; currentTextureCoords -= dtex; heightFromTexture = texture(sheight, currentTextureCoords).r; }
if (heightFromTexture > curLayerHeight) { curLayerHeight += layerHeight; currentTextureCoords -= dtex; heightFromTexture = texture(sheight, currentTextureCoords).r; }
if (heightFromTexture > curLayerHeight) { curLayerHeight += layerHeight; currentTextureCoords -= dtex; heightFromTexture = texture(sheight, currentTextureCoords).r; }
if (heightFromTexture > curLayerHeight) { curLayerHeight += layerHeight; currentTextureCoords -= dtex; heightFromTexture = texture(sheight, currentTextureCoords).r; }
if (heightFromTexture > curLayerHeight) { curLayerHeight += layerHeight; currentTextureCoords -= dtex; heightFromTexture = texture(sheight, currentTextureCoords).r; }
if (heightFromTexture > curLayerHeight) { curLayerHeight += layerHeight; currentTextureCoords -= dtex; heightFromTexture = texture(sheight, currentTextureCoords).r; }
if (heightFromTexture > curLayerHeight) { curLayerHeight += layerHeight; currentTextureCoords -= dtex; heightFromTexture = texture(sheight, currentTextureCoords).r; }
if (heightFromTexture > curLayerHeight) { curLayerHeight += layerHeight; currentTextureCoords -= dtex; heightFromTexture = texture(sheight, currentTextureCoords).r; }
if (heightFromTexture > curLayerHeight) { curLayerHeight += layerHeight; currentTextureCoords -= dtex; heightFromTexture = texture(sheight, currentTextureCoords).r; }
if (heightFromTexture > curLayerHeight) { curLayerHeight += layerHeight; currentTextureCoords -= dtex; heightFromTexture = texture(sheight, currentTextureCoords).r; }
if (heightFromTexture > curLayerHeight) { curLayerHeight += layerHeight; currentTextureCoords -= dtex; heightFromTexture = texture(sheight, currentTextureCoords).r; }
if (heightFromTexture > curLayerHeight) { curLayerHeight += layerHeight; currentTextureCoords -= dtex; heightFromTexture = texture(sheight, currentTextureCoords).r; }
if (heightFromTexture > curLayerHeight) { curLayerHeight += layerHeight; currentTextureCoords -= dtex; heightFromTexture = texture(sheight, currentTextureCoords).r; }
2016-06-18 13:58:12 +02:00
// }
vec2 texStep = dtex;
vec2 prevTCoords = currentTextureCoords + texStep;
// Heights for linear interpolation
float nextH = heightFromTexture - curLayerHeight;
2016-08-25 00:26:01 +02:00
float prevH = texture(sheight, prevTCoords).r - curLayerHeight + layerHeight;
2016-06-18 13:58:12 +02:00
float weight = nextH / (nextH - prevH);
// Interpolation of texture coordinates
vec2 finalTexCoords = prevTCoords * weight + currentTextureCoords * (1.0 - weight);
// Interpolation of depth values
parallaxHeight = curLayerHeight + prevH * weight + nextH * (1.0 - weight);
return finalTexCoords;
}
float parallaxShadow(vec3 L, vec2 initialTexCoord, float initialHeight) {
float parallaxScale = -0.06 * heightStrength;
float shadowMultiplier = 1.0;
// Calculate lighting only for surface oriented to the light source
if (dot(vec3(0, 0, 1), L) > 0) {
shadowMultiplier = 0;
float numSamplesUnderSurface = 0;
float numLayers = mix(maxLayers, minLayers, abs(dot(vec3(0, 0, 1), L)));
float layerHeight = initialHeight / numLayers;
vec2 texStep = parallaxScale * L.xy / L.z / numLayers;
float currentLayerHeight = initialHeight - layerHeight;
vec2 currentTextureCoords = initialTexCoord + texStep;
2016-08-25 00:26:01 +02:00
float heightFromTexture = texture(sheight, currentTextureCoords).r;
2016-06-18 13:58:12 +02:00
int stepIndex = 1;
// while(currentLayerHeight > 0) {
if (currentLayerHeight > 0) {
if(heightFromTexture < currentLayerHeight) {
numSamplesUnderSurface += 1;
float newShadowMultiplier = (currentLayerHeight - heightFromTexture) * (1.0 - stepIndex / numLayers);
shadowMultiplier = max(shadowMultiplier, newShadowMultiplier);
}
stepIndex += 1;
currentLayerHeight -= layerHeight;
currentTextureCoords += texStep;
2016-08-25 00:26:01 +02:00
heightFromTexture = texture(sheight, currentTextureCoords).r;
2016-06-18 13:58:12 +02:00
}
// ...
// Shadowing factor should be 1 if there were no points under the surface
2016-08-29 09:56:34 +02:00
if (numSamplesUnderSurface < 1) shadowMultiplier = 1;
2016-06-18 13:58:12 +02:00
else shadowMultiplier = 1.0 - shadowMultiplier;
}
return shadowMultiplier;
}
#endif
2016-03-18 23:02:00 +01:00
void main() {
2016-06-21 13:29:27 +02:00
#ifdef _Tex
2016-06-18 13:58:12 +02:00
vec2 newCoord = texCoord;
#endif
2016-08-25 00:26:01 +02:00
#ifdef _HeightTex
2016-06-18 13:58:12 +02:00
vec3 tanv = normalize(tanEyeDir);
vec3 tanl = normalize(tanLightDir);
newCoord = parallaxMapping(tanv, texCoord);
float shadowMultiplier = 1.0;//parallaxShadow(tanl, newCoord, parallaxHeight - 0.001);
#endif
2016-03-18 23:02:00 +01:00
2016-08-25 00:26:01 +02:00
#ifdef _NorTex
2016-06-18 13:58:12 +02:00
vec3 n = (texture(snormal, newCoord).rgb * 2.0 - 1.0);
2016-03-18 23:02:00 +01:00
n = normalize(TBN * normalize(n));
#else
vec3 n = normalize(normal);
#endif
2016-08-25 00:26:01 +02:00
#ifdef _NorStr
2016-08-04 22:38:56 +02:00
n *= normalStrength;
#endif
2016-03-18 23:02:00 +01:00
2016-05-18 18:55:53 +02:00
vec3 baseColor = matColor.rgb;
2016-08-25 00:26:01 +02:00
#ifdef _BaseTex
vec4 texel = texture(sbase, newCoord);
2016-03-18 23:02:00 +01:00
#ifdef _AlphaTest
if(texel.a < 0.4)
discard;
#endif
2016-06-18 13:58:12 +02:00
texel.rgb = pow(texel.rgb, vec3(2.2)); // Variant 1
2016-05-18 18:55:53 +02:00
baseColor *= texel.rgb;
2016-03-18 23:02:00 +01:00
#endif
2016-06-18 13:58:12 +02:00
// baseColor = pow(baseColor, vec3(2.2)); // Variant 2
2016-03-18 23:02:00 +01:00
2016-08-25 00:26:01 +02:00
#ifdef _MetTex
float metalness = texture(smetal, newCoord).r;
2016-03-18 23:02:00 +01:00
#endif
2016-08-25 00:26:01 +02:00
#ifdef _RoughTex
float roughness = texture(srough, newCoord).r;
2016-03-18 23:02:00 +01:00
#endif
2016-08-25 00:26:01 +02:00
#ifdef _RoughStr
2016-08-04 22:38:56 +02:00
roughness *= roughnessStrength;
#endif
2016-03-18 23:02:00 +01:00
2016-08-25 00:26:01 +02:00
#ifdef _OccTex
float occ = texture(socclusion, newCoord).r;
2016-03-18 23:02:00 +01:00
#else
2016-06-21 13:29:27 +02:00
float occ = occlusion;
2016-03-18 23:02:00 +01:00
#endif
2016-06-18 13:58:12 +02:00
2016-08-25 00:26:01 +02:00
#ifdef _HeightTex
2016-06-21 13:29:27 +02:00
occ *= shadowMultiplier;
2016-06-18 13:58:12 +02:00
#endif
2016-03-18 23:02:00 +01:00
2016-08-07 01:43:21 +02:00
// Pack normal
2016-04-16 18:57:32 +02:00
n /= (abs(n.x) + abs(n.y) + abs(n.z));
n.xy = n.z >= 0.0 ? n.xy : octahedronWrap(n.xy);
2016-06-18 13:58:12 +02:00
#ifdef _Probes
2016-06-07 09:38:49 +02:00
float mask_probe = probeID;
if (probeID > 0) { // Non-global probe attached
2016-06-07 09:38:49 +02:00
const float eps = 0.00001;
// Distance of vertex located inside probe to probe bounds
2016-08-25 00:26:01 +02:00
float dist = distanceBox(wpos.xyz, probeVolumeCenter, probeVolumeSize);
// Blend local probe with global probe
if (dist > -0.1) {
2016-08-23 22:55:46 +02:00
const float blending = 10.0;
float clampres = clamp((0.1 + dist) * blending, 0.0, 1.0 - eps);
mask_probe += clampres;
}
if (dist > 0) mask_probe = 0;
2016-06-07 09:38:49 +02:00
}
2016-08-29 09:56:34 +02:00
outColor[0] = vec4(n.xy, packFloat(metalness, roughness), mask_probe);
2016-06-07 09:38:49 +02:00
#else
2016-08-29 09:56:34 +02:00
outColor[0] = vec4(n.xy, packFloat(metalness, roughness), mask);
2016-06-07 09:38:49 +02:00
#endif
2016-08-13 20:38:45 +02:00
outColor[1] = vec4(baseColor.rgb, occ);
2016-07-31 23:25:33 +02:00
#ifdef _Veloc
2016-08-25 00:26:01 +02:00
vec2 posa = (wvppos.xy / wvppos.w) * 0.5 + 0.5;
vec2 posb = (prevwvppos.xy / prevwvppos.w) * 0.5 + 0.5;
2016-08-13 20:38:45 +02:00
outColor[2].rg = vec2(posa - posb);
2016-07-31 23:25:33 +02:00
#endif
2016-03-18 23:02:00 +01:00
}