Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411490 Posts in 69371 Topics- by 58428 Members - Latest Member: shelton786

April 24, 2024, 08:32:21 PM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsCommunityTownhallForum IssuesArchived subforums (read only)TutorialsUnity Shield Effect (Scripts for Texture3D / Perlin noise + Shader)
Pages: [1]
Print
Author Topic: Unity Shield Effect (Scripts for Texture3D / Perlin noise + Shader)  (Read 3786 times)
NightBox-Studios
Level 0
*



View Profile WWW
« on: September 05, 2015, 06:15:06 AM »

Introduction

We wanted to have an animated shield effect for our game Tri.Defender. Such an effect is pretty common and seems to follow a specific rulebook. For example, it has to be tinted blue for the good guys, because… that’s how it always is.
However, we had a few specific constrains: Since the effect is used on a plane, a falloff in transparency, where the rim is brighter and less transparent then the inner part, wasn’t applicable. We tried to wrap a texture around in an animation but decided that we wanted a more sophisticated effect. This called for a more customizable approach, which I want to share with you.


A big warning now, what we provide here is a script and shader based solution. The more artistic reader probably expects the first step to be a run-of-the-mill cloud noise effect from Photoshop like on the right. The idea is not bad, actually. The elegance of the Photoshop effect comes from it being not really random: the color of one pixel is not random, but depends in fact on the neighboring pixel and will not differ too much from it. The technical term for that is correlation and it looks more natural to the human eye. Similarly, for an animated noise effect, we want the noise to change gradually with time. So we need a noise that is correlated in two dimensions and time, or equivalently, correlated in three dimensions.

In Unity, we can use a Texture3D for this, where the third dimension corresponds to the time. Imagine a cube filled with such a cloud-like noise and the 2D texture seen in each frame is a cut plane through this cube that is moving over time. This is what we will generate with our scripts. Alternatively, an animation could be pre-renderend using, e.g., After Effects and imported as a Movie Texture, which has its own pros and cons, like being more straightforward to use, but with have less control over it in the shader.

Note: This is the first part on the shield effect. This part will cover the script assets to generate Texture3Ds with Perlin noise. The next part will focus on the graphics shader. You may want to follow the post on our website, as it has more pictures supporting the explanation of the scripts.

Texture3D and Perlin noise

How do you generate a three-dimensional noise? The second-best algorithm for these cloud-like noise is called Perlin noise. It comes in second because its inventor, Ken Perlin, created an improved algorithm named Simplex noise a decade later, which is more efficient and has less artifacts. Unfortunately, people often don’t make the distinction and both are referred to as Perlin noise.

Unity has a built function Mathf.PerlinNoise, but it only generates 2D noise. Still we don’t want to create everything from scratch, so I’ll redirect you to an implementation of the algorithms in 2D and 3D at catlikecoding.com, which also has a great explanation of the mathematics behind it. You may simply skip to the end of the site and download the package there.
Import only Noise.cs and NoiseSample.cs into your Unity project.

Afterwards, import the package with our scripts from here.
It provides you with a demo scene and the necessary scripts to create this effect:



Script: Generating different 3D noises

The final texture is actually a combination of two different noises, very much like you would combine several noise layers in Photoshop.

The noise textures are created by the script CreateNoise.cs, which you can add as an component on any GameObject in the scene. In the preview scene, the first two child objects of the (deactivated) “Create Textures” object each have an individual CreateNoise instance. The assets are then created with the help of a custom Editor. I admit this is definitely a quick-and-dirty setup, but worked good enough for me. You’ll probably want to put this creation process in its own scene that is excluded from builds.

Let’s take a look at how the spherical noise is created:

  • The Output Text path needs the relative path and filename for the Texture3D file to be created. You can customize the path to a subfolder of the project, but as with all assets, the file must be somewhere beneath “Assets/”. There isn’t any specific file format for Texture3D, but Unity will recognize the type correctly if you give the file a “.asset” extension.
  • Width, height and depth give the size of the texture. You should be quite conservative with these values, as the resulting textures will have a file size many times bigger than a normal 2d texture (more precisely, it will be depth times bigger).
  • For each dimension, you can scale the noise. A factor larger than 1 will stretch the nice, whereas a number smaller than 1 will repeat the noise.
  • The Noise library from catlikecoding.com has two types of noise: Value and Simplex noise (which, mathematically, is a gradient noise in contrast to value noise). I will wholeheartedly admit that this is confusing and the only thing you should care about which one looks better for your purpose.
  • Smallest Frequency sets the size of the structures in the noise. A lower frequency means less repeating, so the features of the noise will get bigger.
  • Max Amplitude determines the strength of the noise, i.e., the contrast to boring gray.
  • However, the amplitude is ignored if you set the Renormalize option. Then the color will always vary between pitch black 0 to 255 white. Otherwise, the darkest and brightest colors will be some shade of gray.
  • The Octaves, Lacunarity and Gain options will be explained below. Having 1 Octave is the default, for which Lacunarity and Gain are meaningless and ignored.

The custom Editor script places a Create button above the default inspector. Don’t panic if Unity freezes for a minute after you have clicked the button! The algorithm isn’t optimized and takes quite a while, but Unity will recover once the texture has been generated and saved. I should also repeat my warning regarding the dimensions of the texture, the size of course also increases the generation time!

The fuzzy noise is actually a fractal noise created with different settings and multiple octaves:

  • Naturally, the filename should be different if you don’t want to overwrite anything
  • Here I chose Simplex noise for aesthetic reasons
  • The Smallest Frequency is now much smaller, resulting in broader features
  • Here I wanted a fractal noise with 8 Octaves. For each octave, a new noise pattern is overlayed on top of the previous one, but with the frequency multiplied by the Lacunarity and the amplitude multiplied by the Gain. So, with a lacunarity bigger than 1, the frequency increases and the features of the noise get more granular. With a gain smaller than 1, the strength of these finer patterns gets diminished in each octave, which is usually what you want. Fractal noise is very common to procedurally generate terrain, so imagine the combination of huge maintains + smaller hills + tiny pebbles.
  • Now Renormalize becomes really useful: Adding up the different octaves might very well lead to values bigger than one, but the color representation will stop at 1=white. If you don’t want to fine tune your values, a renormalization is probably best.

Having more octaves again increases the generation time. Be patient.


Script: Combining two Texture3Ds

Finally we have two nice noise textures, but most likely they would look cooler if combined…
So let’s do that with the “Combine Texture 3D” script.

  • The Output Text path is used in the same way as before and requires a path and filename to some place under “Assets/” and must end in “.asset”
  • Width, height and depth specify the size of the combined output texture
  • Blend Mode defines how the two input textures should be combined. I have implemented some common blend modes from Photoshop, that is, a 50% Normal mode, Multiply, Negative Multipy and Overlay. This is by no means comprehensive, but should suffice for a start. You are free to take these modes as a template and add your own into the script, or you may implement the evidently missing feature of an opacity value…
  • Both Path Texture 1,2 and Input Texture 1,2 fulfill the same purpose: You can either type in the path to an input texture (i.e., the “.asset” file from the previous step), or drag in the asset from the project view within Unity. The latter is of course more elegant, but if you overwrite the asset file, the reference to it will be lost. That could have been worked out by Editor script, but I have deemed it not important enough.
  • Each input texture can be scaled along each dimension, for example if you want to combine two Texture3Ds of different sizes and have one stretched or shrinked to fit the other. If the sizes do not match even after scaling, the textures are tiled in the output.

Press Combine and enjoy a much, much quicker process! You can see the result in the inspector preview after selecting it in your project.

Preview Shader

Unity has no built-in shader that is capable of displaying a Texture3D. The next part will cover our more complex shield effect shader.

For now, the package contains a bare-bones shader that willl give you an animated preview of the textures. In the demo scene, the shader is used in the material of the Plane object.
The vertex shader is pretty standard, as it saves the uv coordinates of the mesh (e.g., the plane) as well as the vertex positions (which aren’t used at the moment).
The fragment shader is more interesting: A three-dimensional uvw coordinate is created from the two-dimensional uv coordinates and the time as the third coordinate, based on the builtin value _Time (which you get from including “UnityCG.cginc”). The time is scaled by the _Period time, which you can modify in the material. The color is finally read from the Texture3D.
Logged
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic