I wanted to show an example of what I am talking about.
You see I have 9 single planes, the mode you see at the end is the overdraw showing there are only 9, but with the below it fakes a few layers. This will be betrayed when you see the grass from more and more glancing angles, and there are ways of fading it so you can blend to maybe another card pointing the other ways, but that’s for later.
The texture I used has 4 layers, with an alpha channel:
Then the shader code looks like, probably better ways of doing some of this for sure, but this seems to work.
shader_type spatial;
render_mode depth_prepass_alpha;
uniform sampler2D main_texture : source_color,repeat_disable;
uniform float push_back;
varying vec3 p;
varying vec3 vertex_normal_ws;
varying vec3 cam_pos_normalized;
void vertex()
{
p = ((MODEL_MATRIX)*vec4(VERTEX,1.0)).xyz;
vertex_normal_ws = ((MODEL_MATRIX)*vec4(NORMAL,1.0)).xyz;
}
vec2 get_layer_uvs(float layer, float layers, vec2 in_uvs)
{
vec2 offset = vec2(layer / layers,0.);
vec2 pushed_uvs = ((in_uvs + (cam_pos_normalized * push_back * layer).xy) / vec2(layers, 1.)) + offset;
float start_pos = .25 * layer;
float end_pos = start_pos + .25;
return vec2(min(max(pushed_uvs.x, start_pos), end_pos), pushed_uvs.y);
}
float clamp_alpha(float alpha)
{
float contrasted = (alpha -.45) / (.55 -.45);
return clamp(contrasted, .0, 1.);
}
void fragment()
{
cam_pos_normalized = normalize(p - CAMERA_POSITION_WORLD);
vec2 forward_mid_uvs = UV / vec2(4.,1.);
vec2 pushed_mid_uvs = get_layer_uvs(1., 4., UV);
vec2 pushed_back_uvs = get_layer_uvs(2., 4., UV);
vec2 pushed_back_back_uvs = get_layer_uvs(3., 4., UV);
vec4 forward_layer = texture(main_texture, forward_mid_uvs);
vec4 mid_layer = texture(main_texture, pushed_mid_uvs);
vec4 back_layer = texture(main_texture, pushed_back_uvs);
vec4 back_back_layer = texture(main_texture, pushed_back_back_uvs);
forward_layer.a = clamp_alpha(forward_layer.a);
mid_layer.a = clamp_alpha(mid_layer.a);
back_layer.a = clamp_alpha(back_layer.a);
back_back_layer.a = clamp_alpha(back_back_layer.a);
vec4 layers = mix(mix(mix(back_back_layer, back_layer,back_layer.a),mid_layer,mid_layer.a), forward_layer, forward_layer.a) ;
ALBEDO = layers.rgb;
ALPHA = layers.a;
}
EDIT: I think this can be done without fetching the same texture 4 times, may be worth a try.