crest icon indicating copy to clipboard operation
crest copied to clipboard

Underwater Fog Input

Open daleeidd opened this issue 3 years ago • 6 comments

Status: Experimental

Adds an input for underwater fog which renders whatever it is attached to after the underwater effect and applies the fog in a separate pass. I have named the component RegisterUnderwaterInput for consistency but it could be renamed.

The original idea was to use Blend and BlendOp to apply the fog but I wasn't able to work it out. I think using subtract might work if we somehow bake density fog and scatter colour into the fragment colour. Instead I rendered the object offscreen and provided texture to the fog pass so it samples itself to get the screen colour. This way it works like the underwater effect does.

Steps:

  1. Register object and disable renderer
  2. Sorts objects back to front using distance from camera
  3. Enables SH and set SH values using LightProbeUtility
  4. Setup main texture to get alpha channel
  5. Copies camera target to temporary texture
  6. Renders object into temporary texture
  7. Passes temporary texture to fog and renders fog over the top using alpha blending

It didn't work out as nice as I hoped as it exposed us a little bit to render pipeline (SH and _MainTex). We need _MainTex to get the alpha value for blending; an example is the particles will be rendered as squares without it.

Also, I had to cull back faces as the example transparent objects in the test scene didn't like culling disabled (need to look into that), but some transparent objects want culling disable for them to look right.

I made the shader a separate pass rather than a separate file as it saves us another material and code reuse.

I have provided test data in the main scene.

Let me know what you think.

daleeidd avatar Jul 09 '21 23:07 daleeidd

I wasn't able to add a general comment without submitting the review. Nice one GitHub.

huwb avatar Jul 10 '21 09:07 huwb

Yeah the blending is worth talking through. I had the following in my head but I don't know if it works

  • User has alpha geo in the scene and unity just draws on top of the underwater i.e. it does not have depth fog applied and looks broken. This uses whatever transparent shader is applied. Unity applies SH and everything else needed to render as normal.
  • We have a component to tag this geo, like you've added, and that renders the geo again but with the depth fog shader which is what I think you have. It alpha blends, with the alpha equal to whatever the depth fog gives (exp(-density*waterRayLength)).

Would that work?

huwb avatar Jul 10 '21 09:07 huwb

The sh code is interesting to see. Is it needed here? I'm aware it's used to light the underwater fog, but had thought it was evaluated at the camera position, and am wondering if we already have it evaluated somewhere else (in oceanrenderer maybe)

I am using it for rendering the transparent object the first time round. For some reason it isn't bound if I render it myself even though I am using DrawRenderer. I also have to enable the SH keyword manually. I will look into what I can do to remove it. I should pass the one we already have from the underwater effect for the fog pass to keep it consistent at the very least.

It alpha blends, with the alpha equal to whatever the depth fog gives (exp(-density*waterRayLength)).

That was my first attempt but density has three components which doesn't look right when converted to a scalar value (tried averaging it or picking only one).

The is what the underwater effect has:

lerp(sceneColour, scatterCol, saturate(1.0 - exp(-_DepthFogDensity.xyz * sceneZ)));

And this is what I tried:

return (scatterCol, saturate(1.0 - exp(-Average(_DepthFogDensity.xyz) * sceneZ)));

Here is a comparison. Current: 2

Using depth fog as alpha value: 1

It might be tolerable?

daleeidd avatar Jul 10 '21 20:07 daleeidd

Ah interesting! It may be worth trying min or max, but otherwise yeah tolerable I would vote. I don't think we should do anything special to render the original alpha geo. I have expanded my understanding notes above accordingly.

huwb avatar Jul 11 '21 08:07 huwb

Ah interesting! It may be worth trying min or max

BlendOp Min or Max? Neither produced good results.

but otherwise yeah tolerable I would vote

I have added both for now for evaluating. Or maybe permanently if you think technical debt is not too high.

User has alpha geo in the scene and unity just draws on top of the underwater i.e. it does not have depth fog applied and looks broken. This uses whatever transparent shader is applied. Unity applies SH and everything else needed to render as normal.

I have thought of another approach which might be closer to this. We render the fog before the transparent pass. And add the fog calculation to the ocean shader again. Then we just duplicate the "tagged" objects and then dilate them slightly. The duplicate will have our material which adds the fog and alpha blends. It should sort correctly and be similar in quality to the lower quality alpha blending above. And requires minimal intervention from us.

daleeidd avatar Jul 24 '21 08:07 daleeidd

Oh I meant use min or max density (of the three channels). Not confident it would help but just an idea.

Would you be able to let me know where my notes are falling short or not going to work? I'm not following I'm afraid and am hoping we can use it as a tool to sync on the plan

huwb avatar Jul 24 '21 10:07 huwb