Advertisement
TomRintjema

WaterShader

Aug 27th, 2014
261
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.48 KB | None | 0 0
  1. Shader "Custom/PlaneDeformer"
  2. {
  3.  
  4. Properties
  5. {
  6. _Color ("Color", Color) = (1, 1, 1, 1)
  7. _PhaseOffset ("PhaseOffset", Range(0,1)) = 0
  8. _Speed ("Speed", Range(0.0,10)) = 1.0
  9. _Depth ("Depth", Range(0.0,1)) = 0.2
  10. _Smoothing ("Smoothing", Range(0,1)) = 0.0
  11. _XDrift ("X Drift", Range(0.0,2.0)) = 0.05
  12. _ZDrift ("Z Drift", Range(0.0,2.0)) = 0.12
  13. _Scale ("Scale", Range(0.1,10)) = 1.0
  14. //_Scale ("Scale", Float) = 1
  15. }
  16.  
  17.  
  18.  
  19.  
  20. SubShader
  21. {
  22.  
  23. Tags
  24. {
  25. "Queue" = "Geometry"
  26. "RenderType" = "Opaque"
  27. "IgnoreProjector" = "True"
  28. }
  29.  
  30. CGPROGRAM
  31. #pragma surface surf Lambert vertex:vert
  32. //#pragma surface surf Lambert finalcolor:showNormals vertex:vert noforwardadd
  33. #pragma target 3.0
  34.  
  35.  
  36. half3 _Color;
  37. float _PhaseOffset;
  38. float _Speed;
  39. float _Depth;
  40. float _Smoothing;
  41. float _XDrift;
  42. float _ZDrift;
  43. float _Scale;
  44.  
  45. struct Input
  46. {
  47. half3 debugColor;
  48. };
  49.  
  50.  
  51.  
  52. // I ran into an enormous, annoying error where the Cg sin() function was causing some geometry mayhem,
  53. // altering properties it shouldn't, if it was given a value of exactly 1.
  54. // Any modulation fixed it. No other sin() implementation has the same problem.
  55. // No idea what the problem is! Using this as a workaround, may go to the forums to see what's up later.
  56. float sine( float x )
  57. {
  58. float b = (1-x)<0.001 ? 1.0001 : 1.0;
  59. return sin(x) * b;
  60. }
  61.  
  62.  
  63.  
  64. void vert( inout appdata_full v, out Input o )
  65. {
  66. // Note that, to start off, all work is in object (local) space.
  67. // We will eventually move normals to world space to handle arbitrary object orientation.
  68. // There is no real need for tangent space in this case.
  69.  
  70. // Do all work in world space
  71. float3 v0 = mul( _Object2World, v.vertex ).xyz;
  72.  
  73. // Create two fake neighbor vertices.
  74. // The important thing is that they be distorted in the same way that a real vertex in their location would.
  75. // This is pretty easy since we're just going to do some trig based on position, so really any samples will do.
  76. float3 v1 = v0 + float3( 0.05, 0, 0 ); // +X
  77. float3 v2 = v0 + float3( 0, 0, 0.05 ); // +Z
  78.  
  79.  
  80.  
  81. // Some animation values
  82. float phase = _PhaseOffset * (3.14 * 2);
  83. float phase2 = _PhaseOffset * (3.14 * 1.123);
  84. float speed = _Time.y * _Speed;
  85. float speed2 = _Time.y * (_Speed * 0.33 );
  86. float _Depth2 = _Depth * 1.0;
  87. float v0alt = v0.x * _XDrift + v0.z * _ZDrift;
  88. float v1alt = v1.x * _XDrift + v1.z * _ZDrift;
  89. float v2alt = v2.x * _XDrift + v2.z * _ZDrift;
  90.  
  91. // Modify the real vertex and two theoretical samples by the distortion algorithm (here a simple sine wave on Y, driven by local X pos)
  92. v0.y += sin( phase + speed + ( v0.x * _Scale ) ) * _Depth;
  93. v0.y += sin( phase2 + speed2 + ( v0alt * _Scale ) ) * _Depth2; // This is just another wave being applied for a bit more complexity.
  94.  
  95. v1.y += sin( phase + speed + ( v1.x * _Scale ) ) * _Depth;
  96. v1.y += sin( phase2 + speed2 + ( v1alt * _Scale ) ) * _Depth2;
  97.  
  98. v2.y += sin( phase + speed + ( v2.x * _Scale ) ) * _Depth;
  99. v2.y += sin( phase2 + speed2 + ( v2alt * _Scale ) ) * _Depth2;
  100.  
  101. // By reducing the delta on Y, we effectively restrict the amout of variation the normals will exhibit.
  102. // This appears like a smoothing effect, separate from the actual displacement depth.
  103. // It's basically undoing the change to the normals, leaving them straight on Y.
  104. v1.y -= (v1.y - v0.y) * _Smoothing;
  105. v2.y -= (v2.y - v0.y) * _Smoothing;
  106.  
  107. // Solve worldspace normal
  108. float3 vna = cross( v2-v0, v1-v0 );
  109.  
  110.  
  111. // OPTIONAL worldspace normal out to a custom value. Uncomment the showNormals finalcolor profile option above to see the result
  112. o.debugColor = ( normalize( vna ) * 0.5 ) + 0.5;
  113. o.debugColor = ( normalize( vna ) );
  114.  
  115. // Put normals back in object space
  116. float3 vn = mul( float3x3(_World2Object), vna );
  117.  
  118. // Normalize
  119. v.normal = normalize( vn );
  120.  
  121. // Put vertex back in object space, Unity will automatically do the MVP projection
  122. v.vertex.xyz = mul( float3x3(_World2Object), v0 );
  123. }
  124.  
  125.  
  126.  
  127. // Optional normal debug function, unccoment profile option to invoke
  128. void showNormals( Input IN, SurfaceOutput o, inout fixed4 color )
  129. {
  130. color.rgb = IN.debugColor.rgb;
  131. color.a = 1;
  132. }
  133.  
  134.  
  135.  
  136. // Regular old surface shader
  137. void surf (Input IN, inout SurfaceOutput o)
  138. {
  139. o.Albedo = _Color.rgb;
  140. }
  141.  
  142. ENDCG
  143.  
  144. }
  145.  
  146. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement