160 lines
5.5 KiB
GLSL
160 lines
5.5 KiB
GLSL
/*
|
|
|
|
Optolith Background
|
|
-------------------
|
|
This shader renders the background from the character creator program
|
|
for The Black Eye 5 "Optolith".
|
|
|
|
The default values are to make the shader as close to the original as
|
|
possible. Thus I recommend using the fullscreen mode to view it, to
|
|
reduce flickering.
|
|
|
|
This is primarily designed to be used as ghostty shader, which
|
|
requires the use of the iChannel0 channel. But feel free to use it
|
|
everywhere you like.
|
|
|
|
If you have any idea of improving it, feel free to let me know or even
|
|
create a fork. :)
|
|
|
|
I tried to make it as simple as possible and to document everything.
|
|
So even if you have no clue, whats going on, I hope my explainations
|
|
are good enough, so you know what you can change and how.
|
|
|
|
License: (as always WTFPL)
|
|
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
|
Version 2, December 2004
|
|
|
|
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
|
|
|
Everyone is permitted to copy and distribute verbatim or modified
|
|
copies of this license document, and changing it is allowed as long
|
|
as the name is changed.
|
|
|
|
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
|
|
|
0. You just DO WHAT THE FUCK YOU WANT TO.
|
|
|
|
*/
|
|
|
|
/* --- USER PARAMETERS --- */
|
|
// These parameters you can change how ever you like.
|
|
|
|
// BACKGROUND and FOREGROUND define the colors.
|
|
#define BACKGROUND vec3(0.0666,0.0666,0.0666) // #111111
|
|
// If you prefer the light mode:
|
|
//#define BACKGROUND vec3(0.9411, 0.9411, 0.9411) // #F0F0F0
|
|
#define FOREGROUND vec3(0.5137,0.4196,0.2431) // #836B3E
|
|
// This value defines how visible the effect is.
|
|
// This default is different to the original.
|
|
// ORIGINAL VALUE: .15
|
|
#define FOREGROUND_OPACITY .25
|
|
|
|
|
|
|
|
// This defines how fast the animation is playing.
|
|
// To decrease the speed, increase the divider. (and vice versa)
|
|
// To stop the animation, just replace everything with 0 or
|
|
// any number in case you want a specific point in time.
|
|
// ORIGINAL VALUE: iTime/50.
|
|
#define TIME iTime / 50.
|
|
|
|
// MASK_DISTANCE define how far away from the center the line starts
|
|
// (should be between 0 and 1)
|
|
// ORIGINAL VALUE: 0.8
|
|
#define MASK_DISTANCE 0.8
|
|
// MASK_WIDTH defines how long the lines should be.
|
|
// ORIGINAL VALUE: 0.05
|
|
#define MASK_WIDTH 0.05
|
|
|
|
// LINE_DISTANCE defines how many degrees should be between two lines.
|
|
// For the best result, the number should be able to divide cleanly
|
|
// with 360.
|
|
// ORIGINAL VALUE: 0.5
|
|
#define LINE_DISTANCE 0.5
|
|
// LINE_WIDTH defines how thick the line is. This is expressed in degrees.
|
|
// This should not be higher than LINE_DISTANCE and should be sufficiantly
|
|
// large, otherwise the image begins to flicker. (as shown in the default)
|
|
// But I mean... I can't stop you either way.
|
|
// ORIGINAL VALUE: 0.05
|
|
#define LINE_WIDTH 0.05
|
|
|
|
/* --- SYSTEM PARAMETERS --- */
|
|
// Changing these parameters may break something... So just don't
|
|
|
|
// This is a constant to convert radians to degrees
|
|
#define RAD2DEG 57.295779513
|
|
|
|
/* --- CODE --- */
|
|
|
|
vec2 rotateUV(vec2 uv) {
|
|
float sinUV = sin(TIME);
|
|
float cosUV = cos(TIME);
|
|
|
|
mat2 rotationMatrix = mat2(cosUV, -sinUV, sinUV, cosUV);
|
|
return uv * rotationMatrix;
|
|
}
|
|
|
|
vec2 createEffectCoordnates(vec2 uv) {
|
|
float aspectRatio = iResolution.y / iResolution.x;
|
|
|
|
// Move (0,0) to the center
|
|
uv -= 0.5;
|
|
// Scale it back up, so we work with a range of 0..1
|
|
// Also here we ensure, that the effect does not strech in an unwanted way
|
|
// This also results in the effect being larger than the screen, but thats
|
|
// intended.
|
|
uv *= vec2(2., aspectRatio * 2.);
|
|
// Finally, we rotate the UV so we get a nice rotation animation going.
|
|
return rotateUV(uv);
|
|
}
|
|
|
|
float getMask(vec2 coordnates) {
|
|
// This function returns a mask, that defines where the lines show up.
|
|
// This can be modified to have more unique masks, but that is left as a
|
|
// exercise to the reader.
|
|
|
|
// Calculate the distance to the center
|
|
float uvLength = length(coordnates);
|
|
// The first step ensures that everything up to MASK_DISTANCE is (0) and
|
|
// everything past it is (1)
|
|
// The other step does the exact oppisite, but with MASK_DISTANCE + MASK_WIDTH.
|
|
// When we multiply those, we get a mask, that only contains the overlapping masks.
|
|
return step(uvLength * -1., -MASK_DISTANCE) * step(uvLength, MASK_DISTANCE + MASK_WIDTH);
|
|
}
|
|
|
|
float getLines(vec2 coordnates) {
|
|
// This returns a mask, that shows the lines on the effect.
|
|
|
|
// This "atan" gives us a nice radial texture.
|
|
// More specifically we get a value in radians.
|
|
float lines = atan(coordnates.x, coordnates.y);
|
|
// Since radians are kinda hard to work with as parameters, I convert it to degrees.
|
|
float linesDegrees = lines * RAD2DEG;
|
|
// This gives us the repeating pattern.
|
|
float result = mod(linesDegrees, LINE_DISTANCE);
|
|
// Finally a step instruction, gives us the mask in the specific width we want.
|
|
return step(result, LINE_WIDTH);
|
|
}
|
|
|
|
void mainImage( out vec4 fragColor, in vec2 fragCoord )
|
|
{
|
|
// Normalized pixel coordinates (from 0 to 1)
|
|
vec2 uv = fragCoord/iResolution.xy;
|
|
|
|
vec2 effectCoords = createEffectCoordnates(uv);
|
|
|
|
float mask = getMask(effectCoords);
|
|
float lines = getLines(effectCoords);
|
|
|
|
float result = lines * mask;
|
|
|
|
vec3 col = mix(BACKGROUND, FOREGROUND, result * FOREGROUND_OPACITY);
|
|
|
|
// Mixing iChannel0 into the mix.
|
|
// If you wish to use the alpha channel, just replace the 1 with
|
|
// "channel.a".
|
|
vec4 channel = texture(iChannel0, uv);
|
|
fragColor = vec4(mix(col, channel.rgb, length(channel.rgb)), 1);
|
|
|
|
}
|