Shaders How do I make a Sinewave shader?

Locki

Member
I want to create a wavy background (in the same lines of the battle backgrounds from earthbound).
but there is no tutorials i could find on it, not even on youtube. (reference point the franky battle from earthbound)
 

NightFrost

Member
The background itself seems to be moving too, so all of it might be generated inside the shader. But important question is, how much do you know about shaders? That affects how much needs to be explained, or if you should be pointed to basic shader tutorials to get you familiar with GLSL language used in shaders. But I'll talk about the math that goes into the wave effect for now.

The effect is horizontal, so the sine wave should be made dependent of the pixel y-position, which you'd read from gl_FragCoord.y. You'd multiply this with some frequency value to set how quickly the left-right waviness runs, and take sin() of that. Next you'd multiply it by some aplitude value to set how far left or right the wave goes. This all would create a static sine wave, as y-coordinate would (of course) start from zero every step, so you'd bring a timer variable into the shader as a uniform, and increment it in linear fashion on GMS side every step (for example by +1). So the final sine value would be fashioned like
Code:
float wave = sin((gl_FragCoord.y + time) * frequency) * amplitude
which can then be applied to creating whatever effect you need. It might be necessary to mod the value before taking sin(), I don't remember whether shader trig functions can handle degrees beyond 0-360.
 

Locki

Member
The background itself seems to be moving too, so all of it might be generated inside the shader. But important question is, how much do you know about shaders? That affects how much needs to be explained, or if you should be pointed to basic shader tutorials to get you familiar with GLSL language used in shaders. But I'll talk about the math that goes into the wave effect for now.

The effect is horizontal, so the sine wave should be made dependent of the pixel y-position, which you'd read from gl_FragCoord.y. You'd multiply this with some frequency value to set how quickly the left-right waviness runs, and take sin() of that. Next you'd multiply it by some amplitude value to set how far left or right the wave goes. This all would create a static sine wave, as y-coordinate would (of course) start from zero every step, so you'd bring a timer variable into the shader as a uniform, and increment it in linear fashion on GMS side every step (for example by +1). So the final sine value would be fashioned like
Code:
float wave = sin((gl_FragCoord.y + time) * frequency) * amplitude
which can then be applied to creating whatever effect you need. It might be necessary to mod the value before taking sin(), I don't remember whether shader trig functions can handle degrees beyond 0-360.

Thanks for helping but I'm fairly new to GLSL and I'm pretty sure I've messed it up somewhere. The little research I've done on it is that it requires a very basic passthrough shader (which is just automatically made when you make a shader).
I don't really know how to declare variables that well, all I know is void (comes with nothing), int(value is an integer), varying, uniform, and attribute. They go with either a vertex/vertices (shortened to vec2,3,4), float and that's about it.

So here's what I've put, please tell me how I've messed up.
Code:
//
// Simple passthrough fragment shader
//
varying vec2 v_vTexcoord;
varying vec4 v_vColour;

void main()
{
    gl_FragColor = v_vColour * texture2D( gm_BaseTexture, v_vTexcoord );
  
   #define freq = 0.1; //frequency
   #define amp = 5.0; //amplitude
   #define time = 1.0;
  
    float wave = sin((gl_FragCoord.y + time) * freq) * amp;
}
(yet again sorry if you're winsing severly at my poor approximation that is that code up there; I am practically a complete noob).

I don't remember whether shader trig functions can handle degrees beyond 0-360
That's wrong, sin uses radiants (or 3.14... aka pi) not degrees.
 
Last edited:
Top