yum-archive/SoggyShaders
Old Unity shaders.
git clone https://git.yummers.dev/yum-archive/SoggyShaders
6a14a2d
master
1#ifndef DISPLACEMENT_LIGHTING 2#define DISPLACEMENT_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; 16 17bool _Disable_Normal_Texture; 18 19sampler2D _Height; 20float _Height_LOD; 21float _Height_Exponent; 22float _Height_Scale; 23float _Height_Speed_X; 24float _Height_Speed_Y; 25float _Height_AA_Sample_Scale; 26 27sampler2D _Height_Mask; 28float _Height_Mask_Exponent; 29 30float _Center_Out_Speed; 31float _Center_Out_Sharpness; 32float _Center_Out_Min_Radius; 33float _Center_Out_Max_Radius; 34 35struct appdata 36{ 37 float4 position : POSITION; 38 float2 uv : TEXCOORD0; 39 float3 normal : NORMAL; 40}; 41 42void getVertexLightColor(inout v2f i) 43{ 44 #if defined(VERTEXLIGHT_ON) 45 float3 light_pos = float3(unity_4LightPosX0.x, unity_4LightPosY0.x, 46 unity_4LightPosZ0.x); 47 float3 light_float = light_pos - i.worldPos; 48 float3 light_dir = normalize(light_float); 49 float ndotl = DotClamped(i.normal, light_dir); 50 // Light fills an expanding sphere with surface area 4 * pi * r^2. 51 // By conservation of energy, this means that at distance r, light intensity 52 // is proportional to 1/(r^2). 53 float attenuation = 1 / (1 + dot(light_float, light_float) * unity_4LightAtten0.x); 54 i.vertexLightColor = unity_LightColor[0].rgb * ndotl * attenuation; 55 56 i.vertexLightColor = Shade4PointLights( 57 unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0, 58 unity_LightColor[0].rgb, 59 unity_LightColor[1].rgb, 60 unity_LightColor[2].rgb, 61 unity_LightColor[3].rgb, 62 unity_4LightAtten0, i.worldPos, i.normal 63 ); 64 #endif 65} 66 67v2f vert(appdata v) 68{ 69 v2f o; 70 71 o.objPos = v.position; 72 o.clipPos = UnityObjectToClipPos(v.position); 73 o.worldPos = mul(unity_ObjectToWorld, v.position); 74 75 o.normal = UnityObjectToWorldNormal(v.normal); 76 o.uv = 1.0 - v.uv; 77 78 getVertexLightColor(o); 79 80 return o; 81} 82 83float getDisplacement(float2 uv) 84{ 85 // Manipulate vertex in world space. 86 float height = 0; 87 88 float2 traveling_uv = uv; 89 traveling_uv.x += _Time[0] * _Height_Speed_X; 90 traveling_uv.y += _Time[0] * _Height_Speed_Y; 91 traveling_uv = glsl_mod(traveling_uv, 1.0); 92 93 const float duv = _Height_AA_Sample_Scale; 94 95 float z0 = tex2Dlod(_Height, float4(traveling_uv.x, traveling_uv.y, _Height_LOD, 0)); 96 #if HEIGHT_AA_LEVEL >= 1 97 float z1 = tex2Dlod(_Height, float4(traveling_uv.x + duv, traveling_uv.y + duv, _Height_LOD, 0)); 98 float z2 = tex2Dlod(_Height, float4(traveling_uv.x + duv, traveling_uv.y - duv, _Height_LOD, 0)); 99 float z3 = tex2Dlod(_Height, float4(traveling_uv.x - duv, traveling_uv.y - duv, _Height_LOD, 0)); 100 float z4 = tex2Dlod(_Height, float4(traveling_uv.x - duv, traveling_uv.y + duv, _Height_LOD, 0)); 101 #endif 102 #if HEIGHT_AA_LEVEL >= 2 103 float z5 = tex2Dlod(_Height, float4(traveling_uv.x + duv, traveling_uv.y, _Height_LOD, 0)); 104 float z6 = tex2Dlod(_Height, float4(traveling_uv.x - duv, traveling_uv.y, _Height_LOD, 0)); 105 float z7 = tex2Dlod(_Height, float4(traveling_uv.x, traveling_uv.y + duv, _Height_LOD, 0)); 106 float z8 = tex2Dlod(_Height, float4(traveling_uv.x, traveling_uv.y - duv, _Height_LOD, 0)); 107 #endif 108 109 #if HEIGHT_AA_LEVEL == 0 110 height += z0; 111 #elif HEIGHT_AA_LEVEL == 1 112 height += (z0 + z1 + z2 + z3 + z4) / 5.0; 113 #elif HEIGHT_AA_LEVEL == 2 114 height += (z0 + z1 + z2 + z3 + z4 + z5 + z6 + z7 + z8) / 9.0; 115 #endif 116 117 height = pow(height, _Height_Exponent); 118 height *= _Height_Scale; 119 120 { 121 float mask = tex2Dlod(_Height_Mask, float4(uv, _Height_LOD, 0)); 122 mask = pow(mask, _Height_Mask_Exponent); 123 height *= mask; 124 } 125 126 // 0 at middle, 1 or -1 at edges 127 if (_Center_Out_Speed > 0.0) { 128 float2 middle_out_uv = uv * 2.0 - 1.0; 129 130 float center_dist2 = length2(middle_out_uv); 131 float ring_radius = fmod(_Time[1] * _Center_Out_Speed, 132 _Center_Out_Max_Radius - _Center_Out_Min_Radius) 133 + _Center_Out_Min_Radius; 134 135 // How far am I from the desired ring? 136 float ring_dist = dabs(center_dist2 - ring_radius, _Center_Out_Sharpness); 137 float ring_scale = exp(-1.0 * ring_dist); 138 139 float middle_out_height = ring_scale; 140 height *= middle_out_height; 141 } 142 143 return height; 144} 145 146void displace(inout v2f vert) 147{ 148 float height = getDisplacement(vert.uv); 149 150 vert.worldPos += height * vert.normal; 151 vert.objPos = mul(unity_WorldToObject, float4(vert.worldPos, 1.0)); 152 vert.clipPos = UnityObjectToClipPos(vert.objPos); 153} 154 155float3 getNormal( 156 v2f v0, 157 v2f v1, 158 v2f v2, 159 float duv_scale) { 160 float2 duv_v0v1 = v1.uv - v0.uv; 161 float2 duv_v0v2 = v2.uv - v0.uv; 162 163 float h0 = getDisplacement(v0.uv); 164 float h1 = getDisplacement(v0.uv + duv_v0v1 * duv_scale); 165 float h2 = getDisplacement(v0.uv + duv_v0v2 * duv_scale); 166 167 float dh_v0v1 = h1 - h0; 168 float dh_v0v2 = h2 - h0; 169 170 float3 dpos_v0v1 = v1.worldPos - v0.worldPos; 171 float3 dpos_v0v2 = v2.worldPos - v0.worldPos; 172 173 float3 p0 = v0.worldPos + h0 * v0.normal; 174 float3 p1 = v0.worldPos + dpos_v0v1 * duv_scale + lerp(h0, h1, duv_scale) * v1.normal; 175 float3 p2 = v0.worldPos + dpos_v0v2 * duv_scale + lerp(h0, h2, duv_scale) * v2.normal; 176 177 float3 tangent = normalize(p1 - p0); 178 float3 bitangent = normalize(p2 - p0); 179 float3 new_normal = normalize(cross(tangent, bitangent)); 180 return new_normal; 181} 182 183// maxvertexcount == the number of vertices we create 184[maxvertexcount(3)] 185void geom(triangle v2f tri_in[3], 186 uint pid: SV_PrimitiveID, 187 inout TriangleStream<v2f> tri_out) 188{ 189 float dx = 0.5; 190 191 v2f t0 = tri_in[0]; 192 v2f t1 = tri_in[1]; 193 v2f t2 = tri_in[2]; 194 195 displace(t0); 196 displace(t1); 197 displace(t2); 198 199 // Math from here: 200 // http://tonfilm.blogspot.com/2007/01/calculate-normals-in-shader.html 201 for (int i = 0; i < 3; i++) { 202 v2f v0 = tri_in[(i + 0) % 3]; 203 v2f v1 = tri_in[(i + 1) % 3]; 204 v2f v2 = tri_in[(i + 2) % 3]; 205 206 float3 aa_normal = 0; 207 aa_normal += getNormal(v0, v1, v2, 0.3); 208 aa_normal += getNormal(v0, v1, v2, 0.4); 209 aa_normal += getNormal(v0, v1, v2, 0.5); 210 aa_normal += getNormal(v0, v1, v2, 0.6); 211 aa_normal += getNormal(v0, v1, v2, 0.7); 212 aa_normal = normalize(aa_normal); 213 214 if (i == 0) { 215 t0.normal = aa_normal; 216 } else if (i == 1) { 217 t1.normal = aa_normal; 218 } else if (i == 2) { 219 t2.normal = aa_normal; 220 } 221 } 222 223 tri_out.Append(t0); 224 tri_out.Append(t1); 225 tri_out.Append(t2); 226 227 tri_out.RestartStrip(); 228} 229 230float getWorldSpaceDepth(in const float3 worldPos) 231{ 232 float4 clip_pos = mul(UNITY_MATRIX_VP, float4(worldPos, 1.0)); 233 return clip_pos.z / clip_pos.w; 234} 235 236float4 effect(inout v2f i, out float depth) 237{ 238 depth = -1000.0; 239 240 float4 albedo = tex2D(_BaseColor, i.uv); 241 float3 normal = _Disable_Normal_Texture ? i.normal : tex2D(_Normal, i.uv); 242 float metallic = tex2D(_Metallic, i.uv); 243 float roughness = tex2D(_Roughness, i.uv); 244 if (albedo.a > 0) { 245 depth = getWorldSpaceDepth(i.worldPos); 246 } 247 248 return getLitColor(i, albedo, i.worldPos, normal, metallic, 1.0 - roughness, 249 /*custom_cubemap=*/true); 250} 251 252fixed4 frag(v2f i, out float depth : SV_DepthLessEqual) : SV_Target 253{ 254 return effect(i, depth); 255} 256 257#endif // DISPLACEMENT_LIGHTING 258