opponent019

Melting Shader

May 2nd, 2018
30
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
  2.  
  3. // To use with this script: https://pastebin.com/pHtJDBND
  4. // Original shader: http://diary.conewars.com/vertex-displacement-shader/
  5. // Edited by Erika Moya
  6.  
  7. Shader "Custom/MeltingEdit" {
  8. Properties {
  9. _Color ("Color", Color) = (1,1,1,1)
  10. _MainTex ("Albedo (RGB)", 2D) = "white" {}
  11. _Glossiness ("Smoothness", Range(0,1)) = 0.5
  12. _Metallic ("Metallic", Range(0,1)) = 0.0
  13.  
  14. _MeltDistance("Melt Distance", Float) = 1.0
  15. _MeltCurve("Melt Curve", Range(1.0,10.0)) = 2.0
  16. _MeltMax("Maximum melting displace", Float) = 1.0
  17.  
  18. _Tess("Tessellation Amount", Range( 1, 32 )) = 10
  19. }
  20. SubShader {
  21. Tags { "RenderType"="Opaque" }
  22. LOD 200
  23.  
  24. CGPROGRAM
  25.  
  26.  
  27. // add the tessellate function here
  28. #pragma surface surf Standard fullforwardshadows vertex:disp addshadow tessellate:tessDistance nolightmap
  29.  
  30. // to use tessellation we must target shader model 4.6 and up
  31. #pragma target 4.6
  32.  
  33. // include Unity's tessellation code
  34. #include "Tessellation.cginc"
  35.  
  36. sampler2D _MainTex;
  37.  
  38. float4x4 collisionMatrix;
  39. float4x4 collisionMatrixInverse;
  40.  
  41. struct Input {
  42. float2 uv_MainTex;
  43. };
  44.  
  45. half _Glossiness;
  46. half _Metallic;
  47. fixed4 _Color;
  48.  
  49. half _MeltDistance;
  50. half _MeltCurve;
  51. half _MeltMax;
  52.  
  53. float _Tess;
  54.  
  55. struct appdata {
  56. float4 vertex : POSITION;
  57. float4 tangent : TANGENT;
  58. float3 normal : NORMAL;
  59. float2 texcoord : TEXCOORD0;
  60. };
  61.  
  62. // A modified version of Unity's UnityCalcDistanceTessFactor that only adds tess verts if the vertex is in the melt range
  63. float MeltCalcDistanceTessFactor (float4 vertex, float minDist, float maxDist, float tess)
  64. {
  65. float3 wpos = mul(unity_ObjectToWorld,vertex).xyz;
  66.  
  67. wpos = mul(wpos, collisionMatrix).xyz; // +
  68.  
  69. float dist = distance (wpos, _WorldSpaceCameraPos);
  70. float f = clamp(1.0 - (dist - minDist) / (maxDist - minDist), 0.01, 1.0);
  71.  
  72. float melt = (( wpos.y ) / _MeltDistance);
  73. // calculate the melt for the world position
  74. // in our normal vert function we saturate this subtract it from 1 so verts near the ground are 1 and join the mesh at 0
  75. // we only care if the object is in the 'melt' range, so any value between 0 & 1, regardless of the sign.
  76. // will add a threshold too so verts near the edges are tessellated too
  77.  
  78. if( melt < -0.1 || melt > 1.1 )
  79. {
  80. f = 0.01; // set the value to the lower end of the clamp
  81. }
  82.  
  83. // move the tess multiply here for clarity
  84. return f * tess;
  85. }
  86.  
  87. // A modified version of Unity's UnityDistanceBasedTess to run our version of TessFactor
  88. // Distance based tessellation:
  89. // Tessellation level is "tess" before "minDist" from camera, and linearly decreases to 1
  90. // up to "maxDist" from camera.
  91. float4 MeltDistanceBasedTess (float4 v0, float4 v1, float4 v2, float minDist, float maxDist, float tess)
  92. {
  93. float3 f;
  94. f.x = MeltCalcDistanceTessFactor (v0,minDist,maxDist,tess);
  95. f.y = MeltCalcDistanceTessFactor (v1,minDist,maxDist,tess);
  96. f.z = MeltCalcDistanceTessFactor (v2,minDist,maxDist,tess);
  97.  
  98. return UnityCalcTriEdgeTessFactors (f);
  99. }
  100.  
  101. float4 tessDistance(appdata v0, appdata v1, appdata v2)
  102. {
  103. float minDist = 10.0;
  104. float maxDist = 25.0;
  105.  
  106. // this unity function scales how much tessellation based on how close the camera is
  107. // objects further away keep the same vert count as before
  108.  
  109. // the last parameter is the factor of tessellation, increasing it in the material inspector increases verts created
  110. return MeltDistanceBasedTess(v0.vertex, v1.vertex, v2.vertex, minDist, maxDist, _Tess);
  111. }
  112.  
  113. float4 getNewVertPosition( float4 objectSpacePosition, float3 objectSpaceNormal )
  114. {
  115. float4 worldSpacePosition = mul( unity_ObjectToWorld, objectSpacePosition );
  116. float4 worldSpaceNormal = mul( unity_ObjectToWorld, float4(objectSpaceNormal,0) );
  117.  
  118. worldSpacePosition = mul(worldSpacePosition, collisionMatrixInverse); // +
  119. worldSpaceNormal = mul(worldSpaceNormal, collisionMatrixInverse); // +
  120.  
  121. float melt = ( worldSpacePosition.y) / _MeltDistance;
  122.  
  123. melt = 1 - saturate( melt);
  124. melt = pow( melt, _MeltCurve );
  125.  
  126. worldSpacePosition.xz += worldSpaceNormal.xz * melt * _MeltMax;
  127.  
  128. worldSpacePosition = mul(worldSpacePosition, collisionMatrix); // +
  129.  
  130. return mul( unity_WorldToObject, worldSpacePosition);
  131. }
  132.  
  133. void disp( inout appdata v )
  134. {
  135. float4 vertPosition = getNewVertPosition( v.vertex, v.normal );
  136.  
  137. float4 bitangent = float4( cross( v.normal, v.tangent ), 0 );
  138. float vertOffset = 0.01;
  139.  
  140. float4 v1 = getNewVertPosition( v.vertex + v.tangent * vertOffset, v.normal );
  141. float4 v2 = getNewVertPosition( v.vertex + bitangent * vertOffset, v.normal );
  142.  
  143. float4 newTangent = v1 - vertPosition;
  144. float4 newBitangent = v2 - vertPosition;
  145.  
  146. v.normal = cross( newTangent, newBitangent );
  147.  
  148. v.vertex = vertPosition;
  149. }
  150.  
  151. void surf (Input IN, inout SurfaceOutputStandard o) {
  152. // Albedo comes from a texture tinted by color
  153. fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
  154. o.Albedo = c.rgb;
  155. // Metallic and smoothness come from slider variables
  156. o.Metallic = _Metallic;
  157. o.Smoothness = _Glossiness;
  158. o.Alpha = c.a;
  159. }
  160. ENDCG
  161. }
  162. FallBack "Diffuse"
  163. }
RAW Paste Data