Here is the most basic version. It has some problems when the obstacle is inside the geometry. One fix is to move the grass slightly away from the obstacle as it gets close, but it looks weird if the ground is visible. Works when you only see the top of the grass though.
It’s a few additions to the standard Windy Grass shader from the Nature pack:
Firts off there’s a global shader color: _Obstacle. Use Shader.SetGlobalColor to get the obstacle position to the shader.
Then the main block (/OBSTACLE AVOIDANCE CALC). The windy grass shader already calculates the world position for vertices so use that and compare with obstacle position to get bend direction vector. Also calculate distance falloff.
Finally we add the bend offset exponentially - v.vertex.xz += …
We could also swap v.texcoord.y for let’s say v.color.r and paint the ‘bendyness’ into the model using vertex colors to have some parts softer than others. Doesn’t really make sense for a simple thing like a grass straw though, but could be cool for more complex models.
Note:
And all this is not really bending, but stretching or skewing so the geometry can look strange sometimes. Feel free to fix 
Shader "Nature/Windy Grass" {
Properties {
_Color ("Main Color", Color) = (.5, .5, .5, 0)
_Color2 ("Fade Color", Color) = (1, .9, .8, 0)
_MainTex ("Base (RGB) Alpha (A)", 2D) = "white" {}
_Cutoff ("Base Alpha cutoff", Range (0,1)) = .5
}
SubShader {
Tags { "Queue" = "Transparent" }
BindChannels {
Bind "Color", color
Bind "Vertex", vertex
Bind "TexCoord", texcoord
}
Pass {
Lighting On
CGPROGRAM
// vertex Vertex
#include "waves.cginc" // Get in the helper wave functions
#include "UnityCG.cginc" // Get standard Unity constants
struct Appdata {
float4 vertex;
float3 normal;
float4 texcoord;
float4 color;
};
struct v2f {
float4 pos : POSITION;
float4 color : COLOR0;
float4 uv : TEXCOORD0;
float fog : FOGC;
};
uniform float4 _Color, _Color2, _SkyLight;
uniform float4 _Obstacle; // OBSTACLE AVOIDANCE
v2f Vertex(Appdata v) {
v2f o;
const float4 _waveXSize = float4(0.012, 0.02, -0.06, 0.048) * 2;
const float4 _waveZSize = float4 (0.006, .02, -0.02, 0.1) * 2;
const float4 waveSpeed = float4 (0.3, .3, .08, .07) * 4;
float4 _waveXmove = _waveXSize * waveSpeed * 25;
float4 _waveZmove = _waveZSize * waveSpeed * 25;
// We model the wind as basic waves...
// Calculate the wind input to leaves from their vertex positions....
// for now, we transform them into world-space x/z positions...
// Later on, we should actually be able to do the whole calc's in post-projective space
float3 worldPos = mul ((float3x4)_Object2World, v.vertex);
// OBSTACLE AVOIDANCE CALC
float3 bendDir = normalize (float3(worldPos.x,0,worldPos.z) - float3(_Obstacle.x,0,_Obstacle.z));//direction of obstacle bend
float distLimit = 3;// how far away does obstacle reach
float distMulti = (distLimit-min(distLimit,distance(float3(worldPos.x,0,worldPos.z),float3(_Obstacle.x,0,_Obstacle.z))))/distLimit; //distance falloff
//OBSTACLE AVOIDANCE END
// This is the input to the sinusiodal warp
float4 waves;
waves = worldPos.x * _waveXSize;
waves += worldPos.z * _waveZSize;
// Add in time to model them over time
waves += _Time.x * waveSpeed;
float4 s, c;
waves = frac (waves);
FastSinCos (waves, s,c);
float waveAmount = v.texcoord.y;
s *= waveAmount;
// Faste winds move the grass more than slow winds
s *= normalize (waveSpeed);
s = s * s;
float fade = dot (s, 1.3);
s = s * s;
float3 waveMove = float3 (0,0,0);
waveMove.x = dot (s, _waveXmove);
waveMove.z = dot (s, _waveZmove);
v.vertex.xz -= mul ((float3x3)_World2Object, waveMove).xz;
v.vertex.xz += bendDir.xz*distMulti*v.texcoord.y*v.texcoord.y*1.5; //ADD OBSTACLE BENDING
o.pos = mul(glstate.matrix.mvp, v.vertex);
o.fog = o.pos.w;
o.uv = v.texcoord;
o.color = lerp (_Color, _Color2, fade.xxxx);
// o.color *= _SkyLight;
return o;
}
ENDCG
AlphaTest Greater [_Cutoff]
Cull Off
SetTexture [_MainTex] { combine texture * primary double, texture}
}
}
SubShader {
Tags { "Queue" = "Transparent" }
Pass {
Blend SrcAlpha oneMinusSrcAlpha
AlphaTest Greater [_Cutoff]
Cull Off
color [_Color]
ZTest Less
SetTexture [_MainTex] { combine texture * primary DOUBLE, texture}
}
}
}
/P