Blend Dot Matrix

A raster shader can transform an image into a comic style.
You can add this material to Sprite and ColorRect nodes.
screenshots charater come from: https://ozzbit-games.itch.io/fantasy-character
Description

  1. dot_density: determines how the grid is divided
  2. dot_size: size of a dot within a grid
  3. edge_softness: the smaller the value, the sharper the edge.
  4. brightness_variation: make the dots brighter
  5. brightness_threshold: The threshold value for brightness is determined
  6. blend_mode: determine whether the dot is a solid color
  7. color1 and color2: based on a linear gradient of two colors of grayscale
Shader code
shader_type canvas_item;

// 点阵密度控制
uniform vec2 dot_density = vec2(128.0, 128.0);
// 点的大小(相对于单元格)
uniform float dot_size : hint_range(0.001, 1.0) = 0.4;
// 边缘柔化程度
uniform float edge_softness : hint_range(0.0, 1.0) = 0.1;

// 亮度变化与阈值
uniform float brightness_variation : hint_range(-1.0, 1.0) = 0.0;
uniform float brightness_threshold : hint_range(0.0, 1.0) = 0.01;

// 旋转
uniform float rotation_angle : hint_range(0.0, 6.28318530718) = 0.0;

// 混合模式 - 是否允许圆形内有多种颜色
uniform bool blend_mode = false;

// 渐变色
uniform vec4 color1 : source_color = vec4(0.0, 0.0, 0.0, 1.0);
uniform vec4 color2 : source_color = vec4(1.0, 1.0, 1.0, 1.0);

// 旋转函数 — 使用 vec2 列向量构造 mat2(Godot 要求此形式)
vec2 rotate(vec2 uv, float angle) {
    float s = sin(angle);
    float c = cos(angle);
    // mat2 的列向量构造:mat2(vec2(col0), vec2(col1))
    return mat2(vec2(c, -s), vec2(s, c)) * uv;
}

void fragment() {
    // 居中旋转UV(先平移到中心,旋转,再平移回去)
    vec2 centered_uv = UV - 0.5;
    vec2 rotated_uv = rotate(centered_uv, rotation_angle) + 0.5;

    // 按XY密度分别划分网格
    vec2 grid_uv = rotated_uv * dot_density;
    vec2 cell = floor(grid_uv);
    vec2 cell_uv = fract(grid_uv);

    // 单元格中心
    vec2 cell_center = vec2(0.5);

    // 到中心距离(使用欧几里得距离)
    float dist = distance(cell_uv, cell_center);

    // 根据混合模式采样颜色
    vec4 original_color;
    if (blend_mode) {
        // 在混合模式下使用当前像素的颜色(允许圆内渐变)
        original_color = texture(TEXTURE, UV);
    } else {
        // 使用单元格中心的采样,使整个圆为单一色
        vec2 sample_uv = (cell + vec2(0.5)) / dot_density;
        original_color = texture(TEXTURE, sample_uv);
    }

    // 圆形点抗锯齿 alpha
    float circle_alpha = 1.0 - smoothstep(dot_size - edge_softness, dot_size + edge_softness, dist);

    // 亮度与阈值
    float brightness = (original_color.r + original_color.g + original_color.b) / 3.0;
    if (brightness < brightness_threshold) {
        circle_alpha = 0.0;
    } else {
        brightness = clamp(brightness + brightness * brightness_variation, 0.0, 1.0);
    }

    // 在 color1 和 color2 之间根据亮度混合点颜色
    vec3 dot_color = mix(color1.rgb, color2.rgb, brightness);

    COLOR = vec4(dot_color, circle_alpha * original_color.a);
}
Tags
2d shader, 4.x, canvas_item
The shader code and all code snippets in this post are under CC0 license and can be used freely without the author's permission. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

Related shaders

Dot Matrix Diagonal Reveal Shader

LED/Dot Matrix

Matrix style 3D hologram

guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments