armory/Shaders/deferred/decals.frag.glsl

132 lines
3.4 KiB
Plaintext
Raw Normal View History

2016-05-18 01:34:21 +02:00
#version 450
#ifdef GL_ES
precision mediump float;
#endif
2016-10-17 17:39:40 +02:00
#include "../std/gbuffer.glsl"
// octahedronWrap()
2016-05-18 01:34:21 +02:00
uniform sampler2D gbufferD;
2016-08-25 00:26:01 +02:00
#ifdef _BaseTex
uniform sampler2D sbase;
2016-05-18 18:55:53 +02:00
#endif
2016-08-25 00:26:01 +02:00
#ifdef _NorTex
2016-05-18 18:55:53 +02:00
uniform sampler2D snormal;
#endif
2016-08-25 00:26:01 +02:00
#ifdef _RoughTex
uniform sampler2D srough;
#else
uniform float roughness;
#endif
2016-08-25 00:26:01 +02:00
#ifdef _MetTex
uniform sampler2D smetal;
#else
uniform float metalness;
#endif
2016-05-18 01:34:21 +02:00
2016-09-08 14:08:31 +02:00
// uniform vec2 screenSize;
2016-05-18 18:55:53 +02:00
uniform mat4 invVP;
2016-08-25 00:26:01 +02:00
uniform mat4 invW;
2016-05-18 18:55:53 +02:00
uniform mat4 V;
2016-05-18 01:34:21 +02:00
2016-08-25 00:26:01 +02:00
in vec4 wvpposition;
2016-05-18 18:55:53 +02:00
in vec4 matColor;
// in vec3 orientation;
2016-10-12 17:52:27 +02:00
out vec4[2] fragColor;
2016-05-18 01:34:21 +02:00
mat3 cotangentFrame(vec3 nor, vec3 pos, vec2 uv) {
2016-10-17 17:39:40 +02:00
// Get edge vectors of the pixel triangle
vec3 dp1 = dFdx(pos);
vec3 dp2 = dFdy(pos);
vec2 duv1 = dFdx(uv);
vec2 duv2 = dFdy(uv);
// Solve the linear system
vec3 dp2perp = cross(dp2, nor);
vec3 dp1perp = cross(nor, dp1);
vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;
vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;
// Construct a scale-invariant frame
float invmax = inversesqrt(max(dot(T,T), dot(B,B)));
return mat3(T * invmax, B * invmax, nor);
2016-05-18 01:34:21 +02:00
}
2016-10-17 17:39:40 +02:00
vec4 reconstructPos(float depth, vec2 uv) {
vec4 sPos = vec4(uv * 2.0 - 1.0, depth, 1.0);
sPos = invVP * sPos;
return vec4((sPos.xyz / sPos.w), 1.0);
}
2016-05-18 01:34:21 +02:00
void main() {
2016-08-25 00:26:01 +02:00
vec2 screenPosition = wvpposition.xy / wvpposition.w;
2016-05-18 18:55:53 +02:00
vec2 depthUV = screenPosition * 0.5 + 0.5;
2016-10-17 17:39:40 +02:00
// depthUV += vec2(0.5 / screenSize); // Half pixel offset
float depth = texture(gbufferD, depthUV).r * 2.0 - 1.0;
2016-05-18 01:34:21 +02:00
2016-05-18 18:55:53 +02:00
vec4 worldPos = reconstructPos(depth, depthUV);
2016-10-17 17:39:40 +02:00
// Angle reject
// Reconstruct normal
// vec3 dnor = normalize(cross(dFdx(worldPos.xyz), dFdy(worldPos.xyz)));
// Get decal box orientation
// vec3 orientation = vec3(1.0, 0.0, 0.0);
// if (dot(dnor, orientation) < cos(3.1415)) discard;
2016-08-25 00:26:01 +02:00
vec4 localPos = invW * worldPos;
2016-05-18 18:55:53 +02:00
localPos.y *= -1.0;
2016-05-18 01:34:21 +02:00
2016-05-18 18:55:53 +02:00
if (abs(localPos.x) > 1.0) discard;
if (abs(localPos.y) > 1.0) discard;
if (abs(localPos.z) > 1.0) discard;
vec2 texCoord = (localPos.xy / 2.0) - 0.5; // / 2.0 - adjust decal box size
2016-05-18 01:34:21 +02:00
2016-08-25 00:26:01 +02:00
#ifdef _BaseTex
vec4 baseColor = texture(sbase, texCoord) * matColor;
#else
vec4 baseColor = matColor;
#endif
2016-05-18 01:34:21 +02:00
// Alpha write is disabled in shader res, we acces all channels for blending
// Use separate texture for base color in the future
2016-10-12 17:52:27 +02:00
fragColor[1].rgb = baseColor.rgb;
fragColor[1].a = baseColor.a;
2016-05-18 01:34:21 +02:00
2016-08-25 00:26:01 +02:00
#ifdef _MetTex
float metalness = texture(smetal, texCoord).r;
#endif
2016-08-25 00:26:01 +02:00
#ifdef _RoughTex
float roughness = texture(srough, texCoord).r;
#endif
2016-05-18 01:34:21 +02:00
2016-08-25 00:26:01 +02:00
#ifdef _NorTex
vec3 normal = texture(snormal, texCoord).rgb * 2.0 - 1.0;
vec3 nn = normalize(normal);
2016-10-17 17:39:40 +02:00
vec3 dp1 = dFdx(worldPos.xyz);
vec3 dp2 = dFdy(worldPos.xyz);
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 = normalize(TBN * nn);
2016-05-18 01:34:21 +02:00
n /= (abs(n.x) + abs(n.y) + abs(n.z));
2016-10-17 17:39:40 +02:00
n.xy = n.z >= 0.0 ? n.xy : octahedronWrap(n.xy);
2016-05-18 01:34:21 +02:00
2016-10-12 17:52:27 +02:00
fragColor[0].rg = n.xy;
#else
2016-10-12 17:52:27 +02:00
fragColor[0].rg = vec2(1.0);
#endif
2016-05-18 18:55:53 +02:00
2016-10-17 17:39:40 +02:00
fragColor[0].b = 0.0; // Unused for now so we can rewrite it
// Use separete RG texture for normal storage in the future
// Color mask does not disable write for all buffers so mask is overwritten
// Half of color alpha to soft normals blend
2016-10-12 17:52:27 +02:00
fragColor[0].a = baseColor.a / 2.0;
2016-05-18 01:34:21 +02:00
}