yum-archive/SoggyShaders

Old Unity shaders.

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

yumAdd scaling to avatar cloning shaderad7e60e

master
9.2 KiB334 linesraw
1#ifndef AVATAR_CLONE_LIGHTING
2#define AVATAR_CLONE_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 _Emission;
14float _Emission_Strength;
15sampler2D _Normal;
16sampler2D _Metallic;
17sampler2D _Roughness;
18
19bool _Disable_Normal_Texture;
20bool _Disable_Normal_Recalc;
21
22sampler2D _Height;
23float _Height_LOD;
24float _Height_Exponent;
25float _Height_Scale;
26float _Height_Speed_X;
27float _Height_Speed_Y;
28float _Height_AA_Sample_Scale;
29
30sampler2D _Height_Mask;
31float _Height_Mask_Exponent;
32
33float _Center_Out_Speed;
34float _Center_Out_Sharpness;
35float _Center_Out_Min_Radius;
36float _Center_Out_Max_Radius;
37
38float _Num_Clones;
39float _Clone_dx;
40float _Clone_dx_cents;
41float _Clone_dy;
42float _Clone_dz;
43float _Clone_Scale;
44float _Clone_Enable_Av_Height_Fix;
45float _Clone_Av_Height_Fix;
46float _Clone_Enable_Rotation;
47
48struct appdata
49{
50  float4 position : POSITION;
51  float2 uv : TEXCOORD0;
52  float3 normal : NORMAL;
53};
54
55void getVertexLightColor(inout v2f i)
56{
57  #if defined(VERTEXLIGHT_ON)
58  float3 light_pos = float3(unity_4LightPosX0.x, unity_4LightPosY0.x,
59      unity_4LightPosZ0.x);
60  float3 light_float = light_pos - i.worldPos;
61  float3 light_dir = normalize(light_float);
62  float ndotl = DotClamped(i.normal, light_dir);
63  // Light fills an expanding sphere with surface area 4 * pi * r^2.
64  // By conservation of energy, this means that at distance r, light intensity
65  // is proportional to 1/(r^2).
66  float attenuation = 1 / (1 + dot(light_float, light_float) * unity_4LightAtten0.x);
67  i.vertexLightColor = unity_LightColor[0].rgb * ndotl * attenuation;
68
69  i.vertexLightColor = Shade4PointLights(
70    unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0,
71    unity_LightColor[0].rgb,
72    unity_LightColor[1].rgb,
73    unity_LightColor[2].rgb,
74    unity_LightColor[3].rgb,
75    unity_4LightAtten0, i.worldPos, i.normal
76  );
77  #endif
78}
79
80v2f vert(appdata v)
81{
82  v2f o;
83
84  o.objPos = v.position;
85  o.clipPos = UnityObjectToClipPos(v.position);
86  o.worldPos = mul(unity_ObjectToWorld, v.position);
87
88  o.normal = UnityObjectToWorldNormal(v.normal);
89  o.uv = v.uv;
90
91  getVertexLightColor(o);
92
93  return o;
94}
95
96float getDisplacement(float2 uv)
97{
98  // Manipulate vertex in world space.
99  float height = 0;
100
101  float2 traveling_uv = uv;
102  traveling_uv.x += _Time[0] * _Height_Speed_X;
103  traveling_uv.y += _Time[0] * _Height_Speed_Y;
104  traveling_uv = glsl_mod(traveling_uv, 1.0);
105
106  const float duv = _Height_AA_Sample_Scale;
107
108  float z0 = tex2Dlod(_Height, float4(traveling_uv.x, traveling_uv.y, _Height_LOD, 0));
109  // Trivial optimization. No need to keep going if no displacement is desired.
110  if (z0 == 0) {
111    return 0;
112  }
113  #if HEIGHT_AA_LEVEL >= 1
114  float z1 = tex2Dlod(_Height, float4(traveling_uv.x + duv, traveling_uv.y + duv, _Height_LOD, 0));
115  float z2 = tex2Dlod(_Height, float4(traveling_uv.x + duv, traveling_uv.y - duv, _Height_LOD, 0));
116  float z3 = tex2Dlod(_Height, float4(traveling_uv.x - duv, traveling_uv.y - duv, _Height_LOD, 0));
117  float z4 = tex2Dlod(_Height, float4(traveling_uv.x - duv, traveling_uv.y + duv, _Height_LOD, 0));
118  #endif
119  #if HEIGHT_AA_LEVEL >= 2
120  float z5 = tex2Dlod(_Height, float4(traveling_uv.x + duv, traveling_uv.y, _Height_LOD, 0));
121  float z6 = tex2Dlod(_Height, float4(traveling_uv.x - duv, traveling_uv.y, _Height_LOD, 0));
122  float z7 = tex2Dlod(_Height, float4(traveling_uv.x, traveling_uv.y + duv, _Height_LOD, 0));
123  float z8 = tex2Dlod(_Height, float4(traveling_uv.x, traveling_uv.y - duv, _Height_LOD, 0));
124  #endif
125
126  #if HEIGHT_AA_LEVEL == 0
127  height += z0;
128  #elif HEIGHT_AA_LEVEL == 1
129  height += (z0 + z1 + z2 + z3 + z4) / 5.0;
130  #elif HEIGHT_AA_LEVEL == 2
131  height += (z0 + z1 + z2 + z3 + z4 + z5 + z6 + z7 + z8) / 9.0;
132  #endif
133
134  height = pow(height, _Height_Exponent);
135  height *= _Height_Scale;
136
137  {
138    float mask = tex2Dlod(_Height_Mask, float4(uv, _Height_LOD, 0));
139    mask = pow(mask, _Height_Mask_Exponent);
140    height *= mask;
141  }
142  
143  // 0 at middle, 1 or -1 at edges
144  if (_Center_Out_Speed > 0.0) {
145    float2 middle_out_uv = uv * 2.0 - 1.0;
146
147    float center_dist2 = length2(middle_out_uv);
148    float ring_radius = fmod(_Time[1] * _Center_Out_Speed,
149        _Center_Out_Max_Radius - _Center_Out_Min_Radius)
150        + _Center_Out_Min_Radius;
151
152    // How far am I from the desired ring?
153    float ring_dist = dabs(center_dist2 - ring_radius, _Center_Out_Sharpness);
154    float ring_scale = exp(-1.0 * ring_dist);
155
156    float middle_out_height = ring_scale;
157    height *= middle_out_height;
158  }
159
160  return height;
161}
162
163void displace(inout v2f vert)
164{
165  float height = getDisplacement(vert.uv);
166
167  vert.worldPos += height * vert.normal;
168  vert.objPos = mul(unity_WorldToObject, float4(vert.worldPos, 1.0));
169  vert.clipPos = UnityObjectToClipPos(vert.objPos);
170}
171
172float3 getNormal(
173    v2f v0,
174    v2f v1,
175    v2f v2,
176    float duv_scale) {
177  float2 duv_v0v1 = v1.uv - v0.uv;
178  float2 duv_v0v2 = v2.uv - v0.uv;
179
180  float h0 = getDisplacement(v0.uv);
181  float h1 = getDisplacement(v0.uv + duv_v0v1 * duv_scale);
182  float h2 = getDisplacement(v0.uv + duv_v0v2 * duv_scale);
183
184  float dh_v0v1 = h1 - h0;
185  float dh_v0v2 = h2 - h0;
186
187  float3 dpos_v0v1 = v1.worldPos - v0.worldPos;
188  float3 dpos_v0v2 = v2.worldPos - v0.worldPos;
189
190  float3 p0 = v0.worldPos + h0 * v0.normal;
191  float3 p1 = v0.worldPos + dpos_v0v1 * duv_scale + lerp(h0, h1, duv_scale) * v1.normal;
192  float3 p2 = v0.worldPos + dpos_v0v2 * duv_scale + lerp(h0, h2, duv_scale) * v2.normal;
193
194  float3 tangent = normalize(p1 - p0);
195  float3 bitangent = normalize(p2 - p0);
196  float3 new_normal = normalize(cross(tangent, bitangent));
197  return new_normal;
198}
199
200// maxvertexcount == the number of vertices we create
201[maxvertexcount(15)]
202void geom(triangle v2f tri_in[3],
203  uint pid: SV_PrimitiveID,
204  inout TriangleStream<v2f> tri_out)
205{
206  float dx = 0.5;
207
208  v2f t0 = tri_in[0];
209  v2f t1 = tri_in[1];
210  v2f t2 = tri_in[2];
211
212  displace(t0);
213  displace(t1);
214  displace(t2);
215
216  // Math from here:
217  //   http://tonfilm.blogspot.com/2007/01/calculate-normals-in-shader.html
218  if (!_Disable_Normal_Recalc) {
219    for (uint i = 0; i < 3; i++) {
220      v2f v0 = tri_in[(i + 0) % 3];
221      v2f v1 = tri_in[(i + 1) % 3];
222      v2f v2 = tri_in[(i + 2) % 3];
223
224      float3 aa_normal = 0;
225      aa_normal += getNormal(v0, v1, v2, 0.3);
226      aa_normal += getNormal(v0, v1, v2, 0.4);
227      aa_normal += getNormal(v0, v1, v2, 0.5);
228      aa_normal += getNormal(v0, v1, v2, 0.6);
229      aa_normal += getNormal(v0, v1, v2, 0.7);
230      aa_normal = normalize(aa_normal);
231
232      if (i == 0) {
233        t0.normal = aa_normal;
234      } else if (i == 1) {
235        t1.normal = aa_normal;
236      } else if (i == 2) {
237        t2.normal = aa_normal;
238      }
239    }
240  }
241
242  tri_out.Append(t0);
243  tri_out.Append(t1);
244  tri_out.Append(t2);
245  tri_out.RestartStrip();
246
247  float4x4 object_rotate = float4x4(
248      unity_ObjectToWorld[0].xyz, 0,
249      0, 1, 0, 0,
250      unity_ObjectToWorld[2].xyz, 0,
251      0, 0, 0, 1
252      );
253  float3 object_offset = transpose(unity_ObjectToWorld)[3].xyz;
254
255  const int num_clones = max((int) floor(_Num_Clones), 0);
256  for (int i = 2; i < num_clones + 2; i++) {
257    v2f t0p = t0;
258    v2f t1p = t1;
259    v2f t2p = t2;
260
261    float3 dpos = 0;
262
263    if (_Clone_Enable_Av_Height_Fix) {
264      dpos.y += _Clone_Av_Height_Fix * pow(_Clone_Scale, i / 2) - object_offset.y;
265    }
266
267    dpos.x += (_Clone_dx + _Clone_dx_cents * 0.01) * (i / 2) * (i % 2 == 0 ? 1.0 : -1.0);
268    dpos.y += _Clone_dy * (i / 2);
269    dpos.z += _Clone_dz * (i / 2);
270
271    if (_Clone_Enable_Rotation) {
272      dpos = mul(object_rotate, float4(dpos, 1.0));
273    }
274
275    t0p.worldPos += dpos;
276    t1p.worldPos += dpos;
277    t2p.worldPos += dpos;
278
279#if 1
280    t0p.worldPos = (t0p.worldPos - (dpos + object_offset)) * pow(_Clone_Scale, i / 2) + (dpos + object_offset);
281    t1p.worldPos = (t1p.worldPos - (dpos + object_offset)) * pow(_Clone_Scale, i / 2) + (dpos + object_offset);
282    t2p.worldPos = (t2p.worldPos - (dpos + object_offset)) * pow(_Clone_Scale, i / 2) + (dpos + object_offset);
283#endif
284
285    t0p.objPos = mul(unity_WorldToObject, float4(t0p.worldPos, 1.0));
286    t0p.clipPos = UnityObjectToClipPos(t0p.objPos);
287
288    t1p.objPos = mul(unity_WorldToObject, float4(t1p.worldPos, 1.0));
289    t1p.clipPos = UnityObjectToClipPos(t1p.objPos);
290
291    t2p.objPos = mul(unity_WorldToObject, float4(t2p.worldPos, 1.0));
292    t2p.clipPos = UnityObjectToClipPos(t2p.objPos);
293
294    tri_out.Append(t0p);
295    tri_out.Append(t1p);
296    tri_out.Append(t2p);
297    tri_out.RestartStrip();
298  }
299}
300
301float getWorldSpaceDepth(in const float3 worldPos)
302{
303  float4 clip_pos = mul(UNITY_MATRIX_VP, float4(worldPos, 1.0));
304  return clip_pos.z / clip_pos.w;
305}
306
307float4 effect(inout v2f i, out float depth)
308{
309  depth = -1000.0;
310
311  float4 albedo = tex2D(_BaseColor, i.uv);
312  float3 emission = tex2D(_Emission, i.uv);
313  float3 normal = _Disable_Normal_Texture ? i.normal : tex2D(_Normal, i.uv);
314  float metallic = tex2D(_Metallic, i.uv);
315  float roughness = tex2D(_Roughness, i.uv);
316  if (albedo.a > 0) {
317    depth = getWorldSpaceDepth(i.worldPos);
318  }
319
320  float4 lit_color = getLitColor(i, albedo, i.worldPos, normal, metallic,
321      1.0 - roughness, /*custom_cubemap=*/true);
322
323  lit_color.rgb += emission * _Emission_Strength;
324
325  return lit_color;
326}
327
328fixed4 frag(v2f i, out float depth : SV_DepthLessEqual) : SV_Target
329{
330  return effect(i, depth);
331}
332
333#endif  // AVATAR_CLONE_LIGHTING
334