I've been hard at work for a school assignment involving shadertoy, which uses GLSL. The project is to make a "distorted" fragment shader, and I figured that I could make mine a slowly moving stream of magma. Essentially what I want to do is make a gradient, map the "brightest" part of the gradient wherever white appears, and blend the rest of the gradient throughout the edges of the bright part. Basically something like this: [flowing lava shader][1]. Here are the issues I'm tasked with:
GLSL comes built in with the function,
mix(a, b, t)
, which works perfectly fine, only my gradient will have more than two values to interpolate between. Writing this now, I realize just how obnoxious (or easy) this might be to code in...Another issue I have with GLSL is the way
mix(a, b, t)
"weights" the gradient. If I usemix(colRed, colBlue, uv.x)
to create my own two-tone gradient that draws red on the left and blue on the right (with shades of purple interpolated in the middle), then I'm unable to edit where the blue part lies on the screen. How would I go about adding in "sliders" to my code so I can change where the blue part lies on the x-axis?
Here is my code thus far, feel free to judge and/or give suggestions.
const vec3 lavaColorBrightOrange = vec3(1.0, 0.6471, 0.0);
const vec3 lavaColorBrightRed = vec3(0.9333, 0.2941, 0.1686);
const vec3 lavaColorDarkRed = vec3(0.6471, 0.1647, 0.1647);
const vec3 lavaColorBrownishRed = vec3(0.5451, 0.0, 0.0);
const vec3 lavaColorBlack = vec3(0.1, 0.1, 0.1);
// Weight Constants
const float lavaWeightBrightOrange = 0.01;
const float lavaWeightBrightRed = 0.03;
const float lavaWeightDarkRed = 0.08;
const float lavaWeightBrownishRed = 0.15;
const float lavaWeightBlack = 0.32;
// Self defined functions
vec3 mixMore(vec3[5] color, float[5] weight, float t) // Mixes (or lerps) more than two color values (for use with multi-color gradients)
{
vec3 result = (color[0] + (color[1] - color[0]) * weight[0]);
return result;
}
float normalizeSine(float x) // Normalizes a sin (or cosine, although it has yet to be programmed in) to a float value
{
float y = sin(x * 0.5 + 0.5);
return y;
}
float normalizeRGB(float x) // Normalizes an RGB float value back to a sin/cosine format value
{
float y = x * 2.0 - 1.0;
return y;
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
// Normalized pixel coordinates (from 0 to 1)
vec2 uv = fragCoord/iResolution.xy;
// Defining the Color and Weight arrays
vec3[5] lavaColors = vec3[] (lavaColorBrightOrange, lavaColorBrightRed, lavaColorDarkRed, lavaColorBrownishRed, lavaColorBlack);
float[5] lavaWeights = float[] (lavaWeightBrightOrange, lavaWeightBrightRed, lavaWeightDarkRed, lavaWeightBrownishRed, lavaWeightBlack);
// Getting the input channel
vec3 col = texture(iChannel0, uv).rgb;
// Lava Gradient (for testing only)
vec3 lavaGradient = mixMore(lavaColors, lavaWeights, uv.x);
// Output to screen
fragColor = vec4(lavaGradient, 1.0);
}```
Thank you in advance
[1]: https://i.stack.imgur.com/TVZcS.jpg