Halloween Pumpkin’s – GLSL Programming

ACW2.rfx-Pumpkin Party

 

For the Advanced Graphics module as part of my BSc in Computer Science, we were tasked to create a 3D scene with a theme of a ‘Halloween Pumpkin Party’. The scene was produced using RenderMonkey and programmed via GLSL vertex and fragment shaders.

The scene displays a variety of shader effects including: Cube mapping, displacement mapping, height bump-mapping, parallax bump-mapping, fragment based-lighting, particle systems, texture bill boarding, smooth-step vertex transformations and stencil masks.

Below is a brief description of each component of the scene and how it was implemented.

Enviroment

Cube Mapped Skybox

I created a new cube map using several textures by creating a DDS file using the ‘DirectX Texture Tool’. The cube map was then applied onto a cube model in RenderMonkey.

Terrain Displacement Map and Height Map

Terrain Displacement Map

Terrain Displacement Map

The terrain features texture displacement mapping, a height bump map and fragment lighting. It was made using a single tessellated plane with a terrain texture. In the vertex shader I displaced each vertex along its normal using the texture colour values. I applied a uniform coefficient to control scaling.

A separate texture is used for bump mapping to create a grass effect. The height map was done by transforming the view direction and light direction into tangent space via a matrix. In the fragment shader, I retrieved the height map data, calculated the difference between two pixel samples and determined the normal for each fragment. All other objects that use height bump maps in the scene are done the same way.

Dispersed Fog Particle System

Fog Particles

Fog Particles

The fog is implemented using a particle system and quad array. A time coefficient is first calculated and then another coefficient used to progressively spread the particles apart from each other. Each quad in the system is ‘bill boarded’ to always face the view, which is achieved using the inverse view matrix. The fog colour transitions across the texture by decrementing it’s coordinate using the timer resulting in multi hued particles. A smooth fade is added around the edge of each quad to help it blend better. By increasing the size of the particles, lowering the speed and extending the particle system range, I created the above effect.

Fireworks Particle System

Firework Particle System

Firework Particle System

The fireworks use the same principles as the fog except using a different algorithm. All particles start on top of each other, ascend into the air, and then spread apart, slowly drifting down. This is achieved by setting an initial velocity, it then checks if each particle is below the explosion threshold. If it is, it increments the particles with positive velocity. If not, it decrements the particle by the negative velocity and spreads them apart over time.The particles slowly fall back down.

Pumpkins

Pumpkin 1

Cube Mapped Pumpkin

Cube Mapped Pumpkin

Features:

  1. Cube mapped.

Each fragment is coloured using a reflection vector to access the texture data from the cube. The shape is a 3D model.

Pumpkin 2

Parallax Bump-mapped Pumpkin

Parallax Bump-mapped Pumpkin

Features:

  1. Parallax Bump Mapping (normal\height map)
  2. Non-uniform vertex transformation light flickering.
  3. Flame bill board.
  4. Fragment lighting.
  5. 3D model used.

The parallax bump-mapping gives a nice bumpy surface using a simple brick texture. The is effect achieved in the fragment shader by retrieving the normal and height texture data and then correcting the texture coordinate.

I created a nice lighting effect to simulate flickering flame light. It works by displacing the normal slightly based on a sine function. This is done on all flame pumpkins.

Flame

Flame billboard

The pumpkin flame is created using 3 different textures, a shape , colour and a noise layer. The vertex shader billboards the quad and in the fragment shader, the shape layers are animated and transformed.

Pumpkin 3

Stencil-masked Spherical Pumpkin

Stencil-masked Spherical Pumpkin

Features:

  1. Stencil masked cut-out holes.
  2. Smooth step transformation from a sphere. Top is removed.
  3. Height Bump Mapping.
  4. Non-uniform vertex transformation (breathing, veins swelling, light flickering).
  5. Flame bill board.
  6. Fragment lighting.

The face is made using holes that are cut out using a simple face texture as a stencil mask and then discarding fragments. The pumpkin shape is made from a basic sphere that has been stretched and the top removed in the shader.

A breathing effect has been added where the veins on the texture swell when the pumpkin exhales, this is achieved by applying a sine function to the bump normal. The breathing is done using a ‘smooth step’ sine function on the lower vertices.

Pumpkin 4:

Glowing Pumpkin

Glowing Pumpkin

Features:

  1. Glowing eye and mouth holes via blended billboard.
  2. Glowing aura via billboard texture.
  3. Non-uniform vertex transformation light flickering.
  4. Fragment lighting.
  5. 3D model used.

The glowing eyes and mouth are made using separate passes. It is done by bill boarding a texture and blending it over the holes. A direction is calculated so that it only glows when it’s looking at the camera.

Pumpkin 5

Transformed an displaced pumpkin from teapot model

Transformed and displaced pumpkin from teapot model

Features:

  1. Smooth step transformation from a teapot. Handle and spout translated inside.
  2. Wings extruded via smooth step and animated.
  3. Displacement mapped spikes.
  4. Hovering animation.
  5. Height Bump mapped fur.
  6. Fragment lighting.

Shape is made by translating the spout and handle vertices inside the pot. The wings are extruded via smooth step to make them curved. The spikes are made by deforming the vertices along the normal based on a texture. The hovering is done by applying a sine and cosine function to the vertices x and z components, the wings are similarly animated.

Gravestones

GravestoneSimple 3D models featuring bump-mapping and fragment lighting.

Summary

The project was challenging and very fun to work on, allowing me to learn many different shader rendering techniques and effects that are a staple in modern graphics and games programming. Using RenderMonkey allowed focus to be directly on shader programming and not the OpenGL framework i.e handling model loading and vertex buffers etc, which made sense considering the limited allocated time for the coursework. I was also very pleased to have received a mark of 90% for it! It really goes to show the power and variety of what can be achieved purely with shaders.

OpenGL Cross-platform PC/PSP Game Coursework

Last semester as part of the Advanced Graphics module of my CS degree at Hull University, we were tasked with a group project to produce a cross-platform OpenGL mini-game for the PC and Sony PSP based on a specification. The game premise was to move around a 3D ‘maze’ consisting of four rooms and connecting corridors, avoiding a patrolling AI that would shoot you if within its line of sight. The objective was to collect 3 keys to activate a portal to escape and beat the game.

The groups were selected at complete random with 4 members. As per usual, group coursework assignments are particularly difficult due to the extra concerns of motivating members and assigning work and by year 3 of University, you get a good idea on the best way of operating within them to secure good grades. I went in with the mindset of doing as much work as possible after we assigned tasks. Hopefully each would carry out their allocated work, if not, I’d just go ahead and do it, no fuss. Luckily one chap in my group was a friend and he did an excellent job coding the AI, mini-map and sound while I worked on coding the geometry, camera, lighting and player functionality etc.

1

Mini-maze model

Static environment lighting

Static environment lighting

Cross-Platform Limitations:

Having worked with OpenGL and shaders last year for my 3D ‘The Column‘ project, it was some-what limiting when I realised that the PSP didn’t support them and that fragment-based lighting was a no go. With one requirement of the game being a torchlight effect that illuminated the geometry, this would therefore mean that for PSP compatibility, vertex-based lighting would need to be implemented and that meant tessellation of primitives to prevent the lighting looking very blocky and…well very 90’s. Luckily the PSP did atleast have support for VBO (Vertex Buffer Objects) which meant effectively each tessellated model could loaded onto the graphics card only once to improve performance.

Unified Code

An interesting aspect of this project was the required consideration for a consolidated code-base that where possible allowed shared functionality for both the PC and PSP platforms i.e limiting how much platform specific code was used. This was essential since the game would be a single C++ Solution for both platforms.

I designed the code structure based around principles Darren McKie (the course lecturer) described, and produced the following class diagram that reflects the final structure:

Unified Cross-platform Class Diagram

Unified Cross-platform Class Diagram

The majority of game code resides in ‘Common Code’ classes that are instantiated by each particular platform ‘Game’ object. Certain code such as API rendering calls were kept platform specific but made use of the common classes where necessary. A particular nice way of ensuring the correct platform specific object was instantiated was carried out using ‘#Ifdef’, ‘#ifndef’ preprocessor statements and handled by a ‘ResourceManager’ class.

As mentioned earlier, per-vertex lighting had to be implemented due to PSP compatibility. A primitive with a low number of vertices would thus result in very blocky lighting. To prevent this I created a tessellation function that subdivided each primitives vertices into many more triangles. I played around with the tessellation depth to find how many iterations of subdivision could be achieved before inducing lag and was very happy with the lighting result considering there is no fragment shader; a given for today’s modern pipelined-based rendering.

Active Portal

Active Portal

The PSP implementation proved more tricky due to getting to grips with the PSP SDK and having access to very little documentation, however the game was successfully implemented onto a PSP device and ran with decent performance after compressing the textures down and removing geometry tessellation to allow for the PSP’s limited memory capacity.

The game was written in C++ and  the following libraries and software were used:

  • GXBase OpenGL API
  • Sony PSP SDK
  • OpenAL
  • Visual Studio 2012
  • Paint .Net

The Column: 3D Graphics Simulation

Top-down

As the single fully weighted piece of work for the 3D Graphics module during my second year of my Computer Science degree at Hull University I had to create an OpenGL graphics simulation. Despite having had little prior experience of using 3D graphics frameworks, I am very pleased with the outcome and look forward to continuing to spend a lot more time with both the OpenGL and DirectX API’s; in particular my final year project looks to be a ray-tracing renderer (potentially CUDA) which should give me additional exposure to what is becoming a more and more promising technology for gaming.

I created a report accompanying the finished program which I’ll simply include bits of below to explain the project and how the simulation works.

The Column

The Column

The Column is a 3D graphics simulation designed around a series of stacked boxes containing cylinders. Balls are emitted at the top of the stack and interact with both the geometry and each other via way of collisions and response. In addition, the simulation features a “Sphere of Doom”, a large sphere near the bottom of the stack that absorbs balls, shrinking their size and mass. A portal lies at the bottom of the stack that transports any balls that enter, back to the top of the column. The entire simulation is made using OpenTK (OpenGL) in C#. All geometry and physics are rendered mathematically.

The specification determined that one emitter should emit balls with the approx density of aluminium, the second one, copper and the third, gold.

The program simulates a dynamic system through various means. The balls use an Euler integration method with a gravitational constant that combined with calculated velocity, mass and density of each ball, simulates the motion of the balls falling down the column.

Ball to ball collision response is handled via “elastic collisions” based on the mass of balls and perpendicular velocities from the collision point, thus a heavier ball will knock a lighter ball out of the way. Additionally the angle of impact effects the amount of force transferred.

Rendering is performed via OpenGL using version 3.1 and Vertex Buffer objects. All primitive 3D models have been constructed manually or mathematically. I use GLSL vertex and fragment shaders for “Phong Shading” based ambient, diffuse and specular lighting calculations that provide interpolated lighting of geometry between vertices. My scene uses 3 point light sources and has built in support for both directional and spot lights if desired.

I have implemented a particle system object that emits particles of a given shape. I have used simple quad planes for the simulation for performance optimisation and rotate them for added effect combined with the lighting. The particles are highly customisable in lifetime, movement, scale and quantity and can be added for any desired event. I use them specifically for collisions with the Sphere of Doom and upon spawning of balls from emitters.

My portals use a Frame Buffer Object which renders the scene from the desired camera position to a texture. I then switch to the Display Frame Buffer and render the entrance and exit portals using the respective textures to give the effect of seeing through the portals to their destination, which in turn is updated in real-time.

Bottom-Up

I have spent considerable time optimising the simulation to maximise the overall frame rate. Much of this has been achieved by streamlining the shader structure to avoid dynamic branching, specifically with the avoidance of “IF” statements , the use of step functions and moving as many calculations as possible to the vertex shader. The fragment lighting calculations are easily the most intensive part of the simulation and reducing my lights to a maximum of 3 per fragment has also helped greatly.

With a simulation such as this, there is always something that could be improved on, tweaked, optimised or added. Suffice to say I am very satisfied however with the quality of the finished product which has more than surpassed my initial expectations and I feel I have learned very useful and contemporary skills that will be essential for the future. Perhaps most importantly, I have thoroughly enjoyed the assignment.

I’ll get a video uploaded of it in motion at some point. I’m currently looking at improving my portals a bit by potentially using an asymmetric frustrum.

Sphere of Doom