PSX Drag-&-Drop Shader
Why:
Hello all! I got tired having to replace the material’s of my meshes everytime I wanted to apply a PSX style shader. Plus I felt there were some options lacking from other PSX style shaders.
So, I made my own that let’s you drag and drop the shader onto a pre-existing Shader Material.
How:
All you have to do is convert the `StandardMaterial3D` on your `MeshInstance3D` into a `ShaderMaterial`, drop/load the `.gdshader` code in, AND VOILÀ! PSX vector-snapping and affine mapping!
Like other PSX Shaders, you can change the amount of `Jitter` the mesh has, and if you want affine mapping or not. But, it comes with many other helpful features as well!
If you notice any bugs, see where improvments can be made, or just want something added, feel free to shout it in the comments!
Also there is a version of the shader with extremely in-depth comments on it, that way anyone who wants to have a deep understanding of what is going on, can! Just let me know if you want it and I can provide it.
Fiending for more?
My digital-wizardry team and I will be dropping a demo for our movement-shooter-esq. game (with deck-building mechanics)! If that interests you, keep up with it through our itch.io’s and related sites: badskulljack, eneme, and (me) brainstinkalex.
P.S.: If you like the creepie-crawlie in the video, let 2nd Lieutenant Digital Wizard eneme know!
Shader code
shader_type spatial;
//IMPORTANT NOTE: SHADOWS ARE DISABLED.
render_mode blend_mix,
depth_draw_opaque,
cull_back,
diffuse_burley,
specular_schlick_ggx,
depth_prepass_alpha,
shadows_disabled,
skip_vertex_transform;
varying float w_comp;
uniform float point_size : hint_range(0,128);
uniform float roughness : hint_range(0,1);
uniform sampler2D texture_metallic : hint_default_white,filter_linear_mipmap,repeat_enable;
uniform vec4 metallic_texture_channel;
uniform sampler2D texture_roughness : hint_roughness_r,filter_linear_mipmap,repeat_enable;
uniform float specular;
uniform float metallic;
uniform sampler2D texture_emission : source_color, hint_default_black,filter_linear_mipmap,repeat_enable;
uniform vec4 emission : source_color;
uniform float emission_energy;
uniform vec3 uv1_scale;
uniform vec3 uv1_offset;
uniform vec3 uv2_scale;
uniform vec3 uv2_offset;
uniform vec4 albedo : source_color;
uniform sampler2D texture_albedo : source_color,filter_linear_mipmap,repeat_enable;
uniform ivec2 resolution = ivec2(320, 240);
uniform bool affine_mapping = true;
uniform float alpha_scissor : hint_range(0, 1) = 0.5;
uniform float jitter: hint_range(0, 1) = 0.25;
void vertex()
{
VERTEX = (MODELVIEW_MATRIX * vec4(VERTEX, 1.0)).xyz;
w_comp = (PROJECTION_MATRIX * vec4(VERTEX, 1.0)).w;
VERTEX /= w_comp;
vec2 grid_to_snap = vec2(resolution) * (1.0 - jitter);
VERTEX.x = floor(VERTEX.x * grid_to_snap.x) / grid_to_snap.x;
VERTEX.y = floor(VERTEX.y * grid_to_snap.y) / grid_to_snap.y;
VERTEX *= w_comp;
if(affine_mapping == true){
UV *= w_comp;
}
//IMPORTANT NOTE: Make sure `NORMAL`s are transformed out of local space aswell.
NORMAL = normalize((MODELVIEW_MATRIX * vec4(NORMAL, 0.0)).xyz);
}
void fragment() {
vec2 base_uv = UV;
if(affine_mapping == true){
base_uv /= w_comp;
}
vec4 color_base = COLOR;
vec4 texture_color = texture(texture_albedo, base_uv);
ALBEDO = albedo.rgb * texture_color.rgb;
ALPHA = texture_color.a * color_base.a;
ALPHA_SCISSOR_THRESHOLD = alpha_scissor;
float metallic_tex = dot(texture(texture_metallic,base_uv),metallic_texture_channel);
METALLIC = metallic_tex * metallic;
vec4 roughness_texture_channel = vec4(1.0,0.0,0.0,0.0);
float roughness_tex = dot(texture(texture_roughness,base_uv),roughness_texture_channel);
ROUGHNESS = roughness_tex * roughness;
SPECULAR = specular;
vec3 emission_tex = texture(texture_emission,base_uv).rgb;
EMISSION = (emission.rgb+emission_tex)*emission_energy;
}
This is super cool, and I managed to rig it up to use ORM maps as all of my assets use them, but I can’t get Godot to automatically add the ORM map to the shader parameters the same way it does with the standalone maps and albedo. Any clues on that?
Let me preface this solution with the fact that I have never used ORMs and to be frank, I don’t fiddle with the materials that are given to me all that much, the 3D Artists will hand me a material and I work with that! So that being said, I believe this will work for you, but toy with it and see if you can make it work better!
SOLUTION:
Okay so when you load in your asset, and you hover over it’s material, it should say “Type: ORMMaterial3D”, right? If so, you can take the
.gdshader
code and add this line to the top where all the class variables are (I will add the line above and below it so that you know where it is at in the shader code):uniform vec4 albedo : source_color;
//ADD LINE BELOW:
uniform sampler2D texture_orm : source_color,filter_linear_mipmap,repeat_enable;
//ADD LINE ABOVE.
uniform sampler2D texture_albedo : source_color,filter_linear_mipmap,repeat_enable;
After doing that, when you convert your
ORMMaterial3D
to aShaderMaterial
, it should have a shader parameter slot already filled with the ORM texture, calledTexture Orm
.Now you can use this
.gdShader
in the future to automatically have a populated ORM Texture. And you can reference this texture in the.gdShader
with the variable nametexture_orm
just like you can with thetexture_albedo
andtexture_emission
and do whatever it is that you need to with it!If you have any other problems, feel free to reach out again!
I was looking through the code and a question popped up in my mind: Does the UV1 and UV2 offset and scale do anything? Point Size seems to do nothing either, or am I just being an idiot?