Onerat Games
  • Home
  • Games
    • Elden: Path of the Forgotten
    • Outback
    • Itch.io
  • Asset Store

Distortion shader effect

10/22/2017

1 Comment

 
Picture
oh crap oh crap that wasn't water inside that cactus was it
So the second region in Elden is set in a desert and an enemy has a poison attack. Rather than doing damage over time, its main impact is an incredibly distracting visual warping effect.

This is implemented with a custom shader. Shaders have a reputation for being a little bit of a black magic topic among game developers, and there's a wide range of tools to allow you to make them without writing any code.

I abhor this. If you have a sufficient understanding of basic linear algebra and basic control flow of software, you have everything you need to make pretty much any shader you want. Effectively you're just passing vectors into a shader, between shaders, and then out of a shader -- with very basic arithmetic operations in between.

The above shader basically follows these steps:
  1. Load the (un-warped) contents of the screen from the back buffer into a texture.
  2. Pass a variable determining the amount of distortion, and the UV coordinates of the screen, into a vertex shader.
  3. The vertex shader then passes those on to a pixel shader.
  4. The pixel shader then generates a 2D vector field determining the texture offset.
  5. The pixel shader then accesses the texture at that offset point, causing the warping effect.
  6. The pixel shader then outputs that texture sample, displaying the output on the screen.

​Since step 4, the vector field, is the only step requiring math, I'll focus on that.

​"Vector field" sounds scary. A vector field is simply a function that takes a pair of coordinates (such as {x=4, y=8}) and spits out another pair of coordinates (possibly the same, possibly different). 

​So to get this distortion effect, we simply offset the texture coordinates that are coming in with the sine function. Everyone knows what a sinewave looks like:
Picture
All you have to do is scale the function so that it distorts in the right proportions. The sine function takes a value from 0 to 2Pi, and outputs a value from -1 to +1.


Bear with me here, code incoming:
        float originalx = texcoords.x;
        texcoords.x -= sin(texcoords.y*10) * 0.1 * waviness;
        
texcoords.y -= sin(originalx*10) * 0.1 * waviness;

We have to store the starting X coordinate because we need it for the Y coordinate calculation.

This is pretty simple. We're taking the X coordinates, taking the sine of the Y coordinates times ten, then multiplying by how severe we want the effect to be. Then we just do the same in reverse for the Y coordinates.

This will work, but we have a problem:

Picture

The problem is, if we distort in this way, we'll go past the 0~1 range of texture coordinates and it'll reach the edge of the texture and smear. That looks bad. So we need a workaround:

        float originalx = texcoords.x;
        texcoords.x -= sin(texcoords.y*10) * 0.1 * (0.5f-abs(texcoords.x-0.5f)) * waviness;
        
texcoords.y -= sin(originalx*10) * 0.1 * (0.5f-abs(texcoords.y-0.5f)) * waviness;

 We take the distance from the center of the screen (texcoords.x-0.5f)) and multiply the distortion factor by this. This way, as it processes the pixels closer and closer to the edge of the screen, it reduces the amount of distortion resulting in a smooth transition to the edge.

So if you're asking, "where was the vector field in that?" -- that's it right there. We're taking coordinates and transforming them in a consistent way. That's literally all it is. Not that hard eh?
1 Comment
Olivia link
6/27/2022 07:10:11 pm

Hi thhanks for sharing this

Reply



Leave a Reply.

    Archives

    January 2018
    December 2017
    November 2017
    October 2017
    September 2017
    June 2017
    May 2017
    April 2017
    March 2017
    February 2017
    January 2017
    December 2016
    November 2016
    October 2016
    September 2016
    August 2016
    July 2016
    June 2016
    May 2016
    April 2016

    Categories

    All
    Gifs
    Screenshots

Home
Mailing List
Contact
© COPYRIGHT 2020. ALL RIGHTS RESERVED. by Onerat™ Pty Ltd
  • Home
  • Games
    • Elden: Path of the Forgotten
    • Outback
    • Itch.io
  • Asset Store