Premier commit
This commit is contained in:
@@ -0,0 +1,169 @@
|
||||
// Shader stolen here : https://godotshaders.com/shader/vertex-animation-texture-uses-openvat-output/
|
||||
shader_type spatial;
|
||||
render_mode cull_disabled; // Prevents GPU hardware culling so shader can handle it
|
||||
/*
|
||||
For use with models exported from Blender using the OpenVAT plugin.
|
||||
Expects:
|
||||
Vertex Normals - Packed (Math gets too complex to include a toggle. Making a separate shader recommended if normals are not needed.)
|
||||
Use Single Row - On
|
||||
Export Model - On
|
||||
Model Format - glTF Binary. (Unsure why the otherse do not work)
|
||||
|
||||
Ensure .exr file is set to Lossless compression and MipMaps - Off.
|
||||
*/
|
||||
|
||||
// --- Uniforms ---
|
||||
group_uniforms openVAT_inputs;
|
||||
/** OpenVAT texture exported from Blender plugin. */
|
||||
uniform sampler2D vertex_animation_texture : repeat_disable;
|
||||
/** Min values from the .json file included with OpenVAT exports. */
|
||||
uniform vec3 min_bounds;
|
||||
/** Max values from the .json file included with OpenVAT exports. */
|
||||
uniform vec3 max_bounds;
|
||||
/** Plays animation automatically. Turn off to control manually via keyframes. */
|
||||
uniform bool autoplay = true;
|
||||
/**
|
||||
Autoplay speed in frames per second. Defaults to 30.
|
||||
[b]Blender default is 24. May require adjustment either in Blender or Here to match speed.[b]
|
||||
*/
|
||||
uniform float autoplay_speed = 30.0;
|
||||
/** Frame to display if animating manually. */
|
||||
uniform float frame = 1.0;
|
||||
|
||||
/** Enable this if the asset does not have 2 UV sets. */
|
||||
uniform bool use_uv_1 = false;
|
||||
/** Cull Mode, editable here for flexibility.
|
||||
0: Backface Cull
|
||||
1: Frontface Cull
|
||||
2: Cull disabled (double sided rendering)*/
|
||||
uniform int cull_mode : hint_enum("Back:0", "Front:1", "Disabled:2") = 0;
|
||||
group_uniforms;
|
||||
|
||||
group_uniforms Albedo_map;
|
||||
uniform sampler2D albedo_map : source_color, hint_default_white;
|
||||
uniform vec4 albedo_tint : source_color = vec4(1.0);
|
||||
group_uniforms;
|
||||
|
||||
group_uniforms ORM_inputs;
|
||||
/**
|
||||
[b]ORM texture.[/b] Standardized detail maps for PBR materials. Ignore, remap, or remove as needed.
|
||||
[b]O[/b]cclusion (Ambient)
|
||||
[b]R[/b]oughness
|
||||
[b]M[/b]etallic
|
||||
*/
|
||||
uniform sampler2D orm_map : hint_default_white;
|
||||
/** Select channel used by Occlusion map. R G [b]or[/b] B, combining will have strange results */
|
||||
uniform vec4 occlusion_channel : source_color = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
/** Strength of Occlusion*/
|
||||
uniform float occlusion : hint_range(0.0, 1.0) = 1.0;
|
||||
/** Select channel used by Roughness map. R G [b]or[/b] B, combining will have strange results */
|
||||
uniform vec4 roughness_channel : source_color = vec4(0.0, 1.0, 0.0, 1.0);
|
||||
/** Strength of Roughness*/
|
||||
uniform float roughness : hint_range(0.0, 1.0) = 1.0;
|
||||
/** Select channel used by Metallic map. R G [b]or[/b] B, combining will have strange results */
|
||||
uniform vec4 metallic_channel : source_color = vec4(0.0, 0.0, 1.0, 1.0);
|
||||
/** Strength of Metallic*/
|
||||
uniform float metallic : hint_range(0.0, 1.0) = 1.0;
|
||||
/** Strength of Specular (No Map Included)*/
|
||||
uniform float specular : hint_range(0.0, 1.0) = 0.5;
|
||||
group_uniforms;
|
||||
|
||||
group_uniforms Normal_map;
|
||||
uniform sampler2D normal_map : hint_roughness_normal;
|
||||
uniform float normal_map_scale : hint_range(-10.0, 10.0) = 1.0;
|
||||
|
||||
/** Passed data from INSTANCE_CUSTOM_VARIABLE :
|
||||
x : Unique Id
|
||||
y : Damage effect
|
||||
z : Size
|
||||
**/
|
||||
|
||||
varying flat float unique_id;
|
||||
varying flat float damage_effect;
|
||||
varying flat float size;
|
||||
|
||||
float remapFloat(float value, float input_min, float input_max, float output_min, float output_max){
|
||||
// Code to replicate the remap feature from Visual Shader.
|
||||
float _input_range = input_max - input_min;
|
||||
float _output_range = output_max - output_min;
|
||||
return output_min + _output_range * ((value - input_min) / _input_range);
|
||||
}
|
||||
|
||||
void vertex() {
|
||||
unique_id = INSTANCE_CUSTOM.x;
|
||||
damage_effect = INSTANCE_CUSTOM.y;
|
||||
size = INSTANCE_CUSTOM.z;
|
||||
|
||||
// Animation Timing
|
||||
// ------
|
||||
// Divided by 2. since bottom half of texture is the normal data.
|
||||
// Second argument (0) is MipMap level. These VATs use no mipmaps so always 0.
|
||||
int total_frames = textureSize(vertex_animation_texture, 0).y / 2;
|
||||
// Checks if Autoplaying is checked
|
||||
float play_frame = autoplay ? (TIME * autoplay_speed / size) : frame;
|
||||
|
||||
|
||||
// Loops the current frame counter so it stays between 0 and total_frames - 1
|
||||
float current_frame = mod(play_frame + unique_id, float(total_frames));
|
||||
|
||||
// Compute UV Coordinates
|
||||
// ------
|
||||
// samples pixel from the center, not the edge. Avoid unwanted bleeding into normal data pixels at the end of the loop.
|
||||
float center_pixel = current_frame - 0.5;
|
||||
float vat_y = center_pixel / float(total_frames);
|
||||
vat_y = clamp(vat_y * 0.5, 0.0, 0.5);
|
||||
|
||||
vec2 vat_uv = vec2((use_uv_1 ? UV.x : UV2.x), vat_y);
|
||||
|
||||
// Vertex Position Displacement
|
||||
// ------
|
||||
vec4 vat_pos_raw = texture(vertex_animation_texture, vat_uv);
|
||||
// Must go through some remapping to convert Blender to Godot coordinates
|
||||
vec3 offset_values = vec3(
|
||||
remapFloat(vat_pos_raw.r, 0.0, 1.0, min_bounds.x, max_bounds.x),
|
||||
remapFloat(vat_pos_raw.b, 0.0, 1.0, min_bounds.z, max_bounds.z),
|
||||
remapFloat(vat_pos_raw.g, 1.0, 0.0, min_bounds.y, max_bounds.y)
|
||||
);
|
||||
VERTEX += offset_values;
|
||||
|
||||
// Normals. 0.5 added to UV.y to shift it down by 1/2 the map - to the normals section.
|
||||
vec4 vat_norm_raw = texture(vertex_animation_texture, vat_uv + vec2(0.0, 0.5));
|
||||
vec3 decoded_normals = vec3(
|
||||
remapFloat(vat_norm_raw.r, 0.0, 1.0, -1.0, 1.0),
|
||||
remapFloat(vat_norm_raw.b, 0.0, 1.0, -1.0, 1.0),
|
||||
remapFloat(vat_norm_raw.g, 1.0, 0.0, -1.0, 1.0)
|
||||
);
|
||||
NORMAL = normalize(decoded_normals);
|
||||
|
||||
// Calculate Tangent and Binormal from computed Normal
|
||||
TANGENT = normalize(vec3(abs(NORMAL.y) + abs(NORMAL.z), 0.0, -abs(NORMAL.x)));
|
||||
BINORMAL = normalize(vec3(0.0, abs(NORMAL.x) + abs(NORMAL.z), -abs(NORMAL.y)));
|
||||
}
|
||||
|
||||
void fragment() {
|
||||
// Cull Mode
|
||||
if (cull_mode == 0 && !FRONT_FACING) {
|
||||
discard; // Cull back faces
|
||||
}
|
||||
else if (cull_mode == 1 && FRONT_FACING) {
|
||||
discard; // Cull front faces
|
||||
}
|
||||
|
||||
// Albedo
|
||||
ALBEDO = texture(albedo_map, UV).rgb * albedo_tint.rgb;
|
||||
|
||||
EMISSION = vec3(1.,1.,1.) * damage_effect;
|
||||
|
||||
// ORM maps (Occlusion, Roughness, Metallic) Packing
|
||||
vec4 orm_tex = texture(orm_map, UV);
|
||||
AO = occlusion * dot(orm_tex.rgb, occlusion_channel.rgb);
|
||||
ROUGHNESS = roughness * dot(orm_tex.rgb, roughness_channel.rgb);
|
||||
METALLIC = metallic * dot(orm_tex.rgb, metallic_channel.rgb);
|
||||
|
||||
// Specular
|
||||
SPECULAR = specular;
|
||||
|
||||
// Normal Map
|
||||
NORMAL_MAP = texture(normal_map, UV).rgb;
|
||||
NORMAL_MAP_DEPTH = normal_map_scale;
|
||||
}
|
||||
Reference in New Issue
Block a user