module CrShader::Docs::B_LANGUAGE_DSL::D_COMPOSITOR_AND_COMPUTE

Overview

Compositor Passes & Compute Shaders

Beyond traditional mesh and surface shaders, CRShader natively supports Godot 4.8's Compositor Effect architecture for post-processing pipelines, as well as general-purpose GLSL compute kernels dispatched via RenderingDevice.

Executive Summary & Key Topics

Topic Method / Anchor Description
Compositor Effect Passes .topic_01_compositor_effects Creating multi-pass post-processing filters with CompositorEffect in Godot 4.
Authoring GLSL Compute Kernels .topic_02_compute_kernels Defining workgroups, buffer bindings, and parallel compute logic.
Transpilation to GLSL & Dispatch via RenderingDevice .topic_03_compilation_and_dispatch Compiling .crshader compute kernels to SPIR-V bytecode and executing via Godot's RenderingDevice.
Compute Shader Particle Simulation .topic_04_compute_particle_simulation Simulating massively parallel GPU particles with std430 storage buffers, attractors, and curl noise.

Related Guides & Source References

Defined in:

docs/b_language_dsl/d_compositor_and_compute.cr

Class Method Summary

Class Method Detail

def self.topic_01_compositor_effects : Nil #

Compositor Effect Passes: Creating multi-pass post-processing filters with CompositorEffect in Godot 4.

Godot 4 introduces CompositorEffect for inserting custom render passes into the engine's 3D rendering pipeline. CRShader provides high-level helpers to bind input color and depth textures, execute a full-screen quad shader, and write the output buffer:

  • Kuwahara painterly edge-preserving filters.
  • CRT phosphor scanlines with barrel distortion.
  • Custom tonemapping and color grading LUTs.
  • Screen-space god rays and volumetric bloom.

Working Examples

# Screen-space CRT filter
shader_type :canvas_item
render_mode :unshaded

uniform scanline_count : float = 240.0
uniform scanline_intensity : float = 0.25

stage :fragment do
  col = texture(TEXTURE, UV).rgb
  scanline = sin(UV.y * scanline_count * TAU) * 0.5 + 0.5
  col -= col * scanline * scanline_intensity
  COLOR = vec4(col, 1.0)
end

def self.topic_02_compute_kernels : Nil #

Authoring GLSL Compute Kernels: Defining workgroups, buffer bindings, and parallel compute logic.

Compute shaders perform massively parallel computations independently of rasterization. Declare workgroup sizes and storage buffers using the :compute target:

shader_type :compute
workgroup_size x: 8, y: 8, z: 1

storage_buffer 0, :particles, layout: :std430 do
  positions : Array(vec4)
  velocities : Array(vec4)
end

stage :compute do
  idx = gl_GlobalInvocationID.x
  positions[idx] += velocities[idx] * delta_time
end

def self.topic_03_compilation_and_dispatch : Nil #

Transpilation to GLSL & Dispatch via RenderingDevice: Compiling .crshader compute kernels to SPIR-V bytecode and executing via Godot's RenderingDevice.

When compiling a compute shader, CRShader generates standard GLSL 450:

crshader build compute_physics.crshader -t glsl -o compute_physics.glsl

In your Crystal or GDScript game logic, load the compiled shader bytecode, create uniform sets, and dispatch the compute list via RenderingDevice:

rd = Godot::RenderingServer.create_local_rendering_device
# Bind buffers, create pipeline, and dispatch workgroups

def self.topic_04_compute_particle_simulation : Nil #

Compute Shader Particle Simulation: Simulating massively parallel GPU particles with std430 storage buffers, attractors, and curl noise.

CRShader provides a Two-Tier Compute Particle Simulation architecture (CrShader::Compute::ParticleSimulationEngine and CrShader::Compute.particle_simulation) along with the particle_simulation / step_particles shader DSL and std/particles physics library (integrate_euler, integrate_verlet, apply_linear_drag, attract_point, vortex_force_3d, wrap_box_3d).

Working Examples

particle_simulation 64 do
  step_particles do |idx, pos, vel, life|
    life = life - sim_params.delta_time
    accel = sim_params.gravity + attract_point(pos, vec3(0.0, 5.0, 0.0), 15.0, 20.0)
    vel = apply_linear_drag(vel + accel * sim_params.delta_time, sim_params.drag, sim_params.delta_time)
    pos = integrate_euler(pos, vel, sim_params.delta_time)
  end
end