Advertisement
Guest User

Untitled

a guest
Sep 23rd, 2019
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.94 KB | None | 0 0
  1. Shader "Custom/Waves" {
  2. Properties {
  3. _Color("Color", Color) = (1,1,1,1)
  4. _GradientMap ("Gradient Map", 2D) = "white" {}
  5. _MainTex ("Albedo (RGB)", 2D) = "white" {}
  6. _DistortTex ("Distortion (displacement)", 2D) = "white" {}
  7. _DistortScale("Distortion Scale", Range(-100, 100)) = 100
  8. // Red is the amount of Y variance in the vertex position.
  9. // Blue is the amount by which the color is pushed towards white.
  10. _WaterInteractionTex ("Object interaction", 2D) = "white" {}
  11. _WaterInteractionScale ("Interaction scale factor", Range(-100, 100)) = 10
  12. _Glossiness ("Smoothness", Range(0,1)) = 0.5
  13. _Metallic ("Metallic", Range(0,1)) = 0.0
  14. _WaveA ("Wave A (dir, steepness, wavelength)", Vector) = (1,0,0.5,10)
  15. _WaveB ("Wave B", Vector) = (0,1,0.25,20)
  16. _WaveC ("Wave C", Vector) = (1,1,0.15,10)
  17. _WaveSpeed ("Wave scroll speed factor", Range(0,1)) = .5
  18. _MaxTessellationDistance("Max tessellation distance", float) = 100
  19. _Tessellation("Tessellation", Range(1.0, 128.0)) = 1.0
  20. }
  21. SubShader {
  22. Tags { "RenderType"="Opaque" }
  23. LOD 200
  24.  
  25. CGPROGRAM
  26. #pragma surface surf Standard fullforwardshadows vertex:vert tessellate:tessDistance addshadow
  27. #include "Tessellation.cginc"
  28. #pragma require tessellation tessHW
  29. #pragma target 4.6
  30.  
  31. sampler2D _MainTex;
  32. sampler2D _DistortTex;
  33. float4 _DistortTex_ST;
  34. float _DistortScale;
  35. sampler2D _WaterInteractionTex;
  36. float _WaterInteractionScale;
  37. sampler2D _GradientMap;
  38. float3 _InteractorPosition;
  39. uniform float _OrthographicCamSize;
  40.  
  41. struct Input {
  42. float2 uv_MainTex;
  43. float3 worldPos;
  44. // HACK: we override the alpha channel to be the amount we push the color towards white.
  45. float4 color : COLOR;
  46. };
  47.  
  48. half _Glossiness;
  49. half _Metallic;
  50. float _WaveSpeed;
  51. fixed4 _Color;
  52. float4 _WaveA, _WaveB, _WaveC;
  53. float _MaxTessellationDistance;
  54. float _Tessellation;
  55.  
  56. float4 tessDistance (appdata_full v0, appdata_full v1, appdata_full v2) {
  57. float minDist = 10.0;
  58. float maxDist = _MaxTessellationDistance;
  59. return UnityDistanceBasedTess(v0.vertex, v1.vertex, v2.vertex, minDist, maxDist, _Tessellation);
  60. }
  61.  
  62. float3 GerstnerWave (
  63. float4 wave, float3 p, inout float3 tangent, inout float3 binormal
  64. ) {
  65. float steepness = wave.z;
  66. float wavelength = wave.w;
  67. float k = 2 * UNITY_PI / wavelength;
  68. float c = sqrt(9.8 / k);
  69. float2 d = normalize(wave.xy);
  70. float f = k * (dot(d, p.xz) - c * _Time.y * _WaveSpeed);
  71. float a = steepness / k;
  72.  
  73. tangent += float3(
  74. -d.x * d.x * (steepness * sin(f)),
  75. d.x * (steepness * cos(f)),
  76. -d.x * d.y * (steepness * sin(f))
  77. );
  78. binormal += float3(
  79. -d.x * d.y * (steepness * sin(f)),
  80. d.y * (steepness * cos(f)),
  81. -d.y * d.y * (steepness * sin(f))
  82. );
  83. return float3(
  84. d.x * (a * cos(f)),
  85. a * sin(f),
  86. d.y * (a * cos(f))
  87. );
  88. }
  89.  
  90. float scaleRipple(float2 rippleUV) {
  91. // Fade out ripples based on distance from center of the render texture,
  92. // so there aren't weird behaviors when we hit the edges (and values get clamped)
  93. float dx = 2 * (rippleUV.x - .5); // Range -1 to 1
  94. float dy = 2 * (rippleUV.y - .5); // Range -1 to 1
  95. float distSq = (dx * dx) + (dy * dy); // Range 0-2
  96. float rippleScale = saturate(1 - sqrt(distSq)); // Range 0-1
  97. return rippleScale;
  98. }
  99.  
  100. void vert(inout appdata_full vertexData){
  101. float3 tangent = float3(1, 0, 0);
  102. float3 binormal = float3(0, 0, 1);
  103. // Use world position coordinates for the wave calculations
  104. // so that our ocean tiles tile smoothly.
  105. float3 worldPos = mul(unity_ObjectToWorld, vertexData.vertex).xyz;
  106. // Distort the world position using some noise, to break up the
  107. // waves a bit.
  108. float4 worldOffset = tex2Dlod(_DistortTex, vertexData.texcoord1) * _DistortScale;
  109. float3 offsetWorldPos = worldPos;
  110. offsetWorldPos.xz += float2(worldOffset.x, worldOffset.y);
  111. float3 offset = float3(0, 0, 0);
  112. offset += GerstnerWave(_WaveA, offsetWorldPos, tangent, binormal);
  113. offset += GerstnerWave(_WaveB, offsetWorldPos, tangent, binormal);
  114. offset += GerstnerWave(_WaveC, offsetWorldPos, tangent, binormal);
  115. // Scale down wave size when they're further from the camera.
  116. float scale = distance(_WorldSpaceCameraPos.xyz, worldPos);
  117. /// Distance < 100 -> scale = 1. Distance = 1100 -> scale = 0.
  118. scale = saturate((1100 - scale) / 1000);
  119. float3 p = vertexData.vertex.xyz + offset * scale;
  120.  
  121. // Apply distortions from the _WaterInteractionTex. Red is vertical
  122. // displacement, blue is how much we push the color towards white.
  123. // Adjust vertical portion of vertex position based on nearby objects
  124. // See https://www.patreon.com/posts/24192529
  125. float4 rippleUV = float4(0, 0, 0, 0);
  126. rippleUV.xy += (worldPos.xz - _InteractorPosition.xz) / (_OrthographicCamSize * 2) + .5;
  127. float4 rippleSample = tex2Dlod(_WaterInteractionTex, rippleUV);
  128. rippleSample *= scaleRipple(rippleUV);
  129. float rippleY = rippleSample.r * _WaterInteractionScale;
  130. p.y += rippleY;
  131.  
  132. vertexData.normal = normalize(cross(binormal, tangent));
  133. vertexData.vertex.xyz = p;
  134. // Brightest colors only come from ripple effects.
  135. vertexData.color = _Color * saturate(.5 + rippleY / _WaterInteractionScale);
  136. // Push color towards white based on the blue channel of the ripple texture.
  137. // See HACK note in the struct definition.
  138. vertexData.color.a = rippleSample.b;
  139. }
  140.  
  141. void surf (Input IN, inout SurfaceOutputStandard o) {
  142. // Arbitrary fiddle factor to make things look decent.
  143. float depth = 1 - (IN.worldPos.y / 400);
  144. fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * tex2D(_GradientMap, float2(depth, 0)) * IN.color;
  145. // See HACK note in the Input struct definition.
  146. c = saturate(c + float4(1,1,1,1) * IN.color.a * 3);
  147. c.a = 1;
  148. o.Albedo = c.rgb;
  149. o.Metallic = _Metallic;
  150. o.Smoothness = _Glossiness;
  151. o.Alpha = c.a;
  152. }
  153. ENDCG
  154. }
  155. FallBack "Diffuse"
  156. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement