160 lines
4.2 KiB
GLSL
160 lines
4.2 KiB
GLSL
@vs vs_plane
|
|
|
|
|
|
in vec4 position;
|
|
|
|
layout(binding=0) uniform plane_vs_params {
|
|
mat4 mvp;
|
|
};
|
|
|
|
out vec4 pos;
|
|
out flat int idx;
|
|
|
|
|
|
void main() {
|
|
vec3 multisize = vec3(position.xyz * 1000.0);
|
|
gl_Position = mvp * vec4(multisize, 1.0);
|
|
pos = vec4(multisize, 1.0);
|
|
idx = gl_InstanceIndex;
|
|
}
|
|
@end
|
|
|
|
@fs fs_plane
|
|
|
|
in vec4 pos;
|
|
in flat int idx;
|
|
out vec4 frag_color;
|
|
|
|
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;
|
|
vec3 sunDisk;
|
|
vec3 horizonHalo;
|
|
vec3 sunHalo;
|
|
vec3 sunLightColor;
|
|
vec3 sunPosition;
|
|
float sunIntensity;
|
|
float skyIntensity;
|
|
|
|
int hasClouds;
|
|
|
|
int hasPlane;
|
|
float planeHeight;
|
|
int planeType;
|
|
|
|
float time;
|
|
|
|
float grassDensity;
|
|
};
|
|
|
|
layout(binding=2) uniform plane_data {
|
|
int screen_w;
|
|
int screen_h;
|
|
int is_reflection_pass;
|
|
};
|
|
|
|
layout(binding = 0) uniform texture2D reftex;
|
|
layout(binding = 1) uniform texture2D groundtex;
|
|
layout(binding = 2) uniform texture2D shadow;
|
|
layout(binding = 0) uniform sampler refsmp;
|
|
layout(binding = 1) uniform sampler groundsmp;
|
|
layout(binding = 2) uniform sampler shadowsmp;
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
void main() {
|
|
vec4 npos = round(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));
|
|
float shadowp = texture(sampler2DShadow(shadow, shadowsmp), vec3(0,0,0));
|
|
|
|
// @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);
|
|
|
|
if(planeType == 1) {
|
|
frag_color = vec4(bf, 1.0);
|
|
} else {
|
|
frag_color = vec4(vec3(shadowp), 1.0);
|
|
}
|
|
}
|
|
@end
|
|
|
|
@program plane vs_plane fs_plane
|