- Home /
What is the best way to draw a 2D sine wave?
I'm creating a 2D space shoot-em-up and the player shoots sine waves with variable amplitude (height) and frequency (period between each cycle of the wave).
I'd like to know the best way to render something like this which is fairly simple, creates a nice smooth curve (making texture-tiling solutions difficult), and is efficient since this sine wave has to be redrawn constantly as the player adjusts the amplitude and frequency. It also frequently will have its colour changed or the line made thicker to indicate the beam is higher in intensity.
The beam will be purely 2D; that is, it will never be seen from any angle except straight on. Because of this, I'm hoping that 2D shader solutions might be possible. Is there any way to dynamically draw something like this directly to a texture at run time with Unity? Or am I stuck using LineRenderers?
Answer by Bampf · Nov 19, 2010 at 06:40 PM
If you have Unity Pro you could draw lines, triangles or quads using the GL class. I don't see a way to make the lines thicker though, so I think you'd have to draw triangles or quads. If you don't have Unity Pro, I suppose you could do the same thing with Meshes.
Probably the easiest way though is to use a LineRenderer.
Either way, you'll need the vertices. You could probably generate a "base" set of sine-wave vertices ahead of time, and then each frame dynamically generate the points to draw by walking the base set and adjusting for frequency, amplitude, and time elapsed.
Another way to think about this is to start with N vertices, and displace each one from the y = 0 axis based on elapsed time. Each would be displaced sinusoidally from the y=0 position, hitting the same offsets at subsequent times. And you'd only have to generate one period's worth before it repeats.
(Edit: Added LineRenderer to the suggestions.)
$$anonymous$$y issue with line renderer is having to make sure the line it draws has enough points of resolution that it can generate the curves smoothly. I guess I'll just have to experiment as I don't want to be constantly destroying and creating new line renders.
Seems to me that you can just move the existing points each frame. For a wave firing vertically along the y axis, they will each be offset from the y=0 axis by x = A*sin(y+t), where t is time elapsed, A is amplitude. A lookup table may help to speed up the sin() calculation.
Answer by duck · Nov 19, 2010 at 12:15 PM
A simple way that springs to mind would be to have a fairly high resolution tiled sinewave texture, placed on a long narrow plane.
You could then simply adjust the material tiling to alter the frequency, which would make the sinewave repeat more frequently along that axis.
For the amplitude you could then scale the plane object itself along the amplitudinal axis.
This method while pretty simple to implement, comes with a visual drawback which may not be acceptable depending on your requirements - the line stroke of the sinewave would not be constant, it would be subject to the same scaling effects that are being applied to the texture as a whole. So a high frequency wave would have much narrower lines where it crosses the zero axis, and fatter at the positive and negative curve peaks.
This was one of my original ideas and that's the reason I had to scrap it. Good explanation though.
Answer by Free286 · May 11, 2016 at 11:02 AM
Probably the easiest way would be to use a particle system to draw the sine wave. Particles are very small, and generally the limiting factor is fill rate (especially on iOS and mobile devices) so having a large number of small instanced particles is extremely fast to render. The ParticleSystem.GetParticles method can be used to set the particle positions directly, and can be set from a script. Another advantage of particles is it is easy to change and iterate the visual style, they are quite flexible.
Your answer
Follow this Question
Related Questions
Convert Sprite Image to Texture 6 Answers
Why didnt my Collider works? 0 Answers
Top down LOS/Field of View 0 Answers
How to create this 2D dynamic light and shadow system? 0 Answers
Cellshading in URP 2D renderer with multiple light sources? 1 Answer