Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- shader_type spatial;
- render_mode blend_mix;
- const float wave_amplitude = 0.3;
- const float wave_frequency = 0.15;
- const float max_sea_height = 0.0;
- const float wave_time_scale = 0.015;
- uniform sampler2D sea_texture : repeat_disable, source_color;
- uniform float water_alpha: hint_range(0.0, 1.0) = 0.5;
- uniform vec3 fresnel_sea_colour : source_color;
- uniform sampler2D foam_texture;
- uniform sampler2D texture_nm_0;
- uniform sampler2D texture_nm_1;
- uniform vec4 error_colour : source_color = vec4(1.0, 0, 0, 1);
- varying float vertex_y;
- float wave_shaping_function(float x) {
- return pow(abs(sin(PI*x/2.0)), 2.5);
- }
- // Time progression should be liner to ensure the wave is shaped correctly
- float get_wave_time_component(float time_offset, vec2 mapwide_uv) {
- float map_pos_contribution = ((1.0/cos(mapwide_uv.x)) + sin(mapwide_uv.y)) * 20.0;
- float time_contribution = (TIME+time_offset)*wave_frequency;
- // Need this to range from -1 to +1.
- // The 1 starts us there
- // The mod restricts us from 0.0 to 2.0 taking the range from -1.0 to 1.0
- return 1.0 -mod(time_contribution + map_pos_contribution, 2.0);
- }
- float get_wave_height(float time_offset, vec2 mapwide_uv) {
- float x = get_wave_time_component(time_offset, mapwide_uv);
- return wave_shaping_function(x)*wave_amplitude;
- }
- void vertex() {
- vertex_y = CUSTOM2.r;
- VERTEX.y = max_sea_height;
- NORMAL = vec3(0.0, 1.0, 0.0);
- }
- float fresnel(float amount, vec3 normal, vec3 view) {
- return pow((1.0 - clamp(dot(normalize(normal), normalize(view)), 0.0, 1.0)), amount);
- }
- float get_front_wave_height(vec2 mapwide_uv) {
- return get_wave_height(0.2/wave_frequency, mapwide_uv);
- }
- float get_rear_wave_height(vec2 mapwide_uv) {
- return get_wave_height(-0.2/wave_frequency, mapwide_uv);
- }
- bool vertex_height_correct_for_foam(float y, vec2 mapwide_uv) {
- float wave_midpoint_height = max_sea_height-wave_amplitude;
- float front_wave_height = get_front_wave_height(mapwide_uv);
- float rear_wave_height = get_rear_wave_height(mapwide_uv);
- bool vertex_is_in_wave_region = (y > wave_midpoint_height+rear_wave_height) && (y < wave_midpoint_height+front_wave_height);
- return vertex_is_in_wave_region;
- }
- float get_position_within_wave(float y, vec2 mapwide_uv) {
- float front_wave_height = get_front_wave_height(mapwide_uv);
- float rear_wave_height = get_rear_wave_height(mapwide_uv);
- float relative_pos = abs(abs(y)-rear_wave_height) / (front_wave_height-rear_wave_height);
- return relative_pos;
- }
- vec3 get_wave_colour(float y, vec2 mapwide_uv, vec3 water_surface_colour) {
- float current_height = get_wave_height(0.0, mapwide_uv);
- vec2 time_sample_point = current_height*vec2(0.5, 0.5)*5.0; // Since height has a time component, this works
- vec2 sample_point = mapwide_uv*500.0+time_sample_point;
- float water_colour_bias = 1.2*get_position_within_wave(y, mapwide_uv);
- float foam_factor = clamp(texture(foam_texture, sample_point).r-water_colour_bias, 0.0, 1.0);
- vec3 foam_white = vec3(1, 0.960784, 0.933333);
- return mix(water_surface_colour, foam_white, foam_factor);
- }
- void fragment() {
- vec2 mapwide_uv = UV; // Goes from 0->1 across the whole map
- if (vertex_y <= 0.0) {
- // Waves via normal maps
- vec2 wave_motion_0 = vec2(0.2, 0.0);
- vec2 wave_motion_1 = vec2(0.0, 0.2);
- vec2 nm0_uv = (mapwide_uv*10.0) + (TIME*wave_motion_0*wave_time_scale);
- vec2 nm1_uv = (mapwide_uv*10.0) + (TIME*wave_motion_1*wave_time_scale);
- vec3 nm0 = texture(texture_nm_0, nm0_uv).rgb;
- vec3 nm1 = texture(texture_nm_1, nm1_uv).rgb;
- NORMAL_MAP = mix(nm0, nm1, 0.5);
- // Alpha being used to pretend its depth
- ALPHA = water_alpha;
- vec3 albd;
- // Actual water colour
- // Allow water colour to only change once we pass the visible depth
- float fresnel_f = fresnel(5.0, NORMAL, VIEW);
- vec3 water_colour = texture(sea_texture, vec2(0.0, 0.0)).rgb;
- vec3 surface_colour = mix(water_colour, fresnel_sea_colour, fresnel_f);
- albd = surface_colour;
- // Foam on edges of waves
- if (vertex_height_correct_for_foam(vertex_y, mapwide_uv)) {
- albd = get_wave_colour(vertex_y, mapwide_uv, surface_colour);
- }
- ALBEDO = albd;
- } else {
- discard;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment