如何在THREE.js中正确制作法线贴图?

5

我刚试着将法线贴图忍者演示应用到我的场景中的一个立方体上,使用了最新的Three.js版本:

// common material parameters

var ambient = 0x050505, diffuse = 0x331100, specular = 0xffffff, shininess = 10, scale = 23;

// normal map shader

var shader = THREE.ShaderUtils.lib[ "normal" ];
var uniforms = THREE.UniformsUtils.clone( shader.uniforms );

uniforms[ "enableAO" ].value = true;
uniforms[ "enableDiffuse" ].value = false;
uniforms[ "enableSpecular" ].value = false;
uniforms[ "enableReflection" ].value = true;

uniforms[ "tNormal" ].texture = THREE.ImageUtils.loadTexture( "normal.jpg" );
uniforms[ "tAO" ].texture = THREE.ImageUtils.loadTexture( "ao.jpg" );

uniforms[ "tDisplacement" ].texture = THREE.ImageUtils.loadTexture( "displacement.jpg" );
uniforms[ "uDisplacementBias" ].value = - 0.428408 * scale;
uniforms[ "uDisplacementScale" ].value = 2.436143 * scale;

uniforms[ "uDiffuseColor" ].value.setHex( diffuse );
uniforms[ "uSpecularColor" ].value.setHex( specular );
uniforms[ "uAmbientColor" ].value.setHex( ambient );

uniforms[ "uShininess" ].value = shininess;

uniforms[ "tCube" ].texture = reflectionCube;
uniforms[ "uReflectivity" ].value = 0.1;

uniforms[ "uDiffuseColor" ].value.convertGammaToLinear();
uniforms[ "uSpecularColor" ].value.convertGammaToLinear();
uniforms[ "uAmbientColor" ].value.convertGammaToLinear();


var parameters = { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: uniforms, lights: true, fog: false };
var displacementMaterial = new THREE.ShaderMaterial( parameters );

/*
var diamond = new THREE.Diamond({
    material: bumpmapMaterial
});
*/

var diamond = new THREE.Mesh(
    new THREE.CubeGeometry(50, 50, 50),
    displacementMaterial
);

然而,我在Chrome浏览器中遇到了以下的WebGL错误:

GL_INVALID_OPERATION : glDrawXXX: attempt to access out of range vertices

在Firefox中,我没有收到这样的错误,但是立方体也不会显示。 使用标准颜色的MeshLambertMaterial,一切正常。因此,ShaderMaterial可能存在冲突。如果我使用来自MASTER分支的最新Three.js版本,情况并未改善-仍然出现相同的错误。 有任何想法为什么会这样,并且我需要更改什么才能使其起作用?
2个回答

4
尝试添加这个了吗?
geometry.computeTangents();

这个着色器在ImmediateRenderObject上可能是无法工作的,甚至可以说是不合逻辑的。这对我来说似乎是有道理的,因为在开发分支中,你只能将顶点位置、法线、UV坐标和颜色输入缓冲区,但没有顶点切线。然而,正确的法线贴图渲染似乎需要顶点切线。这是正确的吗?还是有办法将"normal"着色器应用于ImmediateRenderObject呢? :) - user1495743

0

更新:

<script src="https://rawgit.com/mrdoob/three.js/dev/examples/js/BufferGeometryUtils.js"></script>

THREE.BufferGeometryUtils.computeTangents( geometry )

需要对 geometry 进行索引


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接