It looks like the renderer adds color to fluids by two sets of little blobs spread throughout the fluid that can only be a very limited amount of primary colors and blend to approximate the color you actually want the fluid to be. But instead of these blobs turning white for as you remove saturation and add lightness to the color, these colored blobs instead become more transparent until they fade away completely at FFFFFF leaving the fluid with no color of its own and only lighting, reflections, and refraction.
This is what you can see in image 1, which has the particle color in the emitter set to FFFFFF. The blueish color is coming only from reflection of the skybox. What I want is what you see in image 4 though, which is an edit of the blue fluid in image 3. I just desaturated and lightened the blue channel, and now the fluid actually has its own color and is much more opaque than what the renderer produces for a white fluid.
The only way I can bring some of the white into the fluid is by lowering the transparency of the fluid renderer as seen in image 2, which is not an option for what I'm trying to do since the white fluid needs to mix with other clear fluids, which means they need to be on the same renderer and same transparency setting. Other than that I also just much prefer the clean transparent look without the shadows, especially the dithered ones from other particles.
Is there any way to get something like image 4 from the renderer with transparency set to 1? I tried playing around with the blending modes, but I found nothing that looks the way I want. The only thing that added some opacity was using one and one / additive blending, but that seems to remove most lighting detail and makes darker fluids way too bright.
11-07-2022, 10:27 AM (This post was last modified: 11-07-2022, 10:43 AM by josemendez.)
Hi there!
(11-07-2022, 08:50 AM)locque Wrote: It looks like the renderer adds color to fluids by two sets of little blobs spread throughout the fluid that can only be a very limited amount of primary colors and blend to approximate the color you actually want the fluid to be.
I'm not sure what you mean by "two sets of little blogs spread throughout the fluid". Do you mean particles? The fluid's volume gets its color from the color of the underlying fluid particles, which can be *any* color. This is used together with the fluid thickness and absorption at any given fragment to get the final color.
Quote:But instead of these blobs turning white for as you remove saturation and add lightness to the color, these colored blobs instead become more transparent until they fade away completely at FFFFFF leaving the fluid with no color of its own and only lighting, reflections, and refraction.
That's the expected behavior for any transparent, transmissive material: as the material absorbs less light, the light passing trough it gets less "tint" until it eventually passes trough untinted. For an object to appear white, it has to reflect light, not absorb it. Only an opaque material could become white.
Quote:The only way I can bring some of the white into the fluid is by lowering the transparency of the fluid renderer as seen in image 2
Yes, that's the correct way to do it: by making the fluid more opaque, "white" progressively shifts its meaning from "allow all light wavelengths to pass", which yields clear/transparent fluid to "reflect all wavelengths", which yields pure white.
Quote:which is not an option for what I'm trying to do since the white fluid needs to mix with other clear fluids, which means they need to be on the same renderer and same transparency setting. Is there any way to get something like image 4 from the renderer with transparency set to 1?
Nope, that's just impossible. You cannot simultaneously have a material be fully transparent and white. A material has to have some degree of opaqueness (that is, reflect some light) in order for it to have some color of its own, all a transmissive object can do is tint light (by absorbing certain wavelengths) as it passes trough it, but it cannot "add" wavelengths unless it's emissive, and it cannot reflect them unless it's opaque. You can try this yourself with a transparent material in Unity: make it white and fully transparent at the same time, you'll soon realize it's impossible. You need to lower transparency (alpha) for any color to be visible.
You might have some success by writing your own fluid shader or modifying the included one (/Obi/Resources/ObiMaterials/FluidShader.shader), as what you're trying to do doesn't seem to have any physical basis.
13-07-2022, 12:50 PM (This post was last modified: 13-07-2022, 02:50 PM by locque.)
Thanks for the in-depth explanation once again!
I suppose I'm stuck with using two fluid renders. It actually looks better than I expected, just rendering the clear fluid on top of the white fluid is cleaner than the mixing effect with both fluids on the same semi-transparent renderer.
Sorry to keep taking up your time, but if there is no way around using a semi-transparent renderer I would really appreciate some help with the resulting issues:
- The shadowmap resolution is way too low, even with the resolution in the light set to very high. Probably because my particles are very small though since I'm working with real-world scale. The shadows also look hard, or at least significantly less blurred than you would want. As far as I can tell the hard / soft setting of the light only affects shadows cast by the fluid, but not the ones received.
- Is there any way to disable dithered shadows? I think the shadows could look pretty good if the resolution was higher, but the dither pattern is going to look nasty either way. I'd much rather have the fluid receive no shadows from transparent things at all.
- As you can see the fluid shadow received from the mortar is disconnected from the mesh, I really need to adjust the bias and near plane specifically for the fluid shadowmap while keeping the current settings for the rest of the scene, which means I have to use a separate light that only affects the fluid. I can't do that though because the fluid doesn't inherit its layer from the emitter or the fluid renderer gameobject and instead always ends up on the default layer, which means I would have to create a new default layer and replace it on every other object in my scene. Is there a less obvious way to affect the layer the fluid is rendered on that I'm unaware of?
13-07-2022, 02:56 PM (This post was last modified: 13-07-2022, 03:04 PM by josemendez.)
(13-07-2022, 12:50 PM)locque Wrote: Thanks for the in-depth explanation once again!
I suppose I'm stuck with using two fluid renders. It actually looks better than I expected, just rendering the clear fluid on top of the white fluid is cleaner than the mixing effect with both fluids on the same semi-transparent renderer.
Two fluid renderers can be quite expensive, even more in VR since you're be forcing the entire fluid rendering pipeline to run 4 times (2 for each eye) which is a lot of work.
Slightly modifying the fluid shader as I suggested before seems like a much simpler, far better performing option imho. If I understood your use case correctly, all you'd need to do is add a constant color (white-ish) to the final fluid color and that would do the trick.
(13-07-2022, 12:50 PM)locque Wrote: The shadowmap resolution is way too low, even with the resolution in the light set to very high. My particles have to be small though since I'm working with real-world scale. They also look like hard shadows, or at least significantly less blurred than you would want. As far as I can tell the hard / soft setting of the light only affects shadows cast by the fluid, but not the ones received.
Fluids do not do any custom shadow mapping, they read from Unity's own shadow maps. The only custom part is reading from them (see below). So shadow map resolution is whatever Unity is using at that point.
(13-07-2022, 12:50 PM)locque Wrote: Is there any way to disable dithered shadows? I think the shadows could look pretty good if the resolution was higher, but the dither pattern is going to look nasty either way. I'd much rather have the fluid receive no shadows from transparent things at all.
I'm not 100% sure, Unity will apply dithered shadows to semi-transparent objects by default. As far as I know it's not possible to choose whether the shadow received by an object is dithered or not. I'm no expert on Unity's shadow pipeline, someone in the Unity forums might be of more help.
Regarding shadow resolution, keep in mind that reducing shadow distance in the render settings will result in better utilization of your shadowmap: If your game takes place in a relatively small room, you could considerably reduce shadow distance to get more detail out of the same resolution.
(13-07-2022, 12:50 PM)locque Wrote: As you can see the fluid shadow received from the mortar is disconnected from the mesh, I really need to adjust the bias and near plane specifically for the fluid shadowmap while keeping the current settings for the rest of the scene, which means I have to use a separate light that only affects the fluid.
I can't do that though because the fluid doesn't inherit its layer from the emitter or the fluid renderer gameobject and instead always ends up on the default layer, which means I would have to create a new default layer and replace it on every other object in my scene. Is there a less obvious way to affect the layer the fluid is rendered on that I'm unaware of?
Fluid isn't rendered the usual way other objects are. It's rendered as a kind of post-process once everything else in the scene has been rendered, so it cannot use layers because it's not being rendered as a regular object that each individual camera/light can choose to render or not.
Instead, while rendering fluid the fluid shader taps into Unity's shadowmap and reads from it. For this reason Unity's built-in shadow softening (which I believe is just variable-width PCF filtering) does not work, since fluids "hijack" the shadowmap to read from it at a much later stage in the render pipeline.
However, it's possible to modify how the fluid shader reads the shadowmap, and do your own filtering/biasing on it if needed. I've modified the fluid shader a bit to include a 3x3 PCF filter, biasing, as well as a white-ish additive color. Here's a comparison of the retail shader and the custom one:
You can find it attached, a few comment lines have been added to let you know which values to modify should you need. let me know if I can be of further help.
15-07-2022, 12:26 PM (This post was last modified: 15-07-2022, 12:35 PM by locque.)
Wow that looks great! :D
Thanks for showing me how to get the the white tint on a transparent renderer, but with the filtering and proper biasing shadows suddenly start looking so good that I don't really want to go back.
I suppose it's not possible to have the fluid shader selectively render particles with the alpha value from their particle renderer / emitter instead of rendering everything with the value from the fluid renderer, otherwise you would have probably implemented it that way. That would be a feature on the very top of my wishlist for a future update, right after single-pass support.
I'm curious, why were filtering and biasing not a thing already if you managed to get it implemented so quickly with only a few lines of code in the shader? To me this makes the difference between shadows degrading visual quality and significantly improving it. With enough filtering you can even get rid of the dithering issue! Just compare this to the video from the first post: https://youtu.be/0FGKEP8GSBk
I really think you should consider adding shadow configuration to the fluid renderer in a future update. I already added it to mine, I attached a package with all the modified scripts and the shader in case you're interested. I had to change the file extension to zip to get it uploaded, it's actually a unitypackage though so you'll have to change the extension back.
I also added the option to disable shadows but keep the surface lighting, and a radius and quality property for the filtering. The quality value just adds some space between sample points for a use case where you need a large shadow radius but can't afford to lose any GPU time. It's not great and creates banding, but I couldn't come up with anything more sophisticated that doesn't require iterating through all possible sample points and performing some kind of condition check or modulus calculation. I guess it beats not having any cheap soft shadows option, but I'm sure you could come up with something much better :)