Merge grass/far into main (gathering every branch; main's side kept on conflicts)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
commit
e72a4d0a13
5 changed files with 40 additions and 2 deletions
|
|
@ -518,6 +518,28 @@ function gvk_layer_views_drop(render3d_st: mut Render3dState, tex: int) -> void
|
|||
while len(texs) > w { List.pop(texs) }
|
||||
}
|
||||
|
||||
# the per-level and per-layer views gvk_view_of made of a texture go with it: kept, each held its
|
||||
# old Metal texture alive, so every rebuild of the screen targets left the last set's memory behind
|
||||
function gvk_layer_views_drop(render3d_st: mut Render3dState, tex: int) -> void {
|
||||
if render3d_st.gvk_layer_views == null { return }
|
||||
let keys = render3d_st.gvk_layer_views
|
||||
let views = render3d_st.gvk_layer_view
|
||||
let texs = render3d_st.gvk_layer_view_tex
|
||||
var w = 0
|
||||
for i in 0 .. len(keys) {
|
||||
if texs[i] == tex {
|
||||
render3d_st.gvk_mk_x_view += 1
|
||||
Vk.destroy_image_view(render3d_st.gvk_dev, views[i], null)
|
||||
} else {
|
||||
keys[w] = keys[i]; views[w] = views[i]; texs[w] = texs[i]
|
||||
w += 1
|
||||
}
|
||||
}
|
||||
while len(keys) > w { List.pop(keys) }
|
||||
while len(views) > w { List.pop(views) }
|
||||
while len(texs) > w { List.pop(texs) }
|
||||
}
|
||||
|
||||
# ---- samplers -----------------------------------------------------------------------------
|
||||
# One VkSampler per distinct way of reading a texture, made the first time it is asked for.
|
||||
# The arguments are what the renderer set through gpu_tex_param (0 where it set nothing, which
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ vec3 bladeField(vec2 xz, float y) {
|
|||
// dry and green patches a few metres across, and the tussocks' own shade of the same green
|
||||
float dryp = smoothstep(0.2, 0.8, gnoise(xz * 0.33 + 17.0) * 0.5 + 0.5);
|
||||
t *= mix(vec3(0.92, 1.0, 0.95), vec3(1.30, 1.10, 0.62), dryp);
|
||||
return t * (0.72 + 0.56 * (gnoise(xz * 1.9 + 41.0) * 0.5 + 0.5));
|
||||
return t * (0.55 + 0.80 * (gnoise(xz * 1.9 + 41.0) * 0.5 + 0.5));
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ vec3 bladeField(vec2 xz, float y) {
|
|||
t *= mix(vec3(0.7, 0.8, 0.55), vec3(1.1, 1.05, 0.85), patchy);
|
||||
float dryp = smoothstep(0.2, 0.8, gnoise(xz * 0.33 + 17.0) * 0.5 + 0.5);
|
||||
t *= mix(vec3(0.92, 1.0, 0.95), vec3(1.30, 1.10, 0.62), dryp);
|
||||
return t * (0.72 + 0.56 * (gnoise(xz * 1.9 + 41.0) * 0.5 + 0.5));
|
||||
return t * (0.55 + 0.80 * (gnoise(xz * 1.9 + 41.0) * 0.5 + 0.5));
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@ vec3 terNormal(vec2 uv) { vec2 xz = terNormalXZ(uv); return vec3(xz.x, sqrt(max
|
|||
uniform sampler2D u_rock_d; uniform sampler2D u_rock_n; uniform sampler2D u_rock_a;
|
||||
uniform sampler2D u_snow_d; uniform sampler2D u_carpet; // the clump cards baked straight down (alpha = coverage)
|
||||
uniform float u_carpet_on;
|
||||
uniform float u_grass_reach; // where the GPU blades stop (0: none): the ground under them is in their shade
|
||||
uniform float u_snow_line;
|
||||
uniform float u_lake_level; // the ground just above the water is wet and dark
|
||||
// ---- RAIN THAT LEAVES SOMETHING BEHIND -----------------------------------------------------
|
||||
|
|
@ -410,6 +411,18 @@ vec3 groundShade(vec3 p, vec3 N, float slope, float dist, float viewDepth, bool
|
|||
vec3 cc = cp.rgb * vec3(0.5, 0.57, 0.45) * mix(vec3(0.85, 0.92, 0.9), vec3(1.1, 1.05, 0.85), smoothstep(-0.35, 0.35, N.z)) * (0.75 + 0.35 * lush);
|
||||
gA = mix(gA, cc, max(cp.a, 0.35) * carpetW * 0.97);
|
||||
}
|
||||
// The blades' own patches (grass_cull.comp's bladeField): patchiness and dry patches, so where
|
||||
// the blades thin out the ground they stand on carries the same meadow, not a lawn
|
||||
{
|
||||
float patchy = fbmC(cheap, p.xz * 0.045, 3) * 0.5 + 0.5;
|
||||
float dryp = smoothstep(0.2, 0.8, gnoise(p.xz * 0.33 + 17.0) * 0.5 + 0.5);
|
||||
vec3 pf = mix(vec3(0.7, 0.8, 0.55), vec3(1.1, 1.05, 0.85), patchy) * mix(vec3(0.92, 1.0, 0.95), vec3(1.30, 1.10, 0.62), dryp);
|
||||
// and the tussocks' own shade, half a metre across: where blades stand a pixel wide the ground
|
||||
// is most of what shows, and it has to carry the same light and dark as the blades on it
|
||||
float tus = 0.55 + 0.80 * (gnoise(p.xz * 1.9 + 41.0) * 0.5 + 0.5);
|
||||
gA *= mix(vec3(1.0), pf / vec3(0.95, 0.96, 0.72) * tus, grassW);
|
||||
if (u_grass_reach > 0.0) gA *= mix(1.0, mix(0.50, 1.0, smoothstep(u_grass_reach * 0.25, u_grass_reach, dist)), grassW);
|
||||
}
|
||||
// Subalpine forest floor: dark duff where the stands are dense. The photograph-driven
|
||||
// term marks duff only where the survey actually shows dense conifer, and is the same
|
||||
// at any distance — ground shading must not depend on where the viewer is.
|
||||
|
|
|
|||
|
|
@ -493,6 +493,9 @@ function terrain_bind_prog(render3d_st: mut Render3dState, p: int) -> void {
|
|||
r3d_bind_2d(render3d_st, p, "u_snow_d", 10, render3d_st.ter_tex[9])
|
||||
if render3d_st.ter_carpet != 0 { r3d_bind_2d(render3d_st, p, "u_carpet", 11, render3d_st.ter_carpet); u_f(render3d_st, gpu_uniform(render3d_st, p, "u_carpet_on"), 1.0) }
|
||||
else { r3d_bind_2d(render3d_st, p, "u_carpet", 11, render3d_st.ter_tex[0]); u_f(render3d_st, gpu_uniform(render3d_st, p, "u_carpet_on"), 0.0) }
|
||||
var reach = 0.0
|
||||
if grass_live(render3d_st) { reach = render3d_st.grass_radius }
|
||||
u_f(render3d_st, gpu_uniform(render3d_st, p, "u_grass_reach"), reach)
|
||||
u_f(render3d_st, gpu_uniform(render3d_st, p, "u_half"), float(render3d_st.TERRAIN_HALF))
|
||||
u_f(render3d_st, gpu_uniform(render3d_st, p, "u_texel"), 1.0 / float(TERRAIN_RES))
|
||||
u_f(render3d_st, gpu_uniform(render3d_st, p, "u_snow_line"), render3d_st.ter_snow_line)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue