jonathanhogg / flitter

A functional programming language and declarative system for describing 2D and 3D visuals
https://flitter.readthedocs.io
BSD 2-Clause "Simplified" License
34 stars 1 forks source link

Can I come up with a decent model of translucency? #46

Closed jonathanhogg closed 2 months ago

jonathanhogg commented 4 months ago

I'm thinking two passes:

In the normal shader, read the backface distance and normal from the first pass texture if this fragment is translucent. Use backface position (${viewpoint} + \vec{V} \cdot d_{backface}$) and normal to calculate how much of each light falling there is absorbed into the object. Use this light multiplied by a transmission colour (is that just the albedo colour?) and multiplied by the translucency raised to the power of the thickness (difference between front and backface distance) to determine an amount of transmitted light that can be added into the fragment colour.

This assumes that our new translucency material property is a fraction of light transmitted per unit distance.

There is an argument that this path should also be taken for transparent instances and that transparency should also take account of the material thickness. So then translucency is how much lights behind an object can be seen through an object and transparency is how much of the scene behind can be seen through an object.

jonathanhogg commented 4 months ago

First pass definitely doesn't need to be done with multi-sampling, probably could be done at a lower resolution – although I'm slightly nervous about whether mad interpolated values might be sampled from the texture near the outside edges of objects…

jonathanhogg commented 2 months ago

Commit notes:

The new translucency attribute on materials specifies a depth "half-life" (in the world coordinate system) that controls both how quickly backface light dissipates as it travels through the material and how much it scatters. Larger values mean less light travelling through the object and greater scattering, lower values mean more light and less scattering. The scattering of light is achieved by taking a selection of random samples of the backface light falling on the object, offset by how much scattering is happening. It is a very loose approximation and will tend to "fizz" a little.

As the amount of light you will see is dependent on scattering, very low values of translucency will actually result in a dark object not a bright one. As translucency becomes lower, the object also becomes more transparent. As with transparency, the background image isn't scattered and so partially transparent objects don't look realistic.

jonathanhogg commented 2 months ago

Of course, sadly those commit notes are wrong. For the record, the truth from the docs is:

translucency= TRANSLUCENCY

Specifies how translucent this material is as a distance (in the world coordinate system) over which half of the light falling on the backfaces of the object will pass through it. The default is 0, meaning no translucency. At low levels of translucency, light will be scattered and will glow through the edges/thin-parts of objects. At higher levels of translucency light will be scattered less and the object will become more transparent. Setting this to non-zero both affects the model render order and also forces an additional render pass to determine the thickness of the object and the light falling on the back faces.