1
\$\begingroup\$

I am trying to wrap my head around how to take advantage of shaders for things like tweening.

For example, there are these simple easing equations, which we can use like this:

var iteration = 0
var totalIterations = 200

requestAnimationFrame(render)

function render() {
  var currentValue = easeOutCubic(iteration, -100, 650, totalIterations)
  // apply current value to some object
  myObject.x = currentValue
  // do that for each object in the scene

  requestAnimationFrame(render)
}

function easeOutCubic(currentIteration, startValue, changeInValue, totalIterations) {
  return changeInValue * (Math.pow(currentIteration / totalIterations - 1, 3) + 1) + startValue;
}

I'm wondering how you can translate something like this to using a shader to calculate the easing function. This is my attempt at piecing things together.

var vert = `
precision mediump float;

attribute float aPosition;
uniform vec2 uScreen;
uniform mat4 uModel;

void main() {
  vec2 position = vec2(aPosition, cubicOut(aPosition));

  position.x /= uScreen.x / uScreen.y;

  gl_Position = uModel * vec4(position.x, position.y, 1.0, 1.0);
}

float cubicOut(float t) {
  float f = t - 1.0;
  return f * f * f + 1.0;
}
`

var frag = `
precision mediump float;

void main() {
  gl_FragColor = vec4(0.9, 0.4, 0.6, 1);
}
`

var dims = []

function render() {
  dims[0] = gl.drawingBufferWidth
  dims[1] = gl.drawingBufferHeight
  gl.clearColor(0, 0, 0, 1)
  gl.clear(gl.COLOR_BUFFER_BIT)
  gl.viewport(0, 0, dims[0], dims[1])

  bindShaders()
  draw()

  requestAnimationFrame(render)
}

My main question is how I can tween multiple properties on multiple objects. I get the multiple objects part, but not sure how exactly to do multiple properties. For example, every object in a game will have it's color, alpha, x, y, width, and height, and rotation tweened.

  • color
  • alpha
  • x
  • y
  • width
  • height
  • rotation

If I wanted to create a shader that can tween all of these properties, I'm not quite sure if that's possible or what it would look like.

Wondering if one could point me in the right direction.

My first guess was to do this in the shader:

void main() {
  vec2 position.x = vec2(aPosition, cubicOut(aPosition.x));
  vec2 position.y = vec2(aPosition, cubicOut(aPosition.y));
  // width...
  // height...

  gl_Position = uModel * vec4(position.x, position.y, 1.0, 1.0);
}

But the shaders don't do width/height/rotation, just points. So I'm wondering generally (a) how many shaders this might need, and (b) a rough point-in-the-right-direction on how to go about calculating the width/height/rotation in the shaders, as well as if we can pack color/alpha/x/y all into one shader, given they might have different easings.

Let me know if it's too broad and I will try to break it up.

\$\endgroup\$
  • 1
    \$\begingroup\$ In the link you provided the from and to are baked into the vertexbuffer ( see the attribute fields ). You could do the same for width/height/rotation as well. Also in your snippet you're creating a vec2 but then try to set the x property by a new vec2. You're clearly not familiar with the syntax, how far are you into shaders?. Have you written a simple one yet that works? But I think it would make more sense to do things with compute shaders instead, don't know if it's overkill for your purpose. \$\endgroup\$ – Sidar Mar 15 at 1:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.