How To Create Cool Effects with Custom Shaders in OpenGL ES 2.0 and Cocos2D 2.X

This is a post by iOS Tutorial Team member Krzysztof Zablocki, a passionate iOS developer with years of experience. Shaders may very well be the biggest step forward in computer graphics since the introduction of 3D into games. They allow programmers to create completely new effects and take full control of what’s seen on the […] By .

Leave a rating/review
Save for later
Share

This is a post by iOS Tutorial Team member Krzysztof Zablocki, a passionate iOS developer with years of experience.

Learn how to make cool effects like this with Cocos2D 2.0 shaders!

Learn how to make cool effects like this with Cocos2D 2.0 shaders!

Shaders may very well be the biggest step forward in computer graphics since the introduction of 3D into games. They allow programmers to create completely new effects and take full control of what’s seen on the screen. If you aren’t using shaders yet, you will be after reading this tutorial!

Cocos2D is one of the best iOS game frameworks available at the moment, and fortunately for us, Cocos2D 2.X now supports OpenGL-ES 2.0 and shaders. In this tutorial, you’ll learn how to create and use shaders with the help of Cocos2D. You’ll learn:

  • The basics of GLSL (OpenGL Shading Language)
  • How to create and use your own shaders in Cocos2D
  • Three shader examples:
    • How to manipulate colors in your game by using ramp textures
    • How to create emboss-like effects
    • How to create waving grass with just a few lines of code
  • How to manipulate colors in your game by using ramp textures
  • How to create emboss-like effects
  • How to create waving grass with just a few lines of code

This is an advanced tutorial so has a number of prerequisites. To get the most out of this tutorial, you need at least some basic knowledge of:

  • Objective-C and iOS. If you are a complete beginner, you may wish to check out some of the other tutorials on this site first.
  • Cocos2D. You’ll want to get familiar with Cocos2D if you aren’t already, perhaps by reading some of the Cocos2D tutorials on this site.
  • OpenGL ES 2.0. You don’t need to be an OpenGL ES 2.0 expert to go through this tutorial, but it will help to at least know the basics. You might want to read some our or OpenGL ES tutorials first.

Lastly, I’ll be using the latest version of Xcode in this tutorial, so make sure you’re fully updated to the latest version available through the Mac App Store.

Without further ado, let’s get shading!

Getting Started

Before exploring shaders and how to use them, you will need to have Cocos2D 2.X and the Cocos2D Xcode templates installed. Then, you should create a new Cocos2D 2.X project. Follow these steps to do so:

  1. Download the latest version of Cocos2D 2.X.
  2. Unpack it into your preferred folder.
  3. Navigate to the Cocos2D folder in the terminal. Then, use the following command to install the Xcode templates: ./install-templates.sh -u -f
  4. Start up Xcode and go to File\New\Project…
  5. Select iOS\cocos2d v2.x\cocos2d iOS and click Next.
  6. Name your project CocosShaderEffects, select iPhone as the Device Family, and click Next.
  7. Choose a folder to save your project in, and click Create.

Next you need to enable ARC in your project. Although Cocos2D doesn’t use ARC, you can enable it for the rest of your project. This will allow you to write less code and have less chance of memory leaks.

Select Edit\Refactor\Convert to Objective-C ARC… from the menu. In the dialog which opens, select main.m, AppDelegate.m and HelloWorldLayer.m (if you don’t see them, click the little triangle next to CocosShaderEffects.app to expand the list and scroll to the very bottom of the files list) and click Check, Next, and Save through the next few dialogs. You will be prompted to enable automatic snapshots before the ARC conversion at this point. You can Disable it for this project but in general, having snapshots on might save you at junctures like this because you have a snapshot of your code before mass changes that you can revert back to, if something went wrong.

Pretty easy, eh? Now you can use the power of Cocos2D while using ARC for your own files :]

Compile and run. You should see this:

Now, download the resources for this project and extract the contents of the ZIP file into a temporary folder.

Drag and drop the extracted files into the project root. Make sure that the “Copy items into destination group’s folder (if needed)” checkbox is ticked if you are dragging and dropping from a temporary folder.

Since you will not be using HD images in this tutorial, if you are running your app on a device with a retina display, you might want to disable HD image loading. Open AppDelegate.m and comment out the following line:

if( ! [director_ enableRetinaDisplay:YES] ) 

Now you’re all set to begin your adventure with shaders and Cocos2D!

What are Shaders?

A shader is a simple C-like program that is used to execute rendering effects. As an example, as the name implies, a very basic function of a shader might be to add a different shade of color to an object (or portion of an object). A shader is executed on the GPU (graphics processing unit). For mobile devices, there are two kinds of shaders:

  1. Vertex shader: a vertex shader is executed on every vertex being rendered. So, when rendering a simple sprite, which would usually be just four vertices, a vertex shader will be executed four times to calculate the color and other attributes for each vertex in the sprite.
  2. Fragment shader: this type of shader is executed on each pixel that is visible onscreen. This means that when rendering a fullscreen quad on the iPhone, a fragment shader will be called 320×480 times.

Vertex and fragment shaders can’t be used alone: they have to be paired together. A pair of vertex and fragment shaders is called a program. It usually works like this:

  1. A vertex shader will first define the attributes for each vertex to be displayed on screen.
  2. Then, each vertex is broken down in turn in to a series of pixels which are run through a fragment shader (also known as a pixel shader)
  3. The final pixels are then rendered on screen.

Before the introduction of shaders, when you needed rendering effects, you only had access to what was known as the fixed-function pipeline. The fixed-function pipeline allowed you to apply effects that were more or less hard-coded. You could change a few parameters here and there (change a color, modify the position etc.), but that’s all you could do.

The limitations of the fixed-function pipelines prompted the creation of shaders which allow you to programmatically create new render effects. Basically, with shaders you can make any effects you can dream up: shaders allow you to write your own programs that are executed each time something is drawn on screen.

OpenGL-ES 2 shaders are written in the OpenGL Shading Language, GLSL. It’s very similar to Objective-C, so you shouldn’t have a problem using it if you’ve some experience coding, and especially if you’ve read some of the previous tutorials on this site. Don’t worry about reading the specification yet: I’ll walk you through the basics in sample code.