โ† All examples

godot shaders

Kuwahara painterly filter

Turn the rendered scene into a painting: for each pixel, four overlapping square regions are compared and the mean colour of the region with the least variance wins, which flattens areas into strokes while keeping edges.

Recorded render of Kuwahara painterly filter

What this component contains

  • ATTRIBUTION.md
  • LICENSE
  • README.md
  • component.json
  • demo.tscn
  • inspect_shader.py
  • material.tres
  • post_kuwahara_painterly.gdshader
  • preview.png
  • test_package.py
  • verification/native.json

How it works

Shader type
spatial
Render modes
unshaded, cull_disabled, depth_test_disabled, depth_draw_never, skip_vertex_transform, fog_disabled
Parameters
screen_texture (sampler2D), radius (int = 4), sample_spacing (float = 1), saturation (float = 1.2)
Use it on
A MeshInstance3D with a 2 x 2 QuadMesh, `material.tres` as its material override and a large extra cull margin, as in `demo.tscn`.
Result
The scene smoothed into flat painterly patches with crisp boundaries between objects.
Renderers
compatibility: compiled and rendered, forward plus: not verified, mobile: not verified
Placement
res://baltor/godot_shaders/post_kuwahara_painterly/

Recorded checks

godot 4.7.2.stable.official.ed1daf0bf

  • contract_static
  • engine_run
  • engine_log_clean
  • shader_in_scene
  • capture_written
  • render_not_uniform
  • shader_changes_pixels

Limits to consider

Cost is (2r + 1) squared samples per pixel: radius 4 reads 81 samples, radius 8 reads 289, which is heavy at high resolution. Square regions produce blocky artefacts at large radii (anisotropic variants avoid them). The pass reads Godot's screen texture after opaque geometry, so transparent objects drawn after it are not processed and its order among other transparent passes is not controlled.