BambooBasic Logo


Custom Shaders in BambooBasic

BambooBasic supports custom HLSL (High-Level Shader Language) shaders for advanced visual effects. Shaders are compiled using DirectX 12 Shader Model 5.0 and can be applied to 2D images, text, or the entire screen as post-processing effects.



Shader Types
Type Purpose Apply Function Example Effects
Image Shader Per-draw 2D image effects b2dDrawImageEx() Glow, blur, color tint, distortion
Text Shader Per-draw text effects b2dDrawTextEx() Glow, rainbow colors, sheen animation
Screen Shader Full-screen post-processing b2dApplyScreenShader() CRT effect, bloom, vignette, color grading


HLSL Shader Structure

All BambooBasic shaders are pixel shaders (fragment shaders) that follow this basic structure:

// Shader header comments (recommended)
// Entry point: main
// Type: Pixel Shader (ps_5_0)

// Resources (textures, samplers)
Texture2D myTexture : register(t0);
SamplerState mySampler : register(s0);

// Shader parameters constant buffer
cbuffer ShaderParams : register(bX)
{
    float param0, param1, param2, ..., param63;
};

// Pixel shader input structure
struct PSInput
{
    float4 position : SV_POSITION;
    float2 texCoord : TEXCOORD0;
    // ... additional fields depend on shader type
};

// Main pixel shader entry point
float4 main(PSInput input) : SV_TARGET
{
    // Your shader code here
    float4 color = myTexture.Sample(mySampler, input.texCoord);
    return color;
}

Important: The entry point must be named main or PSMain. Shader Model 5.0 is required (ps_5_0).



Image Shaders (2D)

Image shaders are applied to individual images using b2dDrawImageEx(). They operate on 2D texture data.

Available Resources:

Register Type Description
t0 Texture2D The image being drawn (imageTexture)
s0 SamplerState Texture sampler
b1 cbuffer Shader parameters (param0-param63)

PSInput Structure:

struct PSInput
{
    float4 position : SV_POSITION;  // Screen position
    float2 texCoord : TEXCOORD0;    // UV coordinates (0-1)
    float alpha : TEXCOORD1;        // Image alpha value
};

Example: Image Glow Shader

// ImageGlow.hlsl
Texture2D imageTexture : register(t0);
SamplerState samplerState : register(s0);

cbuffer ShaderParams : register(b1)
{
    float param0, param1, param2, param3, param4, param5, param6, param7;
    // ... param8-param63 ...
    // param0 = glowIntensity (0.0 - 2.0)
};

struct PSInput
{
    float4 position : SV_POSITION;
    float2 texCoord : TEXCOORD0;
    float alpha : TEXCOORD1;
};

float4 main(PSInput input) : SV_TARGET
{
    float glowIntensity = param0;

    // Sample the original image
    float4 color = imageTexture.Sample(samplerState, input.texCoord);

    // Brighten based on intensity
    color.rgb *= (1.0 + glowIntensity);

    // Apply alpha
    color.a *= input.alpha;

    return color;
}

Usage in BambooBasic:

; Load and configure image shader
glowShader = b2dLoadImageShader("ImageGlow.hlsl")
b2dSetImageShaderFloat(glowShader, "0", 1.5)   ; glowIntensity

; Draw image with shader
b2dDrawImageEx(myImage, 100, 100, glowShader)

; Cleanup
b2dFreeImageShader(glowShader)


Text Shaders (2D)

Text shaders are applied to text rendering using b2dDrawTextEx(). They operate on the font atlas texture.

Available Resources:

Register Type Description
t0 Texture2D Font atlas texture (fontTexture)
s0 SamplerState Texture sampler
b1 cbuffer Shader parameters (param0-param63)

PSInput Structure:

struct PSInput
{
    float4 position : SV_POSITION;  // Screen position
    float2 texCoord : TEXCOORD0;    // Font atlas UV coordinates
    float4 color : COLOR0;          // Text color
};

Example: Text Sheen Shader (SEGA-style)

// TextSheen.hlsl
Texture2D fontTexture : register(t0);
SamplerState samplerState : register(s0);

cbuffer ShaderParams : register(b1)
{
    float param0, param1, param2, param3, param4, param5, param6, param7;
    // ... param8-param63 ...
    // param0 = sheenPosition (0.0 - 1.0, position of sheen sweep)
    // param1 = sheenWidth (0.0 - 1.0)
    // param2 = sheenIntensity (0.0 - 2.0)
};

struct PSInput
{
    float4 position : SV_POSITION;
    float2 texCoord : TEXCOORD0;
    float4 color : COLOR0;
};

float4 main(PSInput input) : SV_TARGET
{
    float sheenPosition = param0;
    float sheenWidth = param1;
    float sheenIntensity = param2;

    // Sample font atlas
    float4 texColor = fontTexture.Sample(samplerState, input.texCoord);

    // Start with darker base text
    float4 color = float4(input.color.rgb * 0.6, texColor.a * input.color.a);

    if (texColor.a > 0.1)  // Only apply to visible text
    {
        float normalizedX = input.position.x / 800.0;  // Normalize to screen
        float distanceFromSheen = abs(normalizedX - sheenPosition);

        if (distanceFromSheen < sheenWidth)
        {
            float falloff = 1.0 - (distanceFromSheen / sheenWidth);
            float sheenAmount = smoothstep(0.0, 1.0, falloff) * sheenIntensity;

            // Blue sheen color (bright cyan-blue like SEGA)
            float3 sheenColor = float3(0.5, 0.9, 1.5);

            color.rgb += sheenColor * sheenAmount * texColor.a;
            color.rgb = saturate(color.rgb);
        }
    }

    return color;
}

Usage in BambooBasic:

; Load and configure text shader
sheenShader = b2dLoadTextShader("TextSheen.hlsl")
b2dSetTextShaderFloat(sheenShader, "0", sheenPos)     ; sheenPosition
b2dSetTextShaderFloat(sheenShader, "1", 0.15)         ; sheenWidth
b2dSetTextShaderFloat(sheenShader, "2", 2.5)          ; sheenIntensity

; Draw text with shader
b2dDrawTextEx("BAMBOO", 200, 100, True, font, sheenShader)

; Animate sheen position each frame
sheenPos = sheenPos + 0.01
If sheenPos > 1.2 Then sheenPos = -0.2

; Cleanup
b2dFreeTextShader(sheenShader)


Screen Shaders (Post-Process)

Screen shaders are full-screen post-processing effects applied after all rendering is complete. They process the entire rendered frame.

Available Resources:

Register Type Description
t0 Texture2D The rendered frame (screenTexture)
s0 SamplerState Texture sampler
b0 cbuffer Shader parameters (param0-param63)

Note: Screen shaders use register(b0) instead of b1.

PSInput Structure:

struct PSInput
{
    float4 position : SV_POSITION;  // Screen position
    float2 texcoord : TEXCOORD0;    // Screen UV coordinates (0-1)
};

Example: CRT Effect Shader

// CRT.hlsl
Texture2D screenTexture : register(t0);
SamplerState samplerState : register(s0);

cbuffer ShaderParams : register(b0)
{
    float param0, param1, param2, param3, param4, param5, param6, param7;
    // ... param8-param63 ...
    // param0 = scanlineIntensity (0.0 - 1.0)
    // param1 = scanlineCount (typically screen height)
};

struct PSInput
{
    float4 position : SV_POSITION;
    float2 texcoord : TEXCOORD0;
};

float4 main(PSInput input) : SV_TARGET
{
    float scanlineIntensity = param0;
    float scanlineCount = param1;

    // Sample screen texture
    float4 color = screenTexture.Sample(samplerState, input.texcoord);

    // Apply scanlines
    float scanline = sin(input.texcoord.y * scanlineCount * 3.14159 * 2.0);
    scanline = scanline * 0.5 + 0.5;
    float scanlineFactor = 1.0 - (1.0 - scanline) * scanlineIntensity;

    color.rgb *= scanlineFactor;

    return color;
}

Usage in BambooBasic:

; Load and configure screen shader
crtShader = b2dLoadScreenShader("CRT.hlsl")
b2dSetShaderFloat(crtShader, "0", 0.5)      ; scanlineIntensity
b2dSetShaderFloat(crtShader, "1", 200.0)    ; scanlineCount

; Enable screen shader
b2dApplyScreenShader(crtShader)

; Disable screen shader
b2dSetDefaultScreenShader()

; Cleanup
b2dFreeScreenShader(crtShader)


Parameter System

All shader types support up to 64 float parameters (param0 through param63) that can be set from BambooBasic code.

Declaring Parameters in HLSL:

cbuffer ShaderParams : register(bX)  // b0 for screen, b1 for image/text, b5 for entity
{
    float param0, param1, param2, param3, param4, param5, param6, param7;
    // ... continue to param63 ...

    // Document what each parameter is:
    // param0 = intensity (0.0 - 2.0)
    // param1 = threshold (0.0 - 1.0)
};

Important: Parameters must be declared as individual named fields. Array indexing (params[0]) does not work due to HLSL constant buffer packing rules.

Setting Parameters from BambooBasic:

Function Description
b2dSetImageShaderFloat(shader, "index", value) Set single float (param0-param63)
b2dSetImageShaderFloat2(shader, "index", x, y) Set two consecutive floats
b2dSetImageShaderFloat3(shader, "index", x, y, z) Set three consecutive floats (RGB)
b2dSetImageShaderFloat4(shader, "index", x, y, z, w) Set four consecutive floats (RGBA)
b2dSetImageShaderInt(shader, "index", value) Set integer (stored as float)

Note: The same parameter functions exist for the shader types: b2dSetImageShader*, b2dSetTextShader*, and b2dSetShader* (screen).

Example Parameter Usage:

; Set individual parameters
b2dSetImageShaderFloat(shader, "0", 1.5)         ; param0 = 1.5
b2dSetImageShaderFloat(shader, "1", 0.8)         ; param1 = 0.8

; Set multiple parameters at once
b2dSetImageShaderFloat2(shader, "2", 10.0, 20.0) ; param2=10.0, param3=20.0


Loading and Compiling

Runtime Compilation (.hlsl files):

BambooBasic can compile HLSL shaders at runtime using the DirectX shader compiler:

; Load and compile .hlsl file at runtime
shader = b2dLoadImageShader("MyShader.hlsl")
If shader = 0 Then
    Print "Failed to compile shader!"
    ; Check console for compilation errors
EndIf

Advantages: Easy to edit and test shaders, no external tools needed.
Disadvantages: Slower initial load, requires D3DCompiler DLL.

Pre-compiled Shaders (.cso files):

For better performance, pre-compile shaders using the BambooBasic Shader Compiler tool (Tools menu):

; Load pre-compiled .cso file
shader = b2dLoadImageShader("MyShader.cso")

Advantages: Faster loading, smaller files, no D3DCompiler dependency.
Disadvantages: Requires compilation step, harder to debug.

Shader Compilation Errors:

If a shader fails to compile, error messages are printed to the console output. Common issues:

Tip: Enable console output to see shader compilation errors during development.



Tips and Best Practices

Performance:

Debugging:

Compatibility:



Examples

Complete shader examples can be found in:

Example shaders include:


Back to Documentation Index