I’m working on a shader for a bottle containing liquid in Unreal Engine 5. I’m currently having trouble masking the bounds of the liquid’s surface based on the shape of the mesh (cross-section at the liquid level).
For now, my mesh is opaque and in default lit mode, and I’m faking the reflection/transparency of the liquid. To create the liquid surface, I drew a horizontal infinite plane at the liquid level (following left image).
What I’d like to do is crop this plane according to the mesh’s bounds, as shown here (random-looking bottle cross-section).
I need a way to get a mask containing the cross-section of the container mesh (square bottle, cylindrical bottle) at the liquid level (like the green flat part in the right image, but as a mask).
But the problem is that I can’t use depthFade (I’d like to have everything inside one material, so no slicing with a plane and using a depthFade). I’ve also tried to use a render target, but I don’t believe it’s the best solution because I would have trouble rendering multiple bottles at the same time, and I have more than just the cross-section.
I’ve also thought about using signed distance fields to mask my plane. This would involve converting it to world coordinates and culling based on the value of the signed distance field of the mesh bounds (I believe that if the distance field < 0 then it is inside ?), but I’m having trouble figuring that out.
I’m fairly new to shaders, so any advice would be nice .
You could also use 2 line traces to get the elipse radius of the pour direction and the orthogonal radius, and scale the (round) surface plane depending on that. Helpful for an open container if you want to determine if fluid is spilled or not. Needs additional material logic to make it look okay.
I don’t know if this helps. I made a simple water bottle shader a few months ago for fun, and this material function is the main method for the shader. After getting the mask I made this shader with a masked unlit material double-sided.
I provided you with the files, there are two simple materials, one texture, and one blueprint actor. Just hook up the texture in the material, and the materials to the actor and you should see this result.
The project is made in Unreal 5.1.
Thinker a little bit with the materials and you will see they are extremely easy to grasp.