• Dear Cerberus X User!

    As we prepare to transition the forum ownership from Mike to Phil (TripleHead GmbH), we need your explicit consent to transfer your user data in accordance with our amended Terms and Rules in order to be compliant with data protection laws.

    Important: If you accept the amended Terms and Rules, you agree to the transfer of your user data to the future forum owner!

    Please read the new Terms and Rules below, check the box to agree, and click "Accept" to continue enjoying your Cerberus X Forum experience. The deadline for consent is April 5, 2024.

    Do not accept the amended Terms and Rules if you do not wish your personal data to be transferred to the future forum owner!

    Accepting ensures:

    - Continued access to your account with a short break for the actual transfer.

    - Retention of your data under the same terms.

    Without consent:

    - You don't have further access to your forum user account.

    - Your account and personal data will be deleted after April 5, 2024.

    - Public posts remain, but usernames indicating real identity will be anonymized. If you disagree with a fictitious name you have the option to contact us so we can find a name that is acceptable to you.

    We hope to keep you in our community and see you on the forum soon!

    All the best

    Your Cerberus X Team

Snippet 8Bit Color Replacer

GTR

Member
Tutorial Author
Joined
Sep 23, 2020
Messages
13
Hello, this time i will share another nice shader , if you want use old console or computer palette try this shader;

Credit: Based on shader from Coldberg NESIFY;
https://www.shadertoy.com/view/MdfXDH

Brigthness is set by default to 1.0, pixelsize(dither) set to 0.005;
Live example here use num_keys to change fx, key_num0 is reset fx;
Image from www freewallpaper, sfx from abandonware

http://gigatron3k.free.fr/html5/CX/8bitcolors/CerberusGame.html

Pics : no fx Cpc-464 C-64 and so on
1601129199741.png
1601129268673.png
1601129341501.png

Include palettes :
TWOBGS ,
BW
EGA
CPC
CGA
GAMEBOY
TELETEXT
VIC-20
C-64

I am now reading documentation so the source code is documented a bit;

8bitcolors.cxs file :

Cerberus:
' Cerberus X - 8Bit console color replacer
'
' V1.0 GTR 2020
' Brightness and pixel dither is set by default lazy :)
'


Strict

Import mojo2

'Our custom shader
Class ConsoleShader Extends Shader

    Private
    Global _instance:ConsoleShader

    Method New()
        Build(LoadString("8bitcolors.glsl"))
    End

    ' this method must be implemented as it sets valid/default material parameters
    ' When texture is used in shader this code is needed , when not used easy way is used !
    ' see Cerberus shader conversion tutorial
    '
    Method OnInitMaterial:Void( myMaterial:Material )
       'store uniforms to material include texture image Sampler2D
        myMaterial.SetTexture("Texture",Texture.White())
        
          myMaterial.SetScalar("nofx",1.0)
         myMaterial.SetScalar("pixelsize",0.005)
        myMaterial.SetScalar("BRIGHTNESS",1.0)
        myMaterial.SetScalar("TWOBGS",1.0)
        myMaterial.SetScalar("BW",0.0)
        myMaterial.SetScalar("EGA",0.0)
        myMaterial.SetScalar("CPC",0.0)
        myMaterial.SetScalar("CGA",0.0)
        myMaterial.SetScalar("GAMEBOY",0.0)
        myMaterial.SetScalar("TELETEXT",0.0)
        myMaterial.SetScalar("VIC20",0.0)
        myMaterial.SetScalar("C64",0.0)
      
      
    End
  
    Function Instance:ConsoleShader()
        If Not _instance _instance = New ConsoleShader()
        Return _instance
    End
      
End


Class ConsoleEffect

    Private
    Global _canvas:Canvas
    Field _material:Material 
  
    Method New()

        ' ensure there is a single instance of the canvas
        If Not _canvas _canvas = New Canvas()
        _material = New Material(ConsoleShader.Instance())
    End

    Method SetNofx:Void( value:Float )
          _material.SetScalar("nofx", value)
    End

    Method SetPixSize:Void( value:Float )
          _material.SetScalar("pixelsize", value)
    End
    Method SetBrightness:Void( value:Float )
          _material.SetScalar("BRIGHTNESS", value)
    End
  
    Method SetTwoBgs:Void( value:Float )
          _material.SetScalar("TWOBGS", value)
    End
    Method SetBw:Void( value:Float )
          _material.SetScalar("BW", value)
    End
    Method SetEga:Void( value:Float )
          _material.SetScalar("EGA", value)
    End
    Method SetCpc:Void( value:Float )
          _material.SetScalar("CPC", value)
    End
    Method SetCga:Void( value:Float )
          _material.SetScalar("CGA", value)
    End
  
    Method SetGameBoy:Void( value:Float )
          _material.SetScalar("GAMEBOY", value)
    End
    Method SetTeletext:Void( value:Float )
          _material.SetScalar("TELETEXT", value)
    End
    Method SetVic20:Void( value:Float )
          _material.SetScalar("VIC20", value)
    End
    Method SetC64:Void( value:Float )
          _material.SetScalar("C64", value)
    End
      
    Method Render:Void(source:Image, target:Image )
  
        _material.SetTexture("Texture", source.Material.ColorTexture)
        _canvas.SetRenderTarget(target)
        _canvas.SetViewport(0, 0, target.Width(), target.Height())
        _canvas.SetProjection2d(0, target.Width(), 0, target.Height())
        _canvas.DrawRect(0, 0, target.Width(), target.Height(), _material)
        _canvas.Flush()
    End
  
End

Class MyApp Extends App

    Field sourceImage:Image
    Field targetImage:Image
    Field myCanvas:Canvas
    Field effect:ConsoleEffect   ' call methods and all function inside like effect.SetNoFx etc
  
    ' uniform float to write in shader parameters
    '
    Field nofx:Float = 1.0       ' no fx orignal image
    Field pixsize:Float = 0.005  ' fake dithering default value
    Field brigtness:Float = 1.0  ' default brigthness
      
    Field twobgs:Float = 0.0
    Field bw:Float = 0.0
    Field ega:Float = 0.0
    Field cpc:Float = 0.0
    Field cga:Float = 0.0
    Field gameboy:Float = 0.0
    Field teletext:Float = 0.0   
    Field vic20:Float = 0.0
    Field c64:Float = 0.0
  
   ' Field sfx:Sound
  
    Method OnCreate:Int()
     '   sfx = LoadSound("ast.mp3")           ' sound or sfx
        sourceImage = Image.Load("fwp.jpg")  ' Image: free wallpaper from www   your logo here ;
        targetImage = New Image(800, 600)    ' image size
        effect = New ConsoleEffect()         ' effect.method()
        myCanvas = New Canvas()              ' canvas
     '   PlaySound(sfx,1,1)                   ' play sfx
        Return 0                             ' return something 0 = ok;
    End
  
    ' reset all fx here
    Method ResetFx:Int()
            nofx    = 0.0
            twobgs  = 0.0
            bw      = 0.0
            ega     = 0.0
            cpc     = 0.0
            cga     = 0.0
            gameboy = 0.0
            teletext= 0.0
            vic20   = 0.0
            c64     = 0.0
      
         Return 0
      
    End
  
    Method OnUpdate:Int()
      
        ' infinite timer unused here this shader is not animated
        ' timer =   Millisecs()/1000.0
              
      
        If KeyHit( KEY_NUM1 )
            ResetFx()
            bw   = 1.0
          
        Endif
        If KeyHit( KEY_NUM2 )
            ResetFx()
            twobgs  = 1.0
        Endif
        If KeyHit( KEY_NUM3 )
            ResetFx()
            ega     = 1.0
        Endif
        If KeyHit( KEY_NUM4 )
            ResetFx()
            cpc     = 1.0
        Endif
        If KeyHit( KEY_NUM5 )
            ResetFx()
            cga     = 1.0
        Endif
        If KeyHit( KEY_NUM6 )
            ResetFx()
            gameboy = 1.0
        Endif
        If KeyHit( KEY_NUM7 )
            ResetFx()
            teletext  = 1.0
        Endif
        If KeyHit( KEY_NUM8 )
            ResetFx()
            vic20   = 1.0
        Endif
        If KeyHit( KEY_NUM9 )
            ResetFx()
            c64     = 1.0
        Endif
      
      
      
        If KeyHit( KEY_NUM0 )
            ResetFx()
            nofx = 1.0
        Endif 
      
              
        Return 0
    End
  
  
    Method OnRender:Int()
        ' call method inside ConsoleEffect to write uniforms params all are float SetScalar used,
        ' vector not used here but in future like color vec3/4 or position x,y vec2;
        '
        effect.SetNofx(nofx)
        effect.SetPixSize(pixsize)
        effect.SetBrightness(brigtness)
      
        effect.SetTwoBgs(twobgs)
        effect.SetBw(bw)
        effect.SetGameBoy(gameboy)
        effect.SetEga(ega)
        effect.SetCpc(cpc)
        effect.SetCga(cga)
        effect.SetTeletext(teletext)
        effect.SetVic20(vic20)
        effect.SetC64(c64)
        ' use default canvas color , use red color after for text
        myCanvas.SetColor(1.0,1.0,1.0)
        effect.Render(sourceImage, targetImage)
        myCanvas.Clear()
        myCanvas.DrawImage(targetImage, 320, 240, 0, 0.7, 0.7)
        myCanvas.SetColor(1.0,1.0,1.0) ' red color for text
        myCanvas.DrawText("8Bit Color Replacer V1.0" , DeviceWidth()/2+40,460, 1.0)
        myCanvas.DrawText("KEYS : 0/1/2/3/4/5/7/8/9" , DeviceWidth()/2+80,10, 2.0)
      
        If bw      = 1.0 myCanvas.DrawText("Black & White" , DeviceWidth()/2-220,460, 1.0)
        If twobgs  = 1.0 myCanvas.DrawText("Two Bgs" ,       DeviceWidth()/2-220,460, 1.0)
        If gameboy = 1.0 myCanvas.DrawText("GameBoy" ,       DeviceWidth()/2-220,460, 1.0)
        If ega     = 1.0 myCanvas.DrawText("EGA" ,           DeviceWidth()/2-220,460, 1.0)
        If cga     = 1.0 myCanvas.DrawText("CGA" ,           DeviceWidth()/2-220,460, 1.0)
        If cpc     = 1.0 myCanvas.DrawText("CPC-464" ,       DeviceWidth()/2-220,460, 1.0)
        If teletext= 1.0 myCanvas.DrawText("Teletext" ,      DeviceWidth()/2-220,460, 1.0)
        If vic20   = 1.0 myCanvas.DrawText("Vic-20" ,        DeviceWidth()/2-220,460, 1.0)
        If c64     = 1.0 myCanvas.DrawText("C-64" ,          DeviceWidth()/2-220,460, 1.0)
      
        myCanvas.Flush()
        Return 0
    End
  
End


Function Main:Int()
    New MyApp()
    Return 0
End

8bitcolors.data drawer contain 8bitcolors.glsl ;

Cerberus:
#ifdef GL_ES
precision mediump float;
#endif

uniform sampler2D Texture;

//uniform float timer;
uniform float nofx;
uniform float pixelsize;
uniform float BRIGHTNESS;
uniform float TWOBGS;
uniform float BW;
uniform float EGA;
uniform float CPC;
uniform float CGA;
uniform float GAMEBOY;
uniform float TELETEXT;
uniform float VIC20;
uniform float C64;


vec3 find_closest (in vec3 ref) { 
    vec3 old = vec3 (100.0*255.0,100.0*255.0,100.0*255.0);     
    #define TRY_COLOR(new) old = mix (new, old, step (length (old-ref), length (new-ref))); 

    if(TWOBGS==1.0){
    TRY_COLOR (vec3 (000.0, 000.0, 000.0));
    TRY_COLOR (vec3 (103.0, 103.0, 103.0));
    TRY_COLOR (vec3 (184.0, 184.0, 184.0)); 
    TRY_COLOR (vec3 (255.0, 255.0, 255.0)); 
    }
  
    if(BW==1.0){
    TRY_COLOR (vec3 (000.0, 000.0, 000.0));
    TRY_COLOR (vec3 (255.0, 255.0, 255.0)); 
    }
      
    if(TELETEXT==1.0){
    TRY_COLOR (vec3 (000.0, 000.0, 000.0));
    TRY_COLOR (vec3 (255.0, 000.0, 000.0));
    TRY_COLOR (vec3 (000.0, 255.0, 000.0));
    TRY_COLOR (vec3 (000.0, 000.0, 255.0));
    TRY_COLOR (vec3 (000.0, 255.0, 255.0));
    TRY_COLOR (vec3 (255.0, 000.0, 255.0));
    TRY_COLOR (vec3 (255.0, 255.0, 000.0));
    TRY_COLOR (vec3 (255.0, 255.0, 255.0)); 
    }
      
    if(GAMEBOY==1.0){
    TRY_COLOR (vec3 (156.0, 189.0, 015.0));
    TRY_COLOR (vec3 (140.0, 173.0, 015.0));
    TRY_COLOR (vec3 (048.0, 098.0, 048.0));
    TRY_COLOR (vec3 (000.0, 000.0, 000.0)); // (015.0, 056.0, 015.0));
    }
  
    if(EGA==1.0){
    TRY_COLOR (vec3 (000.0,000.0,000.0));
    TRY_COLOR (vec3 (255.0,255.0,255.0));
    TRY_COLOR (vec3 (255.0,  0.0,  0.0));
    TRY_COLOR (vec3 (  0.0,255.0,  0.0));
    TRY_COLOR (vec3 (  0.0,  0.0,255.0));
    TRY_COLOR (vec3 (255.0,255.0,  0.0));
    TRY_COLOR (vec3  (  0.0,255.0,255.0));
    TRY_COLOR (vec3 (255.0,  0.0,255.0));
    TRY_COLOR (vec3 (128.0,  0.0,  0.0));
    TRY_COLOR (vec3 (  0.0,128.0,  0.0));
    TRY_COLOR (vec3 (  0.0,  0.0,128.0));
    TRY_COLOR (vec3 (128.0,128.0,  0.0));
    TRY_COLOR (vec3 (  0.0,128.0,128.0));
    TRY_COLOR (vec3 (128.0,  0.0,128.0));
    TRY_COLOR (vec3 (128.0,128.0,128.0));
    TRY_COLOR (vec3 (255.0,128.0,128.0));
    }
  
    if(CGA==1.0){
    TRY_COLOR (vec3 (000.0,000.0,000.0));
    TRY_COLOR (vec3 (000.0,170.0,170.0));
    TRY_COLOR (vec3 (170.0,000.0,170.0));
    TRY_COLOR (vec3 (170.0,170.0,170.0));
    }
  
    if(CPC==1.0){
    TRY_COLOR ( vec3(000.0,000.0,000.0));
    TRY_COLOR ( vec3(000.0,000.0,128.0));
    TRY_COLOR ( vec3(000.0,000.0,255.0));
    TRY_COLOR ( vec3(128.0,000.0,000.0));
    TRY_COLOR ( vec3(128.0,000.0,128.0));
    TRY_COLOR ( vec3(128.0,000.0,255.0));
    TRY_COLOR ( vec3(255.0,000.0,000.0));
    TRY_COLOR ( vec3(255.0,000.0,128.0));
    TRY_COLOR ( vec3(255.0,000.0,255.0));
    TRY_COLOR ( vec3(000.0,128.0,000.0));
    TRY_COLOR ( vec3(000.0,128.0,128.0));
    TRY_COLOR ( vec3(000.0,128.0,255.0));
    TRY_COLOR ( vec3(128.0,128.0,000.0));
    TRY_COLOR ( vec3(128.0,128.0,128.0));
    TRY_COLOR ( vec3(128.0,128.0,255.0));
    TRY_COLOR ( vec3(255.0,128.0,000.0));
    TRY_COLOR ( vec3(255.0,128.0,128.0));
    TRY_COLOR ( vec3(255.0,128.0,255.0));
    TRY_COLOR ( vec3(000.0,255.0,000.0));
    TRY_COLOR ( vec3(000.0,255.0,128.0));
    TRY_COLOR ( vec3(000.0,255.0,255.0));
    TRY_COLOR ( vec3(128.0,255.0,000.0));
    TRY_COLOR ( vec3(128.0,255.0,128.0));
    TRY_COLOR ( vec3(128.0,255.0,255.0));
    TRY_COLOR ( vec3(255.0,255.0,000.0));
    TRY_COLOR ( vec3(255.0,255.0,128.0));
    TRY_COLOR ( vec3(255.0,255.0,255.0));
    }
  
    if(VIC20==1.0){
    TRY_COLOR (vec3(000.0,000.0,000.0));
    TRY_COLOR (vec3(255.0,255.0,255.0));
    TRY_COLOR (vec3(168.0,115.0,074.0));
    TRY_COLOR (vec3(233.0,178.0,135.0));
    TRY_COLOR (vec3(119.0,045.0,038.0));
    TRY_COLOR (vec3(182.0,104.0,098.0));
    TRY_COLOR (vec3(133.0,212.0,220.0));
    TRY_COLOR (vec3(197.0,255.0,255.0));
    TRY_COLOR (vec3(168.0,095.0,180.0));
    TRY_COLOR (vec3(233.0,157.0,245.0));
    TRY_COLOR (vec3(085.0,158.0,074.0));
    TRY_COLOR (vec3(146.0,223.0,135.0));
    TRY_COLOR (vec3(066.0,052.0,139.0));
    TRY_COLOR (vec3(126.0,112.0,202.0));
    TRY_COLOR (vec3(189.0,204.0,113.0));
    TRY_COLOR (vec3(255.0,255.0,176.0));
    }
    if(C64==1.0){
    TRY_COLOR (vec3(0.0, 0.0,0.0));
    TRY_COLOR (vec3(098.0,098.0,098.0));
    TRY_COLOR (vec3(137.0,137.0,137.0));
    TRY_COLOR (vec3(173.0,173.0,173.0));
    TRY_COLOR (vec3(255.0,255.0,255.0));
    TRY_COLOR (vec3(159.0,078.0,068.0));
    TRY_COLOR (vec3(203.0,126.0,117.0));
    TRY_COLOR (vec3(109.0,084.0,018.0));
    TRY_COLOR (vec3(161.0,104.0,060.0));
    TRY_COLOR (vec3(201.0,212.0,135.0));
    TRY_COLOR (vec3(154.0,226.0,155.0));
    TRY_COLOR (vec3(092.0,171.0,094.0));
    TRY_COLOR (vec3(106.0,191.0,198.0));
    TRY_COLOR (vec3(136.0,126.0,203.0));
    TRY_COLOR (vec3(080.0,069.0,155.0));
    TRY_COLOR (vec3(160.0,087.0,163.0));
    }
  
  
  
    return old ;
}




vec3 dither (vec3 color, vec2 uv) { 
    color *= 255.0 * BRIGHTNESS; 
  
    color = find_closest (clamp (color, 0.0, 255.0));
    return color / 255.0;
}


void shader(){

    //convert clip position to valid tex coords

     //vec2 uv = (b3d_ClipPosition.st/b3d_ClipPosition.w)*0.5+0.5;
     vec2 uv = b3d_Texcoord0  ;
  
     uv = uv - mod(uv, pixelsize); // pixelsize 0.005
    
     vec3 tc = texture2D(Texture,uv).xyz;
  
     if(nofx==1.0)
         b3d_FragColor =  vec4 (tc,1.0);
     else   
      
     b3d_FragColor =  vec4 (dither (tc, uv.xy),1.0);     
    
  
}

Don't forget you need texture like image.png or jpeg like descripted in the source code;
If you need help feel free to contact me;

Regards
 
Last edited:
Back
Top Bottom