• Docs
  • Install
  • Follow @cosplayengine
  • v.0.9.5
  • GitHub
  • Watch
  • Examples
  1. Home
  2. Shaders

Shaders

  • Introduction
  • Install
  • ASCII Games
  • Demos
  • Examples
  • Macarena
  • Pong
  • Snake
  • Bird
  • Developer Guide
  • Quick Game 🏃
  • Key Concepts
  • Game Structure
  • Scenes & Objects
  • Log & Debugging
  • Pixels & Colors
  • Images
  • Keyboard Input
  • Sprite Animation
  • Shaders
  • Particle Effects
  • Fonts
  • Canvas Drawing
  • Text Input
  • Camera Tracking
  • Tile Mapping
  • Audio
  • Video
  • UI Toolkit
  • Build & Run

Shaders

Shader is a piece of user-defined code that is executed on each frame pass for each scene object that has one or more shaders attached to it. Shader is defined by the CPShader trait:

  • Each CPSceneObject can have zero or more shaders associated with it.
  • Shaders are attached to CPSceneObject via its getShaders() method.
  • Shader pass is the last pass during the frame update.

Animation in CosPlay

In CosPlay there are different ways one could implement animated scene objects. In the end, all of these approaches deliver the same result but each individual technique is tailor-made for a specific animation type:

  • Animated Sprites
  • Particle Effects
  • Canvas Drawing
  • Video Sprites
  • Shaders

Shader is a piece of user-defined code that is executed on each frame for each scene object that has one or more shaders attached to it. There are types of animations that simply don't fit any other type of animation. The typical example of shader-based animation is the various lighting effect: flash-lite, sun shadows, transitions, highlighting, etc. These types of animation simply cannot be reasonably implemented using sprites, or particles, or canvas drawing. In such cases, shaders provide simple and effective contract to implement this behavior. Note also that If the shader is stateless it can be added to multiple scene objects to provide its effect.

Shader Is An Asset

Just like other assets such as CPFont, CPImage, CPParticleEmitter, CPAnimation or CPVideo they are not managed or governed by the CosPlay game engine unlike scenes and scene object, that are managed and governed by the game engine. Assets are typically created outside the game loop and managed by the developer, they can be freely shared between scenes or scene objects as any other standard Scala objects.

Creating A Shader

Shader is any class or object that implements CPShader trait. Let's develop a flashlight effect shader that can be programmatically toggled on and off. When turned on it should produce the effect similar to this (screenshot is taken from Shader Example):

Here's full code for this type of shader:

        object FlashLightShader extends CPShader:
            private final val RADIUS = 8
            private var on = false

            // Method to programmatically turn the effect on and off.
            def toggle(): Unit = on = !on

            // Called on each frame update.
            override def render(ctx: CPSceneObjectContext, objRect: CPRect, inCamera: Boolean): Unit =
                if on then
                    val canv = ctx.getCanvas
                    val cx = objRect.centerX
                    val cy = objRect.centerY
                    val effRect = CPRect(cx - RADIUS * 2, cy - RADIUS, RADIUS * 4, RADIUS * 2)
                    effRect.loop((x, y) => {
                        if canv.isValid(x, y) then
                            // Account for character with/height ratio to make a proper circle...
                            val dx = (cx - x).abs.toFloat / 1.85
                            val dy = (cy - y).abs.toFloat
                            val r = Math.sqrt(dx * dx + dy * dy).toFloat
                            if r <= RADIUS then // Flashlight is a circular effect.
                                val zpx = canv.getZPixel(x, y)
                                val px = zpx.px
                                val newFg = px.fg.lighter(0.8f * (1.0f - r / RADIUS))
                                canv.drawPixel(px.withFg(newFg), x, y, zpx.z)
                    })
        

NOTES:

  • To implement a shader you just need to implement one method render(...) (line 9).
  • Method toggle() on line 6 provides a way to turn on and off this effect from the outside of this shader, e.g. based on keyboard event.
  • The bulk of the shader code is a simple geometry of determining the pixels within the given radius from the center of the scene object (that this shader is attached to) and gradually brightening the foreground color of those pixels.
  • That's it! 👌

Once shader is created it can be attached to any scene object. For example, in the code below we create a simple image sprite with our shader attached to it. On Space press the flashlight effect toggles on and off:

            val bulbImg = ...
            val bulbSpr = new CPImageSprite("bulb", 10, 10, 1, bulbImg, false, Seq(FlashLightShader)):
                override def update(ctx: CPSceneObjectContext): Unit =
                    super.update(ctx)
                    ctx.getKbEvent match
                        case Some(evt) => if evt.key == KEY_SPACE then FlashLightShader.toggle()
                        case None => ()
        

Prefab Shader

CosPlay comes with number of built-in prefab shaders:

  • CPBeatShader
  • CPFadeInShader
  • CPFadeOutShader
  • CPRandomFadeInShader
  • CPShimmerShader
  • CPSlideInShader
  • CPSlideOutShader
  • CPSparkleShader
  • CPFlashlightShader
  • CPStarStreakShader
  • CPBorderShader

These prefab shaders are used in various games that are shipped with CosPlay.

  • On This Page
  • Shaders
  • Create Shader
  • Prefab Shader
  • Example
  • Shader Example
  • Quick Links
  • Discord
  • Stack Overflow
  • GitHub
  • @cosplayengine
  • YouTube
  • API
Copyright © 2023 Rowan Games, Inc. Privacy • Docs release: 0.9.5 Latest: