如何使反射材料在相机旋转时发生变化



我能够通过使用Skybox Cube/环境映射来制作一些好看的金属和玻璃材质。

我制作了自己的控件,可以像在FirstPersonControls中一样环绕和移动/四处查看。

问题是,当我四处移动时,反射看起来很有说服力——我可以看到反射随着我的相机移动而移动和改变。然而,当我环顾四周(旋转相机/更改其目标)时,反射没有变化,它们只是静态的。

例如,我可以在three.js/examples/webgl_materials_cubemap_escher.html中看到同样的行为——如果我将其修改为使用FirstPersonControls,当我环顾四周时,该材质看起来根本不会反射/折射。

以下是我如何设置立方体贴图的,说实话,它是从一些例子中复制的,我不了解所有的。但它很有效,除了这个问题。。。

createSkyBox = function(urlPrefix) {
var sceneCube = new THREE.Scene();
var path = urlPrefix;
var format = '.jpg';
var urls = [
path + 'px' + format, path + 'nx' + format,
path + 'py' + format, path + 'ny' + format,
path + 'pz' + format, path + 'nz' + format
];
var reflectionCube = THREE.ImageUtils.loadTextureCube( urls );
reflectionCube.format = THREE.RGBFormat;
var refractionCube = new THREE.Texture( reflectionCube.image, new THREE.CubeRefractionMapping() );
refractionCube.format = THREE.RGBFormat;

// Skybox
var shader = THREE.ShaderUtils.lib[ "cube" ];
shader.uniforms[ "tCube" ].value = reflectionCube;
var material = new THREE.ShaderMaterial( {
fragmentShader: shader.fragmentShader,
vertexShader: shader.vertexShader,
uniforms: shader.uniforms,
depthWrite: false,
side: THREE.BackSide
} );
var size = 8000;
mesh = new THREE.Mesh( new THREE.CubeGeometry( size, size, size ), material );
mesh.geometry.computeBoundingBox();
sceneCube.add( mesh );
this._threejs_cube_scene = sceneCube;
this._threejs_cube_mesh = mesh;
this._threejs_envmap = reflectionCube;
this._threejs_envmap_refraction = refractionCube;
this._threejs_scene.add( sceneCube );  
}

这是我创建材料的方法:

var material = new THREE.MeshLambertMaterial( { color: 0xff00, ambient: 0xaaaaaa, envMap: this._threejs_envmap});

然后我在渲染器中使用材质。overrideMaterial(如果有任何不同,我使用的是EffectComposer)

编辑:现在我想一想,我不确定。。我的大脑融化了。。这可能是现实生活的运作方式:)至少从直觉上看,当我看到代码在运行时,旋转相机时的静态感觉不太好。但也许是因为在现实生活中,很难在不稍微移动(eye.position=xyz)的情况下环顾四周(eye.lookAt())。

您应该计算世界空间中的反射向量(在"fragmentShader"的代码中,此处未显示)。如果它在对象空间或视图(相机)空间中,它不会自然移动。

是的,这可能意味着曲面法线会发生一些欺骗。若要将对象空间法线转换为世界空间法线,请使用世界矩阵的反向转置。您还需要获得世界空间坐标中的视图向量,以便计算最终的世界空间反射向量。

另一件比更改着色器更简单的事情是,如果你想让相机像人头一样旋转,可以给它一个偏移。将其添加到Object3d中,并将其设置为从Object3d的位置偏移一小部分(相当于从人类中心到眼睛的距离),然后旋转Object3d而不是相机。

从你的描述中很难判断出你想要什么效果,因为当你只是转动眼球时,反射不会改变。是你的头的轻微倾斜改变了它。

最新更新