Monday, January 18, 2010
Introduction (or: The Part which explains why I'm posting this)
The other day I was discussing with Brad about the aura and ended up deciding to mock up my idea in 3S Studio Max. It's quite similar to Brad's idea of a screen aligned quad-mesh encircling the player but taken a bit further. As it's a bit much to convey in IRC I decided to write up this document explaining the technique with the added bonus of ironing out some of the issues as I worked through the idea.
This post will be structured in four parts. You're reading Part 1 now. Part 2 describes the underlying theory behind the technique and has pictures, I expect most will stop reading after that Part 3 goes into detail about the way the Aura's geometry is handled while Part 4 describes how basic texturing is handled.
NOTE: This is just theory at the moment, it's not implemented in the game at any level yet so don't ask when it'll be released! Any replies that are off topic or unproductive will be deleted. It also assumes a hardwareshader pipeline is available, however I don't see any problem in implementing a fixed function alternative, nor any more processor intensive than the current or other proposed methods. This document only covers the shape and basictexturing methods in detail, further possible texture effects are mentioned but are not explained in detail as that would be an entirely different topic and pretty much agnostic to the rest of the technique.
Overview (or: The Part with the most pictures and a video)
The aura mesh, rather than needing to be generated per-character, would be just a simple circular shape with a hole in the middle. Each quad is UV-Mapped to the full texture and a vertex attribute (could be the vertex colour channel or a texture coordinate channel) is used to store some information about the vertex positions relative to the center.
So, the initial aura would look like this:
When the aura is rendered it takes the player's bounding box and transforms it into screen-space, taking the four outterly points and reshaping the aura based on these points as so:
Along with reshaping the aura to match the Screen Space Bounding Box, it also reshapes the outer vertices to simulate the "strength" of the aura. This effect can be seen in the following video: http://www.youtube.com/watch?v=3aZtOot9M5k
The tip of the aura extends against the direction of the force acting upon it while the base gets flattened in that direction to produce a tear-drop like shape orientated correctly. This force can be the movement direction, gravity, wind or whatever is desired. The texture always moves towards the tip in a flowing manner.
How It Works: The Quad Mesh (or: The Vertex Shader Stage)
To illustrate some of the technical details of the effect, here's an annotated picture:
The Red and Green channels of the vertex attribute are used to denote the positions of the vertices relative to the center of the aura. Here's a few examples of such values:
Left is [Red=0.0, Green=0.5]
Right is [Red=1.0, Green=0.5]
Up is [Red=0.5, Green=1.0]
Down is [Red=0.5, Green=0.0]
Inner and Outer vertices share the same values for the Red and Green channels, this is to keep consistency in their final positioning between the two layers. However, the Blue channel determines whether the vertex lies on the Inner or Outer portion of the aura.
Taking the center of the player, the vertex shader repositions the Inner vertices to match the shape of a bounding area and expands the Outer vertices from the Inner vertex away from the Aura's Origin. The distance between the Aura's Origin and the Inner vertices is controlled by an origin distance variable and a bounding box padding variable. The distance from the Inner vertices to the Outer vertices is controlled by a strength attribute, the higher value it has the more the Outer vertices are expanded. Furthermore, the strength is exaggerated towards the Tip but muted towards the base.
(Technical Note: Realistically, we could store this information in the standard Position attribute as we just need the "origin" position, bounding box points and this offset & inner/outer data, the Position is never used. However that does feel a bit dirty and we will need the Position attribute for the Fixed Function Pipeline alternative.)
A further input is the force variable. This is a vector defining the direction the player is moving in and is used to determine which direction the Base and Tip are formed as well as how far along this axis the aura is stretched. When the player is moving very faster the aura will be more elongated leading up to the Tip and flatter at the Base while at slower speeds it would be rounder overall. When the player is not moving the force vector would be set to the gravity direction.
The force variable could also be used to simulate the aura being "blown" away from an explosion or a more powerful player charging up, however that would be calculated along with the movement direction. (Technical note: it could be a normalized vector and a float for the size of the force, though it might be best to split it up in theshader anyway)
In order to make keep the player model from going outside the Aura's shape during animation this technique use of the per-frame bounding box stored in thezAnimation format to give an accurate representation of the area the Aura needs to encompass. The coordinates of the 8 corners of this Object Space Bounding Box are passed to the vertexshader along with the model-view transformation matrix of the player model, the points are then transformed into Screen Space. These transformed points are then used to determine a Screen Space Bounding box.
The Aura's vertex positions are then calculated using the vertex attribute data mentioned above and the Screen Space Bounding Box, effectively scaling the Aura mesh so the corner points of the Aura are bounding box padding distance away from the relevant corners of the Screen Space Bounding Box. Next, the force vector is flattened against the viewing plane and normalized in order to find the Dot Product of the between it and the vector between the Vertex position and the Aura's Origin.
If the Dot Product 0 or more then the vertex is moved in the direction of the force vector, moving less as the Dot Product reaches 1. If the Dot Product is less than 0 then the vertex is moved in the opposite direction, moving more as the Dot Product reaches -1, thus creating a flatter Base and a pointed Tip.
If the vertex is an Outer vertex then it is moved along the vector from the Origin to the calculated position using the strength variable to determine the distance it has to move, again using the Dot Product previously calculated to scale the strength so it has a more prominent effect at the Tip than the Base.
How It Works: Texturing (or: The Final Part, are you still awake?)
The mesh's Texture Coordinates are set up per-quad to take up the whole texture, allowing tiling controlled in a predictable manner. In order to have the texture on either side of the Aura flow towards the Tip the horizontal Texture Coordinate must be flipped (TN: multiply it by -1) on quads which require the texture to scroll in a Counter-Clockwise direction. To determine which quads lie on which side of the Aura, we find the Cross-Product of the force vector and a vector going in to the screen (X=0, why=0, Z=1). This returns a vector perpendicular to the force vector which is used to find another Dot Product between it and the Origin-to-Inner-Position vector in a similar manner to how the Base & Tipvertices were determined in the previous section.
The vertical Texture Coordinate is scaled based on an amplitude variable to allow for the spikes to be less prominent if desired (for example. low amplitude for lowpowerlevels , high for overpowered Aura's). In order to produce the flowing effect we shift the horizontal Texture Coordinate along by a set amount, scaled by a speed variable. Furthermore we have a wavelength variable which scales the horizontal Texture Coordinate to allow control over how many spikes are rendered.
(Technical note: While the texture coordinates are mostly calculated during the vertex shader stage I've documented them in this section as it's they're only relevant to the texturing not the shape.)
As can be observed in the video posted above, this leaves a slight issue when the spikes join up at the Tip, but this can be resolved by pushing thevertices closest to the Tip out a bit further and squashing the Inner vertices towards the Outer vertices to create a more constant peak as can be seen in the following example where each frame displays the aura at different stages of animation both with Tipvertices peaked (on the left) and without (on the right) at the same stage for comparison purposes:
While the idea only currently extends to a single texture without effects, any texture level effects are compatible with it, for instance multiple spikes could be layered atop each other with different amplitude, wavelength and speed settings for a parallax like effect.Jittering, distortion and blurring effects could also be used to make the spikes look less uniform and more chaotic.
A further extension would be to blend in a secondary texture which scrolls outwards, such as an expanding wave or a particle like sparks coming away from the aura. If this were done, it would also be beneficial to fade out the outward scrolling texture near the edges so there isn't a sharp cut off.
I think that covers everything. If you have any questions, suggestions, etc. are welcome. Again, don't ask for a "release" as it's actually implemented and any off topic or unproductive posts will be deleted
Monday, January 18, 2010
Super Snake wrote : When in high speed flight the aura actually starts at the top and flows to the bottom, thus inverting it. This is something to take into consideration because it COULD make some textures stretch.
I'm not a coder as well, but I believe, inversing the vectors direction should be possible, yes, though, as Alex stated there will be a lot of parameters that will force the aura's movement. Changing it's direction shouldn't be a problem.
Yet again, I can be mistaken, only the guys, who have the powers to type can answer correctly.
Monday, January 18, 2010
Different characters would be able to have completely different textures, different flow speeds, roundness of the base and spikiness of the tip, different colours, even completely different texture effects. This is all explained in the post.
As I explained at the start of the post this technique is all about how to achieve an accurate but cheap and controllable aura around the character rather than the texture effects
Maybe with this approach you could even make attack aura's. Like gallic gun, Vegeta's aura turns in a circular aura. With this tech. you could make the aura actually stay the same which makes it more consistent. (I think you have already planned this though)
Totally, the technique isn't only applicable to player auras but any screen-aligned effect of that nature.
I hope this will also work when the flow gets inverted. When in high speed flight the aura actually starts at the top and flows to the bottom, thus inverting it. This is something to take into consideration because it COULD make some textures stretch.
As Ramunas pointed out, the Aura orientates itself where the direction the player is moving, so it should always have the flow in the right direction.