armory/Shaders/ssao_pass/ssao_pass.frag.glsl

85 lines
2.4 KiB
Plaintext
Raw Normal View History

2016-03-26 12:53:25 +01:00
// Alchemy AO
// Compute kernel
// var kernel:Array<Float> = [];
// var kernelSize = 8;
// for (i in 0...kernelSize) {
// var angle = i / kernelSize;
// angle *= 3.1415926535 * 2.0;
// var x1 = Math.cos(angle);
// var y1 = Math.sin(angle);
// x1 = Std.int(x1 * 10000000) / 10000000;
// y1 = Std.int(y1 * 10000000) / 10000000;
// trace(x1, y1);
// }
2016-03-15 11:29:53 +01:00
#version 450
#include "compiled.inc"
2017-12-13 14:21:42 +01:00
#include "std/gbuffer.glsl"
2016-07-17 20:29:53 +02:00
2018-12-05 17:47:45 +01:00
const int kernelSize = 12;
const vec2 kernel[12] = vec2[] (
vec2(1.0, 0.0),
vec2(0.8660254, 0.4999999),
vec2(0.5, 0.8660254),
vec2(0.0, 1.0),
vec2(-0.4999999, 0.8660254),
vec2(-0.8660254, 0.5),
vec2(-1.0, 0.0),
vec2(-0.8660254, -0.4999999),
vec2(-0.5, -0.8660254),
vec2(0.0, -1.0),
vec2(0.4999999, -0.8660254),
vec2(0.8660254, -0.5)
);
2016-05-13 00:08:11 +02:00
uniform sampler2D gbufferD;
2016-03-22 12:04:08 +01:00
uniform sampler2D gbuffer0;
2016-03-26 12:53:25 +01:00
uniform sampler2D snoise;
2018-12-05 17:47:45 +01:00
uniform vec2 cameraProj;
uniform vec3 eyeLook;
2016-06-21 13:29:27 +02:00
uniform vec2 screenSize;
uniform vec2 aspectRatio;
2016-03-26 12:53:25 +01:00
2016-03-15 11:29:53 +01:00
in vec2 texCoord;
2018-12-05 17:47:45 +01:00
in vec3 viewRay;
2016-10-12 17:52:27 +02:00
out vec4 fragColor;
2016-03-15 11:29:53 +01:00
void main() {
2018-12-05 17:47:45 +01:00
float depth = textureLod(gbufferD, texCoord, 0.0).r * 2.0 - 1.0;
if (depth == 1.0) { fragColor.r = 1.0; return; }
2016-08-07 23:12:14 +02:00
2018-12-05 17:47:45 +01:00
vec2 enc = textureLod(gbuffer0, texCoord, 0.0).rg;
2017-03-12 17:29:22 +01:00
vec3 n;
n.z = 1.0 - abs(enc.x) - abs(enc.y);
n.xy = n.z >= 0.0 ? enc.xy : octahedronWrap(enc.xy);
n = normalize(n);
2016-04-16 13:19:03 +02:00
2018-12-05 17:47:45 +01:00
vec3 vray = normalize(viewRay);
vec3 currentPos = getPosNoEye(eyeLook, vray, depth, cameraProj);
float currentDistance = length(currentPos);
2018-12-05 17:47:45 +01:00
float currentDistanceA = currentDistance * 0.002;
float currentDistanceB = min(currentDistance * 0.25, 1.0);
2016-03-26 12:53:25 +01:00
2018-12-05 17:47:45 +01:00
vec2 randomVec = textureLod(snoise, (texCoord * screenSize) / 8.0, 0.0).xy * 2.0 - 1.0;
mat2 rotMat = mat2(vec2(cos(randomVec.x * PI), -sin(randomVec.x * PI)),
vec2(sin(randomVec.x * PI), cos(randomVec.x * PI)));
2018-12-05 17:47:45 +01:00
float radius = ssaoSize * randomVec.y;
2018-11-27 21:34:42 +01:00
fragColor.r = 0;
for (int i = 0; i < 12; ++i) {
2018-12-05 17:47:45 +01:00
vec2 k = ((rotMat * kernel[i] * aspectRatio) / currentDistance) * radius;
depth = textureLod(gbufferD, texCoord + k, 0.0).r * 2.0 - 1.0;
vec3 pos = getPosNoEye(eyeLook, vray, depth, cameraProj) - currentPos;
float angle = dot(pos, n);
angle *= step(0.1, angle / length(pos)); // Fix intersect
angle -= currentDistanceA;
angle = max(0.0, angle);
angle /= dot(pos, pos) / currentDistanceB + 0.015; // Fix darkening
fragColor.r += angle;
2018-11-27 21:34:42 +01:00
}
2016-03-26 12:53:25 +01:00
2017-03-12 17:29:22 +01:00
fragColor.r *= ssaoStrength / kernelSize;
2018-12-05 17:47:45 +01:00
fragColor.r = 1.0 - fragColor.r;
2016-03-15 11:29:53 +01:00
}