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:
We first filter out the pixels that are not blocked by the fluid particles and return them to the previously rendered color.
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;
}
Based on the above parameters, you can play with the shader to create different effects.
For example, I first made a blinn-phong rendering
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;
In addition, you can use parameters such as thickness, fluid color, IOR, smoothness, etc. to create water rendering effects that include refraction and reflection:
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);
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.