PS1/PSX Model

Usage

  1. Add a new ShaderMaterial in the 3D model
  2. In the ShaderMaterial add a new Shader
  3. Copy the script below into the Shader-Editor.

Documentation

  • affine_mapping: Normalizes the vertices if true.
  • albedo: Texture that will be used for this model.
  • alpha scissor: Threshold when the alpha value will be not rendered.
  • jitter: Amount of jitter that will be used. Higher values result in more jitter.
  • resolution: The screen resolution that will be used to apply the jitter

Hint

This shader is written for Godot 4.

Shader code
shader_type spatial;
render_mode blend_mix,
	cull_disabled,
	depth_prepass_alpha,
	shadows_disabled,
	specular_disabled,
	vertex_lighting;

uniform bool affine_mapping = false;
uniform sampler2D albedo : source_color, filter_nearest;
uniform float alpha_scissor : hint_range(0, 1) = 0.5;
uniform float jitter: hint_range(0, 1) = 0.25;
uniform ivec2 resolution = ivec2(320, 240);

vec4 snap_to_position(vec4 base_position)
{
	vec4 snapped_position = base_position;
	snapped_position.xyz = base_position.xyz / base_position.w;
	
	vec2 snap_resulotion = floor(vec2(resolution) * (1.0 - jitter));
	snapped_position.x = floor(snap_resulotion.x * snapped_position.x) / snap_resulotion.x;
	snapped_position.y = floor(snap_resulotion.y * snapped_position.y) / snap_resulotion.y;
	
	snapped_position.xyz *= base_position.w;
	return snapped_position;
}

void vertex()
{
	vec4 snapped_position = snap_to_position(PROJECTION_MATRIX * MODELVIEW_MATRIX * vec4(VERTEX, 1.0));
	if (affine_mapping)
	{
		POSITION = snapped_position;
		POSITION /= abs(POSITION.w);
	}
	else
	{
		POSITION = snapped_position;
	}
}

void fragment()
{
	vec4 color_base = COLOR;
	vec4 texture_color = texture(albedo, UV);

	ALBEDO = (color_base * texture_color).rgb;
	ALPHA = texture_color.a * color_base.a;
	ALPHA_SCISSOR_THRESHOLD = alpha_scissor;
}
Tags
godot4, lowpoly, ps1, psx, retro
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.

More from Grau

PS1/PSX PostProcessing

Aberration Vignette – Phasmophobia effect

Gameboy Look

Related shaders

PS1/PSX PostProcessing

First Person View Model Shader (UPDATED FOR GODOT 4.3+)

First Person View Model Shader

Subscribe
Notify of
guest

6 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Wilker
1 year ago

it’s already written in the description, but here’s another reminder: this shader is intended a primary material as a ShaderMaterial3D resource. place your Albedo as the Shader parameter instead of a StandardMaterial3D with the shader as a second pass.

if you’re having issues with your Albedo flickering white or black, double-check that.

Arcadia
7 months ago

Excellent work, thank you!

emoanaber
emoanaber
5 months ago

can you control the affine mapping because it freaks out a lot more than i want.

trackback

[…] started in Godot 4.2.2) Programming: me 3D modeling, texturing, animation and artwork: me Shaders: PS1/PSX model VHS with wiggle Addons used: Godot Texture […]

trackback

[…] in Godot 4.2.2) Programming: me 3D modeling, texturing, animation and artwork: me Shaders used: PS1/PSX model VHS with wiggle Addons used: Godot Texture Fonts Phantom […]

Akihiro
Akihiro
3 days ago

how to use this with next pass?

i want to set albedo from primary shader material

Last edited 3 days ago by Akihiro