marcofugaro / three-projected-material

📽 Three.js Material which lets you do Texture Projection on a 3d Model
https://marcofugaro.github.io/three-projected-material/
MIT License
671 stars 57 forks source link

setting `.camera` does not update `ORTHOGRAPHIC` define. #45

Closed trusktr closed 1 year ago

trusktr commented 2 years ago

onBeforeCompile only ever runs once, initially, and never again. Therefore if someone does this:

const mat = new ProjectedMaterial()
renderer.render(scene, camera) // runs onBeforeCompile

// ...later...
mat.camera = new OrthographicCamera 

renderer.render(scene, camera) // does NOT run onBeforeCompile again, ORTHOGRAPHIC is undefined.

mat.needsUpdate = true // even this doesn't help
renderer.render(scene, camera) // does NOT run onBeforeCompile again, ORTHOGRAPHIC is undefined.

the shader's ORTHOGRAPHIC define will not be defined.

And conversely, if the user starts with an OrthographicCamera then later switches to a PerspectiveCamera, ORTHOGRAPHIC will still be defined.

This leads to the shader's conditional branches running the wrong code, not matching the camera that is used.

The issue with onBeforeCompile, and how to make it work, is described here:

https://discourse.threejs.org/t/onbeforecompile-fires-only-once-although-i-set-needsupdate-true/38614

marcofugaro commented 1 year ago

Yup, the material uses #defines for camera type to avoid branching since changing camera type is not a common usecase.

You can use another material with for the other camera, and then switch the material at runtime when needed. You can use the materialIndex property if you want to precompile the material.