Grass Grid Shader

A Grass Grid Shader.

 

Shader code
/*
	格子草シェーダー by あるる(きのもと 結衣) @arlez80
	Grid Grass Shader by Yui Kinomoto @arlez80

	MIT License
*/
shader_type spatial;

// 草画像
uniform sampler2D albedo_tex : hint_albedo;
// 格子サイズ
uniform float grid = 0.54;
// 草の高さ
uniform float height = 1.0;
// 揺れ度合い
uniform vec3 frequency_rate = vec3( 0.03, 0.0, 0.06 );
// 揺れ速度
uniform float frequency_speed = 1.0;
// 重ねる回数
uniform int overlap_count = 12;

uniform float metallic = 0.2;
uniform float roughness = 0.2;

// モデル/ローカル座標
varying vec3 model_vertex;

void vertex( )
{
	model_vertex = VERTEX;
}

/**
 * 面チェック
 */
void check_surface( int i, float ray_dir, float surface_plane, inout float min_t, inout int id )
{
	float old_min_t = min_t;
	bool is_flip = ray_dir < 0.0;
	float t = - ( surface_plane + float( is_flip ) * grid ) / ray_dir;
	min_t = min( min_t, t );
	id = max( id, ( int( is_flip ) + i * 2 ) * int( min_t < old_min_t ) );
}

void fragment( )
{
	vec3 ray_dir = ( -( vec4( VIEW, 1.0 ) ) * INV_CAMERA_MATRIX ).xyz;
	vec3 surface = mod( model_vertex, -vec3( grid ) );

	// 格子チェック
	vec4 color = vec4( 0.0, 0.0, 0.0, 0.0 );
	float t = TIME * frequency_speed;
	for( int i=0; i<overlap_count; i++ ) {
		float min_t = 1e10;
		int id = -1;
		check_surface( 0, ray_dir.x, surface.x, min_t, id );
		check_surface( 2, ray_dir.z, surface.z, min_t, id );

		vec3 hit = model_vertex + min_t * ray_dir;
		hit.y = clamp( -hit.y, -height, 0.0 ) / height;

		hit.x += sin( t ) * frequency_rate.x * hit.y;// + float(i) * 0.7;
		hit.z += cos( t ) * frequency_rate.z * hit.y;// - float(i) * 0.7;

		// 色決定
		vec4 new_color = (
			// X+ X-
			textureLod( albedo_tex, vec2( hit.z, hit.y ), 0 ) * float( id == 0 || id == 1 )
			// Z+ Z-
		+	textureLod( albedo_tex, vec2( hit.x, hit.y ), 0 ) * float( id == 4 || id == 5 )
		);
		new_color.a *= float( -0.995 < hit.y && hit.y < 0.0 );
		NORMAL = mix(
			( INV_CAMERA_MATRIX * WORLD_MATRIX * 
			vec4(
				- float( id == 0 ) + float( id == 1 )
			,	0.0
			,	- float( id == 4 ) + float( id == 5 )
			,	0.0
			) ).xyz
		,	NORMAL
		,	color.a
		);
		color.rgb = mix( new_color.rgb, color.rgb, clamp( color.a + 1.0 - new_color.a, 0.0, 1.0 ) );
		color.a = max( color.a, new_color.a );
		surface.x -= sign( ray_dir.x ) * float( id == 0 || id == 1 ) * grid;
		surface.z -= sign( ray_dir.z ) * float( id == 4 || id == 5 ) * grid;
	}
	ALBEDO = color.rgb;
	ALPHA = color.a;
	METALLIC = metallic;
	ROUGHNESS = roughness;
}
Tags
grass
The shader code and all code snippets in this post are under MIT license and can be used freely. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

More from arlez80

Procedural Marble Shader

Electric Hatch Background Shader

Soap Bubble Shader

Related shaders

Dashed Grid (The Best Darn Grid Shader (Yet))

Grass shader

Stylized Multimesh Grass Shader

Subscribe
Notify of
guest

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Instructions
Instructions
1 day ago

Quite interesting, thanks for sharing!!