No Description
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.

Particles.hlsl 8.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. #ifndef UNIVERSAL_PARTICLES_INCLUDED
  2. #define UNIVERSAL_PARTICLES_INCLUDED
  3. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
  4. #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
  5. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl"
  6. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
  7. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareOpaqueTexture.hlsl"
  8. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ParticlesInstancing.hlsl"
  9. #include_with_pragmas "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl"
  10. #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRendering.hlsl"
  11. struct ParticleParams
  12. {
  13. float4 positionWS;
  14. float4 vertexColor;
  15. float4 projectedPosition;
  16. half4 baseColor;
  17. float3 blendUv;
  18. float2 uv;
  19. };
  20. void InitParticleParams(VaryingsParticle input, out ParticleParams output)
  21. {
  22. output = (ParticleParams) 0;
  23. output.uv = input.texcoord;
  24. output.vertexColor = input.color;
  25. #if defined(_FLIPBOOKBLENDING_ON)
  26. output.blendUv = input.texcoord2AndBlend;
  27. #else
  28. output.blendUv = float3(0,0,0);
  29. #endif
  30. #if !defined(PARTICLES_EDITOR_META_PASS)
  31. output.positionWS = input.positionWS;
  32. output.baseColor = _BaseColor;
  33. #if defined(_SOFTPARTICLES_ON) || defined(_FADING_ON) || defined(_DISTORTION_ON)
  34. output.projectedPosition = input.projectedPosition;
  35. #else
  36. output.projectedPosition = float4(0,0,0,0);
  37. #endif
  38. #endif
  39. }
  40. // Pre-multiplied alpha helper
  41. #if defined(_ALPHAPREMULTIPLY_ON)
  42. #define ALBEDO_MUL albedo
  43. #else
  44. #define ALBEDO_MUL albedo.a
  45. #endif
  46. #if defined(_ALPHAPREMULTIPLY_ON)
  47. #define SOFT_PARTICLE_MUL_ALBEDO(albedo, val) albedo * val
  48. #elif defined(_ALPHAMODULATE_ON)
  49. #define SOFT_PARTICLE_MUL_ALBEDO(albedo, val) half4(lerp(half3(1.0, 1.0, 1.0), albedo.rgb, albedo.a * val), albedo.a * val)
  50. #else
  51. #define SOFT_PARTICLE_MUL_ALBEDO(albedo, val) albedo * half4(1.0, 1.0, 1.0, val)
  52. #endif
  53. // Color blending fragment function
  54. half4 MixParticleColor(half4 baseColor, half4 particleColor, half4 colorAddSubDiff)
  55. {
  56. #if defined(_COLOROVERLAY_ON) // Overlay blend
  57. half4 output = baseColor;
  58. output.rgb = lerp(1 - 2 * (1 - baseColor.rgb) * (1 - particleColor.rgb), 2 * baseColor.rgb * particleColor.rgb, step(baseColor.rgb, 0.5));
  59. output.a *= particleColor.a;
  60. return output;
  61. #elif defined(_COLORCOLOR_ON) // Color blend
  62. half3 aHSL = RgbToHsv(baseColor.rgb);
  63. half3 bHSL = RgbToHsv(particleColor.rgb);
  64. half3 rHSL = half3(bHSL.x, bHSL.y, aHSL.z);
  65. return half4(HsvToRgb(rHSL), baseColor.a * particleColor.a);
  66. #elif defined(_COLORADDSUBDIFF_ON) // Additive, Subtractive and Difference blends based on 'colorAddSubDiff'
  67. half4 output = baseColor;
  68. output.rgb = baseColor.rgb + particleColor.rgb * colorAddSubDiff.x;
  69. output.rgb = lerp(output.rgb, abs(output.rgb), colorAddSubDiff.y);
  70. output.a *= particleColor.a;
  71. return output;
  72. #else // Default to Multiply blend
  73. return baseColor * particleColor;
  74. #endif
  75. }
  76. // Soft particles - returns alpha value for fading particles based on the depth to the background pixel
  77. float SoftParticles(float near, float far, float4 projection)
  78. {
  79. float fade = 1;
  80. if (near > 0.0 || far > 0.0)
  81. {
  82. float2 uv = UnityStereoTransformScreenSpaceTex(projection.xy / projection.w);
  83. uv = FoveatedRemapLinearToNonUniform(uv);
  84. float rawDepth = SAMPLE_TEXTURE2D_X(_CameraDepthTexture, sampler_PointClamp, uv).r;
  85. float sceneZ = (unity_OrthoParams.w == 0) ? LinearEyeDepth(rawDepth, _ZBufferParams) : LinearDepthToEyeDepth(rawDepth);
  86. float thisZ = LinearEyeDepth(projection.z / projection.w, _ZBufferParams);
  87. fade = saturate(far * ((sceneZ - near) - thisZ));
  88. }
  89. return fade;
  90. }
  91. // Soft particles - returns alpha value for fading particles based on the depth to the background pixel
  92. float SoftParticles(float near, float far, ParticleParams params)
  93. {
  94. float fade = 1;
  95. if (near > 0.0 || far > 0.0)
  96. {
  97. float2 uv = UnityStereoTransformScreenSpaceTex(params.projectedPosition.xy / params.projectedPosition.w);
  98. uv = FoveatedRemapLinearToNonUniform(uv);
  99. float rawDepth = SAMPLE_TEXTURE2D_X(_CameraDepthTexture, sampler_CameraDepthTexture, uv).r;
  100. float sceneZ = (unity_OrthoParams.w == 0) ? LinearEyeDepth(rawDepth, _ZBufferParams) : LinearDepthToEyeDepth(rawDepth);
  101. float thisZ = LinearEyeDepth(params.positionWS.xyz, GetWorldToViewMatrix());
  102. fade = saturate(far * ((sceneZ - near) - thisZ));
  103. }
  104. return fade;
  105. }
  106. // Camera fade - returns alpha value for fading particles based on camera distance
  107. half CameraFade(float near, float far, float4 projection)
  108. {
  109. float thisZ = LinearEyeDepth(projection.z / projection.w, _ZBufferParams);
  110. return half(saturate((thisZ - near) * far));
  111. }
  112. half3 AlphaModulateAndPremultiply(half3 albedo, half alpha)
  113. {
  114. #if defined(_ALPHAMODULATE_ON)
  115. return AlphaModulate(albedo, alpha);
  116. #elif defined(_ALPHAPREMULTIPLY_ON)
  117. return AlphaPremultiply(albedo, alpha);
  118. #endif
  119. return albedo;
  120. }
  121. half3 Distortion(float4 baseColor, float3 normal, half strength, half blend, float4 projection)
  122. {
  123. float2 screenUV = (projection.xy / projection.w) + normal.xy * strength * baseColor.a;
  124. screenUV = UnityStereoTransformScreenSpaceTex(screenUV);
  125. float3 distortion = SampleSceneColor(screenUV);
  126. return half3(lerp(distortion, baseColor.rgb, saturate(baseColor.a - blend)));
  127. }
  128. // Sample a texture and do blending for texture sheet animation if needed
  129. half4 BlendTexture(TEXTURE2D_PARAM(_Texture, sampler_Texture), float2 uv, float3 blendUv)
  130. {
  131. half4 color = half4(SAMPLE_TEXTURE2D(_Texture, sampler_Texture, uv));
  132. #ifdef _FLIPBOOKBLENDING_ON
  133. half4 color2 = half4(SAMPLE_TEXTURE2D(_Texture, sampler_Texture, blendUv.xy));
  134. color = lerp(color, color2, half(blendUv.z));
  135. #endif
  136. return color;
  137. }
  138. // Sample a normal map in tangent space
  139. half3 SampleNormalTS(float2 uv, float3 blendUv, TEXTURE2D_PARAM(bumpMap, sampler_bumpMap), half scale = half(1.0))
  140. {
  141. #if defined(_NORMALMAP)
  142. half4 n = BlendTexture(TEXTURE2D_ARGS(bumpMap, sampler_bumpMap), uv, blendUv);
  143. #if BUMP_SCALE_NOT_SUPPORTED
  144. return UnpackNormal(n);
  145. #else
  146. return UnpackNormalScale(n, scale);
  147. #endif
  148. #else
  149. return half3(0.0, 0.0, 1.0);
  150. #endif
  151. }
  152. half4 GetParticleColor(half4 color)
  153. {
  154. #if defined(UNITY_PARTICLE_INSTANCING_ENABLED)
  155. #if !defined(UNITY_PARTICLE_INSTANCE_DATA_NO_COLOR)
  156. UNITY_PARTICLE_INSTANCE_DATA data = unity_ParticleInstanceData[unity_InstanceID];
  157. color = lerp(half4(1.0, 1.0, 1.0, 1.0), color, unity_ParticleUseMeshColors);
  158. color *= half4(UnpackFromR8G8B8A8(data.color));
  159. #endif
  160. #endif
  161. return color;
  162. }
  163. void GetParticleTexcoords(out float2 outputTexcoord, out float3 outputTexcoord2AndBlend, in float4 inputTexcoords, in float inputBlend)
  164. {
  165. #if defined(UNITY_PARTICLE_INSTANCING_ENABLED)
  166. if (unity_ParticleUVShiftData.x != 0.0)
  167. {
  168. UNITY_PARTICLE_INSTANCE_DATA data = unity_ParticleInstanceData[unity_InstanceID];
  169. float numTilesX = unity_ParticleUVShiftData.y;
  170. float2 animScale = unity_ParticleUVShiftData.zw;
  171. #ifdef UNITY_PARTICLE_INSTANCE_DATA_NO_ANIM_FRAME
  172. float sheetIndex = 0.0;
  173. #else
  174. float sheetIndex = data.animFrame;
  175. #endif
  176. float index0 = floor(sheetIndex);
  177. float vIdx0 = floor(index0 / numTilesX);
  178. float uIdx0 = floor(index0 - vIdx0 * numTilesX);
  179. float2 offset0 = float2(uIdx0 * animScale.x, (1.0 - animScale.y) - vIdx0 * animScale.y); // Copied from built-in as is and it looks like upside-down flip
  180. outputTexcoord = inputTexcoords.xy * animScale.xy + offset0.xy;
  181. #ifdef _FLIPBOOKBLENDING_ON
  182. float index1 = floor(sheetIndex + 1.0);
  183. float vIdx1 = floor(index1 / numTilesX);
  184. float uIdx1 = floor(index1 - vIdx1 * numTilesX);
  185. float2 offset1 = float2(uIdx1 * animScale.x, (1.0 - animScale.y) - vIdx1 * animScale.y);
  186. outputTexcoord2AndBlend.xy = inputTexcoords.xy * animScale.xy + offset1.xy;
  187. outputTexcoord2AndBlend.z = frac(sheetIndex);
  188. #endif
  189. }
  190. else
  191. #endif
  192. {
  193. outputTexcoord = inputTexcoords.xy;
  194. #ifdef _FLIPBOOKBLENDING_ON
  195. outputTexcoord2AndBlend.xy = inputTexcoords.zw;
  196. outputTexcoord2AndBlend.z = inputBlend;
  197. #endif
  198. }
  199. #ifndef _FLIPBOOKBLENDING_ON
  200. outputTexcoord2AndBlend.xy = inputTexcoords.xy;
  201. outputTexcoord2AndBlend.z = 0.5;
  202. #endif
  203. }
  204. void GetParticleTexcoords(out float2 outputTexcoord, in float2 inputTexcoord)
  205. {
  206. float3 dummyTexcoord2AndBlend = 0.0;
  207. GetParticleTexcoords(outputTexcoord, dummyTexcoord2AndBlend, inputTexcoord.xyxy, 0.0);
  208. }
  209. #endif // UNIVERSAL_PARTICLES_INCLUDED