Time Spent: 3 weeks, and additional 3 weeks on and off for cubemap second iteration

Liquid Shader Goals/Scope:

  1. https://www.youtube.com/watch?v=p9NeBW4pgGk + https://twitter.com/Vuthric/status/1343678273776013312 // https://www.youtube.com/watch?v=2nB5v-fYjXw
  2. Liquid in bottles/containers that can grabbed, moved, rotated in VR (Start with a cylindrical container)
  3. Shaking the container should still create believable reaction
  4. Visual Meniscus
  5. Stretch: (for the future)
    1. Skirt Mesh
    2. Try something with Niagara and Grid2D
    3. Liquid can be poured out

References ( Research )

https://www.youtube.com/watch?v=p9NeBW4pgGk

https://www.youtube.com/watch?v=9XWxsJKpYYI

https://www.patreon.com/posts/quick-game-art-18245226

https://www.youtube.com/watch?v=dFv8lM-kS4E

https://twitter.com/Un1cornHuntrSam/status/1475856497401679872

Vocabulary:

  • Caustics
  • Meniscus
    water+ glass tube vs. mercury + glass tube
  • Tangent Space (Under the Context of Normals)
  • Reflection
    • Light bouncing off an object
  • Refraction
    • Light bouncing through an object
  • Cube maps (Unreliable for reflection, but handy for refraction)

Normals

https://www.youtube.com/watch?v=g57mNKE8IYc

https://www.youtube.com/watch?v=hkTjreiookM “Normals are the direction of a face or vertex”

https://www.youtube.com/watch?v=6_-NNKc4lrk

https://www.youtube.com/watch?v=LUjXAoP5GG0
https://www.youtube.com/watch?v=j2BEEtpPgdk

How do normals influence shadows?

Flat Shading: Face Normals

Faces have two sides each with their own normal

Smooth Shading: Vertex Normals


Meniscus

Tangent Space

Raytraced Sphere: https://www.youtube.com/watch?v=5ZHh8vUcEak

Ended up going with a 3 part simple visual solution that mimics how a meniscus looks.

The most confusing part of this was finding a way to keep the changes in the normals consistent on the material when an object is moved and rotated.

All 3 components are derived from the mask that influences the water level (feeds into the opacity mask)

straight to the opacity mask

influencing the normals

tangent space normal – unchecked

for a more 3d look


In a glass material


Keeping water volume at the right level (Fancy Math)

https://share.glasp.co/emerald/?p=w4ENzydZt4NBC7EFD96Y

Found this through a video – honestly, not sure if it works…


Angular Vel to Shear and Add Wobble

https://www.youtube.com/watch?v=3Lape_vG0Sc
https://www.youtube.com/watch?v=3Lape_vG0Sc (linear speed/tangential speed)

https://www.reddit.com/r/unrealengine/comments/q86t7i/are_quaternions_used_in_ue4/

https://stackoverflow.com/questions/70375975/what-is-a-break-rotator-and-make-rotator-in-unreal-engine-4

https://forums.unrealengine.com/t/rotator-angles-independent/22890/2

https://forums.unrealengine.com/t/manually-calculate-and-apply-rotation-velocity/368255 ← Ended up going with this method of breaking the rotator and feeding the values back into a Vector.

https://www.youtube.com/watch?v=zc8b2Jo7mno

I didn’t add in linear velocity…why is it necessary to do so? Is it only so that the liquid is more responsive to faster linear movement (movement not including rotation)? Is there some physics based reason?

➡️Added it in! Linear velocity will tilt the water according to the direction you are moving in so it’s pretty important and effective


More believable water behavior (believable when you shake the object)

Didn’t end up
Didn’t end up implementing the circular wobble direction – too complex.


I added a grab component, adjusted some values and popped this into VR!


Cubemap Reflections

The reflections from the out of the box UE simple glass material did not translate well into VR. The refractions and reflections were way off.

I used a material function from https://developer.arm.com/documentation/100959/0100/optimizations-and-optimization-techniques/cubemaps/implementing-reflections-in-unreal-engine for ray-box intersection to map the cubemap onto the material.

As well as this guide on reflection and refraction: https://www.youtube.com/watch?v=TNGNtVhCGvs

A great writeup on ray-box intersection: https://www.scratchapixel.com/lessons/3d-basic-rendering/minimal-ray-tracer-rendering-simple-shapes/ray-box-intersection

Used the two-sided sign function to mask out certain areas and add them back together. The saturate node is key here.

Using inverted vertex normals to create the illusion of a frontface by making the backface be convex and adding that to the backface.


The localcorrection transparency looks amazing in editor, but doesn’t work well in VR due to inaccuracy. So I switched the transparency to a simple flipped camera input that is more accurate to the camera/head position in VR.


There was also the issue of the disappearing top on a non-spherical object…my goal is to use a cylinder so I accentuated the top with a mask that faded outward, multiplied by a texture sample. This ruins the illusion of reflections a bit…but it’s worth the trade.


Averaging out the vel over 5 frames to reduce jitter and error from VR controllers (ideally you would measure a predicted curve)


Adding the current velocity pos-lerp to resting velocity before the final output is super important for giving the wobble lag time. I kept getting stuck on this.

The order per frame goes: Set output for material with value > Lerp and reduce current vel avg > Add diff in vel from previous and current frame to reduced current vel avg > Populate vel history with value

This format allows us to base our lerp on higher vel values from past frames.

Physics is looking pretty nice now

https://imgur.com/jZ9hNyu

Added some displacement with noise and a flowmap to mimic refraction for the water and glass.

Final result

Hoping to come back to this one day and polish more/try some other approaches

The final node graph (spaghetti!)

Categories: TechArt