• 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 Shader using multiple textures

Wingnut

Well-known member
3rd Party Module Dev
Tutorial Author
Joined
Jan 2, 2020
Messages
1,414
This shader will read the red channel from one texture and use that as the index to pick from a palette, which is the second texture. Red being read as 0-255 and used as the x coordinate on the top pixel row of the texture called palette. So this is a an alternate way to convert lots more without any conditionals.
It's also a great beginning for starting to write your own shaders.

GLSL is just a simple language like good ole BASIC. You need to re-think how to code in parallal though and the way to do that is to think about one pixel at a time. You write your program for ONE pixel. You can read and write textures and there's plenty of limitations of course, but even more freedom, just use your imagination.


I create a definition for pixel position at the top, sometimes you want pixels and sometimes you want normalized, so take your pick.

Hope this will get you started!

shader.glsl
Code:
uniform sampler2D ColorTexture; // source
uniform sampler2D ColorTexture2; // palette
uniform sampler2D ColorTexture3; // target

void shader(){
  
    // Get coordinate
    vec2 uv=(b3d_ClipPosition.st/b3d_ClipPosition.w)*0.5+0.5 ;    // Location as normal (0.0 - 1.0)
    vec2 p = vec2(floor(uv.x*256.0),floor(uv.y*256.0)) ;        // Location as pixel

    // Palette
    vec2 location;
    float paletteIndex = texture2D(ColorTexture, uv).r; // Read red 0-255 of sprite
    location.x = paletteIndex;    // x coord. And index that to the x position 0-255 of a texture with a width of 256 pixels
    location.y = 0.0;            // y coord. We use only top line of the palette texture
     vec4 fragColor = texture2D(ColorTexture2, location);

    // Make sure there is only one fragColor assignment in the shader
     // fragColor = texture2D(ColorTexture, uv);        // Simple texture 1 (sprite)
    // fragColor = texture2D(ColorTexture2, uv);    // Simple texture 2 (palette)

    b3d_FragColor = fragColor ;
// -------------------------------------------------------------------------------------------------
}

shader.cxs
Cerberus:
Import mojo2
Function Main()
    New MyApp
End

Class MyApp Extends App

    Field sourceImage : Image
    Field palette:Image
    Field targetImage : Image
    Field canvas : Canvas
    Field effect : ShaderEffect
    Field value : Float
    Field r:Floar, g:Float, b:Float,a:float
    
    Method OnCreate()
        sourceImage = Image.Load("sprite.png",0,0,0) ' Sprite of any size that will use red 0-255 as index to palette
        palette = Image.Load("palette.png",0,0,0) ' 256 x ? texture containing the presets
        targetImage = New Image(sourceImage.Width,sourceImage.Height)
        effect = New ShaderEffect
        canvas = New Canvas
          SetUpdateRate 0
    End
  
    Method OnRender()
        canvas.Clear 0, 0.5, 1, 1 
        effect.SetValue value
        value = value + 0.01       
        effect.Render sourceImage, palette,targetImage
        canvas.DrawRect 0,0, 256*1,256*1,targetImage,0,0,512,512
        canvas.Flush
    End

End

Class myShader Extends Shader

    Method New()
        Build(LoadString("shader.glsl"))
    End 
  
    Method OnInitMaterial:Void(material:Material)
        material.SetTexture "ColorTexture",Texture.White()
        material.SetTexture "ColorTexture2",Texture.White()
        'material.SetScalar "color_r",1
        'material.SetScalar "color_g",1
        'material.SetScalar "color_b",1
        'material.SetScalar "color_a",1
    End
  
    Function Instance:myShader()
        If Not _instance _instance=New myShader
        Return _instance
    End
  
    Private
    Global _instance:myShader
End

Class ShaderEffect

    Private
    Global _canvas:Canvas
    Field _material:Material
      
    Method New()
        If Not _canvas _canvas=New Canvas
        _material=New Material( myShader.Instance() )
    End
  
    Method SetValue:Void( value:Float )
    End
  
    Method Render:Void(source:Image,source2:Image,target:Image)
        _material.SetTexture "ColorTexture",source.Material.ColorTexture
        _material.SetTexture "ColorTexture2",source2.Material.ColorTexture ' ?
        _material.SetTexture "ColorTexture3",target.Material.ColorTexture ' ?
        _canvas.Clear 0, 0, 0, 0
        _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
 

Attachments

  • ShaderBase.zip
    19.4 KB · Views: 70
Back
Top Bottom