mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Rain shader
This commit is contained in:
parent
b7c0196129
commit
9cb67e6283
@ -62,6 +62,19 @@ vec3 wpos_at(vec2 uv) {
|
||||
}
|
||||
}
|
||||
|
||||
mat4 spin_in_axis(vec3 axis, float angle)
|
||||
{
|
||||
axis = normalize(axis);
|
||||
float s = sin(angle);
|
||||
float c = cos(angle);
|
||||
float oc = 1.0 - c;
|
||||
|
||||
return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0,
|
||||
oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0,
|
||||
oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 color = texture(sampler2D(t_src_color, s_src_color), uv);
|
||||
|
||||
@ -86,5 +99,49 @@ void main() {
|
||||
color.rgb = apply_point_glow(cam_pos.xyz + focus_off.xyz, dir, dist, color.rgb);
|
||||
#endif
|
||||
|
||||
vec3 old_color = color.rgb;
|
||||
|
||||
float fall_rate = 20.0;
|
||||
|
||||
dir.xy += wind_vel * dir.z / fall_rate;
|
||||
dir = normalize(dir);
|
||||
|
||||
float z = (-1 / (abs(dir.z) - 1) - 1) * sign(dir.z);
|
||||
vec2 dir_2d = normalize(dir.xy);
|
||||
vec2 view_pos = vec2(atan2(dir_2d.x, dir_2d.y), z);
|
||||
|
||||
vec3 cam_wpos = cam_pos.xyz + focus_off.xyz;
|
||||
float rain_density = rain_density_at(cam_wpos.xy);
|
||||
if (rain_density > 0) {
|
||||
float rain_dist = 50.0;
|
||||
for (int i = 0; i < 5; i ++) {
|
||||
rain_dist *= 0.3;
|
||||
|
||||
vec3 rpos = vec3(vec2(dir_2d), view_pos.y) * rain_dist;
|
||||
float dist_to_rain = length(rpos);
|
||||
|
||||
if (dist < dist_to_rain || cam_wpos.z + rpos.z > CLOUD_AVG_ALT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
float drop_density = 3;
|
||||
vec2 drop_size = vec2(0.0025, 0.17);
|
||||
|
||||
vec2 rain_pos = (view_pos * rain_dist);
|
||||
rain_pos += vec2(0, tick.x * fall_rate + cam_wpos.z);
|
||||
|
||||
vec2 cell = floor(rain_pos * drop_density) / drop_density;
|
||||
if (hash(fract(vec4(cell, rain_dist, 0) * 0.01)) > rain_density) {
|
||||
continue;
|
||||
}
|
||||
vec2 near_drop = cell + (vec2(0.5) + (vec2(hash(vec4(cell, 0, 0)), 0.5) - 0.5) * vec2(2, 0)) / drop_density;
|
||||
|
||||
float avg_alpha = (drop_size.x * drop_size.y) / 1;
|
||||
float alpha = sign(max(1 - length((rain_pos - near_drop) / drop_size), 0));
|
||||
float light = sqrt(dot(old_color, vec3(1))) + (get_sun_brightness() + get_moon_brightness()) * 0.01;
|
||||
color.rgb = mix(color.rgb, vec3(0.3, 0.4, 0.5) * light, mix(avg_alpha, alpha, min(1000 / dist_to_rain, 1)) * 0.25);
|
||||
}
|
||||
}
|
||||
|
||||
tgt_color = vec4(color.rgb, 1);
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ vec3 warp_normal(vec3 norm, vec3 pos, float time) {
|
||||
+ smooth_rand(pos * 0.25, time * 0.25) * 0.1);
|
||||
}
|
||||
|
||||
float wave_height(vec3 pos) {
|
||||
float wave_height(vec3 pos, vec3 surf_norm) {
|
||||
float timer = tick.x * 0.75;
|
||||
|
||||
pos *= 0.5;
|
||||
@ -103,7 +103,8 @@ void main() {
|
||||
uint norm_dir = ((f_pos_norm >> 29) & 0x1u) * 3u;
|
||||
// Use an array to avoid conditional branching
|
||||
// Temporarily assume all water faces up (this is incorrect but looks better)
|
||||
vec3 f_norm = vec3(0, 0, 1);//normals[norm_axis + norm_dir];
|
||||
vec3 surf_norm = normals[norm_axis + norm_dir];
|
||||
vec3 f_norm = vec3(0, 0, 1);//surf_norm;
|
||||
vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz);
|
||||
|
||||
// vec4 light_pos[2];
|
||||
@ -131,10 +132,11 @@ void main() {
|
||||
}
|
||||
vec3 c_norm = cross(f_norm, b_norm);
|
||||
|
||||
vec3 wave_pos = f_pos + focus_off.xyz;
|
||||
float wave00 = wave_height(wave_pos);
|
||||
float wave10 = wave_height(wave_pos + vec3(0.1, 0, 0));
|
||||
float wave01 = wave_height(wave_pos + vec3(0, 0.1, 0));
|
||||
vec3 wave_pos = mod(f_pos + focus_off.xyz, vec3(100.0));
|
||||
float wave_sample_dist = 0.025;
|
||||
float wave00 = wave_height(wave_pos, surf_norm);
|
||||
float wave10 = wave_height(wave_pos + vec3(wave_sample_dist, 0, 0), surf_norm);
|
||||
float wave01 = wave_height(wave_pos + vec3(0, wave_sample_dist, 0), surf_norm);
|
||||
|
||||
// Possibility of div by zero when slope = 0,
|
||||
// however this only results in no water surface appearing
|
||||
@ -142,11 +144,34 @@ void main() {
|
||||
float slope = abs((wave00 - wave10) * (wave00 - wave01)) + 0.001;
|
||||
|
||||
vec3 nmap = vec3(
|
||||
-(wave10 - wave00) / 0.1,
|
||||
-(wave01 - wave00) / 0.1,
|
||||
0.1 / slope
|
||||
-(wave10 - wave00) / wave_sample_dist,
|
||||
-(wave01 - wave00) / wave_sample_dist,
|
||||
wave_sample_dist / slope
|
||||
);
|
||||
|
||||
float rain_density = rain_density_at(cam_pos.xy + focus_off.xy);
|
||||
if (rain_density > 0 && surf_norm.z > 0.5) {
|
||||
vec3 drop_density = vec3(2, 2, 1);
|
||||
vec3 drop_pos = wave_pos + vec3(0, 0, -time_of_day.x * 0.025);
|
||||
drop_pos.z += noise_2d(floor(drop_pos.xy * drop_density.xy) * 13.1) * 10;
|
||||
vec2 cell2d = floor(drop_pos.xy * drop_density.xy);
|
||||
drop_pos.z *= 0.5 + hash_fast(uvec3(cell2d, 0));
|
||||
vec3 cell = vec3(cell2d, floor(drop_pos.z * drop_density.z));
|
||||
|
||||
if (hash(fract(vec4(cell, 0) * 0.01)) < rain_density) {
|
||||
vec3 off = vec3(hash_fast(uvec3(cell * 13)), hash_fast(uvec3(cell * 5)), 0);
|
||||
vec3 near_cell = (cell + 0.5 + (off - 0.5) * 0.5) / drop_density;
|
||||
|
||||
float dist = length((drop_pos - near_cell) / vec3(1, 1, 2));
|
||||
float drop_rad = 0.125;
|
||||
nmap.xy += (drop_pos - near_cell).xy
|
||||
* max(1.0 - abs(dist - drop_rad) * 50, 0)
|
||||
* 2500
|
||||
* sign(dist - drop_rad)
|
||||
* max(drop_pos.z - near_cell.z, 0);
|
||||
}
|
||||
}
|
||||
|
||||
nmap = mix(f_norm, normalize(nmap), min(1.0 / pow(frag_dist, 0.75), 1));
|
||||
|
||||
//float suppress_waves = max(dot(), 0);
|
||||
|
@ -256,13 +256,15 @@ vec3 get_cloud_color(vec3 surf_color, vec3 dir, vec3 origin, const float time_of
|
||||
float step = (ldist - cdist) * 0.01;
|
||||
float cloud_darken = pow(1.0 / (1.0 + cloud_scatter_factor), step);
|
||||
float global_darken = pow(1.0 / (1.0 + global_scatter_factor), step);
|
||||
// Proportion of light diffusely scattered instead of absorbed
|
||||
float cloud_diffuse = 0.25;
|
||||
|
||||
surf_color =
|
||||
// Attenuate light passing through the clouds
|
||||
surf_color * cloud_darken * global_darken +
|
||||
// Add the directed light light scattered into the camera by the clouds and the atmosphere (global illumination)
|
||||
sun_color * sun_scatter * get_sun_brightness() * (sun_access * (1.0 - cloud_darken) /*+ sky_color * global_scatter_factor*/) +
|
||||
moon_color * moon_scatter * get_moon_brightness() * (moon_access * (1.0 - cloud_darken) /*+ sky_color * global_scatter_factor*/) +
|
||||
sun_color * sun_scatter * get_sun_brightness() * (sun_access * (1.0 - cloud_darken) * cloud_diffuse /*+ sky_color * global_scatter_factor*/) +
|
||||
moon_color * moon_scatter * get_moon_brightness() * (moon_access * (1.0 - cloud_darken) * cloud_diffuse /*+ sky_color * global_scatter_factor*/) +
|
||||
sky_light * (1.0 - global_darken) * not_underground +
|
||||
emission * density_integrals.y * step;
|
||||
}
|
||||
|
@ -37,4 +37,6 @@ mat4 threshold_matrix = mat4(
|
||||
float distance_divider = 2;
|
||||
float shadow_dithering = 0.5;
|
||||
|
||||
vec2 wind_vel = vec2(0.0);
|
||||
|
||||
#endif
|
||||
|
@ -115,8 +115,6 @@ float cloud_tendency_at(vec2 pos) {
|
||||
return nz;
|
||||
}
|
||||
|
||||
// vec2 get_wind(vec2 pos) {}
|
||||
|
||||
const float RAIN_CLOUD = 0.05;
|
||||
float rain_density_at(vec2 pos) {
|
||||
return clamp((cloud_tendency_at(pos) - RAIN_CLOUD) * 10, 0, 1);
|
||||
|
@ -231,6 +231,35 @@ void main() {
|
||||
vec3 k_d = vec3(1.0);
|
||||
vec3 k_s = vec3(R_s);
|
||||
|
||||
float rain_density = rain_density_at(cam_pos.xy + focus_off.xy);
|
||||
if (rain_density > 0 && !faces_fluid && f_norm.z > 0.5) {
|
||||
vec3 pos = f_pos + focus_off.xyz;
|
||||
vec3 drop_density = vec3(2, 2, 1);
|
||||
vec3 drop_pos = pos + vec3(pos.zz, 0) + vec3(0, 0, -tick.x * 1.0);
|
||||
drop_pos.z += noise_2d(floor(drop_pos.xy * drop_density.xy) * 13.1) * 10;
|
||||
vec2 cell2d = floor(drop_pos.xy * drop_density.xy);
|
||||
drop_pos.z *= 0.5 + hash_fast(uvec3(cell2d, 0));
|
||||
vec3 cell = vec3(cell2d, floor(drop_pos.z * drop_density.z));
|
||||
|
||||
if (hash(fract(vec4(cell, 0) * 0.01)) < rain_density) {
|
||||
vec3 off = vec3(hash_fast(uvec3(cell * 13)), hash_fast(uvec3(cell * 5)), 0);
|
||||
vec3 near_cell = (cell + 0.5 + (off - 0.5) * 0.5) / drop_density;
|
||||
|
||||
float dist = length((drop_pos - near_cell) / vec3(1, 1, 2));
|
||||
float drop_rad = 0.1;
|
||||
float distort = max(1.0 - abs(dist - drop_rad) * 100, 0) * 1.5 * max(drop_pos.z - near_cell.z, 0);
|
||||
k_a += distort;
|
||||
k_d += distort;
|
||||
k_s += distort;
|
||||
f_norm.xy += (drop_pos - near_cell).xy
|
||||
* max(1.0 - abs(dist - drop_rad) * 30, 0)
|
||||
* 500.0
|
||||
* max(drop_pos.z - near_cell.z, 0)
|
||||
* sign(dist - drop_rad)
|
||||
* max(drop_pos.z - near_cell.z, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// float sun_light = get_sun_brightness(sun_dir);
|
||||
// float moon_light = get_moon_brightness(moon_dir);
|
||||
/* float sun_shade_frac = horizon_at(f_pos, sun_dir);
|
||||
|
Loading…
Reference in New Issue
Block a user