Hey folks. So, I’m working on the biggest shader I’ve written so far - a humble grass shader. But I need this shader to apply to a host of weird, knotty tree things, which cover the walls of a cave - and they should all move somewhat in unison, as if seaweed swaying in the tide.
Unfortunately, my trees currently look more like this - ‘epileptic trees’, if you get the LOST reference. The individual ‘branches’ are shaking at the vertex level, and my attempts to fix my problems by changing the environment size and my perlin noise texture don’t seem to be having any effect.
The script was originally inspired by Linden Reid’s grass shader, though I wanted it working with the Standard Shader. There’s also a lot of Jose M. Olea’s grass shader in this… but I seem to have screwed it up royally.
Can anybody please point me in the right direction? I’m really lost in the weeds (no pun intended) here.
My shader code…
Shader "RS/WindGrassRS"
{
Properties
{
// Surface shader parameters
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
// Wind effect parameters
_WindDirection ("Wind Direction", vector) = (1,0, 1,0)
_WindTex ("Wind Texture", 2D) = "white" {}
_WorldSize ("World Size", vector) = (1,1,1,1)
_WindSpeed ("Wind Speed", vector) = (1,1,1,1)
}
SubShader
{
Tags {"RenderType" = "Opaque"}
LOD 200
CGPROGRAM
#pragma surface surf Standard vertex:vert
struct Input
{
float2 uv_MainTex;
};
sampler2D _MainTex;
half _Glossiness;
half _Metallic;
fixed4 _Color;
float3 _WindDirection;
sampler2D _WindTex;
float4 _WorldSize;
float4 _WindSpeed;
// our vert modification function
void vert( inout appdata_full v )
{
float4 localSpaceVertex = v.vertex;
// Takes the mesh's verts and turns it into a point in world space
// this is the equivalent of Transform.TransformPoint on the scripting side
float4 worldSpaceVertex = mul( unity_ObjectToWorld, localSpaceVertex );
// normalize position based on world Size
float2 samplePos = ((worldSpaceVertex.xz + _WorldSize.xz/2) / _WorldSize.xz);
// scroll sample position based on time
samplePos += _Time.x * _WindSpeed.xy;
// Sample wind texture
float windSample = tex2Dlod (_WindTex, float4(samplePos, 0, 0));
// Height of the vertex in the range (0,1)
float height = (localSpaceVertex.y/2 + .5);
float sineX = sin(worldSpaceVertex.x * windSample);
float sineZ = sin(worldSpaceVertex.z * windSample);
worldSpaceVertex.x += sineX * height * _WindDirection.x * v.color;
worldSpaceVertex.z += sineZ * height * _WindDirection.z * v.color;
// takes the new modified position of the vert in world space and then puts it back in local space
v.vertex = mul( unity_WorldToObject, worldSpaceVertex );
}
void surf (Input IN, inout SurfaceOutputStandard o)
{
// Albedo comes from a texture tinted by color
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
// Metallic and smoothness come from slider variables
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}