[WIP] PSX Shaders

PLEASE DO NOT USE IT FOR NOW.

Shader code
shader_type spatial;
render_mode cull_back, depth_prepass_alpha, diffuse_lambert, specular_disabled, vertex_lighting;

uniform sampler2D albedo_texture : source_color, filter_nearest, repeat_enable;
uniform vec4 tint : source_color = vec4(1.0);
uniform vec2 texture_size = vec2(256.0);
uniform vec2 snap_resolution = vec2(320.0, 240.0);
uniform float affine_strength : hint_range(0.0, 1.0, 0.01) = 1.0;
uniform float color_levels : hint_range(2.0, 32.0, 1.0) = 24.0;
uniform float dither_strength : hint_range(0.0, 1.0, 0.01) = 0.7;
uniform float alpha_cutoff : hint_range(0.0, 1.0, 0.01) = 0.0;

varying vec2 affine_uv;
varying float affine_w;

float bayer2(vec2 p) {
	p = mod(floor(p), 2.0);
	return (p.x + p.y * 2.0) * 0.25;
}

void vertex() {
	vec4 clip = PROJECTION_MATRIX * MODELVIEW_MATRIX * vec4(VERTEX, 1.0);
	float w = max(clip.w, 0.0001);
	vec2 snap = max(snap_resolution, vec2(1.0));

	affine_uv = UV * w;
	affine_w = w;

	vec2 screen = (clip.xy / w) * 0.5 + 0.5;
	screen = floor(screen * snap) / snap;
	clip.xy = (screen * 2.0 - 1.0) * w;
	POSITION = clip;
}

void fragment() {
	vec2 tex_size = max(texture_size, vec2(1.0));
	vec2 uv = mix(UV, affine_uv / affine_w, affine_strength);
	uv = (floor(uv * tex_size) + 0.5) / tex_size;

	vec4 tex = texture(albedo_texture, uv) * tint;
	if (alpha_cutoff > 0.0 && tex.a < alpha_cutoff) discard;

	float levels = max(color_levels, 2.0);
	float dither = (bayer2(FRAGCOORD.xy) - 0.375) * dither_strength;
	ALBEDO = clamp(floor(tex.rgb * (levels - 1.0) + dither + 0.5) / (levels - 1.0), vec3(0.0), vec3(1.0));
	ALPHA = tex.a;
	ROUGHNESS = 1.0;
	SPECULAR = 0.0;
}
Live Preview
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

guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments