> For the complete documentation index, see [llms.txt](https://morningheartgames.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://morningheartgames.gitbook.io/docs/getting-started/fluid-shader-file.md).

# Fluid Shader File

The files used for fluid shading are in <mark style="background-color:yellow;">Assets/SSF\_Particle2Fluid\_ShaderUtil/Shaders/FluidRender.shader</mark>

The whole process can be divided into the following steps:

* Read the surface parameters through the map:

```hlsl
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.

```hlsl
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

```hlsl
// 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;
```

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

```hlsl
// 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) ;
```

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.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://morningheartgames.gitbook.io/docs/getting-started/fluid-shader-file.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
