Last active
July 12, 2024 14:00
-
-
Save PixHammer/b3b29dfd5f25a1378f0f814e9ce5772f to your computer and use it in GitHub Desktop.
Local Y Space Billboard Shader - Godot 4.2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// By default Godot does not include a local y space billboard option within the StandardMaterial3D, and only includes a world up. | |
// This is annoying, as for a lot of effects you need the billboard to align with an axis that isn't world up. | |
// For example bullet tracers, or muzzle flashes shown from the side, or grass aligned with a slopes normal. | |
// This shader adds this feature. | |
// To use it, simply add this as the shader on a quad's material. | |
shader_type spatial; | |
render_mode blend_mix,depth_draw_opaque,cull_back,unshaded; | |
uniform vec4 albedo : source_color; | |
uniform sampler2D texture_albedo : source_color,filter_linear_mipmap,repeat_enable; | |
uniform float point_size : hint_range(0,128); | |
// you can just steal this vertex code if you want to inject this behaviour into another shader of your own | |
void vertex() { | |
// direction from mesh to camera (world space) | |
// we use this instead of view direction, as view direction is wrong lol | |
vec3 direction_to_camera = INV_VIEW_MATRIX[3].xyz - MODEL_MATRIX[3].xyz; | |
// model matrix [1] = direction of local y axis in world space | |
vec3 local_x = MODEL_MATRIX[0].xyz; | |
vec3 local_y = MODEL_MATRIX[1].xyz; | |
vec3 local_z = MODEL_MATRIX[2].xyz; | |
//use cross products to find world space axis for the billboard | |
// local_y cross direction_to_camera = right | |
vec3 billboard_x = normalize(cross(local_y, direction_to_camera)); | |
// billboard_x cross local_y = forward | |
vec3 billboard_z = normalize(cross(billboard_x, local_y)); | |
// override the model view matrix, this mat4 shenanigan is setting the X, Y, and Z axis of the matrix, to the axis we just made (keeping local y) | |
MODELVIEW_MATRIX = VIEW_MATRIX * mat4(vec4(billboard_x * length(local_x), 0.0), vec4(local_y, 0.0), vec4(billboard_z * length(local_z), 0.0), MODEL_MATRIX[3]); | |
// and then remmake the normal matrix | |
MODELVIEW_NORMAL_MATRIX = mat3(MODELVIEW_MATRIX); | |
} | |
void fragment() { | |
vec4 albedo_tex = texture(texture_albedo,UV); | |
ALBEDO = albedo.rgb * albedo_tex.rgb; | |
ALPHA *= albedo.a * albedo_tex.a; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment