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.
| 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 |
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 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 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 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)
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
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:
ps_5_0)main or PSMain)Tip: Enable console output to see shader compilation errors during development.
Performance:
Debugging:
Compatibility:
ps_5_0)main or PSMainComplete shader examples can be found in:
Example shaders include:
ImageGlow.hlsl - 2D image glow effectTextSheen.hlsl - SEGA-style text animationCRT.hlsl - Retro CRT screen effect with scanlines