Skip to content

New PMREM#684

Merged
elalish merged 40 commits intomasterfrom
newPMREM
Aug 6, 2019
Merged

New PMREM#684
elalish merged 40 commits intomasterfrom
newPMREM

Conversation

@elalish
Copy link
Contributor

@elalish elalish commented Jul 23, 2019

Fixes #671

Really, the point of this change is to change PMREM to not have sparkles anymore and to be faster. In this PR, it basically makes the rendering mirror the case where you use an HDR floating-point environment with three's Standard Material, but now it can work with an RGBE texture, thus requiring no special gl extensions. That handles very HDR environments well, but does a poor job on roughness > ~0.2. I'm working on a new method to improve that.

This PR demonstrates the method I found to extend the Standard Material, but it does not show the diffs for the shader chunks (since it has nothing to compare them to here). The only changes to envmap_physical_pars_fragment.glsl.js were lines 31 and 92. cube_uv_reflection_fragment.glsl.js on the other hand, was completely rewritten. PMREMGenerator.ts pulls many ideas from PMREMGenerator.js and PMREMCubeUVPacker.js in three, but is also a rewrite.

Emmett Lalish and others added 30 commits May 31, 2019 14:18
* generated environment map now RGBM16

* switched RGBM16 to RGBE

* started gaussianBlur

* gaussianBlur compiles

* gaussian blur functional

* gaussianBlur properly parameterized

* target caching works

* removed extraneous cache, cleaned up generation

* Reuse renderer in tests

* switched cubeGenerators

* reuse renderer in TextureUtils-spec

* addressing feedback

* generated environment map now RGBM16

* switched RGBM16 to RGBE

* started gaussianBlur

* gaussianBlur compiles

* gaussian blur functional

* gaussianBlur properly parameterized

* switched cubeGenerators

* reuse renderer in TextureUtils-spec

* addressing feedback

* fixed IE11 shader bug
@elalish elalish requested a review from cdata July 23, 2019 20:31
@elalish elalish self-assigned this Jul 23, 2019
@elalish
Copy link
Contributor Author

elalish commented Jul 23, 2019

@cdata I have a strange problem with the current state of this branch. Try loading examples/lighting-and-environment.html: I get a black render for the second one down the page (the rest are fine), and sometimes even a white skybox. However, if I comment out all the others, then this one renders just fine. I assume I've messed up a cache or dispose or something, but I haven't found it. A second set of eyes would be much appreciated.

@elalish elalish requested a review from mrdoob July 24, 2019 17:24
@elalish
Copy link
Contributor Author

elalish commented Jul 24, 2019

@mrdoob This is more FYI than requesting a code review, but I thought you might be interested in where I'm headed as far as updating PMREM and the MeshStandardMaterial. Also, onBeforeCompile is great, but it would be nice if the uniforms were more accessible / extensible. Maybe I'm missing something?

@mrdoob
Copy link
Collaborator

mrdoob commented Jul 24, 2019

I wouldn't rely too much in onBeforeCompile(). It's meant to allow people modify built-in materials, but wasn't meant to be more than that.

Glad to see that you're reworking the PMREM code. Feel free to propose the change upstream whenever you think is ready. WestLangley and others will be able to take a good look.

Copy link
Contributor

@cdata cdata left a comment

Choose a reason for hiding this comment

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

This is looking very promising. I had tons of feedback, but most of it is minor stuff.

const gltf = cloneGltf(await cache.get(url)!);
const model = gltf.scene ? gltf.scene : null;

// This is a patch to three's handling of PMREM environments.
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a better description of what this actually does somewhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I'm working on a doc, but it's not going to fit in a comment.

};

return renderTarget;
return cubeUVTarget;
Copy link
Contributor

Choose a reason for hiding this comment

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

If I understand the implementation correctly, this means you are sharing the same render target instance for all environment maps. That probably explains why you were only getting one working environment map.

@@ -0,0 +1,135 @@
export default /* glsl */ `
Copy link
Contributor

Choose a reason for hiding this comment

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

There seems to be some pretty inconsistent indentation here. Is it possible to align it with cube_uv_reflection_fragment?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I left it intentionally with unchanged formatting from the three.js version since I only changed two lines and this makes the diff a lot nicer.

let offset = 0;
for (let i = 0; i <= maxLods; i++) {
const sizeLod = Math.pow(2, i);
const renderTarget = new WebGLRenderTargetCube(sizeLod, sizeLod, params);
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we create an extra WebGLRenderTargetCube here and throw it away in the case that i === maxLods?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

indeed, fixed.

@elalish elalish requested a review from cdata July 30, 2019 22:21
cdata
cdata previously approved these changes Jul 30, 2019
Copy link
Contributor

@cdata cdata left a comment

Choose a reason for hiding this comment

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

Look great, works great. Ship it!

* (PMREM) from a cubeMap environment texture. This allows different levels of
* blur to be quickly accessed based on material roughness. It is packed into a
* special CubeUV format that allows us to perform custom interpolation so that
* we can support nonlinear formats such as RGBE.
Copy link
Contributor

Choose a reason for hiding this comment

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

💯

export const generatePMREM =
(cubeTarget: WebGLRenderTargetCube, renderer: WebGLRenderer):
WebGLRenderTarget => {
const {cubeUVRenderTarget, cubeLods, meshes} = setup(cubeTarget);
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

renderer.gammaOutput = gammaOutput;

cubeLods.forEach((target) => {
target.dispose();
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need to do any disposal of meshes here? Or are we explicitly relying on them not being disposed (on account of internal caching side-effects in Three.js)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not relying on it. Honestly I wasn't sure what needed disposal besides renderTargets.

(cubeTarget: WebGLRenderTargetCube, renderer: WebGLRenderer):
WebGLRenderTarget => {
const {cubeUVRenderTarget, cubeLods, meshes} = setup(cubeTarget);
// This hack in necessary for now because CubeUV is not really a
Copy link
Contributor

Choose a reason for hiding this comment

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

in => is

mrdoob
mrdoob previously approved these changes Jul 31, 2019
@elalish elalish dismissed stale reviews from mrdoob and cdata via 347e5ac July 31, 2019 15:58
Copy link
Contributor

@cdata cdata left a comment

Choose a reason for hiding this comment

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

Looking great 🙌 we'll land #689 shortly to further improve things. Hopefully test flakes aren't a big deal and just Sauce being sucky 🙏

@elalish elalish merged commit 81b0d04 into master Aug 6, 2019
@cdata cdata added this to the v0.6.0 milestone Aug 13, 2019
@elalish elalish deleted the newPMREM branch September 27, 2019 16:46
elalish added a commit to elalish/model-viewer that referenced this pull request Feb 4, 2020
 
New PMREM (google#684)

* removed pmrem attribute

* removed pmrem attribute from non-code files

* default environment map now uses PMREM

* fixed tests

* using PMREM for all cases, fixing google#565

* increasing sauce timeout to 3min

* target caching works

* removed extraneous cache, cleaned up generation

* added LDR and HDR environment tests

* updated goldens

* Reuse renderer in tests (google#668)

* Refactor envmap / skybox generation

* default stage light to zero, removed hemisphere light (google#674)

* added new PMREMGenerator

* modified MeshStandardShader to show it can work

* Switch environment generation from HalfFloat to RGBE (google#670)

* generated environment map now RGBM16

* switched RGBM16 to RGBE

* started gaussianBlur

* gaussianBlur compiles

* gaussian blur functional

* gaussianBlur properly parameterized

* target caching works

* removed extraneous cache, cleaned up generation

* Reuse renderer in tests

* switched cubeGenerators

* reuse renderer in TextureUtils-spec

* addressing feedback

* generated environment map now RGBM16

* switched RGBM16 to RGBE

* started gaussianBlur

* gaussianBlur compiles

* gaussian blur functional

* gaussianBlur properly parameterized

* switched cubeGenerators

* reuse renderer in TextureUtils-spec

* addressing feedback

* fixed IE11 shader bug

* added envmap chunk

* updated three's shaders

* fixed shaders

* shaders compile

* fixed all WebGL errors

* PMREMGenerator now takes any encoding of input texture

* fixed several shader bugs

* fixed mipmap generation

* fixed maxLod

* PMREM mostly working

* recreate intermediate targets

* fixed mipmap level selection

* minor cleanup

* addressing feedback

* refactored PMREM

* cleanup

* dispose of temp materials

* removed envMap hack

* removed android sauce test
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 changes the environment even for mirrored objects

3 participants