Created
March 2, 2025 15:36
-
-
Save undefined06855/30208e7a1cd8c19f6c22f85bf0ef7600 to your computer and use it in GitHub Desktop.
Robtop's Geometry Dash post-processing shader
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #ifdef GL_ES | |
| precision mediump float; | |
| #ifdef GL_FRAGMENT_PRECISION_HIGH | |
| #define PRECISION highp | |
| #else | |
| #define PRECISION mediump | |
| #endif | |
| #else | |
| #define PRECISION | |
| #endif | |
| varying vec2 v_texCoord; | |
| uniform sampler2D CC_Texture0; | |
| // --------------------- | |
| // COMMON | |
| // --------------------- | |
| uniform vec2 _textureScale; | |
| uniform vec2 _textureScaleInv; | |
| uniform float _screenAspect; | |
| uniform float _screenAspectInv; | |
| // --------------------- | |
| // SHOCKWAVE | |
| // --------------------- | |
| uniform float _shockWaveTime; | |
| uniform float _shockWaveTime1; | |
| uniform float _shockWaveTime2; | |
| uniform float _shockWaveTime3; | |
| uniform float _shockWaveTime4; | |
| uniform float _shockWaveStrength; | |
| uniform float _shockWaveWaves; | |
| uniform vec2 _shockWaveCenter; | |
| uniform bool _shockWaveInvert; | |
| uniform float _shockWaveMinSize; | |
| uniform float _shockWaveMaxSize; | |
| uniform float _shockWaveMaxDistVal; | |
| // --------------------- | |
| // SHOCKLINE | |
| // --------------------- | |
| uniform float _shockLineTime; | |
| uniform float _shockLineTime1; | |
| uniform float _shockLineTime2; | |
| uniform float _shockLineTime3; | |
| uniform float _shockLineTime4; | |
| uniform bool _shockLineAxis; | |
| uniform bool _shockLineDirection; | |
| uniform bool _shockLineDual; | |
| uniform float _shockLineWaves; | |
| uniform vec2 _shockLineStrength; | |
| uniform float _shockLineCenter; | |
| uniform float _shockLineMaxDistVal; | |
| // --------------------- | |
| // GLITCH | |
| // --------------------- | |
| uniform float _glitchBot; | |
| uniform float _glitchTop; | |
| uniform float _glitchXOffset; | |
| uniform vec2 _glitchColOffset; | |
| uniform float _glitchRnd; | |
| // --------------------- | |
| // CHROMATIC | |
| // --------------------- | |
| uniform float _chromaticXOff; | |
| uniform float _chromaticYOff; | |
| // --------------------- | |
| // LENSCIRCLE | |
| // --------------------- | |
| uniform PRECISION vec2 _lensCircleOrigin; | |
| uniform float _lensCircleStart; | |
| uniform float _lensCircleEnd; | |
| uniform float _lensCircleStrength; | |
| uniform vec3 _lensCircleTint; | |
| uniform bool _lensCircleAdditive; | |
| // --------------------- | |
| // BULGE | |
| // --------------------- | |
| uniform vec2 _bulgeOrigin; | |
| uniform float _bulgeValue; | |
| uniform float _bulgeValue2; | |
| uniform float _bulgeRadius; | |
| // --------------------- | |
| // PINCH | |
| // --------------------- | |
| uniform vec2 _pinchCenterPos; | |
| uniform vec2 _pinchValue; | |
| uniform vec2 _pinchCalc1; | |
| uniform float _pinchRadius; | |
| // --------------------- | |
| // BLUR COMMON | |
| // --------------------- | |
| uniform bool _blurUseRef; | |
| uniform vec3 _blurRefColor; | |
| uniform float _blurIntensity; | |
| uniform float _blurFade; | |
| uniform bool _blurOnlyEmpty; | |
| // --------------------- | |
| // RADIALBLUR | |
| // --------------------- | |
| uniform vec2 _radialBlurCenter; | |
| uniform float _radialBlurValue; | |
| #define radialBlurSamples 10 | |
| #define radialBlurSamplesInv 0.1 | |
| // --------------------- | |
| // MOTIONBLUR | |
| // --------------------- | |
| uniform vec2 _motionBlurValue; | |
| uniform float _motionBlurMult; | |
| uniform bool _motionBlurDual; | |
| #define mbSamples 9.0 | |
| #define mbSamplesLoop 9.0 | |
| const float mbSamplesInv = 1.0/mbSamples; | |
| #define mbSamplesDual 9.0 | |
| #define mbSamplesLoopDual 5.0 | |
| const float mbSamplesDualInv = 1.0/mbSamplesDual; | |
| // --------------------- | |
| // CHROMATICGLITCH | |
| // --------------------- | |
| uniform float _cGTime; | |
| uniform float _cGRGBOffset; // 1.0 | |
| uniform float _cGYOffset; | |
| uniform float _cGStrength; // 0.02 | |
| uniform float _cGHeight; | |
| uniform float _cGLineStrength; | |
| uniform float _cGLineThick; | |
| // --------------------- | |
| // SEPIA | |
| // --------------------- | |
| uniform float _sepiaValue; | |
| const mat4 sepiaMat = mat4(0.393, 0.769, 0.189, 0.0, 0.349, 0.686, 0.168, 0.0, 0.272, 0.534, 0.131, 0.0, 0,0,0,0); | |
| // --------------------- | |
| // INVERT | |
| // --------------------- | |
| uniform vec4 _invertColorValue; | |
| // --------------------- | |
| // GRAYSCALE | |
| // --------------------- | |
| uniform float _grayscaleValue; | |
| uniform vec3 _grayscaleTint; | |
| uniform bool _grayscaleUseLum; | |
| // --------------------- | |
| // HUESHIFT | |
| // --------------------- | |
| uniform float _hueShiftCosA; | |
| uniform float _hueShiftSinA; | |
| // --------------------- | |
| // COLORCHANGE | |
| // --------------------- | |
| uniform vec3 _colorChangeC; | |
| uniform vec3 _colorChangeB; | |
| const vec3 _hueShiftK = vec3(0.57735, 0.57735, 0.57735); | |
| // --------------------- | |
| // SPLITSCREEN | |
| // --------------------- | |
| uniform float _rowmod; | |
| uniform float _colmod; | |
| uniform float _rowmodCalc; | |
| uniform float _colmodCalc; | |
| uniform float _splitXStart; | |
| uniform float _splitXRange; | |
| uniform float _splitXRangeMult; | |
| uniform float _splitYStart; | |
| uniform float _splitYRange; | |
| uniform float _splitYRangeMult; | |
| // --------------------- | |
| // FUNCTIONS | |
| // --------------------- | |
| // return 1 if v inside 1d range | |
| float insideRange(float v, float bottom, float top) { | |
| return step(bottom, v) - step(top, v); | |
| } | |
| float rand(vec2 n) { | |
| return fract(sin(dot(n, vec2(12.9898, 4.1414))) * 437.5854); | |
| } | |
| float noise(vec2 n) { | |
| const vec2 d = vec2(0.0, 1.0); | |
| vec2 b = floor(n), f = smoothstep(vec2(0.0), vec2(1.0), fract(n)); | |
| return mix(mix(rand(b), rand(b + d.yx), f.x), mix(rand(b + d.xy), rand(b + d.yy), f.x), f.y); | |
| } | |
| // --------------------- | |
| // MAIN | |
| // --------------------- | |
| void main() | |
| { | |
| vec2 targetVec = v_texCoord; | |
| // --------------------- | |
| // SHOCKWAVE | |
| // --------------------- | |
| if (_shockWaveTime > 0.0) { | |
| PRECISION vec2 p = (targetVec*_textureScaleInv - _shockWaveCenter) * vec2(1.0, _screenAspect); | |
| float dis = max(length(p), 0.0001); | |
| float k = _shockWaveMaxDistVal != 0.0 ? clamp(1.0 - dis * _shockWaveMaxDistVal, 0.0, 1.0) : 1.0; | |
| if (_shockWaveInvert) dis = _shockWaveMaxSize - max(dis, _shockWaveMinSize); | |
| k *= clamp(smoothstep(_shockWaveTime1, _shockWaveTime2, dis) - smoothstep(_shockWaveTime3, _shockWaveTime4, dis), 0.0, 1.0); | |
| // Ripples equation multiplied with ring circles so that it will be shockwave | |
| targetVec += k * ((p/dis) * sin(dis * _shockWaveWaves - _shockWaveTime) * _shockWaveStrength) * vec2(1.0, _screenAspectInv); | |
| } | |
| // --------------------- | |
| // SHOCKLINE | |
| // --------------------- | |
| if (_shockLineTime != 0.0) { | |
| float dis = _shockLineAxis ? ((targetVec.y * _textureScaleInv.y - _shockLineCenter) * _screenAspect) : (targetVec.x * _textureScaleInv.x - _shockLineCenter); | |
| float k = _shockLineMaxDistVal == 0.0 ? 1.0 : (clamp(1.0 + (dis < 0.0 ? 1.0 : -1.0) * dis * _shockLineMaxDistVal, 0.0, 1.0)); | |
| if (_shockLineDual) dis = abs(dis); | |
| if (_shockLineDirection) dis = 1.0-dis; | |
| k *= clamp(smoothstep(_shockLineTime1, _shockLineTime2, dis) - smoothstep(_shockLineTime3, _shockLineTime4, dis), 0.0, 1.0); | |
| targetVec += k * sin(dis*_shockLineWaves-_shockLineTime) * _shockLineStrength * vec2(1.0, _screenAspectInv); | |
| } | |
| // --------------------- | |
| // BULGE | |
| // --------------------- | |
| if (_bulgeValue > 0.0) { | |
| PRECISION vec2 d = (targetVec*_textureScaleInv - _bulgeOrigin) * vec2(1.0, _screenAspect); | |
| float di = length(d); | |
| if (di < _bulgeRadius) { | |
| float fadeValue = pow(di / _bulgeRadius, 3.0); | |
| vec2 bulgedVec = (_bulgeOrigin * vec2(1.0, _screenAspect) + normalize(d) * tan(sqrt(dot(d, d)) * _bulgeValue) * _bulgeValue2) * _textureScale * vec2(1.0, _screenAspectInv); | |
| targetVec = targetVec * fadeValue + bulgedVec * (1.0 - fadeValue); | |
| } | |
| } | |
| // --------------------- | |
| // PINCH | |
| // --------------------- | |
| // Original function | |
| if (_pinchValue.x != 0.0 || _pinchValue.y != 0.0) { | |
| PRECISION vec2 d = (targetVec*_textureScaleInv - _pinchCenterPos) * vec2(1.0, _screenAspect); | |
| float di = length(d); | |
| if (di < _pinchRadius) { | |
| float fadeValue = pow(di / _pinchRadius, 2.0); | |
| vec2 pinchedVec = (_pinchCenterPos * vec2(1.0, _screenAspect) + normalize(d) * atan(sqrt(dot(d, d)) * -_pinchValue * 20.0) * _pinchCalc1) * _textureScale * vec2(1.0, _screenAspectInv); | |
| targetVec = targetVec * fadeValue + pinchedVec * (1.0 - fadeValue); | |
| } | |
| } | |
| // --------------------- | |
| // GLITCH | |
| // --------------------- | |
| if (_glitchTop > 0.0) { | |
| // Random offset slices horizontally | |
| targetVec.x += _glitchXOffset * insideRange(targetVec.y, _glitchBot, _glitchTop); | |
| } | |
| // --------------------- | |
| // SPLITSCREEN | |
| // --------------------- | |
| if (_colmod != 1.0 || _rowmod != 1.0) { | |
| float normalizedX = (targetVec.x - _splitXStart) * _splitXRangeMult; | |
| normalizedX = (normalizedX < 0.5*_textureScale.x) ? normalizedX * _colmod : (normalizedX * _colmod) + _colmodCalc; | |
| targetVec.x = _splitXStart + fract(normalizedX) * _splitXRange; | |
| float normalizedY = (targetVec.y - _splitYStart) * _splitYRangeMult; | |
| normalizedY = (normalizedY < 0.5*_textureScale.y) ? normalizedY * _rowmod : (normalizedY * _rowmod) + _rowmodCalc; | |
| targetVec.y = _splitYStart + fract(normalizedY) * _splitYRange; | |
| } | |
| // --------------------- --------------------- --------------------- | |
| // --------------------- --------------------- --------------------- | |
| // --------------------- | |
| // APPLY THE COLOR | |
| // --------------------- | |
| gl_FragColor = texture2D(CC_Texture0, targetVec); | |
| // --------------------- --------------------- --------------------- | |
| // --------------------- --------------------- --------------------- | |
| // --------------------- | |
| // CHROMATICGLITCH | |
| // ---)\O?-------------- | |
| if (_cGRGBOffset != 0.0) { | |
| float cVal = (v_texCoord.y+_cGYOffset)*50.0*_cGHeight; | |
| targetVec.x += (noise(vec2(_cGTime,cVal))-noise(vec2(0,cVal)))*_cGStrength; | |
| vec4 r = texture2D(CC_Texture0, vec2(targetVec.x - _cGRGBOffset, targetVec.y)); | |
| vec4 g = texture2D(CC_Texture0, vec2(targetVec.x, targetVec.y)); | |
| vec4 b = texture2D(CC_Texture0, vec2(targetVec.x + _cGRGBOffset, targetVec.y)); | |
| vec3 color = vec3(r.r, g.g, b.b); | |
| if (_cGLineThick > 0.0) { | |
| color -= smoothstep(_cGLineThick - 0.01, _cGLineThick + 0.01, sin((v_texCoord.y+_cGYOffset)*300.0*_cGHeight))*_cGLineStrength; | |
| } | |
| gl_FragColor = vec4(color, (r.a+g.a+b.a)*0.3333); | |
| } | |
| // --------------------- | |
| // GLITCH | |
| // --------------------- | |
| if (_glitchTop > 0.0) { | |
| // Offset one channel | |
| if (_glitchRnd < 0.33) { | |
| vec4 col2 = texture2D(CC_Texture0, targetVec + _glitchColOffset); | |
| gl_FragColor.r = col2.r; | |
| gl_FragColor.a = max(gl_FragColor.a, col2.a); | |
| } | |
| else if (_glitchRnd < 0.66) { | |
| vec4 col2 = texture2D(CC_Texture0, targetVec + _glitchColOffset); | |
| gl_FragColor.g = col2.g; | |
| gl_FragColor.a = max(gl_FragColor.a, col2.a); | |
| } | |
| else { | |
| vec4 col2 = texture2D(CC_Texture0, targetVec + _glitchColOffset); | |
| gl_FragColor.b = col2.b; | |
| gl_FragColor.a = max(gl_FragColor.a, col2.a); | |
| } | |
| } | |
| // --------------------- | |
| // CHROMATIC | |
| // --------------------- | |
| if (_chromaticXOff != 0.0 || _chromaticYOff != 0.0) { | |
| vec4 r = texture2D(CC_Texture0, targetVec + vec2(_chromaticXOff, _chromaticYOff)); | |
| vec4 b = texture2D(CC_Texture0, targetVec + vec2(-_chromaticXOff, -_chromaticYOff)); | |
| gl_FragColor = vec4(r.r, gl_FragColor.g, b.b, max(r.a, max(gl_FragColor.a,b.a))); | |
| } | |
| // --------------------- | |
| // RADIALBLUR | |
| // --------------------- | |
| if (_radialBlurValue != 0.0) { | |
| vec4 result = gl_FragColor; | |
| if (!_blurOnlyEmpty || result.a < 0.1) { | |
| vec2 uv = targetVec; | |
| vec2 blurVector = (_radialBlurCenter - uv) * _radialBlurValue; | |
| float modVal = 1.0 + 4.5*_blurFade; | |
| result *= modVal; | |
| for (int i = 1; i < radialBlurSamples; i++) { | |
| modVal -= _blurFade; | |
| uv.xy += blurVector.xy; | |
| result += texture2D(CC_Texture0, uv) * modVal; | |
| } | |
| result *= radialBlurSamplesInv; | |
| // Output to screen | |
| if (_blurUseRef) { | |
| gl_FragColor = vec4((result.rgb + _blurRefColor * (1.0-result.a)), result.a * _blurIntensity); | |
| } | |
| else gl_FragColor = result; | |
| } | |
| } | |
| // --------------------- | |
| // MOTIONBLUR | |
| // --------------------- | |
| else if (_motionBlurValue.x != 0.0 || _motionBlurValue.y != 0.0) | |
| { | |
| //vec4 result = texture2D(CC_Texture0, targetVec); | |
| vec4 result = gl_FragColor; | |
| if (!_blurOnlyEmpty || result.a < 0.1) { | |
| if (_motionBlurDual) { | |
| for (float i = 1.0; i < mbSamplesLoopDual; ++i) { | |
| float modVal = 1.0 - (i * _blurFade); | |
| vec2 offset = _motionBlurValue * (i * mbSamplesDualInv); | |
| result += texture2D(CC_Texture0, targetVec + offset) * modVal; | |
| result += texture2D(CC_Texture0, targetVec - offset) * modVal; | |
| } | |
| } | |
| else { | |
| for (float i = 1.0; i < mbSamplesLoop; ++i) { | |
| float modVal = 1.0 - (i * _blurFade); | |
| vec2 offset = _motionBlurValue * (i * mbSamplesInv); | |
| result += texture2D(CC_Texture0, targetVec + offset) * modVal; | |
| } | |
| } | |
| result *= _motionBlurMult; // 1/(9 - 20 * _blurFade) | |
| if (_blurUseRef) { | |
| gl_FragColor = vec4((result.rgb + _blurRefColor * (1.0-result.a)), result.a * _blurIntensity); | |
| } | |
| else gl_FragColor = result; | |
| } | |
| } | |
| // --------------------- | |
| // GRAYSCALE | |
| // --------------------- | |
| if (_grayscaleValue > 0.0) { | |
| float gray = !_grayscaleUseLum ? (gl_FragColor.r + gl_FragColor.g + gl_FragColor.b)*0.333 : dot(gl_FragColor.rgb, vec3(0.299, 0.587, 0.114)); | |
| gl_FragColor.rgb = gl_FragColor.rgb*(1.0-_grayscaleValue) + vec3(gray)*_grayscaleValue*_grayscaleTint; | |
| } | |
| // --------------------- | |
| // SEPIA | |
| // --------------------- | |
| if (_sepiaValue > 0.0) { | |
| vec4 texColor = gl_FragColor * sepiaMat; | |
| gl_FragColor.rgb = gl_FragColor.rgb*(1.0-_sepiaValue) + texColor.rgb*_sepiaValue; | |
| } | |
| // --------------------- | |
| // INVERTCOLOR | |
| // --------------------- | |
| if (_invertColorValue.a > 0.0) { | |
| vec4 texColor = 1.0 - gl_FragColor; | |
| gl_FragColor.rgb = gl_FragColor.rgb * (1.0 - _invertColorValue.rgb) + texColor.rgb * _invertColorValue.rgb; | |
| } | |
| // --------------------- | |
| // HUESHIFT | |
| // --------------------- | |
| if (_hueShiftCosA != 0.0) { | |
| gl_FragColor.rgb = vec3(gl_FragColor.rgb * _hueShiftCosA + cross(_hueShiftK, gl_FragColor.rgb) * _hueShiftSinA + _hueShiftK * dot(_hueShiftK, gl_FragColor.rgb) * (1.0 - _hueShiftCosA)); | |
| } | |
| // --------------------- | |
| // COLORCHANGE | |
| // --------------------- | |
| if (_colorChangeC.r > 0.0) { | |
| gl_FragColor.rgb = gl_FragColor.rgb * _colorChangeC + _colorChangeB; | |
| } | |
| // --------------------- | |
| // LENSCIRCLE | |
| // --------------------- | |
| if (_lensCircleStrength > 0.0) { | |
| float dist = distance(v_texCoord * _textureScaleInv * vec2(1.0, _screenAspect), _lensCircleOrigin); | |
| float k = _lensCircleStart == _lensCircleEnd ? ((dist >= _lensCircleEnd ? _lensCircleStrength : 0.0)) : _lensCircleStrength * (1.0 - smoothstep(_lensCircleEnd, _lensCircleStart, dist)); | |
| if (_lensCircleAdditive) gl_FragColor.rgb = gl_FragColor.rgb + (_lensCircleTint * k); | |
| else gl_FragColor.rgb = gl_FragColor.rgb * (1.0 - k) + (_lensCircleTint * k); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment