yum-archive/SoggyShaders

Old Unity shaders.

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

yumCheck in cloud shader8427cb4

master
5.3 KiB195 linesraw
1#ifndef CLOUD_LIGHTING
2#define CLOUD_LIGHTING
3
4#include "AutoLight.cginc"
5#include "UnityPBSLighting.cginc"
6#include "iq_sdf.cginc"
7#include "math.cginc"
8#include "Motion.cginc"
9#include "pbr.cginc"
10#include "pema99.cginc"
11
12#define MY_COORD_SCALE 100
13#define MY_COORD_SCALE_INV 1.0 / MY_COORD_SCALE
14#define OBJ_SPACE_TO_MINE \
15  float4x4( \
16      MY_COORD_SCALE, 0, 0, 0, \
17      0, MY_COORD_SCALE, 0, 0, \
18      0, 0, MY_COORD_SCALE, 0, \
19      0, 0, 0, MY_COORD_SCALE \
20      )
21#define WORLD_SPACE_TO_MINE \
22  mul(unity_WorldToObject, OBJ_SPACE_TO_MINE)
23#define MY_SPACE_TO_OBJ \
24  float4x4( \
25      MY_COORD_SCALE_INV, 0, 0, 0, \
26      0, MY_COORD_SCALE_INV, 0, 0, \
27      0, 0, MY_COORD_SCALE_INV, 0, \
28      0, 0, 0, MY_COORD_SCALE_INV \
29      )
30#define MY_SPACE_TO_WORLD \
31  mul(MY_SPACE_TO_OBJ, unity_ObjectToWorld)
32
33#define MINIMUM_HIT_DISTANCE .00002 * MY_COORD_SCALE
34#define MAXIMUM_TRACE_DISTANCE 20 * MY_COORD_SCALE
35
36float _Ball_Height;
37float _Ball_Scale;
38float _Cloud_Y_Off;
39float _Cloud_Opacity;
40float _Cloud_W;
41float _Cloud_Scale;
42float _Sphere_Scale;
43float _Global_Scale;
44float4 _Orientation;
45float3 _Offset;
46
47// Return the density of the mist at position `p`.
48float mist_map(float3 p)
49{
50  float scale = MY_COORD_SCALE * _Global_Scale;
51  float dist_fade = max(length(p / scale) - .8, 0) * 12;
52  dist_fade = 1 / (1 + dist_fade);
53
54  p.x += _Time[0] * scale * .1;
55  float noise = clamp(fbm(p * _Cloud_Scale / scale, /*n_octaves=*/5, _Cloud_W), 0, 1);
56  noise *= noise;
57
58  // On [0,1]
59  float y_fade = p.y / scale + .5;
60  y_fade -= _Cloud_Y_Off;
61  y_fade = max(0, y_fade);
62  y_fade = 1 - y_fade;
63  noise *= y_fade;
64
65  return clamp(noise * dist_fade, 0, 1);
66}
67
68float3 mist_march(float3 ro, float3 rd, out float density)
69{
70  float3 current_position;
71#define CLOUD_MARCH_ITER 7
72  float scale = MY_COORD_SCALE * _Global_Scale;
73  float step_sz = (float(scale) / CLOUD_MARCH_ITER);
74  float total_distance = (CLOUD_MARCH_ITER - 1) * step_sz;
75
76  // Dither starting point to avoid color banding
77  total_distance += step_sz * rand3(ro.xyz);
78
79  float mist_v = 0;
80  for (int i = CLOUD_MARCH_ITER - 1; (i >= 0); --i)
81  {
82    current_position = ro + total_distance * rd;
83
84    float4 cur_world_pos = mul(MY_SPACE_TO_WORLD, float4(current_position, MY_COORD_SCALE));
85    float d0 = getWorldSpaceDepth(cur_world_pos);
86    float d1 = getDepthBufferAt(cur_world_pos);
87    //bool use_result = (d0 < d1);
88    bool use_result = true;
89    {
90      float3 axis = _Orientation.xyz;
91      float theta = _Orientation.w;
92
93      Quaternion q = Quaternion(axis * cos(theta/2), sin(theta/2));
94      current_position = qrot(current_position, q);
95    }
96
97    float cur_v = mist_map(current_position) * _Cloud_Opacity;
98    float new_mist = cur_v + mist_v * (1 - cur_v);
99    mist_v = lerp(mist_v, new_mist, use_result);
100
101    total_distance -= step_sz;
102  }
103
104  density = mist_v;
105
106  return current_position;
107}
108
109float4 mist_ray_march(float3 ro, float3 rd, inout v2f v2f_i)
110{
111  float density;
112  float3 final_pos = mist_march(ro, rd, density);
113
114  // Mist scatters light. The denser it is, the more it scatters it.
115  float r0 = rand3(v2f_i.worldPos + float3(_Time[0], 0, 0));
116  float r1 = rand3(v2f_i.worldPos + float3(0, _Time[0], 0));
117  float r2 = rand3(v2f_i.worldPos + float3(0, 0, _Time[0]));
118  v2f_i.normal = normalize(v2f_i.normal + density * normalize(float3(r0, r1, r2)));
119
120  density = pow(density, 2) * 2;
121  density = smoothstep_quintic(density);
122  return float4(1, 1, 1, density);
123}
124
125float4 ray_march(inout v2f v2f_i)
126{
127  float4 ray_march_color;
128  {
129    float3 camera_position = mul(WORLD_SPACE_TO_MINE, float4(_WorldSpaceCameraPos, 1.0)).xyz;
130    float3 ro = camera_position;
131    float3 mesh_position = mul(WORLD_SPACE_TO_MINE, v2f_i.worldPos).xyz;
132    float3 rd = normalize(mesh_position - ro);
133    ro = mesh_position;
134
135    float4 mist_color = mist_ray_march(ro, rd, v2f_i);
136    ray_march_color = clamp(mist_color, 0, 1);
137  }
138
139  return ray_march_color;
140}
141
142void getVertexLightColor(inout v2f i)
143{
144  #if defined(VERTEXLIGHT_ON)
145  float3 light_pos = float3(unity_4LightPosX0.x, unity_4LightPosY0.x,
146      unity_4LightPosZ0.x);
147  float3 light_vec = light_pos - i.worldPos;
148  float3 light_dir = normalize(light_vec);
149  float ndotl = DotClamped(i.normal, light_dir);
150  // Light fills an expanding sphere with surface area 4 * pi * r^2.
151  // By conservation of energy, this means that at distance r, light intensity
152  // is proportional to 1/(r^2).
153  float attenuation = 1 / (1 + dot(light_vec, light_vec) * unity_4LightAtten0.x);
154  i.vertexLightColor = unity_LightColor[0].rgb * ndotl * attenuation;
155
156  i.vertexLightColor = Shade4PointLights(
157    unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0,
158    unity_LightColor[0].rgb,
159    unity_LightColor[1].rgb,
160    unity_LightColor[2].rgb,
161    unity_LightColor[3].rgb,
162    unity_4LightAtten0, i.worldPos, i.normal
163  );
164  #endif
165}
166
167v2f vert(appdata v)
168{
169  v2f o;
170  o.position = UnityObjectToClipPos(v.position);
171  o.worldPos = mul(unity_ObjectToWorld, v.position);
172  o.normal = UnityObjectToWorldNormal(v.normal);
173
174  o.uv = v.uv;
175  getVertexLightColor(o);
176
177  return o;
178}
179
180fixed4 frag(v2f i) : SV_Target
181{
182  float4 mist_unlit = ray_march(i);
183
184  float4 mist_lit = light(
185      i,
186      mist_unlit,
187      /*metallic=*/0,
188      /*smoothness=*/0.7);
189  float emission_str = 1.0;
190  float4 mist_color = mist_lit + float4((mist_unlit * emission_str).xyz, 0);
191
192  return mist_color;
193}
194
195#endif  // CLOUD_LIGHTING