3D wind sway shader with wind mask texture controll

Assign the Wind Mask Texture to the wind_mask uniform in the ShaderMaterial.

In the context of the wind mask texture, where we are using it to control wind sway:

  • Black (0.0): Represents no wind effect (or minimal sway) in that area of the mesh.
  • White (1.0): Represents full wind effect, where the wind sway will be most pronounced in that area.
Shader code
shader_type spatial;
//specular_schlick_ggx for shaded in place of unshaded
render_mode blend_mix, unshaded, cull_disabled, diffuse_burley, depth_prepass_alpha;

// Base material properties
uniform vec4 albedo : source_color;
uniform sampler2D texture_albedo : source_color, filter_linear_mipmap, repeat_enable;

uniform float roughness : hint_range(0.0, 1.0);
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 : hint_range(0.0, 1.0, 0.01);
uniform float metallic : hint_range(0.0, 1.0, 0.01);

// Normal mapping
uniform sampler2D texture_normal : hint_normal, filter_linear_mipmap, repeat_enable;
uniform float normal_scale : hint_range(0.0, 2.0) = 1.0;

uniform sampler2D wind_mask : source_color; // Grayscale texture to control sway

// Wind sway parameters
uniform bool enable_wind = false;
uniform int wind_type = 0; // 0: Smooth, 1: Gusty, 2: Wave, 3: Directional

uniform float wind_strength : hint_range(0.0, 2.0) = 0.9;
uniform float wind_speed : hint_range(0.0, 5.0) = 1.0;
uniform float wind_frequency : hint_range(0.0, 10.0) = 2.0;
uniform vec2 wind_direction = vec2(1.0, 0.0);

// Distance fade settings
uniform bool enable_fade = false; // Toggle for enabling/disabling fade effect
uniform float fade_start_distance : hint_range(0.0, 200.0) = 50.0; // Distance at which fading starts
uniform float fade_length : hint_range(1.0, 50.0) = 20.0; // Distance over which fading occurs

void vertex() {
    if (enable_wind) {
        float sway_intensity = texture(wind_mask, UV).r; // Sample the wind mask texture (grayscale value)
        
        // Apply sway based on the sampled intensity
        if (wind_type == 0) { // Smooth wind
            VERTEX.y += sin(VERTEX.x * wind_frequency + TIME * wind_speed) * wind_strength * sway_intensity;
        } else if (wind_type == 1) { // Gusty wind
            float turbulence = sin(TIME * wind_speed * 0.7) * cos(TIME * wind_speed * 1.3);
            VERTEX.y += sin(VERTEX.x * wind_frequency + TIME * wind_speed) * turbulence * wind_strength * sway_intensity;
        } else if (wind_type == 2) { // Wave-like wind
            VERTEX.y += sin(VERTEX.x * wind_frequency + TIME * wind_speed) * cos(VERTEX.z * wind_frequency + TIME * wind_speed) * wind_strength * sway_intensity;
        } else if (wind_type == 3) { // Directional wind
            VERTEX.xz += wind_direction * sin(TIME * wind_speed) * wind_strength * sway_intensity;
        }
    }
}


void fragment() {
    vec2 base_uv = UV;

    // Sample textures
    vec4 albedo_tex = texture(texture_albedo, base_uv);
    float metallic_tex = dot(texture(texture_metallic, base_uv), metallic_texture_channel);
    float roughness_tex = texture(texture_roughness, base_uv).r;

    // Compute base material properties
    ALBEDO = albedo.rgb * albedo_tex.rgb;
    METALLIC = metallic_tex * metallic;
    SPECULAR = specular;
    ROUGHNESS = roughness_tex * roughness;

    // Normal mapping
    vec3 normal_map = texture(texture_normal, base_uv).rgb * 2.0 - 1.0;
    normal_map.xy *= normal_scale;
    NORMAL_MAP = normal_map;

    // Compute fade effect only if enabled
    float fade = 1.0; // Default fully visible
    if (enable_fade) {
        float dist = length(VERTEX);
        fade = clamp(1.0 - (dist - fade_start_distance) / fade_length, 0.0, 1.0);
    }

    // Apply fading to alpha
    ALPHA = albedo.a * albedo_tex.a * fade;
}
Tags
out line, outline, outline for 3d
The shader code and all code snippets in this post are under MIT license and can be used freely. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

More from buddhanomad

Best outline shader for 3d object **

simple static shader optimized for lowpoly game

Godot 4 Shader: Dual-Channel Overlay Effect for Dynamic Texturing

Related shaders

vertex paint controlled simple 3D wind sway shader

Pixel Art Wind Sway (MeshInstance3D, Godot 4.0)

Blend damage revealed with noise texture mask

Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments