Sin descripción
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SpeedTree7BillboardPasses.hlsl 7.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. #ifndef UNIVERSAL_SPEEDTREE7BILLBOARD_PASSES_INCLUDED
  2. #define UNIVERSAL_SPEEDTREE7BILLBOARD_PASSES_INCLUDED
  3. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
  4. #include "SpeedTree7CommonPasses.hlsl"
  5. void InitializeData(inout SpeedTreeVertexInput input, out half2 outUV, out half outHueVariation)
  6. {
  7. // assume no scaling & rotation
  8. float3 worldPos = input.vertex.xyz + float3(UNITY_MATRIX_M[0].w, UNITY_MATRIX_M[1].w, UNITY_MATRIX_M[2].w);
  9. #ifdef BILLBOARD_FACE_CAMERA_POS
  10. float3 eyeVec = normalize(unity_BillboardCameraPosition - worldPos);
  11. float3 billboardTangent = normalize(float3(-eyeVec.z, 0, eyeVec.x)); // cross(eyeVec, {0,1,0})
  12. float3 billboardNormal = float3(billboardTangent.z, 0, -billboardTangent.x); // cross({0,1,0},billboardTangent)
  13. float angle = atan2(billboardNormal.z, billboardNormal.x); // signed angle between billboardNormal to {0,0,1}
  14. angle += angle < 0 ? 2 * SPEEDTREE_PI : 0;
  15. #else
  16. float3 billboardTangent = unity_BillboardTangent;
  17. float3 billboardNormal = unity_BillboardNormal;
  18. float angle = unity_BillboardCameraXZAngle;
  19. #endif
  20. float widthScale = input.texcoord1.x;
  21. float heightScale = input.texcoord1.y;
  22. float rotation = input.texcoord1.z;
  23. float2 percent = input.texcoord.xy;
  24. float3 billboardPos = (percent.x - 0.5f) * unity_BillboardSize.x * widthScale * billboardTangent;
  25. billboardPos.y += (percent.y * unity_BillboardSize.y + unity_BillboardSize.z) * heightScale;
  26. #ifdef ENABLE_WIND
  27. if (_WindQuality * _WindEnabled > 0)
  28. {
  29. billboardPos = GlobalWind(billboardPos, worldPos, true, _ST_WindVector.xyz, input.texcoord1.w);
  30. }
  31. #endif
  32. input.vertex.xyz += billboardPos;
  33. input.vertex.w = 1.0f;
  34. input.normal = billboardNormal.xyz;
  35. input.tangent = float4(billboardTangent.xyz, -1);
  36. float slices = unity_BillboardInfo.x;
  37. float invDelta = unity_BillboardInfo.y;
  38. angle += rotation;
  39. float imageIndex = fmod(floor(angle * invDelta + 0.5f), slices);
  40. float4 imageTexCoords = unity_BillboardImageTexCoords[imageIndex];
  41. if (imageTexCoords.w < 0)
  42. {
  43. outUV = imageTexCoords.xy - imageTexCoords.zw * percent.yx;
  44. }
  45. else
  46. {
  47. outUV = imageTexCoords.xy + imageTexCoords.zw * percent;
  48. }
  49. #ifdef EFFECT_HUE_VARIATION
  50. float hueVariationAmount = frac(worldPos.x + worldPos.y + worldPos.z);
  51. outHueVariation = saturate(hueVariationAmount * _HueVariation.a);
  52. #else
  53. outHueVariation = 0;
  54. #endif
  55. }
  56. SpeedTreeVertexOutput SpeedTree7Vert(SpeedTreeVertexInput input)
  57. {
  58. SpeedTreeVertexOutput output = (SpeedTreeVertexOutput)0;
  59. UNITY_SETUP_INSTANCE_ID(input);
  60. UNITY_TRANSFER_INSTANCE_ID(input, output);
  61. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
  62. // handle speedtree wind and lod
  63. InitializeData(input, output.uvHueVariation.xy, output.uvHueVariation.z);
  64. VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz);
  65. half3 normalWS = input.normal; // Already calculated in world space. Can probably get rid of the world space transform in GetVertexPositionInputs too.
  66. half3 vertexLight = VertexLighting(vertexInput.positionWS, normalWS);
  67. half fogFactor = 0.0;
  68. #if !defined(_FOG_FRAGMENT)
  69. fogFactor = ComputeFogFactor(vertexInput.positionCS.z);
  70. #endif
  71. output.fogFactorAndVertexLight = half4(fogFactor, vertexLight);
  72. half3 viewDirWS = GetWorldSpaceNormalizeViewDir(vertexInput.positionWS);
  73. #ifdef EFFECT_BUMP
  74. real sign = input.tangent.w * GetOddNegativeScale();
  75. output.normalWS.xyz = TransformObjectToWorldNormal(input.normal);
  76. output.tangentWS.xyz = TransformObjectToWorldDir(input.tangent.xyz);
  77. output.bitangentWS.xyz = cross(output.normalWS.xyz, output.tangentWS.xyz) * sign;
  78. // View dir packed in w.
  79. output.normalWS.w = viewDirWS.x;
  80. output.tangentWS.w = viewDirWS.y;
  81. output.bitangentWS.w = viewDirWS.z;
  82. #else
  83. output.normalWS.xyz = TransformObjectToWorldNormal(input.normal);
  84. output.viewDirWS = viewDirWS;
  85. #endif
  86. output.positionWS = vertexInput.positionWS;
  87. output.clipPos = vertexInput.positionCS;
  88. #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
  89. output.shadowCoord = GetShadowCoord(vertexInput);
  90. #endif
  91. return output;
  92. }
  93. SpeedTreeVertexDepthOutput SpeedTree7VertDepth(SpeedTreeVertexInput input)
  94. {
  95. SpeedTreeVertexDepthOutput output = (SpeedTreeVertexDepthOutput)0;
  96. UNITY_SETUP_INSTANCE_ID(input);
  97. UNITY_TRANSFER_INSTANCE_ID(input, output);
  98. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
  99. // handle speedtree wind and lod
  100. InitializeData(input, output.uvHueVariation.xy, output.uvHueVariation.z);
  101. VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz);
  102. #ifdef SHADOW_CASTER
  103. half3 normalWS = TransformObjectToWorldNormal(input.normal);
  104. #if _CASTING_PUNCTUAL_LIGHT_SHADOW
  105. float3 lightDirectionWS = normalize(_LightPosition - vertexInput.positionWS);
  106. #else
  107. float3 lightDirectionWS = _LightDirection;
  108. #endif
  109. output.clipPos = TransformWorldToHClip(ApplyShadowBias(vertexInput.positionWS, normalWS, lightDirectionWS));
  110. #else
  111. output.clipPos = vertexInput.positionCS;
  112. #endif
  113. return output;
  114. }
  115. SpeedTreeVertexDepthNormalOutput SpeedTree7VertDepthNormalBillboard(SpeedTreeVertexInput input)
  116. {
  117. SpeedTreeVertexDepthNormalOutput output = (SpeedTreeVertexDepthNormalOutput)0;
  118. UNITY_SETUP_INSTANCE_ID(input);
  119. UNITY_TRANSFER_INSTANCE_ID(input, output);
  120. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
  121. // handle speedtree wind and lod
  122. InitializeData(input, output.uvHueVariation.xy, output.uvHueVariation.z);
  123. VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz);
  124. half3 normalWS = TransformObjectToWorldNormal(input.normal);
  125. half3 viewDirWS = GetWorldSpaceNormalizeViewDir(vertexInput.positionWS);
  126. #ifdef EFFECT_BUMP
  127. real sign = input.tangent.w * GetOddNegativeScale();
  128. output.normalWS.xyz = normalWS;
  129. output.tangentWS.xyz = TransformObjectToWorldDir(input.tangent.xyz);
  130. output.bitangentWS.xyz = cross(output.normalWS.xyz, output.tangentWS.xyz) * sign;
  131. // View dir packed in w.
  132. output.normalWS.w = viewDirWS.x;
  133. output.tangentWS.w = viewDirWS.y;
  134. output.bitangentWS.w = viewDirWS.z;
  135. #else
  136. output.normalWS = normalWS;
  137. output.viewDirWS = viewDirWS;
  138. #endif
  139. output.clipPos = vertexInput.positionCS;
  140. return output;
  141. }
  142. half4 SpeedTree7FragDepthNormalBillboard(SpeedTreeVertexDepthNormalOutput input) : SV_Target
  143. {
  144. UNITY_SETUP_INSTANCE_ID(input);
  145. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
  146. half2 uv = input.uvHueVariation.xy;
  147. half4 diffuse = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_MainTex, sampler_MainTex));
  148. diffuse.a *= _Color.a;
  149. #ifdef SPEEDTREE_ALPHATEST
  150. AlphaDiscard(diffuse.a, _Cutoff);
  151. #endif
  152. #ifdef LOD_FADE_CROSSFADE
  153. LODFadeCrossFade(input.clipPos);
  154. #endif
  155. #if defined(EFFECT_BUMP)
  156. half3 normalTS = SampleNormal(uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap));
  157. half3 normalWS = TransformTangentToWorld(normalTS, half3x3(input.tangentWS.xyz, input.bitangentWS.xyz, input.normalWS.xyz)).xyz;
  158. #else
  159. half3 normalWS = input.normalWS.xyz;
  160. #endif
  161. return half4(NormalizeNormalPerPixel(normalWS), 0.0);
  162. }
  163. #endif