Simple image shader (GLSL)

About Monkey 2 Forums Monkey 2 Code Library Simple image shader (GLSL)

This topic contains 12 replies, has 3 voices, and was last updated by  DruggedBunny 4 months, 1 week ago.

Viewing 13 posts - 1 through 13 (of 13 total)
  • Author
  • #15895


    This is a very simple pixel shader for modifying images using a GLSL shader.

    In this case, the shader changes each pixel’s colour to a greyscale (average) version:

    It’s formed of two parts, the Monkey2 code and the GLSL shader code.

    The file structure should be:

    • the Monkey2 code and an assets folder next to each other;
    • the GLSL file in a shaders folder within assets. (“assets/shaders/basic.glsl”)

    A pre-made zip setup can be downloaded here.



    This code must be placed into assets/shaders/basic.glsl:

    You just create an ImageRenderTarget, using the image and canvas fields like so:

    • canvas to draw to the canvas;
    • image for drawing the resulting shaded image.

    To set/get shader variables, you use the image.Material‘s Set/Get methods, as in the SetInt (“Toggle”, toggle) seen in this example. The Toggle string here relates to the m_Toggle value in the GLSL code (notice that the GLSL variable name is formed from this string, auto-prefixed by mojo with “m_”).

    Thanks to DoctorWhoof (aka. Ethernaut) for the render target code and PixelPaladin for the example GLSL interfacing code.

    Next up, to finally do a workable ZX Spectrum shader on my Island demo (use L to toggle resolution), since I only need to operate on a tiny 256 x 192 image now, which is upscaled to the actual display size… (Done it before but it was far too slow as I was working on the entire display, and the attribute-clash part of the Spectrum shader is very intensive, checking 64 pixels around every single pixel for the most common colour!)



    Updated Island demo with the ImageRenderTarget code from above, now offers simple greyscale for starters. (L to toggle low-res, P to toggle greyscale in low-res mode.)



    Update to Speccy Island!

    Hit L to go Low-res, Spectrum-style, with attribute clash.

    Hit P in low-res mode to toggle real colours. Full-screen it!

    L gets back to normal res/colours.

    Still WIP, but finally got a decent-performing shader that at least outputs legit Spectrum-compatible imagery, needs much tweaking still.

    In theory, you could save a bunch of frames and display them for real on the Spectrum, as-is… which I’ll eventually try.


    Abe _King_

    Which browser are you using? It’s not working on Chrome!

    Failed to compile shader:ERROR: too many uniform



    Working fairly nicely in FireFox!



    Ah, only tried in FF, web not really being my main target, but had to do a few tweaks to get that to work. Get the impression cross-browser shaders are not a lot of fun!



    Hmm, weird, just installed Chrome and it’s working fine here! What platform/gfx card you on?



    Well, 256 x 192 is rather a “challenging” candidate for turning a low-contrast, fairly washed-out, realtime rendered scene into 8 Spectrum colours (each with associated ‘dark’ version) with correct colour-clash, and without sampling every 8×8 block of pixels (a MASSIVE framerate hit since GLSL isn’t meant to read anything other than the ‘current’ pixel), it wasn’t feasible to select a suitable foreground and background colour that avoided constant flickering between the two as the scene changed, so I’ve amended the Spectrum’s display size.

    Here’s how the scene would be rendered if the Spectrum’s display size was 1024 x 768 instead of 256 x 192, but still with correct colours and clash.

    Full-screen it. (Only testing web version in Firefox, apologies.)

    I’ll upload my code once I’m done messing about…



    Also quite cool back in 256 x 192 but with colour clash turned off. (Separate link; again recommend full-screening it. Key L is still available to toggle low-res mode off.)



    Updated and placed code on GitHub.

    WebGL version [Only testing on Firefox!]



    Crude C64 resolution/palette shader. (No attribute clash implemented or planned!)

    C64 Island [WebGL, Firefox-tested only!]

    Will update GitHub probably tomorrow night (GMT) or over the weekend, once I’ve tweaked it more and implemented switching between Speccy and C64 modes…

    Next up will have to be simple Amiga 32 and 256-colour modes, maybe 320 x 200 and/or 640 x 512, and SNES?



    On safari, both don’t work



    It’ll be the shaders needing tweaked, probably… I’m only testing on Firefox just for throwing up quick demos, but my own interest is desktop. As I mentioned, shaders and web browsers seem to be a minefield of misery.

    I don’t think they do Safari for Windows these days, so…



    I’ve just updated this with some cool palette-selection/dither code to loosely represent a few different ‘retro’ systems…

    Try it out at:

    Code at:


    Hit R for retro mode: expect MASSIVE pause here on web, maybe 20-30 seconds or more! Need to somehow get this done during startup…

    Hit [ and ] to cycle through a few cool ‘retro’ modes.

    Hit H to hide text in retro mode.

    Tested in Firefox, Chrome and Vivaldi on Windows 7 64-bit only. Download code from GitHub and build natively if it fails for you!


Viewing 13 posts - 1 through 13 (of 13 total)

You must be logged in to reply to this topic.