I've applied the water planes material from Epic (lake one) as well as the automatic landscape material to my drone game prototype. Both the water and the landscape material required some tweaking. But this was easy to do after carefully studying the inner workings on both (which I discussed in my two previous posts). I was having issues getting my game to cook correctly for Windows due to the long names in the automatic material shader assets. To go around that I had to rename a few of the assets as well as the directories. Anyways, the result of what I got so far is sown below.
Drone Mesh and Material
I found the drone mesh in a website that had many free 3d meshes. However, I've lost the exact link where I got it from :( I do remember that the mesh was in a non-FBX format so I had to import it to blender first just to export it to FBX right afterwards. In the import/export process I lost a piece of the mesh that represented the blades. Hence, rather than trying to create some blades in blender and then somehow animate them, I decided to make believe my drone is a military prototype that uses jet propulsion...
For the military looking material, I used a navy cammo texture for the base color and the noise texture shown below as my roughness map. This is how I'm achieving the wear look on the surface. Btw, I've made this a fully metallic material in UE4s physically based shaders.
Finally, I generated a physics body for the mesh inside the editor. I've used a simple bounding volume and its shown above as the purple box wireframe. Nothing fancy. Later through script I attached 4 thrusters to this box and this is how I'm achieving flight.
The blueprint class components
All in all, this blueprint class contains the following components and a screenshot of the components view for this blueprint class is shared below.
This is the mesh described above.
There are two cameras. The first one is attached to a spring arm which is in turn attached to the mesh and set up to be active by default. It achieves the third person camera. The second camera is set right at the nose of the drone to achieve a first person camera and its deactivated by default. Inside the event graph I'm using the 'Select' button release event on my PS3 gamepad to trigger a flip-flop node that switches between third person and first person cameras.
In the picture below the red arrows represent the positive x-axis for each of the four physics thrusters components. The thruster's strength is set through script and depends on the gamepad's left and right thumbstick axis inputs. More specifically, the left thumbstick y-axis controls the initial strength for each thruster. The right thumbstick controls pitch and roll via the y-axis and x-axis respectively. In order to implement flying controls, the overall strength for each thruster is calculated as follows
Thrust = overall thrust strength (left thumbstick y-axis) - pitch amount (right thumbstick y-axis) - roll amount (right thumbstick x-axis).
Jet Exhaust Particle System
This is the exact same particle system discussed in my previous post. As pointed out in the previous post, the particles' initial speed was made a parameter so that it can be set through script in a way that is proportional to the overall strength of each thruster component respectively. Controlling the initial speed of the particles is a proxy for the intensity of the thruster visual effect.
I found a rocket booster sound in the www.freesound.org website and added it as an audio component to my blueprint. I then make its pitch and volume change proportionally to the left thumbstick y-axis (the one that controls the main thrusters strength).
This particle system was designed using three emitters that are briefly discussed below: Combustion emitter, Smoke emitter and Heat emitter.
Combustion is achieved by creating a GPU Sprites Emitter with 500 particles that are put through a vector field. This vector field is designed to push the particles in a jet stream like motion. Further, the vector field is set up as local vector field with a constant 'intensity' value and a 'tightness' value of zero, meaning that it only influences the particle's velocity (as opposed to completely taking over its velocity). Therefore, the particles need to have an initial velocity when spawned. The velocity cone module is used to spawn the particles with an initial velocity along a cone with a small angle aperture that is always pointing downwards. The angle of the combustion cone is fixed but the velocity distribution is set up to be a 'Distribution Float Particle Parameter' in order to be able to control this parameter from code or blueprints. Exposing this parameter to code or blueprints allows for controlling how strong the overall combustion effect looks like and, in this particular case, its hooked to the strength of the thrusters. Which is in turn controlled by pulling the gamepad left thumbstick up and down.
It is worth mention that an alternative way to controlling the overall strength of the combustion effect could have been set up by using a global vector field instead. This means that is up to the blueprint/code to define and own the vector field allowing it to modify the vector field intensity dynamically (instead of modifying the velocity cone's velocity parameter).
A color over life module is used to create the blue to red gradient effect. Also the size over life effect allows for the sprite to grow twice its size as it ages.
Lastly, another key module to achieve this combustion effect is to use a subimage index module (sub UV). First of all, this subuv module allows for a sprite to play a sprite animation. In this case the explosion sprite atlas shown below was used.
It should be noted that there are two ways to achieve sprite animations via subuvs: One option is to create a custom material that uses time to programmatically sweep the uvs horizontally and vertically across the sprite atlas. Another simpler approach, which was used here, is to create a custom material and just use a particle subuv expression. This expression automatically does the uvs horizontal and vertical sweeps (cascade tells it how many sub images there are horizontally and vertically). All there is left to do when using this expression is to provide the sprite atlas texture. When using this approach the subimage index module needs to be created in order to define how many subimages are to be used. Moreover, the amount of subimages horizontally and vertically is defined through the subuv section parameters in the 'required' module.
Finally, a couple comments regarding collision. I found that GPU collision only works when the option 'Use Local Space' is disabled in the required module. According to Unreal Forums this is because "collision on GPU particles calls from Scene Depth and cannot function in local space". However, disabling this local space option causes the particle effect to have a trailing effect when flying and I didn't like that. Hence I disabled collisions on this combustion emitter (The cascade screenshot may not reflect that tho).
Originally the smoke emitter was simply meant to be a simple CPU sprite emitter to simulate spark collisions when the jet exhaust got too close to the ground. This was meant to overcome the limitation of the GPU sprites from above not supporting collisions when dealing with local space. However, I couldn't get the sparks to look natural enough and eventually this module evolved into smoke. The particles in this emitter are simply shot down with an initial velocity and made to collide with any static actor in the world. A maximum of two collisions per particle was chosen and a damping factor vector that makes the particles (smoke) jump in an upward fashion when colliding. To create the sprite material a smoke alpha texture was used in a translucent material configuration. As usual, the particle color modulates the material emissive color as well as the opacity. Hence, to create smooth smoke a color over life was chosen where smoke is born light gray and dies black. Also, it is born almost translucent just to become fully opaque halfway and die fully translucent again. Finally, this is alpha texture used for the smoke sprite.
The heat effect is mainly achieved by the sprite material. This material is set up as a lit translucent surface and the main thing about it is its refraction variation. The refraction variation is being driven by a lerp module that interpolates between 1.0 and 1.6 for the refraction index input parameter in the shader. Furthermore, this lerp is driven by a modulation between the particle's color and a noise texure being panned. Finally, the normal of this material is driven by two normal maps that are panned and then added to each other in order to create random motion. With the material set up, the emitter is setup to spawn particles on the surface of a sphere centered around the combustion emitter with an initial velocity pointing up (heat rises). A drag module helps slow down the particles as they mature and grow in size. Finally, the scale color module allows for the emitter to communicate to the material to increase that modulation factor driving the refraction interpolation.
I've built upon the particle system created in my last blog and added a Beam Emitter to simulate electrical beams. The material for the beam emitter was procedurally generated using a sine function to drive the emissive color as well as the transparency (along with a power function in the middle). One tricky thing to keep in mind when creating beam emitters is to make sure to lock the target position to the life of the particle. Otherwise, it looks like you are generating tons of electrical beams per second! Another tricky thing was to uniformly distribute the tangents for the target endpoints. This is for the purpose of making the beam bend randomly. It helps to remember that 'tangents' are basically defined by the two control points used by the Bezier curve at the endpoints. For my beam emitter I'm only generating random tangents and the target endpoint. Furthermore, in order to give the jumpy feeling to the beam, I've added a Noise module to my Emitter and let the noise range to be uniformly distributed across a small range. Finally, if you really want to get that emissive color feeling you need to bump the colors above the 1.0 range.
In order to produce the video shown above I used the engine's Matinee editor. It was easy to set up following this guide. However, I ran into an issue where I would get this annoying untextured sphere at random places every time I launched the game as a standalone. Upon some googling I found it had something to do with not having a game object defined which in turn was auto generating a default pawn. I'm still new to UE4 so not sure what all that means. Nevertheless, I was able to resolve the random ugly looking sphere by selecting the Matine object in my scene and, in the details panel, selecting the 'Hide Player' option. Also, the only way I was able to get the movie to start at gameplay was by using Blueprints as described in the guide. That little box in the Matinee object details window called 'Play on level Load' doesn't seem to work by itself.
It's been a week or so since the folks at Epic made their big announcement during GDC 2015 (i.e., UE4 its now for free) and I'm still very excited. I think its a bold but brilliant step. Can't wait to get comfortable enough with UE4 editor so hat I can start working with the source. I'm pretty sure from a computer science standpoint there is a lot to learn from reading UE4 source code.
Now, I've been trying to catch up on the tutorials every now and then and, so far, I've gotten through the Materials and the Particle System ones. Hence, I decided to play around with Cascade: UE4's Particle System Editor. The scene above was created by using two CPU Particle Emitters. The one in the middle acts as a particle attractor and the others are spawned randomly within a bounding box with an initial velocity. Because these particles are CPU type, I was able to attach a point light to them. Its hard to show off particle systems using screenshots so my next step is going to be learning more about the Matinee feature and see if I can render a small video :-)
I'm a software engineer with a passion for computer graphics.