How to render color for a whole MultiMeshInstance3D?
Asked Answered
F

2

0

I want to accomplish the effect like this video:

So I use wind grass shader from: https://godotshaders.com/shader/stylized-grass-with-wind-and-deformation/

Wind is cool, but problem is how to render color for a whole MultiMeshInstance3D?

My samlpe2D set-up is:

if i use shader like this, it will be guly, because UV is for each mesh but not for MultiMeshInstance3D

uniform sampler2D color_sample;
void fragment() {
	ALBEDO = texture(color_sample, UV).rgb;
}

result:

And I try to transform NODE_POSITION_WORLD to uv of MultiMeshInstance3D, but i fail:

uniform float wind_texture_tile_size = 20.0;

uniform sampler2D color_sample;

vec2 pos_world_to_uv_world(vec2 pos_world){
	pos_world += vec2(wind_texture_tile_size, wind_texture_tile_size)/2.0;
	vec2 uv_world = pos_world/(wind_texture_tile_size/2.0);
	return uv_world;
}

void fragment() {
	vec2 uv_world = pos_world_to_uv_world(NODE_POSITION_WORLD.xz);
	ALBEDO = texture(color_sample, uv_world).rgb;
}

result:

I am sure my wind_texture_tile_size in inspector is set rightly, and I have used vertex() verify my uv_world is correctly form 0 to 1 :

void vertex() {
	VERTEX.y += pos_world_to_uv_world(NODE_POSITION_WORLD.xz).x;
}

result:

how can I do next?


update:

I use this to test and found NODE_POSITION_WORLD in fragment() is always the MultiMeshInstance3D node transform.global_position property...

void fragment() {
	vec2 uv_world = pos_world_to_uv_world(NODE_POSITION_WORLD.xz);
	ALBEDO = vec3(uv_world.x, uv_world.y, 1.0);
}
Frascati answered 23/1, 2023 at 6:33 Comment(0)
F
0

OK, I know. NODE_POSITION_WORLD in vertex() is truly each global position of mesh instances in MultiMeshInstance3D, but NODE_POSITION_WORLD in fragment() is always the global_position of MultiMeshInstance3D node. What I need is caculate uv_world in vertex() and then pass it to fragment()

So it make it:

uniform float wind_texture_tile_size = 20.0;

uniform sampler2D color_ramp;
uniform sampler2D color_sample;

varying vec2 vertex_uv_world;

vec2 pos_world_to_uv_world(vec2 pos_world){
	pos_world += vec2(wind_texture_tile_size, wind_texture_tile_size)/2.0;
	vec2 uv_world = pos_world/wind_texture_tile_size;
	return uv_world;
}

void vertex() {
	vertex_uv_world = pos_world_to_uv_world(NODE_POSITION_WORLD.xz);
}

void fragment() {
	vec3 color_damp = texture(color_ramp, vec2(1.0 - UV.y, 0.0)).rgb;
	ALBEDO = color_damp * texture(color_sample, vertex_uv_world).rgb;
}

set-up:

result:

Frascati answered 23/1, 2023 at 7:11 Comment(0)
T
0

Oh, that's pretty cool.

Taction answered 23/1, 2023 at 7:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.