mirror of
https://github.com/italicsjenga/slang-shaders.git
synced 2024-11-23 00:01:31 +11:00
185 lines
5.6 KiB
Plaintext
185 lines
5.6 KiB
Plaintext
#version 450
|
|
|
|
layout(push_constant) uniform Push
|
|
{
|
|
vec4 SourceSize;
|
|
vec4 OriginalSize;
|
|
vec4 OutputSize;
|
|
uint FrameCount;
|
|
} params;
|
|
|
|
layout(std140, set = 0, binding = 0) uniform UBO
|
|
{
|
|
mat4 MVP;
|
|
} global;
|
|
|
|
#include "smaa-common.h"
|
|
|
|
#pragma stage vertex
|
|
layout(location = 0) in vec4 Position;
|
|
layout(location = 1) in vec2 TexCoord;
|
|
layout(location = 0) out vec2 texcoord;
|
|
layout(location = 1) out vec4 offset[3];
|
|
|
|
void main()
|
|
{
|
|
gl_Position = global.MVP * Position;
|
|
texcoord = TexCoord;
|
|
offset[0] = fma(SMAA_RT_METRICS.xyxy, vec4(-1.0, 0.0, 0.0, -1.0), texcoord.xyxy);
|
|
offset[1] = fma(SMAA_RT_METRICS.xyxy, vec4( 1.0, 0.0, 0.0, 1.0), texcoord.xyxy);
|
|
offset[2] = fma(SMAA_RT_METRICS.xyxy, vec4(-2.0, 0.0, 0.0, -2.0), texcoord.xyxy);
|
|
}
|
|
|
|
#pragma stage fragment
|
|
layout(location = 0) in vec2 texcoord;
|
|
layout(location = 1) in vec4 offset[3];
|
|
layout(location = 0) out vec4 FragColor;
|
|
layout(set = 0, binding = 2) uniform sampler2D Source;
|
|
|
|
/**
|
|
* Luma Edge Detection
|
|
*
|
|
* IMPORTANT NOTICE: luma edge detection requires gamma-corrected colors, and
|
|
* thus 'colorTex' should be a non-sRGB texture.
|
|
*/
|
|
vec2 SMAALumaEdgeDetectionPS(vec2 texcoord, vec4 offset[3], sampler2D colorTex
|
|
#if SMAA_PREDICATION
|
|
, SMAATexture2D(predicationTex)
|
|
#endif
|
|
) {
|
|
// Calculate the threshold:
|
|
#if SMAA_PREDICATION
|
|
vec2 threshold = SMAACalculatePredicatedThreshold(texcoord, offset, predicationTex);
|
|
#else
|
|
vec2 threshold = vec2(SMAA_THRESHOLD, SMAA_THRESHOLD);
|
|
#endif
|
|
|
|
// Calculate lumas:
|
|
vec3 weights = vec3(0.2126, 0.7152, 0.0722);
|
|
float L = dot(texture(colorTex, texcoord).rgb, weights);
|
|
|
|
float Lleft = dot(texture(colorTex, offset[0].xy).rgb, weights);
|
|
float Ltop = dot(texture(colorTex, offset[0].zw).rgb, weights);
|
|
|
|
// We do the usual threshold:
|
|
vec4 delta;
|
|
delta.xy = abs(L - vec2(Lleft, Ltop));
|
|
vec2 edges = step(threshold, delta.xy);
|
|
|
|
// Then discard if there is no edge:
|
|
if (dot(edges, vec2(1.0, 1.0)) == 0.0)
|
|
discard;
|
|
|
|
// Calculate right and bottom deltas:
|
|
float Lright = dot(texture(colorTex, offset[1].xy).rgb, weights);
|
|
float Lbottom = dot(texture(colorTex, offset[1].zw).rgb, weights);
|
|
delta.zw = abs(L - vec2(Lright, Lbottom));
|
|
|
|
// Calculate the maximum delta in the direct neighborhood:
|
|
vec2 maxDelta = max(delta.xy, delta.zw);
|
|
|
|
// Calculate left-left and top-top deltas:
|
|
float Lleftleft = dot(texture(colorTex, offset[2].xy).rgb, weights);
|
|
float Ltoptop = dot(texture(colorTex, offset[2].zw).rgb, weights);
|
|
delta.zw = abs(vec2(Lleft, Ltop) - vec2(Lleftleft, Ltoptop));
|
|
|
|
// Calculate the final maximum delta:
|
|
maxDelta = max(maxDelta.xy, delta.zw);
|
|
float finalDelta = max(maxDelta.x, maxDelta.y);
|
|
|
|
// Local contrast adaptation:
|
|
edges.xy *= step(finalDelta, SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR * delta.xy);
|
|
|
|
return edges;
|
|
}
|
|
|
|
/**
|
|
* Color Edge Detection
|
|
*
|
|
* IMPORTANT NOTICE: color edge detection requires gamma-corrected colors, and
|
|
* thus 'colorTex' should be a non-sRGB texture.
|
|
*/
|
|
vec2 SMAAColorEdgeDetectionPS(vec2 texcoord,
|
|
vec4 offset[3],
|
|
sampler2D colorTex
|
|
#if SMAA_PREDICATION
|
|
, sampler2D predicationTex
|
|
#endif
|
|
) {
|
|
// Calculate the threshold:
|
|
#if SMAA_PREDICATION
|
|
vec2 threshold = SMAACalculatePredicatedThreshold(texcoord, offset, predicationTex);
|
|
#else
|
|
vec2 threshold = vec2(SMAA_THRESHOLD, SMAA_THRESHOLD);
|
|
#endif
|
|
|
|
// Calculate color deltas:
|
|
vec4 delta;
|
|
vec3 C = texture(colorTex, texcoord).rgb;
|
|
|
|
vec3 Cleft = texture(colorTex, offset[0].xy).rgb;
|
|
vec3 t = abs(C - Cleft);
|
|
delta.x = max(max(t.r, t.g), t.b);
|
|
|
|
vec3 Ctop = texture(colorTex, offset[0].zw).rgb;
|
|
t = abs(C - Ctop);
|
|
delta.y = max(max(t.r, t.g), t.b);
|
|
|
|
// We do the usual threshold:
|
|
vec2 edges = step(threshold, delta.xy);
|
|
|
|
// Then discard if there is no edge:
|
|
if (dot(edges, vec2(1.0, 1.0)) == 0.0)
|
|
discard;
|
|
|
|
// Calculate right and bottom deltas:
|
|
vec3 Cright = texture(colorTex, offset[1].xy).rgb;
|
|
t = abs(C - Cright);
|
|
delta.z = max(max(t.r, t.g), t.b);
|
|
|
|
vec3 Cbottom = texture(colorTex, offset[1].zw).rgb;
|
|
t = abs(C - Cbottom);
|
|
delta.w = max(max(t.r, t.g), t.b);
|
|
|
|
// Calculate the maximum delta in the direct neighborhood:
|
|
vec2 maxDelta = max(delta.xy, delta.zw);
|
|
|
|
// Calculate left-left and top-top deltas:
|
|
vec3 Cleftleft = texture(colorTex, offset[2].xy).rgb;
|
|
t = abs(C - Cleftleft);
|
|
delta.z = max(max(t.r, t.g), t.b);
|
|
|
|
vec3 Ctoptop = texture(colorTex, offset[2].zw).rgb;
|
|
t = abs(C - Ctoptop);
|
|
delta.w = max(max(t.r, t.g), t.b);
|
|
|
|
// Calculate the final maximum delta:
|
|
maxDelta = max(maxDelta.xy, delta.zw);
|
|
float finalDelta = max(maxDelta.x, maxDelta.y);
|
|
|
|
// Local contrast adaptation:
|
|
edges.xy *= step(finalDelta, SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR * delta.xy);
|
|
|
|
return edges;
|
|
}
|
|
|
|
/**
|
|
* Depth Edge Detection
|
|
*/
|
|
vec2 SMAADepthEdgeDetectionPS(vec2 texcoord,
|
|
vec4 offset[3],
|
|
sampler2D depthTex) {
|
|
vec3 neighbours = SMAAGatherNeighbours(texcoord, offset, depthTex);
|
|
vec2 delta = abs(neighbours.xx - vec2(neighbours.y, neighbours.z));
|
|
vec2 edges = step(SMAA_DEPTH_THRESHOLD, delta);
|
|
|
|
if (dot(edges, vec2(1.0, 1.0)) == 0.0)
|
|
discard;
|
|
|
|
return edges;
|
|
}
|
|
|
|
void main()
|
|
{
|
|
FragColor = vec4(SMAALumaEdgeDetectionPS(texcoord, offset, Source), 0.0, 0.0);
|
|
} |