It now works correctly, and will output a "proper" depth of field effect. There's still work to be done to make it look smoother, but it's already pretty convincing.
77 lines
3.3 KiB
GLSL
Executable file
77 lines
3.3 KiB
GLSL
Executable file
#version 460 core
|
|
#extension GL_GOOGLE_include_directive : enable
|
|
|
|
#define SMAA_RT_METRICS vec4(1.0 / 1280.0, 1.0 / 720.0, 1280.0, 720.0)
|
|
|
|
#define SMAA_PRESET_ULTRA 1
|
|
#define SMAA_GLSL_4 1
|
|
#define SMAA_INCLUDE_VS 0
|
|
#define SMAA_INCLUDE_PS 1
|
|
#define SMAA_PREDICATION 1
|
|
#define SMAA_FLIP_Y 0
|
|
|
|
#include "smaa.glsl"
|
|
|
|
layout(location = 0) in vec2 inUV;
|
|
layout(location = 1) in vec4 inOffset;
|
|
|
|
layout(location = 0) out vec4 outColor;
|
|
|
|
layout(binding = 0) uniform sampler2D sceneSampler;
|
|
layout(binding = 1) uniform sampler2D depthSampler;
|
|
layout(binding = 2) uniform sampler2D nearFieldSampler;
|
|
layout(binding = 3) uniform sampler2D farFieldSampler;
|
|
layout(binding = 4) uniform sampler2D blendSampler;
|
|
layout(binding = 5) uniform sampler2D sobelSampler;
|
|
|
|
layout(push_constant) uniform PushConstants {
|
|
vec4 viewport;
|
|
} pushConstants;
|
|
|
|
void main() {
|
|
vec3 sceneColor = SMAANeighborhoodBlendingPS(inUV, inOffset, sceneSampler, blendSampler).rgb;
|
|
|
|
const vec4 farPlaneColor = texture(farFieldSampler, inUV);
|
|
const vec4 nearPlaneColor = texture(nearFieldSampler, inUV);
|
|
|
|
// we perform alpha divide reconstruction, or else the results will look really blown out because of additive blending
|
|
const vec3 farColor = farPlaneColor.rgb / max(farPlaneColor.a, 0.0001);
|
|
const vec3 nearColor = nearPlaneColor.rgb / max(nearPlaneColor.a, 0.0001);
|
|
|
|
// read coc stored in the alpha channel
|
|
const float coc = texture(farFieldSampler, inUV).a;
|
|
const float coc2 = texture(nearFieldSampler, inUV).a;
|
|
|
|
// transition between out of focus and regular scene
|
|
// TODO: make this softer
|
|
vec3 farColorBlurred = mix(sceneColor, farColor, clamp(coc - 2.0, 0.0, 1.0));
|
|
farColorBlurred = mix(sceneColor, farColor, clamp(coc * 5.0, 0.0, 1.0));
|
|
|
|
// now we take into account the near field, using it's own coc
|
|
const vec3 final = mix(farColorBlurred, nearColor, clamp(coc2 * 5.0, 0.0, 1.0));
|
|
|
|
// sobel calculation
|
|
float thickness = 3.0;
|
|
float thicknessX = thickness * pushConstants.viewport.x * (pushConstants.viewport.z / 1920.0);
|
|
float thicknessY = thickness * pushConstants.viewport.y * (pushConstants.viewport.w / 1080.0);
|
|
|
|
vec4 top = texture(sobelSampler, vec2(inUV.x, inUV.y + thicknessY));
|
|
vec4 bottom = texture(sobelSampler, vec2(inUV.x, inUV.y - thicknessY));
|
|
vec4 left = texture(sobelSampler, vec2(inUV.x - thicknessX, inUV.y));
|
|
vec4 right = texture(sobelSampler, vec2(inUV.x + thicknessX, inUV.y));
|
|
vec4 topLeft = texture(sobelSampler, vec2(inUV.x - thicknessX, inUV.y + thicknessY));
|
|
vec4 topRight = texture(sobelSampler, vec2(inUV.x + thicknessX, inUV.y + thicknessY));
|
|
vec4 bottomLeft = texture(sobelSampler, vec2(inUV.x - thicknessX, inUV.y - thicknessY));
|
|
vec4 bottomRight = texture(sobelSampler, vec2(inUV.x + thicknessX, inUV.y - thicknessY));
|
|
|
|
vec4 sx = -topLeft - 2 * left - bottomLeft + topRight + 2 * right + bottomRight;
|
|
vec4 sy = -topLeft - 2 * top - topRight + bottomLeft + 2 * bottom + bottomRight;
|
|
vec4 sobel = sqrt(sx * sx + sy * sy);
|
|
sobel = clamp(sobel / 5.0, 0.0, 1.0);
|
|
|
|
vec4 outlineColor = vec4(0.1, 0.5, 0.9, 1.0);
|
|
|
|
outColor = vec4(final, 1.0);
|
|
outColor = outlineColor*sobel + outColor*(1.0 - sobel);
|
|
outColor += outlineColor * texture(sobelSampler, inUV) * 0.3;
|
|
}
|