#[compute] #version 450 float clamp01( float value ) { return clamp( value, 0.0, 1.0 ); } vec4 clamp01_v4( vec4 value ) { value.r = clamp01( value.r ); value.g = clamp01( value.g ); value.b = clamp01( value.b ); value.a = clamp01( value.a ); return value; } vec2 clamp01( vec2 value ) { return clamp( value, 0.0, 1.0 ); } vec3 clamp01( vec3 value ) { return clamp( value, 0.0, 1.0 ); } vec4 clamp01( vec4 value ) { return clamp( value, 0.0, 1.0 ); } float normalizeToRange( float value, float min, float max ) { return ( value - min ) / ( max - min ); } float normalizeToRange01( float value, float min, float max ) { return clamp01( normalizeToRange( value, min, max ) ); } float map( float value, float inMin, float inMax, float outMin, float outMax ) { return mix( outMin, outMax, normalizeToRange( value, inMin, inMax ) ); } vec2 map_v2( vec2 value, vec2 inMin, vec2 inMax, vec2 outMin, vec2 outMax ) { float x = map( value.x, inMin.x, inMax.x, outMin.x, outMax.x ); float y = map( value.y, inMin.y, inMax.y, outMin.y, outMax.y ); return vec2( x, y ); } float mapClamped( float value, float inMin, float inMax, float outMin, float outMax ) { return mix( outMin, outMax, normalizeToRange01( value, inMin, inMax ) ); } vec3 colorize( vec3 original, vec3 color ) { float grey = ( original.r + original.g + original.b ) / 3.0; return grey < 0.5 ? mix( vec3( 0.0 ), color, grey * 2.0 ) : mix( color, vec3( 1.0 ), ( grey - 0.5 ) * 2.0 ); } layout( local_size_x = 16, local_size_y = 16, local_size_z = 1 ) in; layout( rgba16f, set = 0, binding = 0) uniform image2D screenImage; layout( push_constant, std430 ) uniform Parameters { vec4 topColor; // 4 vec4 bottomColor; // 8 vec2 rasterSize; // 6 float amount; // 7 float fadeIn; // 8 float fadeOut; // 9 float circelize; // 10 float power; // 12 float replace; // 13 float add; // 14 float multiply; // 15 float colorize; // 16 } parameters; void main() { ivec2 coordinate = ivec2( gl_GlobalInvocationID.xy ); ivec2 size = ivec2( parameters.rasterSize ); if ( coordinate.x >= size.x || coordinate.y >= size.y ) { return; } vec4 color = imageLoad( screenImage, coordinate ); // color = vec4( 0.0, 0.0, 0.0, 1.0 ); vec2 uv = ( vec2( coordinate ) + vec2( 0.5 ) ) / vec2( parameters.rasterSize ) ; float ratio = parameters.rasterSize.y / parameters.rasterSize.x; uv.y = mix( uv.y, ( uv.y - 0.5 ) * ratio + 0.5, parameters.circelize ); float centerDistance = length( uv - vec2( 0.5 ) ); float distanceAmount = mapClamped( centerDistance, parameters.fadeIn, parameters.fadeOut, 0.0, 1.0 ); distanceAmount = pow( distanceAmount, parameters.power ); vec4 vignetteColor = mix( parameters.topColor, parameters.bottomColor, uv.y ); vec4 multiplied = vignetteColor * color; vec4 added = vignetteColor + color; vec4 colorized = vec4( colorize( color.rgb, vignetteColor.rgb ), 1.0 ); vec4 mixed = vignetteColor * parameters.replace + added * parameters.add + multiplied * parameters.multiply + colorized * parameters.colorize; color.rgb = mix( color.rgb, mixed.rgb, vignetteColor.a * distanceAmount * parameters.amount ); // color.rgb = vignetteColor.rgb; imageStore( screenImage, coordinate, color ); }