Preview_TriplanarNode.shader 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. Shader "Hidden/TriplanarNode"
  2. {
  3. Properties
  4. {
  5. _A ("_TopTex", 2D) = "white" {}
  6. _B ("_MidTex", 2D) = "white" {}
  7. _C ("_BotTex", 2D) = "white" {}
  8. _D ("_Tilling", 2D) = "white" {}
  9. _E ("_Falloff", 2D) = "white" {}
  10. }
  11. SubShader
  12. {
  13. Pass
  14. {
  15. CGPROGRAM
  16. #pragma vertex vert_img
  17. #pragma fragment frag
  18. #pragma target 3.0
  19. #include "UnityCG.cginc"
  20. #include "Preview.cginc"
  21. #include "UnityStandardUtils.cginc"
  22. sampler2D _A;
  23. sampler2D _B;
  24. sampler2D _C;
  25. sampler2D _D;
  26. sampler2D _E;
  27. float _IsNormal;
  28. float _IsTangent;
  29. float _IsSpherical;
  30. inline float3 TriplanarSamplingCNF( sampler2D topTexMap, sampler2D midTexMap, sampler2D botTexMap, float3 worldPos, float3 worldNormal, float falloff, float tilling )
  31. {
  32. float3 projNormal = ( pow( abs( worldNormal ), falloff ) );
  33. projNormal /= projNormal.x + projNormal.y + projNormal.z;
  34. float3 nsign = sign( worldNormal );
  35. float negProjNormalY = max( 0, projNormal.y * -nsign.y );
  36. projNormal.y = max( 0, projNormal.y * nsign.y );
  37. half4 xNorm; half4 yNorm; half4 yNormN; half4 zNorm;
  38. xNorm = ( tex2D( midTexMap, tilling * worldPos.zy * float2( nsign.x, 1.0 ) ) );
  39. yNorm = ( tex2D( topTexMap, tilling * worldPos.xz * float2( nsign.y, 1.0 ) ) );
  40. yNormN = ( tex2D( botTexMap, tilling * worldPos.xz * float2( nsign.y, 1.0 ) ) );
  41. zNorm = ( tex2D( midTexMap, tilling * worldPos.xy * float2( -nsign.z, 1.0 ) ) );
  42. xNorm.xyz = half3( UnpackNormal( xNorm ).xy * float2( nsign.x, 1.0 ) + worldNormal.zy, worldNormal.x ).zyx;
  43. yNorm.xyz = half3( UnpackNormal( yNorm ).xy * float2( nsign.y, 1.0 ) + worldNormal.xz, worldNormal.y ).xzy;
  44. zNorm.xyz = half3( UnpackNormal( zNorm ).xy * float2( -nsign.z, 1.0 ) + worldNormal.xy, worldNormal.z ).xyz;
  45. yNormN.xyz = half3( UnpackNormal( yNormN ).xy * float2( nsign.y, 1.0 ) + worldNormal.xz, worldNormal.y ).xzy;
  46. return normalize( xNorm.xyz * projNormal.x + yNorm.xyz * projNormal.y + yNormN.xyz * negProjNormalY + zNorm.xyz * projNormal.z );
  47. }
  48. inline float4 TriplanarSamplingCF( sampler2D topTexMap, sampler2D midTexMap, sampler2D botTexMap, float3 worldPos, float3 worldNormal, float falloff, float tilling )
  49. {
  50. float3 projNormal = ( pow( abs( worldNormal ), falloff ) );
  51. projNormal /= projNormal.x + projNormal.y + projNormal.z;
  52. float3 nsign = sign( worldNormal );
  53. float negProjNormalY = max( 0, projNormal.y * -nsign.y );
  54. projNormal.y = max( 0, projNormal.y * nsign.y );
  55. half4 xNorm; half4 yNorm; half4 yNormN; half4 zNorm;
  56. xNorm = ( tex2D( midTexMap, tilling * worldPos.zy * float2( nsign.x, 1.0 ) ) );
  57. yNorm = ( tex2D( topTexMap, tilling * worldPos.xz * float2( nsign.y, 1.0 ) ) );
  58. yNormN = ( tex2D( botTexMap, tilling * worldPos.xz * float2( nsign.y, 1.0 ) ) );
  59. zNorm = ( tex2D( midTexMap, tilling * worldPos.xy * float2( -nsign.z, 1.0 ) ) );
  60. return xNorm * projNormal.x + yNorm * projNormal.y + yNormN * negProjNormalY + zNorm * projNormal.z;
  61. }
  62. float4 frag( v2f_img i ) : SV_Target
  63. {
  64. float3 vertexPos = PreviewFragmentPositionOS( i.uv );
  65. float3 normal = PreviewFragmentNormalOS( i.uv );
  66. float3 worldNormal = UnityObjectToWorldNormal(normal);
  67. float3 worldPos = mul(unity_ObjectToWorld, vertexPos).xyz;
  68. float falloff = tex2D( _E, vertexPos.xy ).r;
  69. float tilling = tex2D( _D, vertexPos.xy ).r * 0.625;
  70. float4 triplanar = 1;
  71. if ( _IsNormal == 1 ) {
  72. float3 tangent = PreviewFragmentTangentOS( i.uv );
  73. float3 worldTangent = UnityObjectToWorldDir(tangent);
  74. float tangentSign = -1;
  75. float3 worldBinormal = normalize( cross(worldNormal, worldTangent) * tangentSign);
  76. float3x3 worldToTangent = float3x3( worldTangent, worldBinormal, worldNormal );
  77. if ( _IsSpherical == 1 )
  78. triplanar.xyz = TriplanarSamplingCNF( _A, _A, _A, worldPos, worldNormal, falloff, tilling );
  79. else
  80. triplanar.xyz = TriplanarSamplingCNF( _A, _B, _C, worldPos, worldNormal, falloff, tilling );
  81. if( _IsTangent == 1 )
  82. triplanar.xyz = mul( worldToTangent, triplanar.xyz );
  83. }
  84. else
  85. {
  86. if ( _IsSpherical == 1 )
  87. triplanar = TriplanarSamplingCF( _A, _A, _A, worldPos, worldNormal, falloff, tilling );
  88. else
  89. triplanar = TriplanarSamplingCF( _A, _B, _C, worldPos, worldNormal, falloff, tilling );
  90. }
  91. return triplanar;
  92. }
  93. ENDCG
  94. }
  95. }
  96. }