improve water
This commit is contained in:
parent
857338993b
commit
68828cb119
@ -1,6 +1,6 @@
|
||||
{
|
||||
"exposure": 0.057475,
|
||||
"contrast": 2.06763,
|
||||
"contrast": 1.075945,
|
||||
"saturation": 1.202777,
|
||||
"gamma": 1.019477,
|
||||
"tonemap": 1
|
||||
|
||||
File diff suppressed because one or more lines are too long
BIN
resources/utiltex/water.png
Normal file
BIN
resources/utiltex/water.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 MiB |
@ -95,6 +95,7 @@ init :: () {
|
||||
}
|
||||
|
||||
init_after_asset_pack :: () {
|
||||
init_plane_textures();
|
||||
add_font_from_pack("./resources/DroidSerif-Regular.ttf");
|
||||
ui_init_font_fields(*state.font_default);
|
||||
|
||||
|
||||
@ -161,6 +161,9 @@ backend_draw_ground :: (wc: *World_Config) {
|
||||
w, h := get_render_size();
|
||||
plane_data.screen_w = w;
|
||||
plane_data.screen_h = h;
|
||||
plane_data.cameraPosition = camera.position.component;
|
||||
plane_data.reflectionDistortion = 0.1;
|
||||
plane_data.shininess = 0.2;
|
||||
|
||||
world_config_to_shader_type(wc, *world_conf);
|
||||
|
||||
|
||||
@ -473,6 +473,12 @@ create_plane_pipeline :: () {
|
||||
mag_filter = .NEAREST,
|
||||
}));
|
||||
|
||||
gPipelines.plane.bind.samplers[3] = sg_make_sampler(*(sg_sampler_desc.{
|
||||
wrap_u = .REPEAT,
|
||||
wrap_v = .REPEAT,
|
||||
min_filter = .LINEAR,
|
||||
mag_filter = .LINEAR,
|
||||
}));
|
||||
|
||||
ground_img_desc := sg_image_desc.{
|
||||
width = 1000,
|
||||
@ -574,3 +580,7 @@ create_postprocess_pipeline :: () {
|
||||
}));
|
||||
|
||||
}
|
||||
|
||||
init_plane_textures :: () {
|
||||
gPipelines.plane.bind.images[3] = create_texture_from_pack("./resources/utiltex/water.png");
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -26,25 +26,12 @@ in vec4 pos;
|
||||
in flat int idx;
|
||||
out vec4 frag_color;
|
||||
|
||||
// Uniform bindings from the original shader
|
||||
layout(binding=3) uniform plane_fs_params {
|
||||
mat4 mvp_shadow;
|
||||
int is_reflection;
|
||||
};
|
||||
|
||||
uint murmurHash12(uvec2 src) {
|
||||
const uint M = 0x5bd1e995u;
|
||||
uint h = 1190494759u;
|
||||
src *= M; src ^= src>>24u; src *= M;
|
||||
h *= M; h ^= src.x; h *= M; h ^= src.y;
|
||||
h ^= h>>13u; h *= M; h ^= h>>15u;
|
||||
return h;
|
||||
}
|
||||
|
||||
float hash12(vec2 src) {
|
||||
uint h = murmurHash12(floatBitsToUint(src));
|
||||
return uintBitsToFloat(h & 0x007fffffu | 0x3f800000u) - 1.0;
|
||||
}
|
||||
|
||||
layout(binding=1) uniform plane_world_config {
|
||||
vec3 skyBase;
|
||||
vec3 skyTop;
|
||||
@ -55,14 +42,11 @@ layout(binding=1) uniform plane_world_config {
|
||||
vec3 sunPosition;
|
||||
float sunIntensity;
|
||||
float skyIntensity;
|
||||
|
||||
int hasClouds;
|
||||
|
||||
float planeHeight;
|
||||
int planeType;
|
||||
vec3 waterColor;
|
||||
vec3 deepColor;
|
||||
|
||||
float time;
|
||||
};
|
||||
|
||||
@ -70,99 +54,64 @@ layout(binding=2) uniform plane_data {
|
||||
int screen_w;
|
||||
int screen_h;
|
||||
int is_reflection_pass;
|
||||
vec3 cameraPosition;
|
||||
float shininess; // Controls the size of the sun's glint, e.g., 64.0
|
||||
float reflectionDistortion; // Controls how much waves distort reflections, e.g., 0.05
|
||||
};
|
||||
|
||||
// Texture bindings
|
||||
layout(binding = 0) uniform texture2D reftex;
|
||||
layout(binding = 1) uniform texture2D groundtex;
|
||||
layout(binding = 2) uniform texture2D shadow;
|
||||
layout(binding = 3) uniform texture2D normal_map;
|
||||
|
||||
// Sampler bindings
|
||||
layout(binding = 0) uniform sampler refsmp;
|
||||
layout(binding = 1) uniform sampler groundsmp;
|
||||
layout(binding = 2) uniform sampler shadowsmp;
|
||||
layout(binding = 3) uniform sampler normalsmp;
|
||||
|
||||
float random (vec2 st) {
|
||||
return fract(sin(dot(st.xy,
|
||||
vec2(12.9898,78.233)))*
|
||||
43758.5453123);
|
||||
}
|
||||
|
||||
// 2D Noise based on Morgan McGuire @morgan3d
|
||||
// https://www.shadertoy.com/view/4dS3Wd
|
||||
float noise (vec2 st) {
|
||||
vec2 i = floor(st); // Integer part of the coordinate
|
||||
vec2 f = fract(st); // Fractional part of the coordinate
|
||||
|
||||
// Four corners in 2D of a tile
|
||||
float a = random(i);
|
||||
float b = random(i + vec2(1.0, 0.0));
|
||||
float c = random(i + vec2(0.0, 1.0));
|
||||
float d = random(i + vec2(1.0, 1.0));
|
||||
|
||||
// Smoothstep for interpolation
|
||||
vec2 u = f*f*(3.0-2.0*f);
|
||||
|
||||
// Mix (interpolate) the corners
|
||||
return mix(a, b, u.x) +
|
||||
(c - a)* u.y * (1.0 - u.x) +
|
||||
(d - b) * u.x * u.y;
|
||||
}
|
||||
|
||||
int sign2(float x) {
|
||||
if(x < 0) return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
vec3 get_ground_sample(vec4 pos, float dirX, float dirY) {
|
||||
ivec2 plane_coord = ivec2(floor(pos.x + dirX) + 500, floor(pos.z + dirY) + 500);
|
||||
vec4 reflection = texelFetch(sampler2D(reftex, refsmp), ivec2(gl_FragCoord.x, screen_h - gl_FragCoord.y), 0);
|
||||
vec4 groundSample = texelFetch(sampler2D(groundtex, groundsmp), plane_coord, 0);
|
||||
|
||||
// Calculate all materials so we can blend them.
|
||||
vec3 water = reflection.xyz * vec3(0.95, 1.0, 0.95);
|
||||
vec3 sand = vec3(mix(0.8, 1.0, hash12(pos.xz)) * vec3(0.8, 0.7, 0.5));
|
||||
vec3 grass = vec3(mix(0.8, 1.0, hash12(pos.xz)) * vec3(0.4, 0.8, 0.3));
|
||||
|
||||
if(groundSample.b == 1.0) {
|
||||
return water;
|
||||
} else if(groundSample.r == 1.0) {
|
||||
return sand;
|
||||
} else {
|
||||
return grass;
|
||||
}
|
||||
vec3 fresnelSchlick(float cosTheta) {
|
||||
vec3 F0 = vec3(0.02);
|
||||
return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0);
|
||||
}
|
||||
|
||||
void main() {
|
||||
// vec4 npos = floor(pos * 16.0) / 16.0;
|
||||
// vec2 tileCenter = vec2(floor(npos.x) + 0.5, floor(npos.z) + 0.5);
|
||||
// vec2 toCenter = npos.xz - tileCenter;
|
||||
|
||||
// // Bilinear filtering
|
||||
// float u = smoothstep(0.2, 0.5, abs(toCenter.x)) * 0.5;
|
||||
// float v = smoothstep(0.2, 0.5, abs(toCenter.y)) * 0.5;
|
||||
|
||||
// // @ToDo: We should implement some sort of fog system and stop doing all this sampling
|
||||
// // stuff if we are far enough from the camera. Currently ground rendering is taking way
|
||||
// // too much time each frame.
|
||||
// vec3 c0 = get_ground_sample(npos, 0.0, 0.0);
|
||||
// vec3 c1 = get_ground_sample(npos, sign2(toCenter.x), 0.0);
|
||||
// vec3 c2 = get_ground_sample(npos, 0.0, sign2(toCenter.y));
|
||||
// vec3 c3 = get_ground_sample(npos, sign2(toCenter.x), sign2(toCenter.y));
|
||||
if(idx == 1) { // Second instance of the plane is the actual water surface.
|
||||
vec2 uv1 = pos.xz * 0.1 + time * 0.01;
|
||||
vec2 uv2 = pos.xz * 0.1 + time * vec2(-0.005, -0.012);
|
||||
|
||||
// // @ToDo: Consider using cool Inigo Quilez trick here to make it even smoother.
|
||||
// vec3 b01 = mix(c0, c1, u);
|
||||
// vec3 b23 = mix(c2, c3, u);
|
||||
// vec3 bf = mix(b01, b23, v);
|
||||
|
||||
// vec4 light_proj_pos = mvp_shadow * vec4(npos.xyz + vec3(1.0/32.0, 0.0, 1.0/32.0), 1.0);
|
||||
// vec3 light_pos = light_proj_pos.xyz / light_proj_pos.w;
|
||||
// light_pos = light_pos * 0.5 + 0.5;
|
||||
// float bias = 0.0005;
|
||||
// float shadowp = max(0.7, texture(sampler2DShadow(shadow, shadowsmp), vec3(light_pos.xy, light_pos.z - bias)));
|
||||
|
||||
if(idx == 1) {
|
||||
float f = skyBase.x * float(screen_h) * mvp_shadow[0][0];
|
||||
vec4 reflection = texelFetch(sampler2D(reftex, refsmp), ivec2(gl_FragCoord.x, screen_h - gl_FragCoord.y), 0);
|
||||
frag_color = vec4(reflection.xyz * 0.5 + waterColor * 0.5 + 0.00001 * f, 0.3);
|
||||
} else {
|
||||
vec3 normal1 = texture(sampler2D(normal_map, normalsmp), uv1).xzy * 2.0 - 1.0;
|
||||
vec3 normal2 = texture(sampler2D(normal_map, normalsmp), uv2).xzy * 2.0 - 1.0;
|
||||
|
||||
vec3 normal = normalize(normal1 + normal2);
|
||||
|
||||
vec3 view_dir = normalize(cameraPosition - pos.xyz);
|
||||
vec3 light_dir = normalize(sunPosition);
|
||||
vec3 halfway_dir = normalize(light_dir + view_dir);
|
||||
float shadow_factor = 1.0; // shadowmap to be implemented
|
||||
|
||||
vec3 base_water_color = waterColor;
|
||||
float diffuse = (dot(normal, light_dir)) + 0.000001 * is_reflection * shininess;
|
||||
float spec = pow(max(0.0, dot(halfway_dir, normal)), 32);
|
||||
float fresnel = min(1.0, fresnelSchlick(dot(view_dir, vec3(0.0, 1.0, 0.0))).x + 0.3);
|
||||
vec3 refracted_color = base_water_color * diffuse * sunLightColor * sunIntensity;
|
||||
vec3 specular_highlight = sunLightColor * sunIntensity * spec;
|
||||
|
||||
vec2 screen_uv = gl_FragCoord.xy / vec2(screen_w, screen_h);
|
||||
vec2 distortion = normal.xz * 0.005;
|
||||
screen_uv.y = 1.0 - screen_uv.y;
|
||||
vec3 reflected_color = texture(sampler2D(reftex, refsmp), screen_uv + distortion).rgb;
|
||||
|
||||
vec3 surface_color = mix(refracted_color, reflected_color, fresnel);
|
||||
vec3 final_color = (surface_color + specular_highlight) * shadow_factor;
|
||||
float refraction_alpha = 0.3; // Base transparency when looking straight down
|
||||
float reflection_alpha = 0.5; // Surface is opaque where it's most reflective
|
||||
float alpha = mix(refraction_alpha, reflection_alpha, fresnel);
|
||||
|
||||
frag_color = vec4(final_color, alpha);
|
||||
|
||||
} else { // Deep water plane (unchanged)
|
||||
frag_color = vec4(deepColor, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,11 +75,11 @@ input_code_from_type_and_notes :: (name: string, type: *Type_Info, notes: []stri
|
||||
if autoconf.kind == .DEFAULT {
|
||||
print_to_builder(*builder, "{\n");
|
||||
print_to_builder(*builder, "orig_w := r.w; orig_x := r.x; r.w = r.w / 3;\n");
|
||||
print_to_builder(*builder, "GR.number_input(r, tprint(\"\%\", value.%.x), *value.%.x, 0, 100, *number_theme);\n", name, name);
|
||||
print_to_builder(*builder, "GR.number_input(r, tprint(\"\%\", value.%.x), *value.%.x, -100, 100, *number_theme);\n", name, name);
|
||||
print_to_builder(*builder, "r.x += r.w;\n");
|
||||
print_to_builder(*builder, "GR.number_input(r, tprint(\"\%\", value.%.y), *value.%.y, 0, 100, *number_theme);\n", name, name);
|
||||
print_to_builder(*builder, "GR.number_input(r, tprint(\"\%\", value.%.y), *value.%.y, -100, 100, *number_theme);\n", name, name);
|
||||
print_to_builder(*builder, "r.x += r.w;\n");
|
||||
print_to_builder(*builder, "GR.number_input(r, tprint(\"\%\", value.%.z), *value.%.z, 0, 100, *number_theme);\n", name, name);
|
||||
print_to_builder(*builder, "GR.number_input(r, tprint(\"\%\", value.%.z), *value.%.z, -100, 100, *number_theme);\n", name, name);
|
||||
print_to_builder(*builder, "r.w = orig_w; r.x = orig_x;\n");
|
||||
print_to_builder(*builder, "}\n");
|
||||
} else if autoconf.kind == .COLOR {
|
||||
|
||||
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user