123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- // Upgrade NOTE: upgraded instancing buffer 'Props' to new syntax.
- // Author: Jason Ederle
- // Description: Sky Studio rain rendering.
- Shader "Funly/Sky Studio/Weather/Rain Splash Instanced"
- {
- Properties
- {
- [NoScaleOffset] _SpriteSheetTex ("Sprite Texture", 2D) = "white" {}
- _SpriteColumnCount ("Sprite Columns", int) = 1
- _SpriteRowCount ("Sprite Rows", int) = 1
- _SpriteItemCount ("Sprite Total Items", int) = 1
- _AnimationSpeed ("Animation Speed", int) = 25
- _Intensity ("Intensity", Range(0, 1)) = .7
- _TintColor("Tint Color", Color) = (1, 1, 1, 1)
- }
- SubShader
- {
- Tags { "RenderType"="Transparent" "Queue"="Transparent" }
- LOD 100
- Blend OneMinusDstColor One
- Cull Back
- Pass
- {
- CGPROGRAM
- #pragma target 3.0
- #pragma vertex vert
- #pragma fragment frag
- #pragma multi_compile_instancing
- #include "UnityCG.cginc"
- struct appdata
- {
- float4 vertex : POSITION;
- float2 uv : TEXCOORD0;
- UNITY_VERTEX_INPUT_INSTANCE_ID
- };
- struct v2f
- {
- float2 uv : TEXCOORD0;
- float4 vertex : SV_POSITION;
- float isOverSurface: TEXCOORD1;
- UNITY_VERTEX_INPUT_INSTANCE_ID
- };
- sampler2D _SpriteSheetTex;
- sampler2D _OverheadDepthTex;
- float4 _OverheadDepthPosition;
- float _OverheadDepthNearClip;
- float _OverheadDepthFarClip;
- float4 _TintColor;
- int _SpriteColumnCount;
- int _SpriteRowCount;
- int _SpriteItemCount;
- int _AnimationSpeed;
- float _Intensity;
- float _SplashGroundOffset;
- float _Scale;
- UNITY_INSTANCING_BUFFER_START(Props)
- UNITY_DEFINE_INSTANCED_PROP(float, _StartTime)
- #define _StartTime_arr Props
- UNITY_DEFINE_INSTANCED_PROP(float, _EndTime)
- #define _EndTime_arr Props
- UNITY_DEFINE_INSTANCED_PROP(float, _OverheadDepthU)
- #define _OverheadDepthU_arr Props
- UNITY_DEFINE_INSTANCED_PROP(float, _OverheadDepthV)
- #define _OverheadDepthV_arr Props
- UNITY_DEFINE_INSTANCED_PROP(float, _SplashStartYPosition)
- #define _SplashStartYPosition_arr Props
- UNITY_INSTANCING_BUFFER_END(Props)
- int GetSpriteTargetIndex(int itemCount, int animationSpeed, float startTime) {
- float delta = _Time.y - startTime;
- float timePerFrame = 1.0f / _AnimationSpeed;
- int frameIndex = (int)(delta / timePerFrame);
- return clamp(frameIndex, 0, _SpriteItemCount - 1);
- }
- float2 GetSpriteItemSize(float2 dimensions) {
- return float2(1.0f / dimensions.x, (1.0f / dimensions.x) * (dimensions.x / dimensions.y));
- }
- float2 GetSpriteSheetCoords(float2 uv, float2 dimensions, int targetFrameIndex, float2 itemSize, int numItems) {
- int rows = dimensions.y;
- int columns = dimensions.x;
- float2 scaledUV = float2(uv.x * itemSize.x, uv.y * itemSize.y);
- float2 offset = float2(
- (int)abs(targetFrameIndex) % (int)abs(columns) * itemSize.x,
- ((rows - 1) - (targetFrameIndex / (int)abs(columns))) * itemSize.y);
- return scaledUV + offset;
- }
- float2 GetAnimatedSpriteCoords(float2 uv, float startTime) {
- int spriteTileIndex = GetSpriteTargetIndex(_SpriteItemCount, _AnimationSpeed, startTime);
- float2 dimensions = float2(_SpriteColumnCount, _SpriteRowCount);
- float2 itemSize = GetSpriteItemSize(dimensions);
-
- return GetSpriteSheetCoords(uv, dimensions, spriteTileIndex, itemSize, _SpriteItemCount);
- }
- // Get a normal ranged value in [-1,1] range from a 0-1 percent value.
- float GetNormalRangeFromPercent(float percent) {
- return -1.0f + (2.0f * percent);
- }
- float3 GetDirectionFromPercent(float3 percentDir) {
- return float3(
- GetNormalRangeFromPercent(percentDir.x),
- GetNormalRangeFromPercent(percentDir.y),
- GetNormalRangeFromPercent(percentDir.z));
- }
- v2f vert (appdata v)
- {
- v2f o;
- UNITY_SETUP_INSTANCE_ID(v);
- UNITY_TRANSFER_INSTANCE_ID(v, o);
- float2 depthUV = float2(UNITY_ACCESS_INSTANCED_PROP(_OverheadDepthU_arr, _OverheadDepthU), UNITY_ACCESS_INSTANCED_PROP(_OverheadDepthV_arr, _OverheadDepthV));
- float4 checkUV = float4(depthUV, 0.0f, 0.0f);
- float4 overInfo = tex2Dlod(_OverheadDepthTex, checkUV);
- float depthValue = overInfo.a;
- float distanceFromCamera = _OverheadDepthNearClip + _OverheadDepthFarClip * depthValue;
- float4 worldPos = mul(unity_ObjectToWorld, float4(v.vertex.xyz, 1.0f));
- // BEGIN TESTING.
- float3 vertex = v.vertex.xyz;
- float3 surfaceNormal = GetDirectionFromPercent(overInfo.xyz);
- float3 up = normalize(surfaceNormal);
- float3 forward = normalize(cross(up, float3(1.0f, 0.0f, 0.0f)));
- float3 right = normalize(cross(up, forward));
- // Extract the original scale from the right axis vector.
- float scale = length(float3(unity_ObjectToWorld[0][0], unity_ObjectToWorld[0][1], unity_ObjectToWorld[0][1]));
- // Restore the scale values.
- up *= scale;
- forward *= scale;
- right *= scale;
- float4x4 objToWorld = unity_ObjectToWorld;
- objToWorld[0][0] = right.x;
- objToWorld[0][1] = right.y;
- objToWorld[0][2] = right.z;
- objToWorld[1][0] = up.x;
- objToWorld[1][1] = up.y;
- objToWorld[1][2] = up.z;
- objToWorld[2][0] = forward.x;
- objToWorld[2][1] = forward.y;
- objToWorld[2][2] = forward.z;
- worldPos = mul(objToWorld, float4(vertex, 1.0f));
-
- // END TESTING
- //worldPos = mul(unity_ObjectToWorld, float4(vertex.xyz, 1.0f));
- float adjustedOrigin = _OverheadDepthPosition.y - distanceFromCamera;
- worldPos.y += adjustedOrigin - UNITY_ACCESS_INSTANCED_PROP(_SplashStartYPosition_arr, _SplashStartYPosition);
- worldPos.xyz = worldPos.xyz + (surfaceNormal * _SplashGroundOffset);
-
- o.vertex = mul(UNITY_MATRIX_VP, worldPos);
- // Easy way to detect no collision is that empty fill color sets -1,-1,-1 which isn't normalized length of 1.
- o.isOverSurface = step(length(surfaceNormal), 1.1f) - .5f;
- o.uv = v.uv;
-
- return o;
- }
-
- fixed4 frag (v2f i) : SV_Target
- {
- UNITY_SETUP_INSTANCE_ID(i);
- clip(i.isOverSurface);
- float startTime = UNITY_ACCESS_INSTANCED_PROP(_StartTime_arr, _StartTime);
- float endTime = UNITY_ACCESS_INSTANCED_PROP(_EndTime_arr, _EndTime);
- float2 spriteUV = saturate(GetAnimatedSpriteCoords(i.uv, startTime));
- fixed4 spriteColor = tex2D(_SpriteSheetTex, spriteUV) * _Intensity * _TintColor;
- // Go transparent if the sprite completed its time loop.
- return spriteColor * step(_Time.y, endTime);
- }
-
- ENDCG
- }
- }
- FallBack "Unlit/Color"
- }
|