All pages
Powered by GitBook
1 of 1

Loading...

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.

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;
}
// Calculate non-transparent color, using old model
Light mainLight = GetMainLight();
// the light direction is also expect to be a inverse since we care its relative angle to the normal
// so its world direction should be considered to treate inversely
float3 lightDir = -mul(unity_MatrixV, float4(mainLight.direction, 0.0)).xyz;
float3 specular = LightingSpecular(mainLight.color,lightDir,fluidEyeNormal,viewDir,specularColor,smoothness*32);
float3 diffuse = LightingLambert(mainLight.color,lightDir,fluidEyeNormal)*diffuseColor.rgb;
float3 ambient = ambientColor.rgb;
float3 finalColorNonTransparent = ambient + diffuse + specular;
// Calculate transparent color, with a combination of refraction and reflection
float eta =  1.0 / refractiveIndex;
float F0 = ((1.0 - eta) * (1.0 - eta)) / ((1.0 + eta) * (1.0 + eta));
float fresnelRatio = clamp(F0 + (1.0 - F0) * pow((1.0 - dot(viewDir, fluidEyeNormal)), fresnelPower), 0, 1);

float3 reflectionDir = reflect(-viewDir, fluidEyeNormal);
float3 reflectionDirWS = mul(unity_MatrixInvV, float4(reflectionDir, 0.0)).xyz;

float3 reflectionColor = GlossyEnvironmentReflection(reflectionDirWS, smoothness, half(1.0));

float3 colorAttennuation = computeAttennuation(thickness*5, 1-fluidColor);

half3 refractionDir = refract(-viewDir, fluidEyeNormal, eta);
float3 refractionColor = colorAttennuation * SAMPLE_TEXTURE2D(_BlitTexture,sampler_LinearRepeat, uv + refractionDir.xy * thickness  * 0.1f).xyz;

fresnelRatio = clamp(fresnelRatio, minReflectionRatio, maxReflectionRatio);
float3 finalColorTransparent = lerp(refractionColor, reflectionColor, fresnelRatio) ;