Only this pageAll pages
Powered by GitBook
1 of 10

Particle Water Shader Pro - HDRP

Loading...

Getting Started

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Paramters Tuning

This page will tell you all need to know on the parameters to ajust the visual outlook.

You will notice that there are a set of parameters on the SSF_LoadParticlesFromParticleSystem inspector:

The meaning of these parameters are as follows:

Name
Description

ParticleBufferUpdateInterval

The interval for updating particle data to GPU, <0 means update every frame. Adjust this value to your preferred visual frame rate

Thickness

The thickness of the liquid. The higher the value, the more precipitated and solid the color will be visually.

Render Params

Name
Description

Here's some comparisions on differnt paramters.

Noise

The detail turbulence of the surface. The higher the value, the more turbulence the surface will show. It is implemented by adding perturbation to the surface normal.

Render Params

Fluid surface rendering related parameters are listed separately below and may change with version iterations

IsTransparent

0 for traditional blinn-phong rendering, 1 for fluid rendering, value in-between means blending

Ior

Refractive Index of Fluid (1.33 for water...)

Smoothness

higher value for more smoothness

Fresnel Power

higher value gives more refraction

Min/Max Reflection Ratio

this constraints the amount of reflection, if no reflection is needed, just set them to 0, vice versa, 1 for no refraction

Ambient/Diffuse/Specular Color

Very traditional Blinn-phong model

Non trasparent
transparent
high thickness
low thickness
no reflection(pure refraction)
reflection and refraction
no reflection, high fresnel power
no reflection, normal fresnel power

Common Q&A

Q: why my surface is sometimes black?

A:

Bake the scene lighting if you do not see reflection! Because the scripts needs the light reflection data. If not baked, the default reflection data is black.

Or else, you may pass in the particle color as black, or there's no lights in the scene.

Introduction

Different from prior version , the principle of this plugin is based on the paper A Narrow-Range Filter for Screen-Space Fluid Rendering.

Fluid simulation is generally based on grids or particles. In consideration of real-time performance, the SPH-based method (a particle-based method) is still used.

Unity does not have a very suitable fluid rendering plugin, which is the main reason for this plugin. I also noticed that there is indeed an very old implementation "Screen Space Fluids Pro"on the Asset Store (last update at year 2016).

In the process of using, I feel that I can do better, no matter from the efficiency or visual effects or ease of use and scalability, thus this plugin was born.

Please see this video on URP for a reference on how parameter works.

Fluid Shader File

For anyone who wants to modify the shader to tweak the shading functionality, I will explain how the shading process works, though i personally not recommend.

The files used for fluid shading are in Assets/SSF_Particle2Fluid_ShaderUtil/Shaders/FluidRender.shader

The whole process can be divided into the following steps:

  • Read the surface parameters through the map:

TEXTURE2D(_ColorTex);
TEXTURE2D_FLOAT(_EyeDepthTex);
TEXTURE2D(_EyeNormalTex);
TEXTURE2D_FLOAT(_ParticleDataTex);
TEXTURE2D_FLOAT(_ThicknessTex);
StructuredBuffer<SSF_RenderParams> _RenderParams;

....
float fluidEyeDepth = SAMPLE_TEXTURE2D(_EyeDepthTex, sampler_PointClamp, uv).r;
float3 fluidColor = SAMPLE_TEXTURE2D(_ColorTex, sampler_LinearRepeat, uv).xyz;
float thickness = SAMPLE_TEXTURE2D(_ThicknessTex, sampler_LinearRepeat, uv).r;
float3 fluidEyeNormal = SAMPLE_TEXTURE2D(_EyeNormalTex, sampler_LinearRepeat, uv).xyz;
int paramIndex = SAMPLE_TEXTURE2D(_ParticleDataTex, sampler_PointClamp,uv).x;
float smoothness = _RenderParams[paramIndex].smoothness;
float refractiveIndex = _RenderParams[paramIndex].ior;
float fresnelPower = _RenderParams[paramIndex].fresnelPower;
float minReflectionRatio = _RenderParams[paramIndex].minReflectionRatio;
float maxReflectionRatio = _RenderParams[paramIndex].maxReflectionRatio;
float isTransparent = _RenderParams[paramIndex].isTransparent;
float4 ambientColor = _RenderParams[paramIndex].ambientColor;
float4 diffuseColor = _RenderParams[paramIndex].diffuseColor;
float4 specularColor = _RenderParams[paramIndex].specularColor;
  • We first filter out the pixels that are not blocked by the fluid particles and return them to the previously rendered color.

Based on the above parameters, you can play with the shader to create different effects.

  • For example, I first made a blinn-phong rendering

  • In addition, you can use parameters such as thickness, fluid color, IOR, smoothness, etc. to create water rendering effects that include refraction and reflection:

Of course, we can also implement shadow effects, but since Unity's API is not stable and open enough, we will consider updating it later.

Step By Step Usage

  1. Create an empty Scene named SSF_Test

  2. Create a ParticleSystem

    1. deactivate its Renderer function

half4 color = SAMPLE_TEXTURE2D_X_LOD(_BlitTexture, sampler_LinearRepeat, uv, _BlitMipLevel);
#if UNITY_REVERSED_Z
real depth = SampleSceneDepth(uv);
#else
// Adjust z to match NDC for OpenGL
real depth = lerp(UNITY_NEAR_CLIP_VALUE, 1, SampleSceneDepth(UV));
#endif
float sceneEyeDepth = LinearEyeDepth(depth, _ZBufferParams);
       	if(fluidEyeDepth <= 0.0f || fluidEyeDepth > 1000.0f ||sceneEyeDepth < fluidEyeDepth) {
	return color;
}
  DirectionalLightData mainLight = _DirectionalLightDatas[0];
  float3 lightColor = mainLight.color;
  float3 lightDir = mainLight.forward;

  //blinn-phong
  float NdotL = saturate(dot(fluidEyeNormal,lightDir));
  lightColor = min(lightColor,1);
  float3 diffuse = lightColor * NdotL * params.diffuseColor.rgb;

  float3 halfVec = SafeNormalize(float3(lightDir) + float3(viewDir));
  half NdotH = half(saturate(dot(fluidEyeNormal, halfVec)));
  half modifier = pow(float(NdotH), float(params.smoothness*64)); // Half produces banding, need full precision
  // NOTE: In order to fix internal compiler error on mobile platforms, this needs to be float3
  float3 specularReflection = params.specularColor.rgb * modifier;
  float3 specular = lightColor * specularReflection;

  float3 ambient = params.ambientColor.rgb ;
  float3 finalColorNonTransparent = diffuse+specular+ambient;
float eta = 1.0 / params.ior;
float F0 = ((1.0 - eta) * (1.0 - eta)) / ((1.0 + eta) * (1.0 + eta));
float fresnel = F0 + (1.0 - F0) * pow(saturate(1.0 - dot(viewDir, fluidEyeNormal)), params.fresnelPower);
fresnel = clamp(fresnel, params.minReflectionRatio, params.maxReflectionRatio);

// reflection
float3 reflectionDir = reflect(-viewDir, fluidEyeNormal);
// a misc to do ssr, hdrp's reflection is way too complex, so we just use a simple reflection
// modify here for any color you want
float3 reflectionColor = SampleCameraColor(uv  + reflectionDir.xy * thickness * 0.1,0).xyz;
// reflectionColor = reflectionColor * 0.5 + 0.5 *diffuse;
reflectionColor = 1;
// float3 reflectionColor = LOAD_TEXTURE2D_X(_CameraColorTex, uv + reflectionDir.xy * thickness * 0.1).xyz;

// refraction
float3 refractionDir = refract(-viewDir, fluidEyeNormal, eta);
float2 refractionUV = uv  + refractionDir.xy * thickness * 0.1;
float3 refractionColor = SampleCameraColor(refractionUV,0).xyz;

float3 attenuation = exp(-(1.0 - fluidColor) * thickness * 5.0);
refractionColor *= attenuation;

// blend with fresnel value.
float3 finalColorTransparent = lerp(refractionColor, reflectionColor, fresnel);

set its StartColor to red

  • Emission -> Rate over time to 1000

  • The Inspector should looks like

    1. Add SSF_LoadParticlesFromParticleSystem onto the GameObject Particle System

    Note that you shall assign the Particle Systems field.

    1. Enter playmode and you shall see

    Check other demos to see how it works with particle systems.

    Mouse over the fields of the script to see tooltips say how the parameters work.

    Extend particle input

    Currently, there are two subclasses in the project that inherit from SSF_ParticleSource, namely SSF_LoadParticlesFromParticleSystem and SSF_LoadParticlesFromFile. SSF_ParticleSource represents the source of particle data required for rendering and is also the starting point for extension.

    Considering that users may have their own source of particle data, such as a particle solution system running in parallel with the GPU, or imported pre-made particle data, here we will explain how to extend the input of particle data.

    Particle Data Struct

    The structure of particle data in SSF is as follows:

    If you modify the particle’s data structure, you need to pay attention to replacing 32 in particleBuffer = new ComputeBuffer (getParticleNum (), 32); in SSF_ParticleSource.cs with the number of bytes of particle data. At the same time, corresponding changes should be made in DepthColorThickness.shader.

    Explain SSF_ParticleSource

    The input and update of extended data is to create a new class inheriting from SSF_ParticleSource and implement the corresponding virtual function.

    The following two member variables exist in SSF_ParticleSource:

    Where particleBuffer is used to provide data to generate related textures for rendering.

    You can notice that the following member function modifiers in SSF_ParticleSource are public virtual:

    • SetupParticleBufferData ()

    • UpdateParticleBufferData ()

    In SetupParticleBufferData , ParticlesData needs to be created and assigned, and updated in UpdateParticleBufferData () , neither of these operations need to involve particleBuffer.

    You should also implement UpdateBounds() , the bounds is used for culling out of view particles, which saves a lot performance.

    Example

    You can also refer to SSF_LoadParticlesFromParticleSystem, this is a bit complicated and tedious.

    public struct SSF_particle
    {
        public Vector3 position;
        public Color color;
        public float radius;
    }
    protected ComputeBuffer particleBuffer;// Buffer sent to GPU
    protected SSF_particle[] particlesData;// Particle Data for above buffer

    Welcome

    This is a Unity shader plugin, not a fluid physics simulation plugin. It is used to render particle data into a smooth liquid surface. Ideal for rendering simulation systems that use particles as simulation units.

    Magic happens when the pure unity particle system gains power through this particle shader plugin.

    This version is for HDRP.

    It has huge changes compared to the previous version.

    • The newly adopted algorithm brings huge performance, performance, and user experience gains:

      • The number of iterations required for smoothing has been reduced from 150 to 3

      • The time required to run the algorithm Reduced (from 5.8ms to 0.5ms) nearly 10x times

      • Higher resolution and finer surface, with clear layers of water droplets and water surface

    • New Rendering process brings performance improvements in the following aspects

      • Required Smoothing + rendering Reduced from Per Fluid Surface Per Frame to Once Per Frame

      • Required RenderTextures Reduced from One Set for all RenderSurfaces to One Set Globally

    • Introduce new DebugVisualize functionality helps locate data problems or debug parameter effects

    • Added down sample option to further reduce bandwidth pressure

    • A unified rendering shader while supporting custom visual parameters for each ParticleSource.

    Jump right in

  • No param tuning anymore! Plane fitting parameters Reduced from 5 to 0

  • The RenderTexture used is managed by the Rendergraph, further increasing potential bandwidth savings

    Getting Started

    Step by step

    Parameters Tuning

    Quickstart

    First you need to download this plugin from the Unity Asset Store or Fab.

    Please buy it legally, i am a solo developer who has to earn something to support coding.

    Import

    • First , please make sure you are at a Unity version greater or equal to Unity 6000.

    • Then, please make sure your project is using universal render pipeline.

    • Check google if you do not know how to create a URP unity project , please ~

    • Import the package and you will get the folder view like below:

    All is set! Party Time~

    Open the Scene at Assets/SSF_Particle2Fluid_ShaderUtil/Scenes/Demo_File.unity and enter play mode. You shall see:

    SSF_RenderPass

    Add the SSF_RenderPass to a CustomPassVolume

    By default, it's brought by the SSF_Manager Prefab under the path:

    Assets/Particle Water Shader Pro 2024 - HDRP/Prefabs/SSF_Manager.prefab

    Check Other Demos

    You can check other scene file under the folder Assets/SSF_Particle2Fluid_ShaderUtil/Scenes/

    DebugVisualize

    Toggle on the "Debug visualize" on the Renderer Feature to check the output.

    Switch the DebugTexture type to see different debug informations.

    Normal
    Thickness
    Color