Applying a custom Cg shader

Shaders are one of the most powerful concepts in today's graphics programming, allowing programmers to program the graphics hardware and thus provide great flexibility for creating amazing effects.

This recipe will show you how to use shaders written in the Cg shading language with the Panda3D engine.

Getting ready

Setup your project as described in Setting up the game structure found in Chapter 1. Add an additional folder called shaders in the top-level source directory and add it to Panda3D's resource search paths.

How to do it...

Let's create a shader and apply it to a model:

  1. Add the following code snippet to Application.py:
    from direct.showbase.ShowBase import ShowBase
    from panda3d.core import *
    class Application(ShowBase):
    def __init__(self):
    ShowBase.__init__(self)
    self.world = loader.loadModel("environment")
    self.world.reparentTo(render)
    self.world.setScale(0.5)
    self.world.setPos(-8, 80, 0)
    shader = loader.loadShader("shader.cg")
    render.setShader(shader)
    self.cam.setPos(0, -40, 10)
    
  2. Create a new file called shader.cg in the shaders subdirectory and enter the code below:
    //Cg
    void vshader(uniform float4x4 mat_modelproj,
    in float4 vtx_position:POSITION,
    in float2 vtx_texcoord0:TEXCOORD0,
    out float4 l_position:POSITION,
    out float2 l_texcoord0:TEXCOORD0)
    {
    l_position = mul(mat_modelproj, vtx_position);
    l_texcoord0 = vtx_texcoord0;
    }
    void fshader(uniform sampler2D tex_0,
    in float2 l_texcoord0:TEXCOORD0,
    out float4 o_color:COLOR0)
    {
    float4 fullColor = tex2D(tex_0, l_texcoord0);
    float3 rgb = fullColor.xyz;
    rgb *= 8;
    rgb = floor(rgb);
    rgb /= 8;
    o_color = float4(rgb, fullColor.w);
    }
    
  3. Press F6 to launch the application and see something similar to the following screenshot. The colors will appear somewhat strange, but don't worry, this is what our shader is supposed to do:
How to do it...

How it works...

In our Python code, loading and applying a shader doesn't require any heavy lifting. We just use the loadShader() method and then enable it on models and actors of our choice, as well as all their children in the scene graph using setShader(). One thing to note though, is that if we use such a custom shader, all render states and all the functionality of the shader generator are overridden and need to be reimplemented within the shader file.

After our Python code is set and ready, we implement the shader code. One very important thing about writing shaders can already be found in the first line, where the line //Cg must be found for the engine to be able to recognize the file as Cg shader code.

The vertex shader function must be called vshader, just as the pixel or fragment shader function needs to be called fshader. The names of the function parameters were not chosen arbitrarily, either. These names have to comply with the hard-coded naming convention of Panda3D, so the data provided by the engine can be used by our shader code.

Our simple vertex shader just transforms the scene vertices to their proper position on the screen and hands the texture coordinates on to the pixel shader.

In the pixel shader, we sample from the texture at the main color texture image channel using the tex2D() function. As a special twist, we limit color output to only 8 possible values, creating an old-school look for our scene.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset