LumixEngine/data/pipelines/water.shd
Mikulas Florek 8854c967bb cleanup
2021-12-12 21:15:55 +01:00

225 lines
No EOL
7.4 KiB
Text

texture_slot {
name = "Normal",
default_texture = "textures/common/default_normal.tga"
}
texture_slot {
name = "Noise",
default_texture = "textures/common/white.tga"
}
include "pipelines/common.glsl"
ignore_property("roughness")
ignore_property("metallic")
ignore_property("emission")
ignore_property("translucency")
uniform("UV scale", "float")
uniform("Specular power", "float")
uniform("R0", "float")
uniform("Normal strength", "float")
uniform("Reflection multiplier", "float")
uniform("Specular multiplier", "float")
uniform("Flow dir", "vec2")
uniform("Water color", "color")
------------------
vertex_shader [[
layout(location = 0) in vec3 a_position;
layout(location = 1) in vec2 a_uv;
layout(location = 2) in vec3 a_normal;
#ifdef _HAS_ATTR3
layout(location = 3) in vec3 a_tangent;
#else
const vec3 a_tangent = vec3(0, 1, 0);
#endif
#if defined INSTANCED
layout(location = 4) in vec4 i_rot_quat;
layout(location = 5) in vec4 i_pos_scale;
#else
layout(std140, binding = 4) uniform Model {
mat4 u_model;
};
#endif
layout (location = 0) out vec2 v_uv;
layout (location = 1) out vec3 v_normal;
layout (location = 2) out vec3 v_tangent;
layout (location = 3) out vec4 v_wpos;
void main() {
v_uv = a_uv;
#if defined INSTANCED
v_normal = rotateByQuat(i_rot_quat, a_normal);
v_tangent = rotateByQuat(i_rot_quat, a_tangent);
vec3 p = a_position * i_pos_scale.w;
v_wpos = vec4(i_pos_scale.xyz + rotateByQuat(i_rot_quat, p), 1);
#else
mat4 model_mtx = u_model;
v_normal = mat3(model_mtx) * a_normal;
v_tangent = mat3(model_mtx) * a_tangent;
vec3 p = a_position;
v_wpos = model_mtx * vec4(p, 1);
#endif
gl_Position = Pass.view_projection * v_wpos;
}
]]
---------------------
fragment_shader [[
layout (binding=0) uniform sampler2D u_normalmap;
layout (binding=1) uniform sampler2D u_noise;
layout (binding=3) uniform sampler2D u_shadowmap;
layout (binding=4) uniform sampler2D u_depthbuffer;
layout (binding=7) uniform samplerCubeArray u_reflection_probes;
layout (location = 0) in vec2 v_uv;
layout (location = 1) in vec3 v_normal;
layout (location = 2) in vec3 v_tangent;
layout (location = 3) in vec4 v_wpos;
layout(location = 0) out vec4 o_color;
vec3 getReflectionColor(vec3 view, vec3 normal, float dist)
{
vec3 reflection = reflect(-view, normal);
return textureLod(u_reflection_probes, vec4(reflection, 0), dist / 2).rgb;
}
float toLinearDepth(float ndc_depth) {
vec4 pos_proj = vec4(0, 0, ndc_depth, 1.0);
vec4 view_pos = Global.inv_projection * pos_proj;
return -view_pos.z / view_pos.w;
}
float getWaterDepth(vec3 wpos, vec3 view, vec3 normal, float wave)
{
float fullColorDepth = 1;
vec3 water_color = u_material_color.rgb * 0.1;
vec4 screen_pos = Global.view_projection * vec4(wpos, 1);
screen_pos /= screen_pos.w;
#ifndef _ORIGIN_BOTTOM_LEFT
screen_pos.y *= -1;
#endif
float depth = texture(u_depthbuffer, screen_pos.xy * 0.5 + 0.5).x;
return toLinearDepth(depth) - toLinearDepth(screen_pos.z) + wave;
}
vec3 getRefractionColor(vec3 wpos, vec3 view, vec3 normal, float wave)
{
float fullColorDepth = 1;
vec3 water_color = u_material_color.rgb * 0.1;
vec4 screen_pos = Global.view_projection * vec4(wpos, 1);
screen_pos /= screen_pos.w;
#ifndef _ORIGIN_BOTTOM_LEFT
screen_pos.y *= -1;
#endif
float depth = texture(u_depthbuffer, screen_pos.xy * 0.5 + 0.5).x;
float depth_diff = toLinearDepth(depth) - toLinearDepth(screen_pos.z) + wave;
vec3 refraction = refract(-view, normal, u_r0);
vec3 refr_color = texture(u_reflection_probes, vec4(refraction, 0)).rgb;
return mix(water_color, refr_color, saturate(1 - depth_diff * depth_diff / (fullColorDepth * fullColorDepth)));
}
vec3 getSurfaceNormal(vec2 uv)
{
float noise_t = texture(u_noise, 1 - uv * 30).x;
vec2 tc0 = uv * u_uv_scale + u_flow_dir * Global.time;
vec2 tc1 = uv * u_uv_scale + u_flow_dir * (Global.time + noise_t * 0.1);
vec3 wnormal0;
wnormal0.xz = (texture(u_normalmap, tc0).xy + texture(u_normalmap, tc1 * 2.7).xy) - 0.5;
wnormal0.xz = wnormal0.xz * 2 - 1;
vec3 wnormal1;
wnormal1.xz = (texture(u_normalmap, vec2(0.5, 0.5) - tc1).xy + texture(u_normalmap, (vec2(0.5, 0.5) - tc1) * 2.3).xy) - 0.5;
wnormal1.xz = wnormal1.xz * 2 - 1;
wnormal0.y = sqrt(saturate(1 - dot(wnormal0.xz, wnormal0.xz)));
wnormal1.y = sqrt(saturate(1 - dot(wnormal1.xz, wnormal1.xz)));
float noise = 0;//texture(u_noise, uv * 30).x;
float t = fract(Global.time * 0.6 + noise * 2);
vec3 wnormal = mix(wnormal0, wnormal1, abs( 0.5 - t ) / 0.5);
return normalize(mix(vec3(0, 1, 0), wnormal, u_normal_strength));
}
void main()
{
vec3 V = normalize(-v_wpos.xyz);
vec3 L = Global.light_dir.xyz;
float shadow = 1; //getShadow(u_shadowmap, data.wpos, data.N);
o_color.rgb = vec3(1, 0, 0);
o_color.w = 1;
/////////
const float WAVE_HEIGHT = 0.0;
const float WAVE_FREQUENCY = 3;
const float FOAM_DEPTH = 0.2;
const float FOAM_TEXTURE_SCALE = 5;
const float FOAM_WIDTH = 1;
mat3 tbn = mat3(
normalize(v_tangent),
normalize(v_normal),
normalize(cross(v_normal, v_tangent))
);
vec3 wnormal = getSurfaceNormal(v_uv.xy);
wnormal = normalize(tbn * wnormal);
float noise = texture(u_noise, v_uv*10).x;
float wave = cos(Global.time * WAVE_FREQUENCY + length(v_wpos)*10.15) * WAVE_HEIGHT - WAVE_HEIGHT /*- WAVE_HEIGHT * noise*/;
//vec3 screen_uv = getScreenCoord(v_wpos);
//float depth = texture(u_gbuffer_depth, screen_uv.xy * 0.5 + 0.5).x;
//float depth_diff = toLinearDepth(Global.inv_projection, depth) - toLinearDepth(screen_uv.z) + wave;
//if(depth_diff < FOAM_DEPTH)
//{
// wnormal = texture(u_gbuffer1, screen_uv.xy * 0.5 + 0.5).xyz * 2 - 1;
// wnormal = mix(vec3(0, 1, 0), wnormal, normal_strength);
// wnormal = normalize(wnormal);
//}
float dist = length(v_wpos.xyz);
vec3 view = normalize(vec4(-v_wpos.xyz, 0).xyz);
vec3 refl_color = getReflectionColor(view, wnormal, dist * u_normal_strength);
vec3 refr_color = getRefractionColor(v_wpos.xyz, view, wnormal, /*wave*/0);
float water_depth = getWaterDepth(v_wpos.xyz, view, wnormal, wave);
//
vec3 halfvec = normalize(mix(Global.light_dir.xyz, view, 0.5));
float spec_strength = pow(max(0.0, dot(halfvec, wnormal)), u_specular_power);
vec3 spec_color = Global.light_color.rgb * spec_strength * u_specular_multiplier;
float fresnel = u_r0 + (1.0 - u_r0) * pow(saturate(1.0 - dot(normalize(view), wnormal)), 5);
fresnel = saturate(fresnel * saturate(water_depth));
//fresnel *= saturate((depth_diff - wave)*10);
//vec3 color = mix(refr_color, refl_color * u_reflection_multiplier, saturate(fresnel));
//color = vec3(dot(normalize(view), wnormal) > 0.5 ? 1 : 0);
//color = vec3(fresnel);
/*#ifdef FOAM_TEXTURE
vec3 foam = texture(u_texFoam, v_texcoord0 * texture_scale * FOAM_TEXTURE_SCALE).rgb;
color = color + foam * saturate(FOAM_DEPTH-abs(FOAM_DEPTH - depth_diff * FOAM_WIDTH)) * (1/FOAM_DEPTH);
#endif*/
//vec4 camera_wpos = mul(u_camInvView, vec4(0, 0, 0, 1));
//vec3 wpos = getViewPosition(u_gbuffer_depth, u_camInvViewProj, screen_uv.xy * 0.5 + 0.5);
//float fog_factor = getFogFactor(camera_wpos.xyz / camera_wpos.w, u_fogColorDensity.w, wpos.xyz, u_fogParams);
//gl_FragColor = vec4(mix(color + spec_color, u_fogColorDensity.rgb, fog_factor), 1);
float t = saturate(1 - exp(-water_depth * 2));
o_color = vec4(fresnel * refl_color + spec_color + pow(u_water_color.rgb, vec3(2.2)) * t, saturate(t + fresnel));
}
]]