yum-archive/SoggyShaders
Old Unity shaders.
git clone https://git.yummers.dev/yum-archive/SoggyShaders
ad7e60e
master
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