3
\$\begingroup\$

I'm learning GLSL shaders on Book of Shaders and I decided to mess around with one of the examples. I wanted to see, whats a more efficient way to calculate to mask out the color?

#ifdef GL_ES
precision mediump float;
#endif
#define TWO_PI 6.28318530718
uniform vec2 u_resolution;
uniform float u_time;
// Function from Iñigo Quiles
// https://www.shadertoy.com/view/MsS3Wc
vec3 hsb2rgb( in vec3 c ){
 vec3 rgb = clamp(abs(mod(c.x*6.0+vec3(0.0,4.0,2.0),6.0)-3.0)-1.0,0.0,1.0);
 rgb = rgb*rgb*(3.0-2.0*rgb);
 return c.z * mix( vec3(1.0), rgb, c.y);
}
void main(){
 vec2 st = gl_FragCoord.xy/u_resolution;
 vec3 color = vec3(0.0);
 // Use polar coordinates instead of cartesian
 vec2 toCenter = vec2(0.5)-st;
 float angle = atan(toCenter.y,toCenter.x);
 float radius = length(toCenter)*2.0;
 angle = angle + u_time;
 float outsideMask = 1.0 - step(distance(st, vec2(0.5)), 0.3);
 float insideMask = 1.0 - step(0.2, distance(st, vec2(0.5)));
 float visibleArea = 1.0 - insideMask - outsideMask;
 // Map the angle (-PI to PI) to the Hue (from 0 to 1)
 // and the Saturation to the radius
 color = hsb2rgb(vec3((angle/TWO_PI)+0.5,radius, 1.0));
 gl_FragColor = vec4(color, visibleArea);
}

Here is an image of the end result.

End Result.

The outsideMask, insideMask and visibleArea variables in particular all have that 1.0 minus something, which seems weird to me. Any suggestions would be appreciated!

asked Jul 26, 2019 at 4:21
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

Distance

In both your step(...) functions, you are computing distance(st, vec2(0.5)). If you computed this once, and stored this in a local variable, you'd be able to reuse this computed value, which should save time in your shader.

But ... wait a second ...

vec2 toCenter = vec2(0.5)-st;
float radius = length(toCenter)*2.0;

You've already computed this distance (length, actually), and stored it (doubled) in the local variable radius. We can use this value directly, by doubling your step thresholds:

float outsideMask = 1.0 - step(radius, 0.6);
float insideMask = 1.0 - step(0.4, radius);
float visibleArea = 1.0 - insideMask - outsideMask;

Or don't multiply the computed radius by 2.0 for the radius variable, and multiply it by 2 when you use it to compute the colour:

float radius = length(toCenter);
float outsideMask = 1.0 - step(radius, 0.3);
float insideMask = 1.0 - step(0.2, radius);
float visibleArea = 1.0 - insideMask - outsideMask;
color = hsb2rgb(vec3((angle/TWO_PI)+0.5, radius*2.0, 1.0));

visibleArea

  1. outsideMask = 1.0 - step(radius, 0.3)
  2. insideMask = 1.0 - step(0.2, radius)
  3. visibleArea = 1.0 - insideMask - outsideMask

Substituting insideMask into (3):

  1. visibleArea = 1.0 - (1.0 - step(0.2, radius)) - outsideMask
  2. visibleArea = 1.0 - 1.0 + step(0.2, radius) - outsideMask
  3. visibleArea = step(0.2, radius) - outsideMask

From step(A,B) = 1 - step(B,A), we can reworking (1) as:

  1. outsideMask = step(0.3, radius)

And substituting into (6):

  1. visibleArea = step(0.2, radius) - step(0.3, radius)
answered Jul 26, 2019 at 5:14
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.