axmol/tests/cpp-tests/Source/shaders/shadertoy_Glow.fsh

124 lines
4.6 KiB
GLSL

#version 310 es
precision highp float;
precision highp int;
//uniform float iChannelTime[4]; // channel playback time (in seconds)
//uniform vec3 iChannelResolution[4]; // channel resolution (in pixels)
//vec4 iMouse = vec4(0,0,0,0); // mouse pixel coords. xy: current (if MLB down), zw: click
//layout(binding = 0) uniform sampler2D iChannel0; // input channel. XX = 2D/Cube
layout(std140, binding = 0) uniform fs_ub {
vec2 center;
vec2 resolution;
vec2 u_screenSize;
vec4 u_Time;
};
layout(location = SV_Target0) out vec4 FragColor;
void main(void)
{
#ifdef METAL
vec2 fragCoord = vec2(gl_FragCoord.x, u_screenSize.y - gl_FragCoord.y);
#else
vec2 fragCoord = gl_FragCoord.xy;
#endif
vec2 iResolution = resolution; // viewport resolution (in pixels)
float iGlobalTime = u_Time[1]; // shader playback time (in seconds)
float pointRadius = 0.06;
float linkSize = 0.04;
float noiseStrength = 0.08; // range: 0-1
float minDimension = min(iResolution.x, iResolution.y);
vec2 bounds = vec2(iResolution.x / minDimension, iResolution.y / minDimension);
//vec2 uv = fragCoord.xy / minDimension;
vec2 uv = (2. * fragCoord.xy - center.xy) / iResolution.xy;
vec3 pointR = vec3(0.0, 0.0, 1.0);
vec3 pointG = vec3(0.0, 0.0, 1.0);
vec3 pointB = vec3(0.0, 0.0, 1.0);
// Make the points orbit round the origin in 3 dimensions.
// Coefficients are arbitrary to give different behaviours.
// The Z coordinate should always be >0.0, as it's used directly to
// multiply the radius to give the impression of depth.
pointR.x += 0.32 * sin(1.32 * iGlobalTime);
pointR.y += 0.3 * sin(1.03 * iGlobalTime);
pointR.z += 0.4 * sin(1.32 * iGlobalTime);
pointG.x += 0.31 * sin(0.92 * iGlobalTime);
pointG.y += 0.29 * sin(0.99 * iGlobalTime);
pointG.z += 0.38 * sin(1.24 * iGlobalTime);
pointB.x += 0.33 * sin(1.245 * iGlobalTime);
pointB.y += 0.3 * sin(1.41 * iGlobalTime);
pointB.z += 0.41 * sin(1.11 * iGlobalTime);
// Centre the points in the display
vec2 midUV = vec2(bounds.x * 0.5, bounds.y * 0.5);
pointR.xy += midUV;
pointG.xy += midUV;
pointB.xy += midUV;
// Calculate the vectors from the current fragment to the coloured points
vec2 vecToR = pointR.xy - uv;
vec2 vecToG = pointG.xy - uv;
vec2 vecToB = pointB.xy - uv;
vec2 dirToR = normalize(vecToR.xy);
vec2 dirToG = normalize(vecToG.xy);
vec2 dirToB = normalize(vecToB.xy);
float distToR = length(vecToR);
float distToG = length(vecToG);
float distToB = length(vecToB);
// Calculate the dot product between vectors from the current fragment to each pair
// of adjacent coloured points. This helps us determine how close the current fragment
// is to a link between points.
float dotRG = dot(dirToR, dirToG);
float dotGB = dot(dirToG, dirToB);
float dotBR = dot(dirToB, dirToR);
// Start with a bright coloured dot around each point
FragColor.x = 1.0 - smoothstep(distToR, 0.0, pointRadius * pointR.z);
FragColor.y = 1.0 - smoothstep(distToG, 0.0, pointRadius * pointG.z);
FragColor.z = 1.0 - smoothstep(distToB, 0.0, pointRadius * pointB.z);
FragColor.w = 1.0;
// We want to show a coloured link between adjacent points.
// Determine the strength of each link at the current fragment.
// This tends towards 1.0 as the vectors to each point tend towards opposite directions.
float linkStrengthRG = 1.0 - smoothstep(dotRG, -1.01, -1.0 + (linkSize * pointR.z * pointG.z));
float linkStrengthGB = 1.0 - smoothstep(dotGB, -1.01, -1.0 + (linkSize * pointG.z * pointB.z));
float linkStrengthBR = 1.0 - smoothstep(dotBR, -1.01, -1.0 + (linkSize * pointB.z * pointR.z));
// If the current fragment is in a link, we need to know how much the
// linked points contribute of their colour.
float sumDistRG = distToR + distToG;
float sumDistGB = distToG + distToB;
float sumDistBR = distToB + distToR;
float contribRonRG = 1.0 - (distToR / sumDistRG);
float contribRonBR = 1.0 - (distToR / sumDistBR);
float contribGonRG = 1.0 - (distToG / sumDistRG);
float contribGonGB = 1.0 - (distToG / sumDistGB);
float contribBonGB = 1.0 - (distToB / sumDistGB);
float contribBonBR = 1.0 - (distToB / sumDistBR);
// Additively blend the link colours into the fragment.
FragColor.x += (linkStrengthRG * contribRonRG) + (linkStrengthBR * contribRonBR);
FragColor.y += (linkStrengthGB * contribGonGB) + (linkStrengthRG * contribGonRG);
FragColor.z += (linkStrengthBR * contribBonBR) + (linkStrengthGB * contribBonGB);
// Use an underlying texture to provide some noise
float noiseMin = 1.0 - noiseStrength;
FragColor.xyz *= (1.0 - noiseStrength) + (noiseStrength * 0.);
}