Last active
June 18, 2024 06:46
-
-
Save cortvi/876ef402b400eddc3450d147c9e4830f to your computer and use it in GitHub Desktop.
Simple shader that imitates a liquid moving inside a vessel.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Created by @cortvi | |
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
// This script lets you easily control the amount of fluid, | |
// but you have to manually set up the height values! | |
[ExecuteInEditMode] | |
public class LiquidControl : MonoBehaviour | |
{ | |
[Range(0f,1f)] | |
public float fillLevel; // How full it is | |
public double fullHeight; // Height at which vessel is full | |
public double emptyHeight; // Height at which vessel is empty | |
int _Level; | |
Material mat; | |
float currentLevel; | |
private void Update() | |
{ | |
if (fillLevel == currentLevel) return; | |
var lerp = Mathf.Lerp (emptyHeight, fullHeight, fillLevel); | |
mat.SetFloat (_Level, lerp); | |
// Cache the value | |
currentLevel = fillLevel; | |
} | |
private void OnEnable () | |
{ | |
_Level = Shader.PropertyToID ("_Level"); | |
#if UNITY_EDITOR | |
if (UnityEditor.EditorApplication.isPlaying) | |
mat = GetComponent<Renderer> ().material; | |
else | |
mat = GetComponent<Renderer> ().sharedMaterial; | |
#else | |
mat = GetComponent<Renderer> ().material; | |
#endif | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// Created by @cortvi | |
Shader "Custom/Simple liquid volume" | |
{ | |
Properties | |
{ | |
_Color ("Liquid color", Color) = (1,1,1,1) | |
// For this shader to work properly, the mesh should | |
// have its pivot point on the geometric center of the object. | |
_Level ("Fill height (object space)", Float) = 0 | |
} | |
SubShader | |
{ | |
Tags | |
{ | |
// You may want to modify the queue | |
// for the object to correctly draw behind other | |
// transparent materials, such as a glass vessel | |
"Queue"="Transparent" | |
} | |
Cull Off | |
CGPROGRAM | |
#pragma surface surf Standard fullforwardshadows vertex:vert | |
struct Input | |
{ | |
float3 worldPos; | |
}; | |
fixed4 _Color; | |
float _Level; | |
void vert (inout appdata_full v, out Input o) | |
{ | |
UNITY_INITIALIZE_OUTPUT (Input, o); | |
// Calculate view direction in object-space | |
float3 viewDir = mul(unity_WorldToObject, float4(_WorldSpaceCameraPos.xyz, 1)).xyz - v.vertex.xyz; | |
// Replace the face normal by the view direction | |
// this way you cannot see that the object is hollow | |
v.normal = normalize(viewDir); | |
} | |
void surf (Input IN, inout SurfaceOutputStandard s) | |
{ | |
// Get the object Y by its mdoel matrix | |
float objectPosY = unity_ObjectToWorld._m13; | |
// Calculate the highest point in world-space of the liquid | |
float3 targetDistance = objectPosY + _Level; | |
// Discard pixels that are over liquid's highest point | |
float value = targetDistance - IN.worldPos.y; | |
clip(value); | |
// Just pass the liquid color. | |
// You could actually do some texture work here! | |
s.Albedo = _Color; | |
} | |
ENDCG | |
} | |
FallBack "Diffuse" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment