yum-archive/SoggyShaders

Old Unity shaders.

git clone https://git.yummers.dev/yum-archive/SoggyShaders

yumDelete far-away grass in geometry shaderdb026d3

master
6.0 KiB240 linesraw
1#ifndef GRASS_LIGHTING
2#define GRASS_LIGHTING
3
4#include "AutoLight.cginc"
5#include "iq_sdf.cginc"
6#include "math.cginc"
7#include "motion.cginc"
8#include "pbr.cginc"
9#include "poi.cginc"
10#include "shadertoy.cginc"
11
12sampler2D _BaseColor;
13sampler2D _Normal;
14sampler2D _Metallic;
15sampler2D _Roughness;
16sampler2D _Wind_Speed;
17float4 _Offset;
18
19bool _Disable_Normal_Texture;
20
21sampler2D _Height;
22float _Height_LOD;
23float _Height_Exponent;
24float _Height_Scale;
25float _Height_Speed_X;
26float _Height_Speed_Y;
27float _Height_AA_Sample_Scale;
28
29sampler2D _Height_Mask;
30float _Height_Mask_Exponent;
31
32float _Center_Out_Speed;
33float _Center_Out_Sharpness;
34float _Center_Out_Min_Radius;
35float _Center_Out_Max_Radius;
36
37struct appdata
38{
39  float4 position : POSITION;
40  float2 uv : TEXCOORD0;
41  float3 normal : NORMAL;
42};
43
44void getVertexLightColor(inout v2f i)
45{
46  #if defined(VERTEXLIGHT_ON)
47  float3 light_pos = float3(unity_4LightPosX0.x, unity_4LightPosY0.x,
48      unity_4LightPosZ0.x);
49  float3 light_float = light_pos - i.worldPos;
50  float3 light_dir = normalize(light_float);
51  float ndotl = DotClamped(i.normal, light_dir);
52  // Light fills an expanding sphere with surface area 4 * pi * r^2.
53  // By conservation of energy, this means that at distance r, light intensity
54  // is proportional to 1/(r^2).
55  float attenuation = 1 / (1 + dot(light_float, light_float) * unity_4LightAtten0.x);
56  i.vertexLightColor = unity_LightColor[0].rgb * ndotl * attenuation;
57
58  i.vertexLightColor = Shade4PointLights(
59    unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0,
60    unity_LightColor[0].rgb,
61    unity_LightColor[1].rgb,
62    unity_LightColor[2].rgb,
63    unity_LightColor[3].rgb,
64    unity_4LightAtten0, i.worldPos, i.normal
65  );
66  #endif
67}
68
69v2f vert(appdata v)
70{
71  v2f o;
72
73  o.objPos = v.position;
74  o.clipPos = UnityObjectToClipPos(v.position);
75  o.worldPos = mul(unity_ObjectToWorld, v.position);
76
77  o.normal = UnityObjectToWorldNormal(v.normal);
78  o.uv = v.uv;
79
80  getVertexLightColor(o);
81
82  return o;
83}
84
85// maxvertexcount == the number of vertices we create
86[maxvertexcount(48)]
87void geom(triangle v2f tri_in[3],
88  uint pid: SV_PrimitiveID,
89  inout TriangleStream<v2f> tri_out)
90{
91  // Generate copies.
92  for (int x = 0; x < 4; x++)
93  for (int y = 0; y < 4; y++) {
94    float xoff = (x - 1) * 10;
95    float yoff = (y - 1) * 10;
96    xoff += _Offset.x;
97    yoff += _Offset.y;
98
99    v2f v0 = tri_in[0];
100    v2f v1 = tri_in[1];
101    v2f v2 = tri_in[2];
102
103    v0.worldPos += float3(xoff, 0, yoff);
104    v1.worldPos += float3(xoff, 0, yoff);
105    v2.worldPos += float3(xoff, 0, yoff);
106
107    // Don't bother rendering geometry if it's too far away.
108    if (length(v0.worldPos - _WorldSpaceCameraPos) > 35) {
109      continue;
110    }
111
112    // Omit polygons in blacklisted regions.
113    {
114      float2 p0 = float2(-4, 0);
115      float2 p1 = float2(8, 6);
116      p0 -= 0.2;
117      p1 += 0.2;
118      if (v0.worldPos.x > p0.x &&
119          v0.worldPos.z > p0.y &&
120          v0.worldPos.x < p1.x &&
121          v0.worldPos.z < p1.y) {
122        continue;
123      }
124      p0 = float2(1.5, 6);
125      p1 = float2(2.5, 24);
126      p0 -= 0.2;
127      p1 += 0.2;
128      if (v0.worldPos.x > p0.x &&
129          v0.worldPos.z > p0.y &&
130          v0.worldPos.x < p1.x &&
131          v0.worldPos.z < p1.y) {
132        continue;
133      }
134    }
135
136    // Apply wind using a noise texture.
137    for (int i = 0; i < 3; i++)
138    {
139      float3 vertex_pos;
140      [forcecase] switch (i) {
141        case 0:
142          vertex_pos = v0.worldPos;
143          break;
144        case 1:
145          vertex_pos = v1.worldPos;
146          break;
147        case 2:
148          vertex_pos = v2.worldPos;
149          break;
150        default:
151          vertex_pos = 0;
152          break;
153      }
154      float3 wind_point = vertex_pos;
155      wind_point *= .02;
156      wind_point.x -= _Time[0]/2;
157      float dx = .02;
158
159      float w0 = tex2Dlod(_Wind_Speed, float4(wind_point.x, wind_point.z, 0, 0));
160      float w1 = tex2Dlod(_Wind_Speed, float4(wind_point.x + dx, wind_point.z, 0, 0));
161      float w2 = tex2Dlod(_Wind_Speed, float4(wind_point.x, wind_point.z + dx, 0, 0));
162
163      float2 wind_speed = float2(w1 - w0, w2 - w0);
164      wind_speed *= 4;
165      wind_speed *= vertex_pos.y;
166
167      [forcecase] switch (i) {
168        case 0:
169          v0.worldPos += float3(wind_speed.x, 0, wind_speed.y);
170          break;
171        case 1:
172          v1.worldPos += float3(wind_speed.x, 0, wind_speed.y);
173          break;
174        case 2:
175          v2.worldPos += float3(wind_speed.x, 0, wind_speed.y);
176          break;
177      }
178    }
179
180    // Apply transformed worldPos to other coordinate systems.
181    v0.objPos = mul(unity_WorldToObject, v0.worldPos);
182    v1.objPos = mul(unity_WorldToObject, v1.worldPos);
183    v2.objPos = mul(unity_WorldToObject, v2.worldPos);
184
185    v0.clipPos = UnityObjectToClipPos(v0.objPos);
186    v1.clipPos = UnityObjectToClipPos(v1.objPos);
187    v2.clipPos = UnityObjectToClipPos(v2.objPos);
188
189    // Output transformed geometry.
190    tri_out.Append(v0);
191    tri_out.Append(v1);
192    tri_out.Append(v2);
193    tri_out.RestartStrip();
194  }
195}
196
197float4 effect(inout v2f i)
198{
199  float4 albedo;
200  {
201    float3 green = HSVtoRGB(float3(.333, .60, .70));
202    float3 brown = HSVtoRGB(float3(.113, .59, .65));
203    float uv_t0 = .85;
204    float uv_t1 = .50;
205    float uv_phase = (i.uv.y - uv_t0) / (uv_t1 - uv_t0);
206    uv_phase = clamp(uv_phase, 0, 1);
207    float3 c = lerp(brown, green, uv_phase);
208    albedo = float4(c, 1.0);
209  }
210  // Poor man's ambient occlusion
211  albedo *= clamp(i.worldPos.y - .03, 0, 1) * 4;
212
213  float3 normal = i.normal;
214  // Rotate the normals a little to make the blades of grass appear more
215  // rounded.
216  {
217    float3 nt = mul(unity_WorldToObject, float4(normal, 1.0)).xyz;
218    float theta = 1.2;
219    theta = (i.uv.x - 0.5) * 2 * theta;
220    float2x2 rot = float2x2(
221        cos(theta), -sin(theta),
222        sin(theta), cos(theta));
223    nt.xz = mul(rot, nt.xz);
224    normal = mul(unity_ObjectToWorld, float4(nt, 1.0)).xyz;
225  }
226
227  float metallic = 0.5;
228  float roughness = 0.2;
229
230  return getLitColor(i, albedo, i.worldPos, normal, metallic, 1.0 - roughness,
231      /*custom_cubemap=*/true);
232}
233
234fixed4 frag(v2f i) : SV_Target
235{
236  return effect(i);
237}
238
239#endif  // GRASS_LIGHTING
240