Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebGLProgram: support cube uv refraction mapping #19623

Merged
merged 2 commits into from
Jul 2, 2020

Conversation

sciecode
Copy link
Contributor

Copy link
Contributor

@JohannesDeml JohannesDeml left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, I love easy fixes!

@Mugen87
Copy link
Collaborator

Mugen87 commented Jun 11, 2020

It should be clarified (if possible) why this change wasn't done in the first place. Also relevant: #19611 (comment)

My guess is that this type of refraction does not play well with PBR models.

@WestLangley
Copy link
Collaborator

It should be clarified (if possible) why this change wasn't done in the first place.

Possibly because our refraction model is inadequate. See the live link above. It is not even reasonably realistic.

@sciecode
Copy link
Contributor Author

sciecode commented Jun 11, 2020

It should be clarified (if possible) why this change wasn't done in the first place.

I guess it is relevant to ping @elalish in that case.

My guess is that this type of refraction does not play well with PBR models.

Possibly because our refraction model is inadequate. See the live link above. It is not even reasonably realistic.

Refraction in the rasterizing pipeline is not a solved problem, there's no simple way of rendering refractive materials, especially in a single pass workflow as we are currently using.

The model we use is more about what can be done, instead of an approach for realistic refraction. We're only considering the front face surface of the object and simulating refraction only in that surface, but even that is still not completely correct, as we are not assuming a complex index of refraction and the effect of dielectrics ( and all that fun stuff ).

It is possible to make it slightly better if we try a multiple depth & normal passes pipeline ( cubemap ) for having a better prediction of how the light being refracted will behave after passing to the interior of the volume. It will look better, but it will still not be photo realistic, simply because it can't be. The interactions of refractive surfaces are way too recursive in nature to be correctly rendered in the rasterizing pipeline.

Related: Does GLTF support refraction?

@mrdoob It does not. They are still considering if that is something they want to venture in for GLTF spec, but it is sitting as "possible" thing. In reality, I don't think it will ever be.

With all of that being said, I still think that if a user is requesting support for something that is entirely possible in our current pipeline, even if it is not realistic, and it involves such a simple fix, we have no reason not to support it, for the time being.

JohannesDeml added a commit to JohannesDeml/three.js that referenced this pull request Jun 11, 2020
@JohannesDeml
Copy link
Contributor

To get a better understanding of the parameters I exposed roughness and refractionRatio: demo

For me it was just very strange to have that constant, but not the result I was expecting. Sadly the resolution of the PMREM texture is not that high, which is very apparent for refractions.

@sciecode
Copy link
Contributor Author

Sadly the resolution of the PMREM texture is not that high.

This is something I'm looking to tackle soon, I just need to find the time for it. We had discussed previously that allowing the user control of the texture resolution is something that we should probably do.

@elalish
Copy link
Contributor

elalish commented Jun 11, 2020

The only reason I didn't do this in the first place was that I had no refractive models to test with and I didn't want to cause any regressions. I think this is a good idea; it may not be accurate, but it's better than nothing. Kind of like soft shadows; their absence is noticeable, but their accuracy is generally not.

As for glTF and refraction, this is actually under very active discussion in the working group. Hopefully before long we will have extensions for a configurable IOR and even a "thickness texture", which kind of like AO, will allow real-time rasterizers to do a halfway decent job of refraction and absorption calculations that would otherwise require raytracing.

@WestLangley
Copy link
Collaborator

Sorry, I have not seen any transparent metals. That is what your example is using.

Can you demonstrate that this works when metalness = 0? You may need to test both MeshStandardMaterial and MeshPhysicalMaterial given that Physical has the additional transparency property.

@sciecode
Copy link
Contributor Author

sciecode commented Jun 12, 2020

Sorry, I have not seen any transparent metals. That is what your example is using.
Can you demonstrate that this works when metalness = 0?

I'm sorry, I copied the example given in the issue, but I did not notice he was applying the refractive envmap to a MeshStandardMaterial. I should have checked that.

It appears the refractive mappings in general are only correctly considered when using MeshLambertMaterial or MeshPhongMaterial or with metalness 1 for the PBR materials ( standard / physical ).

But this is an issue outside of the scope of this PR, to be honest. This PR just ensures that WebGLProgram correctly understands CubeUVRefractionMapping as a refractive map and correctly sets the appropriated define for the shaders.

@WestLangley
Copy link
Collaborator

Let's see a live demo before considering merging this.

@JohannesDeml
Copy link
Contributor

Sorry, I have not seen any transparent metals. That is what your example is using.

That is my fault. When I tried to get it working, I used metals, since reflections are way more visible there. Here is the updated example: Demo

@sciecode
Copy link
Contributor Author

sciecode commented Jun 13, 2020

Let's see a live demo before considering merging this.

standard_physical_refraction left is standard, right is physical

Just to be absolutely clear, this behavior is not exclusive to CubeUVRefractionMapping.
It already happens in dev with CubeRefractionMapping and EquirectangularRefractionMapping

@JohannesDeml
Copy link
Contributor

After taking a closer look at the results again, there is one inconsistency for me with refraction in the standard and physical material when metalness is set to 0. The fresnel, which makes a lot of sense for reflection does not make any sense (at least I think so) for refraction. I think the result would need to look like metalness 1.0 for refraction, for which you see the pure refraction without any fresnel effect. Of course, going one step further it would be nice to have a fresnel reflection and a pure refraction on the material.

Here is the current effect with metalness 0:
image

and this is a changed version with fresnel reflection + refraction with metalness 0:
image

Here is the live example with reflections + refractions: https://rawcdn.githack.com/johannesdeml/three.js/6e57f55b3f3af594dcd23f6fb89ccbfb2dbda5f0/examples/webgl_materials_envmaps.html

Not sure if this is a path you want to go, or if you want to wait for gltf to define ior and then implement a general solution.

Repository owner deleted a comment from lm199406 Jun 16, 2020
@sciecode sciecode changed the title WebGLProgram: support cube uv refaction mapping WebGLProgram: support cube uv refraction mapping Jun 18, 2020
@Mugen87
Copy link
Collaborator

Mugen87 commented Jun 26, 2020

Regarding #19623 (comment), is it still desirable to merge this PR?

If not, it might be better to remove CubeUVRefractionMapping for now since it has no effect anyway.

@sciecode
Copy link
Contributor Author

sciecode commented Jun 26, 2020

Regarding #19623 (comment), is it still desirable to merge this PR?

If not, it might be better to remove CubeUVRefractionMapping for now since it has no effect anyway.

Not sure to be honest, as I mentioned, the refraction map will really only work reliably with metalness = 1.0.
But, as correctly pointed out by @JohannesDeml, we lose the ability to represent the fresnel effect correctly.

Ideally we would want both things to happen for PBR materials, but it is tricky.

CubeUVRefractionMapping would still work, more or less, as expected for other materials, but it does have a lot of problems in its current form, much like the CubeRefractionMapping. I'm not attached to this PR in the slightest, I leave this decision to you guys.

@mrdoob mrdoob added this to the r119 milestone Jul 2, 2020
@mrdoob
Copy link
Owner

mrdoob commented Jul 2, 2020

I think incorrect is better than nothing 🤔

@mrdoob mrdoob merged commit 6343f3a into mrdoob:dev Jul 2, 2020
@mrdoob
Copy link
Owner

mrdoob commented Jul 2, 2020

Thanks!

@sciecode sciecode deleted the dev-cubeuv-refraction branch July 2, 2020 03:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

PMREM Refraction support
6 participants