Update (nature, engine changes)
This commit is contained in:
@@ -1,7 +1,49 @@
|
||||
shader_type spatial;
|
||||
|
||||
uniform sampler2D u_texture_top : hint_albedo;
|
||||
uniform sampler2D u_texture_sides : hint_albedo;
|
||||
|
||||
// Bitmask telling which of the 6 faces of the block are bordered by a block of lower resolution
|
||||
uniform int u_transition_mask;
|
||||
|
||||
// We'll need to pass data from the vertex shader to the fragment shader
|
||||
varying vec3 v_world_pos;
|
||||
varying vec3 v_world_normal;
|
||||
varying vec4 v_weights;
|
||||
varying vec4 v_indices;
|
||||
|
||||
// We'll use a utility function to decode components.
|
||||
// It returns 4 values in the range [0..255].
|
||||
vec4 decode_8bit_vec4(float v) {
|
||||
uint i = floatBitsToUint(v);
|
||||
return vec4(
|
||||
float(i & uint(0xff)),
|
||||
float((i >> uint(8)) & uint(0xff)),
|
||||
float((i >> uint(16)) & uint(0xff)),
|
||||
float((i >> uint(24)) & uint(0xff)));
|
||||
}
|
||||
|
||||
// A voxel mesh can have overhangs in any direction,
|
||||
// so we may have to use triplanar mapping functions.
|
||||
vec3 get_triplanar_blend(vec3 world_normal) {
|
||||
vec3 blending = abs(world_normal);
|
||||
blending = normalize(max(blending, vec3(0.00001))); // Force weights to sum to 1.0
|
||||
float b = blending.x + blending.y + blending.z;
|
||||
return blending / vec3(b, b, b);
|
||||
}
|
||||
|
||||
vec4 texture_triplanar(sampler2D tex, vec3 world_pos, vec3 blend) {
|
||||
vec4 xaxis = texture(tex, world_pos.yz);
|
||||
vec4 yaxis = texture(tex, world_pos.xz);
|
||||
vec4 zaxis = texture(tex, world_pos.xy);
|
||||
// blend the results of the 3 planar projections.
|
||||
return xaxis * blend.x + yaxis * blend.y + zaxis * blend.z;
|
||||
}
|
||||
|
||||
float get_hash(vec2 c) {
|
||||
return fract(sin(dot(c.xy, vec2(12.9898,78.233))) * 43758.5453);
|
||||
}
|
||||
|
||||
vec3 get_transvoxel_position(vec3 vertex_pos, vec4 vertex_col) {
|
||||
|
||||
int border_mask = int(vertex_col.a);
|
||||
@@ -23,9 +65,42 @@ vec3 get_transvoxel_position(vec3 vertex_pos, vec4 vertex_col) {
|
||||
}
|
||||
|
||||
void vertex() {
|
||||
VERTEX = get_transvoxel_position(VERTEX, COLOR);
|
||||
// Indices are integer values so we can decode them as-is
|
||||
v_indices = decode_8bit_vec4(UV.x);
|
||||
|
||||
// Weights must be in [0..1] so we divide them
|
||||
v_weights = decode_8bit_vec4(UV.y) / 255.0;
|
||||
|
||||
//v_normal = NORMAL;
|
||||
vec3 world_pos = (WORLD_MATRIX * vec4(VERTEX, 1.0)).xyz;
|
||||
v_world_pos = world_pos;
|
||||
v_world_normal = NORMAL;
|
||||
|
||||
VERTEX = get_transvoxel_position(VERTEX, COLOR);
|
||||
}
|
||||
|
||||
void fragment() {
|
||||
ALBEDO = vec3(1, 1, 0);
|
||||
vec3 normal = v_world_normal;//normalize(v_world_normal);
|
||||
vec3 wpos = v_world_pos * 0.2;
|
||||
// Sample the 4 blending textures, all with triplanar mapping.
|
||||
// We can re-use the same triplanar blending factors for all of them so separating that part
|
||||
// of the function improves performance a little.
|
||||
vec3 blending = get_triplanar_blend(v_world_normal);
|
||||
|
||||
vec3 top_col = texture_triplanar(u_texture_top, wpos, blending).rgb;
|
||||
vec3 side_col = texture_triplanar(u_texture_sides, wpos, blending).rgb;
|
||||
|
||||
// Get weights and make sure they are normalized.
|
||||
// We may add a tiny safety margin so we can afford some degree of error.
|
||||
vec4 weights = v_weights;
|
||||
weights /= (weights.x + weights.y + weights.z + weights.w + 0.00001);
|
||||
|
||||
// Calculate albedo
|
||||
//vec3 col =
|
||||
// col0 * weights.r +
|
||||
// col1 * weights.g +
|
||||
// col2 * weights.b +
|
||||
// col3 * weights.a;
|
||||
float r = top_col.r;
|
||||
ALBEDO = mix(side_col, top_col, clamp(normal.y * 10.0 - 4.0 - 8.0*r, 0.0, 1.0));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user