PSX Shader with Vertex Lighting

Shader code
shader_type spatial;
render_mode vertex_lighting, skip_vertex_transform, 
            specular_phong, diffuse_lambert_wrap, shadows_disabled;

uniform vec4 modulate: hint_color = vec4(1,1,1,1);
uniform sampler2D image_texture: hint_albedo;
uniform vec2 uv_scrolling_velocity = vec2(0.0);

const float vertex_snapping_offset = 0.8;


varying float vertex_distance;

void vertex() {
    UV += uv_scrolling_velocity * TIME;

    VERTEX = (MODELVIEW_MATRIX * vec4(VERTEX, 1.0)).xyz;

    float z_origin = VERTEX.z;
    float snap_i = (1.0 - vertex_snapping_offset) * min(VIEWPORT_SIZE.x, VIEWPORT_SIZE.y) / 2.0;

    float projection_w = (PROJECTION_MATRIX * vec4(VERTEX, 1.0)).w;
    VERTEX = round(VERTEX / projection_w * snap_i) / snap_i * projection_w;
    VERTEX = VERTEX;
    
    NORMAL = (MODELVIEW_MATRIX * vec4(NORMAL, 0.0)).xyz;

    vertex_distance = length((WORLD_MATRIX * vec4(VERTEX, 1.0)));

    UV *= VERTEX.z;
}

float get_dither_brightness(vec3 given_color, vec4 fragcoord) {

    int x = int(fragcoord.x) % 4;
    int y = int(fragcoord.y) % 4;
    const vec3 luminance = vec3(0.2126, 0.7152, 0.0722);
    float calculated_brightness = (luminance.r * given_color.r) + (luminance.g * given_color.g) + (luminance.b * given_color.b);


    float thresholdMatrix[16] = float[16] (
        1.0 / 17.0,  9.0 / 17.0,  3.0 / 17.0, 11.0 / 17.0,
        13.0 / 17.0,  5.0 / 17.0, 15.0 / 17.0,  7.0 / 17.0,
        4.0 / 17.0, 12.0 / 17.0,  2.0 / 17.0, 10.0 / 17.0,
        16.0 / 17.0,  8.0 / 17.0, 14.0 / 17.0,  6.0 / 17.0
    );

    float dithering = thresholdMatrix[x * 4 + y];
    
    if ((calculated_brightness - 0.2 < dithering) && (vertex_distance < 60.)) {
        return ((dithering - 0.5) * 0.25) + 1.0;
    } else {
        return 1.;
    }
}

void fragment() {
    vec2 uv = UV / VERTEX.z;

    vec3 texture_rgb = (texture(image_texture, uv).rgb * COLOR.rgb) * modulate.rgb;
    vec4 texture_rgba = vec4(texture_rgb.r, texture_rgb.g, texture_rgb.b, 1.0);

    texture_rgba = texture_rgba * get_dither_brightness(texture_rgba.rgb, FRAGCOORD);
    ALBEDO = texture_rgba.rgb;
    ALPHA = texture(image_texture, uv).a * modulate.a;
    ALPHA_SCISSOR = 0.1;
}
Tags
psx, retro, vertex lighting
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

Ramp Lighting

Noise vertex displacement

global vertex snapping with 3dresolution scaling

Subscribe
Notify of
guest

2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Xeyod
Xeyod
3 months ago

Your shader is amazing, but could you help me with removing the texture afflining?

Xeyod
Xeyod
3 months ago
Reply to  Xeyod

Nevermind I figured it out. Again, thank you for this amazing shader.