Advertisement
Guest User

Dynamic Deformation Shader

a guest
Apr 15th, 2019
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. Shader "DynamicDeformation"
  2. {
  3.     Properties
  4.     {
  5.         [Header(Textures and Colors)]
  6.         [NoScaleOffset]_MainTex("Base (RGB)", 2D) = "white" {} //Base triplanar texture
  7.         [NoScaleOffset]_DispTex("Displacement Texture", 2D) = "gray" {} //Displacement map, medium grey smoothly peaking in white works best.
  8.         [NoScaleOffset]_BumpMap("Normal Map", 2D) = "bump" {} //Normal triplanar texture
  9.         _IntersectionColor("Intersection Color", Color) = (1, 0, 1, 1) //color when intersecting
  10.         _NormalIntensity("Normal Intensity", Range(0, 5)) = 1 //Intensity of normals
  11.         _NormalScaling("Normal Scaling", Range(0, 1)) = 0.5 //Scaling intensity of normals
  12.         _IntersectionLength("Intersection Length", Range(0, 2)) = 2.0 //distance of intersecting effect
  13.         _TextureScale("Texture Scale", Range(0.01, 2)) = 1 //Scale of triplanar textures.
  14.  
  15.         [Header(Displacement)]
  16.         _CheckAngle("Disp Dir & Tess Amt", Vector) = (0,1,0) //Direction of effect displacement
  17.         _DispSmoothing("Dsip. Smoothing", Range(0.1, 10)) = 1 //Displacement Smoothing effect
  18.         _Displacement("Displacement Scale", Range(0.01, 1.0)) = 0.25 //Displacement scale
  19.         _UndersideDisp("Underside Scaling", Range(-0.1, 1.0)) = 0.1 //Displacement underside scaling
  20.         _MossReduction("Disp Reduction", Range(0, 15)) = 0  //Displacement reduction
  21.         _AngleReduction("Angle Reduction", Range(1, -5)) = 0 //Angle of displacement reduction
  22.  
  23.         [Header(Tesselation)]
  24.         _MinimumTess("Min Tess. Ammount", Range(1, 10)) = 2 //Minimum tesselation value
  25.         _MinDist("Min Tess. Distance", Range(0, 10)) = 5 //Inner limit of tesselation distance
  26.         _MaxDist("Max Tess. Distance", Range(10, 50)) = 25 //Outer limit of tesselation distance
  27.  
  28.         [Header(Properties)]
  29.         _Gloss("Smoothness", Range(0, 1)) = 0 //Standard property values
  30.         _Metalness("Mettalic", Range(0, 1)) = 0 //Standard property values
  31.  
  32.     }
  33.         SubShader
  34.     {
  35.         Tags{ "Queue" = "Transparent" "RenderType" = "Transparent" }
  36.         CGPROGRAM
  37. #pragma surface surf Standard addshadow fullforwardshadows vertex:vert tessellate:tessEdge nolightmap
  38. #pragma target 5.0
  39. #include "Tessellation.cginc"
  40. #include "UnityPBSLighting.cginc"
  41.  
  42.     sampler2D _CameraDepthTexture; //Shader Gobal accessed for intersection values.
  43.     sampler2D _MainTex;
  44.     sampler2D _BumpMap;
  45.     sampler2D _DispTex;
  46.     half4 _IntersectionColor;
  47.     float3 _CheckAngle;
  48.     float _TextureScale;
  49.     float _Displacement;
  50.     float _DispSmoothing;
  51.     float _UndersideDisp;
  52.     float _MossReduction;
  53.     float _NormalIntensity;
  54.     float _NormalScaling;
  55.     float _MinimumTess;
  56.     float _AngleReduction;
  57.     float _MinDist;
  58.     float _MaxDist;
  59.     float _IntersectionLength;
  60.     float _Gloss;
  61.     float _Metalness;
  62.  
  63.     struct appdata
  64.     {
  65.         float4 vertex : POSITION;
  66.         float4 tangent : TANGENT;
  67.         float3 normal : NORMAL;
  68.         float2 texcoord : TEXCOORD0;
  69.     };
  70.  
  71.     struct Input
  72.     {
  73.         float2 uv_MainTex;
  74.         float3 vertex;
  75.         float3 worldNormal;
  76.         float3 worldPos;
  77.         float4 screenPos;
  78.         INTERNAL_DATA
  79.     };
  80.  
  81.     //Tesselation function, use the dot product of the averaged normal per polygon & a given direciton to decide on tesselation ammount.
  82.     float4 tessEdge(appdata v0, appdata v1, appdata v2)
  83.     {
  84.         float tessValue = _MinimumTess;
  85.         float3 averagedNormal = normalize(v0.normal + v1.normal + v2.normal);
  86.         if (dot(mul(unity_ObjectToWorld, averagedNormal), _CheckAngle) < 0)
  87.         {
  88.             tessValue = 0;
  89.         }
  90.         return UnityDistanceBasedTess(v0.vertex, v1.vertex, v2.vertex, _MinDist, _MaxDist, tessValue);
  91.     }
  92.  
  93.     //Vertex function to deform tesselated surface, based on a triplanar map.
  94.     void vert(inout appdata v)
  95.     {
  96.         float2 uvX = v.vertex.zy; // x facing plane
  97.         float2 uvY = v.vertex.xz; // y facing plane
  98.         float2 uvZ = v.vertex.xy; // z facing plane
  99.  
  100.         half3 worldDisp;
  101.         worldDisp.x = tex2Dlod(_DispTex, float4(uvX, 0, 0)) * _Displacement;
  102.         worldDisp.y = tex2Dlod(_DispTex, float4(uvY, 0, 0)) * _Displacement;
  103.         worldDisp.z = tex2Dlod(_DispTex, float4(uvZ, 0, 0)) * _Displacement;
  104.  
  105.         float resultAngle = smoothstep(10, 1, _DispSmoothing);
  106.         if (_CheckAngle.x || _CheckAngle.y || _CheckAngle.z)
  107.         {
  108.             resultAngle = smoothstep(0, _DispSmoothing, saturate(dot(mul(unity_ObjectToWorld, float4(v.normal, 0.0)).xyz, _CheckAngle) + (_AngleReduction * length(_CheckAngle))));
  109.         }
  110.  
  111.         //Apply displacement based on the dot product, and various values given in the material.
  112.         v.vertex.xyz += lerp(v.normal.xyz * -worldDisp.xyz * _UndersideDisp, (v.normal.xyz * worldDisp.xyz) - (v.normal.xyz * _MossReduction), resultAngle);
  113.     }
  114.  
  115.     //Surface function to add material values and textures.
  116.     void surf(Input IN, inout SurfaceOutputStandard o)
  117.     {
  118.         //Calculate distance from depth values
  119.         float sceneZ = LinearEyeDepth(SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(IN.screenPos)));
  120.         float surfZ = -mul(UNITY_MATRIX_V, float4(IN.worldPos.xyz, 1)).z;
  121.         float diff = sceneZ - surfZ;
  122.         float result = 1 - saturate(diff / _IntersectionLength);
  123.  
  124.         //Calculate triplanar values
  125.         float3 localPos = IN.worldPos - mul(unity_ObjectToWorld, float4(0, 0, 0, 1)).xyz;;
  126.         float2 uvX = localPos.zy * _TextureScale; // x facing plane
  127.         float2 uvY = localPos.xz * _TextureScale; // y facing plane
  128.         float2 uvZ = localPos.xy * _TextureScale; // z facing plane
  129.  
  130.         //Find resulting albedo
  131.         half4 resultTex = (tex2D(_MainTex, uvX) + tex2D(_MainTex, uvY) + tex2D(_MainTex, uvZ)) / 3;
  132.         o.Albedo = lerp(resultTex, resultTex * _IntersectionColor, result);
  133.  
  134.         //Calculate normal values & blend
  135.         float dist = distance(_WorldSpaceCameraPos, IN.worldPos);
  136.         o.Normal = UnpackScaleNormal(tex2D(_BumpMap, uvX), max(_NormalIntensity, dist * _NormalScaling)) +
  137.             UnpackScaleNormal(tex2D(_BumpMap, uvY), max(_NormalIntensity, dist * _NormalScaling)) +
  138.             UnpackScaleNormal(tex2D(_BumpMap, uvZ), max(_NormalIntensity, dist * _NormalScaling));
  139.         o.Smoothness = _Gloss;
  140.         o.Metallic = _Metalness;
  141.     }
  142.     ENDCG
  143.     }
  144.         FallBack "Diffuse"
  145. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement