Since I’m quite new to this shader business I’m bumping into problems here and there, and this time I’m really struggling with solving it.
I’ve made this shader that I’ve gotten to cast shadows with a custom ShadowCaster pass but I’m still not able to get it to collect shadows in any way. I’ve tried getting the fallback to handle the ShadowCollector pass, I’ve tried diffent ways to write the shadowcollector pass, and I’ve tried setting the Queue to geometry and RenderType to Opaque instead of Transparent..
Shader coding in Unity is hard, because there isn’t much info to be found anywhere about how things work and how it should be done. Does anyone out there have any tips on how I can get this to work?
See the code below or download the shader here.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 |
Shader "Trolltunga/LowPolyCollisionRadialWaves" { Properties { _MainTex("Diffuse (RGB)", 2D) = "white" {} _Color("Color", Color) = (1,0,0,1) _SpecColor("Specular Material Color", Color) = (1,1,1,1) _Shininess("Shininess", Float) = 1.0 _AlphaFactor("Alpha factor", Range(0, 1.0)) = 0.5 _WaveLength("Wave length", Float) = 0.5 _WaveHeight("Wave height", Float) = 0.5 _WaveSpeed("Wave speed", Float) = 1.0 _RandomHeight("Random height", Float) = 0.5 _RandomSpeed("Random Speed", Float) = 0.5 _CollisionWaveLength("Collision wave length", Float) = 2.0 } SubShader { Tags { "Queue" = "Geometry" "RenderType" = "Opaque" } //"AlphaTest" "IgnoreProjector" = "True" "RenderType" = "Transparent" } Blend SrcAlpha OneMinusSrcAlpha Pass { Tags{ "LightMode" = "ForwardBase" } CGPROGRAM #pragma target 5.0 #pragma vertex vert #pragma geometry geom #pragma fragment frag #pragma fragmentoption ARB_precision_hint_fastest #pragma multi_compile_fwdbase #include "UnityCG.cginc" #include "AutoLight.cginc" float rand(float3 co) { return frac(sin(dot(co.xyz ,float3(12.9898,78.233,45.5432))) * 43758.5453); } float rand2(float3 co) { return frac(sin(dot(co.xyz ,float3(19.9128,75.2,34.5122))) * 12765.5213); } float _WaveLength; float _WaveHeight; float _WaveSpeed; float _RandomHeight; float _RandomSpeed; float _CollisionWaveLength; vector _CollisionVectors[20]; uniform float4 _LightColor0; uniform float4 _Color; uniform float4 _SpecColor; uniform float _Shininess; uniform float _AlphaFactor; sampler2D _CameraDepthTexture; struct v2g { float4 pos : SV_POSITION; float3 norm : NORMAL; LIGHTING_COORDS(0, 1) }; struct g2f { float4 pos : SV_POSITION; float3 norm : NORMAL; float3 diffuseColor : TEXCOORD2; float3 specularColor : TEXCOORD3; }; v2g vert(appdata_full v) { float3 v0 = mul((float3x3)_Object2World, v.vertex).xyz; float collPhase = 0.0; for (int i = 0; i < 20; i++) { float distanceToCenter = length(v0.xz - _CollisionVectors[i].xy); float waveHeight = _CollisionVectors[i].z; float waveState = _CollisionVectors[i].w; if (distanceToCenter < _CollisionWaveLength * 10 * waveState) { collPhase += (waveHeight * ((1.0 - waveState) * distanceToCenter) / (_CollisionWaveLength * 10 * waveState)) * sin(distanceToCenter - (_CollisionWaveLength * 10 * waveState)); } } float phase0 = (_WaveHeight)* sin((_Time[1] * _WaveSpeed) + (v0.x * _WaveLength) + (v0.z * _WaveLength) + rand2(v0.xzz)); float phase0_1 = (_RandomHeight)* sin(cos(rand(v0.xzz) * _RandomHeight * cos(_Time[1] * _RandomSpeed * sin(rand(v0.xxz))))); float phase0_2 = (_WaveHeight / 5.0) * sin((_Time[1] * _WaveSpeed * 3.0) + (v0.x * -_WaveLength * 4.0) + (v0.z * _WaveLength * 4.0) + rand2(v0.xzz)); v0.y += collPhase + phase0 + phase0_1 + phase0_2; v.vertex.xyz = mul((float3x3)_World2Object, v0); v2g o; o.pos = v.vertex; o.norm = v.normal; TRANSFER_VERTEX_TO_FRAGMENT(o); return o; } [maxvertexcount(3)] void geom(triangle v2g IN[3], inout TriangleStream<g2f> triStream) { float3 v0 = IN[0].pos.xyz; float3 v1 = IN[1].pos.xyz; float3 v2 = IN[2].pos.xyz; float3 centerPos = (v0 + v1 + v2) / 3.0; float3 vn = normalize(cross(v1 - v0, v2 - v0)); float4x4 modelMatrix = _Object2World; float4x4 modelMatrixInverse = _World2Object; float3 normalDirection = normalize( mul(float4(vn, 0.0), modelMatrixInverse).xyz); float3 viewDirection = normalize(_WorldSpaceCameraPos - mul(modelMatrix, float4(centerPos, 0.0)).xyz); float3 lightDirection = normalize(_WorldSpaceLightPos0.xyz); float attenuation = (LIGHT_ATTENUATION(IN[0]) + LIGHT_ATTENUATION(IN[1]) + LIGHT_ATTENUATION(IN[2])) / 3; float3 ambientLighting = UNITY_LIGHTMODEL_AMBIENT.rgb * _Color.rgb; float3 diffuseReflection = attenuation * _LightColor0.rgb * _Color.rgb * max(0.0, dot(normalDirection, lightDirection)); float3 specularReflection; if (dot(normalDirection, lightDirection) < 0.0) { specularReflection = float3(0.0, 0.0, 0.0); } else { specularReflection = attenuation * _LightColor0.rgb * _SpecColor.rgb * pow(max(0.0, dot( reflect(-lightDirection, normalDirection), viewDirection)), _Shininess); } g2f o; o.pos = mul(UNITY_MATRIX_MVP, IN[0].pos); o.norm = vn; o.diffuseColor = ambientLighting + diffuseReflection; o.specularColor = specularReflection; triStream.Append(o); o.pos = mul(UNITY_MATRIX_MVP, IN[1].pos); o.norm = vn; o.diffuseColor = ambientLighting + diffuseReflection; o.specularColor = specularReflection; triStream.Append(o); o.pos = mul(UNITY_MATRIX_MVP, IN[2].pos); o.norm = vn; o.diffuseColor = ambientLighting + diffuseReflection; o.specularColor = specularReflection; triStream.Append(o); } half4 frag(g2f IN) : COLOR { float z1 = tex2Dproj(_CameraDepthTexture, IN.pos); z1 = LinearEyeDepth(z1); float z2 = (IN.pos.z); z1 = saturate(0.125 * (abs(z2 - z1))); fixed atten = LIGHT_ATTENUATION(IN); return float4(IN.specularColor + IN.diffuseColor * atten, saturate(z1*0.1) + _AlphaFactor); } ENDCG } Pass { Name "ShadowCaster" Tags{ "LightMode" = "ShadowCaster" } Fog{ Mode Off } ZWrite On ZTest Less Cull Off Offset [_ShadowBias],[_ShadowBiasSlope] CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile_shadowcaster #pragma fragmentoption ARB_precision_hint_fastest #include "UnityCG.cginc" float rand(float3 co) { return frac(sin(dot(co.xyz ,float3(12.9898,78.233,45.5432))) * 43758.5453); } float rand2(float3 co) { return frac(sin(dot(co.xyz ,float3(19.9128,75.2,34.5122))) * 12765.5213); } float _WaveLength; float _WaveHeight; float _WaveSpeed; float _RandomHeight; float _RandomSpeed; float _CollisionWaveLength; vector _CollisionVectors[20]; struct v2f { V2F_SHADOW_CASTER; }; v2f vert(appdata_base v) { float3 v0 = mul((float3x3)_Object2World, v.vertex).xyz; float collPhase = 0.0; for (int i = 0; i < 20; i++) { float distanceToCenter = length(v0.xz - _CollisionVectors[i].xy); float waveHeight = _CollisionVectors[i].z; float waveState = _CollisionVectors[i].w; if (distanceToCenter < _CollisionWaveLength * 10 * waveState) { collPhase += (waveHeight * ((1.0 - waveState) * distanceToCenter) / (_CollisionWaveLength * 10 * waveState)) * sin(distanceToCenter - (_CollisionWaveLength * 10 * waveState)); } } float phase0 = (_WaveHeight)* sin((_Time[1] * _WaveSpeed) + (v0.x * _WaveLength) + (v0.z * _WaveLength) + rand2(v0.xzz)); float phase0_1 = (_RandomHeight)* sin(cos(rand(v0.xzz) * _RandomHeight * cos(_Time[1] * _RandomSpeed * sin(rand(v0.xxz))))); float phase0_2 = (_WaveHeight / 5.0) * sin((_Time[1] * _WaveSpeed * 3.0) + (v0.x * -_WaveLength * 4.0) + (v0.z * _WaveLength * 4.0) + rand2(v0.xzz)); v0.y += collPhase + phase0 + phase0_1 + phase0_2; v.vertex.xyz = mul((float3x3)_World2Object, v0); v2f o; o.pos = mul(UNITY_MATRIX_MVP, v.vertex); return o; } float4 frag(v2f i) : COLOR { SHADOW_CASTER_FRAGMENT(i) } ENDCG } Pass { Name "ShadowCollector" Tags{ "LightMode" = "ShadowCollector" } Fog{ Mode Off } ZWrite On ZTest LEqual CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma fragmentoption ARB_precision_hint_fastest #pragma multi_compile_shadowcollector #define SHADOW_COLLECTOR_PASS #include "UnityCG.cginc" float rand(float3 co) { return frac(sin(dot(co.xyz ,float3(12.9898,78.233,45.5432))) * 43758.5453); } float rand2(float3 co) { return frac(sin(dot(co.xyz ,float3(19.9128,75.2,34.5122))) * 12765.5213); } float _WaveLength; float _WaveHeight; float _WaveSpeed; float _RandomHeight; float _RandomSpeed; float _CollisionWaveLength; vector _CollisionVectors[20]; struct appdata { float4 vertex : POSITION; }; struct v2f { V2F_SHADOW_COLLECTOR; }; v2f vert(appdata v) { float3 v0 = mul((float3x3)_Object2World, v.vertex).xyz; float collPhase = 0.0; for (int i = 0; i < 20; i++) { float distanceToCenter = length(v0.xz - _CollisionVectors[i].xy); float waveHeight = _CollisionVectors[i].z; float waveState = _CollisionVectors[i].w; if (distanceToCenter < _CollisionWaveLength * 10 * waveState) { collPhase += (waveHeight * ((1.0 - waveState) * distanceToCenter) / (_CollisionWaveLength * 10 * waveState)) * sin(distanceToCenter - (_CollisionWaveLength * 10 * waveState)); } } float phase0 = (_WaveHeight)* sin((_Time[1] * _WaveSpeed) + (v0.x * _WaveLength) + (v0.z * _WaveLength) + rand2(v0.xzz)); float phase0_1 = (_RandomHeight)* sin(cos(rand(v0.xzz) * _RandomHeight * cos(_Time[1] * _RandomSpeed * sin(rand(v0.xxz))))); float phase0_2 = (_WaveHeight / 5.0) * sin((_Time[1] * _WaveSpeed * 3.0) + (v0.x * -_WaveLength * 4.0) + (v0.z * _WaveLength * 4.0) + rand2(v0.xzz)); v0.y += collPhase + phase0 + phase0_1 + phase0_2; v.vertex.xyz = mul((float3x3)_World2Object, v0); v2f o; o.pos = mul(UNITY_MATRIX_MVP, v.vertex); TRANSFER_SHADOW_COLLECTOR(o) return o; } fixed4 frag(v2f i) : COLOR { SHADOW_COLLECTOR_FRAGMENT(i) } ENDCG } } Fallback "Diffuse" } |