forked from townforge/townforge
155 lines
5.1 KiB
GLSL
Executable File
155 lines
5.1 KiB
GLSL
Executable File
// MIT License
|
|
|
|
// Copyright (c) 2020 Arnis Lielturks
|
|
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files (the "Software"), to deal
|
|
// in the Software without restriction, including without limitation the rights
|
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
// copies of the Software, and to permit persons to whom the Software is
|
|
// furnished to do so, subject to the following conditions:
|
|
|
|
// The above copyright notice and this permission notice shall be included in all
|
|
// copies or substantial portions of the Software.
|
|
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
// SOFTWARE.
|
|
|
|
#include "Uniforms.glsl"
|
|
#include "Samplers.glsl"
|
|
#include "Transform.glsl"
|
|
#include "ScreenPos.glsl"
|
|
#include "PostProcess.glsl"
|
|
|
|
varying vec2 vTexCoord;
|
|
|
|
#ifdef COMPILEPS
|
|
uniform vec2 cSSAOInvSize;
|
|
uniform vec2 cBlurHInvSize;
|
|
uniform vec2 cBlurVInvSize;
|
|
uniform float cSSAOStrength;
|
|
uniform float cSSAORadius;
|
|
uniform float cSSAOBase;
|
|
uniform float cSSAOArea;
|
|
uniform float cSSAOFalloff;
|
|
uniform float cSSAONoiseFactor;
|
|
#endif
|
|
|
|
void VS()
|
|
{
|
|
mat4 modelMatrix = iModelMatrix;
|
|
vec3 worldPos = GetWorldPos(modelMatrix);
|
|
gl_Position = GetClipPos(worldPos);
|
|
vTexCoord = GetQuadTexCoord(gl_Position);
|
|
}
|
|
|
|
#ifdef COMPILEPS
|
|
|
|
vec3 normalFromDepth(float depth, vec2 texcoords)
|
|
{
|
|
vec2 offset1 = vec2(0.0, cSSAOInvSize.y);
|
|
vec2 offset2 = vec2(cSSAOInvSize.x, 0.0);
|
|
|
|
float depth1 = DecodeDepth(texture2D(sDepthBuffer, texcoords + offset1).rgb) * cFarClipPS;
|
|
float depth2 = DecodeDepth(texture2D(sDepthBuffer, texcoords + offset2).rgb) * cFarClipPS;
|
|
|
|
|
|
vec3 p1 = vec3(offset1, depth1 - depth);
|
|
vec3 p2 = vec3(offset2, depth2 - depth);
|
|
|
|
vec3 normal = cross(p1, p2);
|
|
|
|
return normalize(normal);
|
|
}
|
|
|
|
vec3 reflection(vec3 v1,vec3 v2)
|
|
{
|
|
vec3 result = 2.0 * dot(v2, v1) * v2;
|
|
result = v1 - result;
|
|
return result;
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
void PS()
|
|
{
|
|
#ifdef OCCLUDE
|
|
|
|
//Edge Mask
|
|
//float edge = min( min( vTexCoord.x, 1.0 - vTexCoord.x ), min( vTexCoord.y, 1.0 - vTexCoord.y ) );
|
|
//edge = clamp( 2 * edge + 0.001, 0.8, 1.0);
|
|
|
|
float depth = DecodeDepth(texture2D(sDepthBuffer, vTexCoord).rgb) * cFarClipPS;
|
|
if( depth >= 1000.0) {
|
|
gl_FragColor = vec4(1.0);
|
|
return;
|
|
}
|
|
|
|
vec3 sample_sphere[16] = vec3[](
|
|
vec3( 0.5381, 0.1856,-0.4319), vec3( 0.1379, 0.2486, 0.4430),
|
|
vec3( 0.3371, 0.5679,-0.0057), vec3(-0.6999,-0.0451,-0.0019),
|
|
vec3( 0.0689,-0.1598,-0.8547), vec3( 0.0560, 0.0069,-0.1843),
|
|
vec3(-0.0146, 0.1402, 0.0762), vec3( 0.0100,-0.1924,-0.0344),
|
|
vec3(-0.3577,-0.5301,-0.4358), vec3(-0.3169, 0.1063, 0.0158),
|
|
vec3( 0.0103,-0.5869, 0.0046), vec3(-0.0897,-0.4940, 0.3287),
|
|
vec3( 0.7119,-0.0154,-0.0918), vec3(-0.0533, 0.0596,-0.5411),
|
|
vec3( 0.0352,-0.0631, 0.5460), vec3(-0.4776, 0.2847,-0.0271)
|
|
);
|
|
vec3 random = normalize( texture2D(sDiffMap, vTexCoord * cSSAONoiseFactor).rgb );
|
|
vec3 position = vec3(vTexCoord.x, vTexCoord.y,depth);
|
|
vec3 normal = normalFromDepth(depth, vTexCoord);
|
|
|
|
|
|
|
|
//AO Radius based on distance
|
|
float radiusDepth = cSSAORadius / depth;
|
|
float occlusion = 0.0;
|
|
int iterations = 8; // 8 More noise / Better performance
|
|
|
|
for (int j = 0; j < iterations; ++j)
|
|
{
|
|
vec3 ray = radiusDepth * reflection(sample_sphere[j], random);
|
|
vec3 hemiRay = position + sign(dot(ray, normal)) * ray;
|
|
|
|
//Fix Distance of SSAO
|
|
float occDepth = DecodeDepth(texture2D(sDepthBuffer, clamp(hemiRay.xy, 0.0, 1.0)).rgb) * cFarClipPS;
|
|
float difference = depth - occDepth * 1.0015;
|
|
|
|
occlusion += step(cSSAOFalloff, difference) * (1.0 - smoothstep(cSSAOFalloff, cSSAOArea, difference));
|
|
}
|
|
//AO intensity based on distance
|
|
float aoDepthInt = mix(0.5, 0.8, depth * 0.02) * mix(1.0, 0.0, depth * 0.001);
|
|
float ao = 1.0 - (cSSAOStrength * aoDepthInt) * occlusion * (1.0 / iterations);
|
|
|
|
float final = clamp(ao + cSSAOBase, 0.0, 1.0);
|
|
|
|
gl_FragColor = vec4(vec3(final), 1.0);
|
|
#endif
|
|
|
|
#ifdef BLURV
|
|
gl_FragColor = GaussianBlur(3, vec2(0.0, 1.0), cBlurVInvSize * 2.0, 2.0, sDiffMap, vTexCoord);
|
|
#endif
|
|
|
|
#ifdef BLURH
|
|
gl_FragColor = GaussianBlur(3, vec2(1.0, 0.0), cBlurHInvSize * 2.0, 2.0, sDiffMap, vTexCoord);
|
|
#endif
|
|
|
|
#ifdef OUTPUT
|
|
gl_FragColor.rgb = texture2D(sDiffMap, vTexCoord).rgb * texture2D(sDepthBuffer, vTexCoord).rgb;
|
|
// gl_FragColor.rgb = texture2D(sDepthBuffer, vTexCoord).rgb;
|
|
// if (vTexCoord.x > 0.5) {
|
|
// gl_FragColor.rgb = texture2D(sDiffMap, vTexCoord).rgb * texture2D(sDepthBuffer, vTexCoord).rgb;
|
|
// }
|
|
// else
|
|
// {
|
|
// gl_FragColor.rgb = texture2D(sDepthBuffer, vTexCoord).rgb;
|
|
// }
|
|
#endif
|
|
}
|