Reputation: 5645
I'm pretty new to Three.js, and 3D in general, so please bear with me!
I'm trying to make a THREE.Mirror and change its opacity. I would think this would work, but unfortunately it does not, nor does any other solution I've tried thus far.
// inside init, render has no been called
// create a THREE.Mirror and add it to the provided THREE.Scene
function createMirror( props ) {
let { name, width, height, options, scene } = props;
this[ name ] = new THREE.Mirror( width, height, options );
scene.add( this[ name ] );
}
// create 3js mirror and add to scene
createMirror.call( this, {
name: "Mirror_1",
width: 1.75,
height: 1.75,
options: {
clipBias: 0.01,
textureWidth: this.width,
textureHeight: this.height,
color: 0xefefef
},
scene: this.Main_Scene
} );
this.Mirror_1.rotation.x = -Math.PI / 2;
this.Mirror_1.material.opacity = 0.1;
this.Mirror_1.material.transparent = true;
// render is called inside an ObjectLoader after objects are loaded, here is
// the render function
renderScene() {
requestAnimationFrame( this.renderScene );
this.P_Camera_1.lookAt( this.Main_Scene.position );
this.controls.update();
this.WebGL_Renderer_1.setViewport(0, 0, this.width, this.height);
this.WebGL_Renderer_1.render( this.Main_Scene, this.P_Camera_1 );
}
Everything else works fine. Objects are loaded, scene renders beautifully, mirror looks great... just can't change it's opacity. Any help would be greatly appreciate. If this is not enough context, please let me know and I can provide more.
P.S. This is inside a React application. render() { ... }
is a method on the component controlling the scene.
EDIT: I edited the fragmentShader
portion of the Mirror.js provided in the examples\js portion of npm install three
and written by @author Slayvin / http://slayvin.net.
var mirrorShader = {
uniforms: {
...
},
vertexShader: [
...
].join( '\n' ),
fragmentShader: [
'uniform vec3 mirrorColor;',
'uniform sampler2D mirrorSampler;',
'varying vec4 mirrorCoord;',
'float blendOverlay(float base, float blend) {',
' return( base < 0.5 ? ( 2.0 * base * blend ) : (1.0 - 2.0 * ( 1.0 - base ) * ( 1.0 - blend ) ) );',
'}',
'void main() {',
' vec4 color = texture2DProj(mirrorSampler, mirrorCoord);',
// Changed the vec4(r, g, b, alpha) alpha from 1.0 to 0.25
// No change in rendered THREE.Mirror
' color = vec4(blendOverlay(mirrorColor.r, color.r), blendOverlay(mirrorColor.g, color.g), blendOverlay(mirrorColor.b, color.b), 0.25);',
' gl_FragColor = color;',
'}'
].join( '\n' )
}
I'm obviously missing something though!
Upvotes: 0
Views: 880
Reputation: 1
add another geometry over mirror and set transparency for it
var mesh = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2000, 2000 ), new THREE.MeshLambertMaterial ( { opacity : 0.98 , transparent: true } ) );
Upvotes: 0
Reputation: 5645
For anyone wondering how to affect the opacity of a THREE.Mirror()
, you need to do two things:
Your_Mirror.material.transparent = true;
Make sure this is done before the scene is rendered, or before the mirror is added to the scene and the fragmentShader has applied it's magic.
Change the alpha in the fragmentShader used by the Your_Mirror.material.fragmentShader
Here is a solution I am using to change the opacity of a mirror dynamically.
const fragmentShaderBeforeAlpha = `
uniform vec3 mirrorColor;
uniform sampler2D mirrorSampler;
varying vec4 mirrorCoord;
float blendOverlay(float base, float blend) {
return( base < 0.5 ? ( 2.0 * base * blend ) : (1.0 - 2.0 * ( 1.0 - base ) * ( 1.0 - blend ) ) );
}
void main() {
vec4 color = texture2DProj(mirrorSampler, mirrorCoord);
color = vec4(blendOverlay(mirrorColor.r, color.r), blendOverlay(mirrorColor.g, color.g), blendOverlay(mirrorColor.b, color.b),
`;
const fragmentShaderAfterAlpha = `
);
gl_FragColor = color;
}
`;
export default function fragmentShader( alpha ) {
return fragmentShaderBeforeAlpha + alpha + fragmentShaderAfterAlpha;
}
Upvotes: 1