yum-archive/SoggyShaders
Old Unity shaders.
git clone https://git.yummers.dev/yum-archive/SoggyShaders
5eda07e
master
1#ifndef PARALLAX_LIGHTING 2#define PARALLAX_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 11struct appdata 12{ 13 float4 position : POSITION; 14 float2 uv : TEXCOORD0; 15 float3 normal : NORMAL; 16}; 17 18float _Curvature_Step; 19float _Min_Hit_Dist; 20float _Max_Dist; 21float _Ray_March_Steps; 22 23#ifdef LAYER0_TEXTURES_ON 24sampler2D _Layer0_BaseColor; 25sampler2D _Layer0_Normal; 26sampler2D _Layer0_Metallic; 27sampler2D _Layer0_Roughness; 28#endif 29 30#ifdef LAYER1_TEXTURES_ON 31sampler2D _Layer1_BaseColor; 32sampler2D _Layer1_Normal; 33sampler2D _Layer1_Metallic; 34sampler2D _Layer1_Roughness; 35#endif 36 37#ifdef LAYER2_TEXTURES_ON 38sampler2D _Layer2_BaseColor; 39sampler2D _Layer2_Normal; 40sampler2D _Layer2_Metallic; 41sampler2D _Layer2_Roughness; 42#endif 43 44float _Layer0_Offset; 45float _Layer0_XScale; 46float _Layer0_YScale; 47float _Layer0_Emission; 48 49float _Layer1_Offset; 50float _Layer1_XScale; 51float _Layer1_YScale; 52float _Layer1_Emission; 53 54float _Layer2_Offset; 55float _Layer2_XScale; 56float _Layer2_YScale; 57float _Layer2_Emission; 58 59#ifdef IRIDESCENCE_TEXTURES_ON 60sampler2D _Iridescence_Ramp; 61sampler2D _Iridescence_Normal; 62float _Iridescence_Offset; 63#endif 64 65void getVertexLightColor(inout v2f i) 66{ 67 #if defined(VERTEXLIGHT_ON) 68 float3 light_pos = float3(unity_4LightPosX0.x, unity_4LightPosY0.x, 69 unity_4LightPosZ0.x); 70 float3 light_float = light_pos - i.worldPos; 71 float3 light_dir = normalize(light_float); 72 float ndotl = DotClamped(i.normal, light_dir); 73 // Light fills an expanding sphere with surface area 4 * pi * r^2. 74 // By conservation of energy, this means that at distance r, light intensity 75 // is proportional to 1/(r^2). 76 float attenuation = 1 / (1 + dot(light_float, light_float) * unity_4LightAtten0.x); 77 i.vertexLightColor = unity_LightColor[0].rgb * ndotl * attenuation; 78 79 i.vertexLightColor = Shade4PointLights( 80 unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0, 81 unity_LightColor[0].rgb, 82 unity_LightColor[1].rgb, 83 unity_LightColor[2].rgb, 84 unity_LightColor[3].rgb, 85 unity_4LightAtten0, i.worldPos, i.normal 86 ); 87 #endif 88} 89 90v2f vert(appdata v) 91{ 92 v2f o; 93 o.position = UnityObjectToClipPos(v.position); 94 o.worldPos = mul(unity_ObjectToWorld, v.position); 95 o.normal = UnityObjectToWorldNormal(v.normal); 96 o.uv.xy = float2(0, 0); 97 o.uv.zw = 1.0 - v.uv; 98 getVertexLightColor(o); 99 return o; 100} 101 102float getWorldSpaceDepth(in const float3 worldPos) 103{ 104 float4 clip_pos = mul(UNITY_MATRIX_VP, float4(worldPos, 1.0)); 105 return clip_pos.z / clip_pos.w; 106} 107 108float4 getLayerBaseColor(in float2 uv, in int layer) 109{ 110 [forcecase] 111 switch (layer) { 112 #ifdef LAYER0_TEXTURES_ON 113 case 0: 114 return tex2Dgrad(_Layer0_BaseColor, uv, ddx(uv.x), ddy(uv.y)); 115 #endif 116 #ifdef LAYER1_TEXTURES_ON 117 case 1: 118 return tex2Dgrad(_Layer1_BaseColor, uv, ddx(uv.x), ddy(uv.y)); 119 #endif 120 #ifdef LAYER2_TEXTURES_ON 121 case 2: 122 return tex2Dgrad(_Layer2_BaseColor, uv, ddx(uv.x), ddy(uv.y)); 123 #endif 124 default: 125 return 0.0; 126 } 127} 128 129float3 getLayerNormal(in float2 uv, in int layer) 130{ 131 [forcecase] 132 switch (layer) { 133 #ifdef LAYER0_TEXTURES_ON 134 case 0: 135 return tex2Dgrad(_Layer0_Normal, uv, ddx(uv.x), ddy(uv.y)); 136 #endif 137 #ifdef LAYER1_TEXTURES_ON 138 case 1: 139 return tex2Dgrad(_Layer1_Normal, uv, ddx(uv.x), ddy(uv.y)); 140 #endif 141 #ifdef LAYER2_TEXTURES_ON 142 case 2: 143 return tex2Dgrad(_Layer2_Normal, uv, ddx(uv.x), ddy(uv.y)); 144 #endif 145 default: 146 return 0.0; 147 } 148} 149 150float getLayerMetallic(in float2 uv, in int layer) 151{ 152 [forcecase] 153 switch (layer) { 154 #ifdef LAYER0_TEXTURES_ON 155 case 0: 156 return tex2Dgrad(_Layer0_Metallic, uv, ddx(uv.x), ddy(uv.y)); 157 #endif 158 #ifdef LAYER1_TEXTURES_ON 159 case 1: 160 return tex2Dgrad(_Layer1_Metallic, uv, ddx(uv.x), ddy(uv.y)); 161 #endif 162 #ifdef LAYER2_TEXTURES_ON 163 case 2: 164 return tex2Dgrad(_Layer2_Metallic, uv, ddx(uv.x), ddy(uv.y)); 165 #endif 166 default: 167 return 0.0; 168 } 169} 170 171float getLayerRoughness(in float2 uv, in int layer) 172{ 173 [forcecase] 174 switch (layer) { 175 #ifdef LAYER0_TEXTURES_ON 176 case 0: 177 return tex2Dgrad(_Layer0_Roughness, uv, ddx(uv.x), ddy(uv.y)); 178 #endif 179 #ifdef LAYER1_TEXTURES_ON 180 case 1: 181 return tex2Dgrad(_Layer1_Roughness, uv, ddx(uv.x), ddy(uv.y)); 182 #endif 183 #ifdef LAYER2_TEXTURES_ON 184 case 2: 185 return tex2Dgrad(_Layer2_Roughness, uv, ddx(uv.x), ddy(uv.y)); 186 #endif 187 default: 188 return 0.0; 189 } 190} 191 192float getLayerOffset(in int layer) 193{ 194 [forcecase] 195 switch (layer) { 196 case 0: 197 return _Layer0_Offset; 198 case 1: 199 return _Layer1_Offset; 200 case 2: 201 return _Layer2_Offset; 202 default: 203 return 0.0; 204 } 205} 206 207float getLayerXScale(in int layer) 208{ 209 [forcecase] 210 switch (layer) { 211 case 0: 212 return _Layer0_XScale; 213 case 1: 214 return _Layer1_XScale; 215 case 2: 216 return _Layer2_XScale; 217 default: 218 return 0.0; 219 } 220} 221 222float getLayerYScale(in int layer) 223{ 224 [forcecase] 225 switch (layer) { 226 case 0: 227 return _Layer0_YScale; 228 case 1: 229 return _Layer1_YScale; 230 case 2: 231 return _Layer2_YScale; 232 default: 233 return 0.0; 234 } 235} 236 237float getLayerEmission(in int layer) 238{ 239 [forcecase] 240 switch (layer) { 241 case 0: 242 return _Layer0_Emission; 243 case 1: 244 return _Layer1_Emission; 245 case 2: 246 return _Layer2_Emission; 247 default: 248 return 0.0; 249 } 250} 251 252float2 getLayerScale(in int layer) 253{ 254 return float2(getLayerXScale(layer), getLayerYScale(layer)); 255} 256 257float4 effect(inout v2f i, out float depth) 258{ 259 float4 clip_pos = mul(UNITY_MATRIX_VP, float4(i.worldPos, 1.0)); 260 depth = clip_pos.z / clip_pos.w; 261 262 float3 camera_position = _WorldSpaceCameraPos.xyz; 263 float3 view_dir = normalize(_WorldSpaceCameraPos - i.worldPos); 264 265 const float3 ro = i.worldPos; 266 const float3 rd = view_dir * -1.0; 267 268 static const float MIN_D = _Min_Hit_Dist; 269 static const float MAX_D = _Max_Dist; 270 271 float4 result = float4(1.0, 1.0, 1.0, 0.0); 272 273 float foreground_depth = -100.0; 274 bool ray_hit = false; 275 276 float3 object_offset = transpose(unity_ObjectToWorld)[3].xyz; 277 278 float4x4 object_rotate = float4x4( 279 unity_ObjectToWorld[0].xyz, 0, 280 unity_ObjectToWorld[1].xyz, 0, 281 unity_ObjectToWorld[2].xyz, 0, 282 0, 0, 0, 1 283 ); 284 float3 object_scale_vec = float3( 285 length(float3(unity_ObjectToWorld[0].x, unity_ObjectToWorld[1].x, unity_ObjectToWorld[2].x)), 286 length(float3(unity_ObjectToWorld[0].y, unity_ObjectToWorld[1].y, unity_ObjectToWorld[2].y)), 287 length(float3(unity_ObjectToWorld[0].z, unity_ObjectToWorld[1].z, unity_ObjectToWorld[2].z)) 288 ); 289 float object_scale = min(object_scale_vec.x, min(object_scale_vec.y, object_scale_vec.z)); 290 291 for (float layer = 3 - 1; layer >= 0; layer--) { 292 bool shade_out = false; 293 float3 layer_offset = float3(0.0, 0.0, 1.0) * getLayerOffset(layer) * object_scale; 294 float2 layer_scale = getLayerScale(layer); 295 296 float cum_dist = 0.0; 297 float3 bbox = float3(1.0, 1.0, 0.0) * 0.2; 298 float3 pp; 299 for (int ii = 0; ii < _Ray_March_Steps; ii++) { 300 pp = ro + rd * cum_dist - object_offset; 301 pp = mul(transpose(object_rotate), float4(pp, 1.0)).xyz; 302 pp /= object_scale_vec; 303 304 const float3 off = layer_offset; 305 pp += off; 306 307 pp.xy /= layer_scale; 308 309 float d0 = distance_from_box(pp / object_scale, bbox) * object_scale; 310 if (d0 < MIN_D) { 311 foreground_depth = getWorldSpaceDepth(pp); 312 shade_out = true; 313 ray_hit = true; 314 break; 315 } 316 cum_dist += d0; 317 if (cum_dist >= MAX_D) { 318 break; 319 } 320 } 321 if (shade_out) { 322 float2 uv = pp.xy; 323 uv /= (bbox.xy * 2.0) * object_scale; 324 uv.x += 0.5; 325 uv.y += 0.5; 326 // Render textures left-to-right when looking in the mirror. 327 if (isInMirror()) { 328 uv.x = 1.0 - uv.x; 329 } 330 uv = clamp(uv, 0.0, 1.0); 331 332 float4 color = getLayerBaseColor(uv, (int) layer); 333 if (color.a < 0.9) { 334 color.a = 0.0; 335 } 336 float3 normal = getLayerNormal(uv, (int) layer); 337 const float metallic = getLayerMetallic(uv, (int) layer); 338 const float smoothness = 1.0 - getLayerRoughness(uv, (int) layer); 339 340 bool custom_cubemap = true; 341 342 // Iridescence 343#ifdef IRIDESCENCE_TEXTURES_ON 344 if (smoothness > 0.0) 345 { 346 float3 ir_normal = normalize(tex2Dgrad(_Iridescence_Normal, uv, ddx(uv.x), ddy(uv.y))); 347 348 float3 camera_position = _WorldSpaceCameraPos.xyz; 349 350 float3 obj_normal = i.normal; 351 352 float ndotl = dot(view_dir, normalize(normal + obj_normal)); 353 ndotl = glsl_mod(ndotl + _Iridescence_Offset, 1.0); 354 355 float3 ir_color = tex2Dgrad(_Iridescence_Ramp, ndotl, ddx(ndotl), ddy(ndotl)); 356 color.rgb = lerp(color.rgb, ir_color, dot(ir_color, ir_color)); 357 normal = lerp(normal, ir_normal, dot(ir_color, ir_color)); 358 } 359#endif 360 361 // Hack: Bright cubemaps cause glare on rough surfaces. To prevent this, 362 // switch to unlit shading when shading a perfectly rough material. 363 float4 lit_color; 364 if (smoothness == 0.0) { 365 lit_color = color; 366 } else { 367 lit_color = getLitColor(i, color, pp, normal, metallic, smoothness, custom_cubemap); 368 } 369 370 lit_color.rgb += color.rgb * getLayerEmission(layer); 371 372 result.rgb = lerp(result.rgb, lit_color.rgb, lit_color.a); 373 374 float a_remainder = abs(result.a - color.a); 375 float a_increment = a_remainder * color.a; 376 result.a += a_increment; 377 } 378 } 379 380 // No ray hit: return default material 381 float base_depth = depth; 382 float metallic = 1.0; 383 float smoothness = 0.5; 384 bool custom_cubemap = true; 385 float4 bg_color = float4(1.0, 1.0, 1.0, 1.0); 386 bg_color = getLitColor(i, bg_color, i.worldPos, i.normal, metallic, smoothness, custom_cubemap); 387 388 result.rgb = lerp(bg_color.rgb, result.rgb, result.a); 389 result.a = 1.0; 390 391 return result; 392} 393 394fixed4 frag(v2f i, out float depth : SV_DepthLessEqual) : SV_Target 395{ 396 return effect(i, depth); 397} 398 399#endif // PARALLAX_LIGHTING 400