three.js:纹理全黑

时间:2015-12-22 08:53:18

标签: javascript three.js

我有一个简单的盒子几何形状,我试图用纹理装饰。但是,我的盒子根本没有显示(或者可能是100%黑色)。目前的问题是从this question演变而来的。我已更新代码,以反映gaitat在原始问题上给出的答案。我已经写了another simple test site来证明这个新问题。这是该网站的内容:



"use strict";

// make DOM elements:
var container = document.createElement( 'div' );
document.body.appendChild( container );
var info = document.createElement( 'div' );
container.appendChild( info );

// a 'Box2' geometry instance:  (see geometry implementation below)
var myBox2geom = new THREE.BoxGeometry( 100, 100, 100, 10, 10, 10 );  // args: x,y,z-dimensions and width of their segments

// create scene:
var scene = new THREE.Scene();

// make a corresponding 'Box2' mesh:
new THREE.TextureLoader().load(
	"http://mrdoob.github.io/three.js/examples/textures/crate.gif",
	function ( texture ) {
		texture.minFilter = THREE.NearestFilter;
		var material = new THREE.MeshLambertMaterial( { map: texture, side: THREE.DoubleSide } );
		var myBox2mesh = new THREE.Mesh(myBox2geom, material);
		// add mesh to scene:
		scene.add( myBox2mesh );
	},
	function () {},  // onProgress function
	function ( error ) { console.log( error ) }  // no error gets logged
);

// make light:
var light = new THREE.PointLight( 0xffffff );
light.position.set(100, 200, 300);
light.lookAt( new THREE.Vector3( 0, 0, 0 ) );
scene.add( light );

// make camera:
var camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.x = 100;
camera.position.y = 200;
camera.position.z = 300;
camera.lookAt( new THREE.Vector3( 0, 0, 0 ) );
scene.add( camera );

// make renderer:
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );

// aaaand render!
renderer.render( scene, camera );



THREE.Box2Geometry = function ( width, height, depth, widthSegments, heightSegments, depthSegments ) {

	THREE.Geometry.call( this );

	this.parameters = {
		width: width,
		height: height,
		depth: depth,
		widthSegments: widthSegments,
		heightSegments: heightSegments,
		depthSegments: depthSegments
	};

	this.widthSegments = widthSegments || 1;
	this.heightSegments = heightSegments || 1;
	this.depthSegments = depthSegments || 1;

	var constructee = this;  // constructee = the instance currently being constructed by the Box2Geometry constructor

	var width_half = width / 2;    // width  = the distance along x in the absolute 3D space
	var height_half = height / 2;  // height = the distance along y in the absolute 3D space
	var depth_half = depth / 2;    // depth  = the distance along z in the absolute 3D space

	buildPlane( 'z', 'y', -1, -1, depth, height, width_half, 0 ); // px
	buildPlane( 'z', 'y',  1, -1, depth, height, -width_half, 1 ); // nx
	buildPlane( 'x', 'z',  1,  1, width, depth, height_half, 2 ); // py
	buildPlane( 'x', 'z',  1, -1, width, depth, -height_half, 3 ); // ny
	buildPlane( 'x', 'y',  1, -1, width, height, depth_half, 4 ); // pz
	buildPlane( 'x', 'y', -1, -1, width, height, -depth_half, 5 ); // nz

	function buildPlane( u, v, uDir, vDir, uDist, vDist, wDist_half, materialIndex ) {

		var w, iu, iv,
			segU = constructee.widthSegments,  // number of segments along u   // width  = x
			segV = constructee.heightSegments, // number of segments along v   // height = y
			uDist_half = uDist / 2,  // the extent of the plane along u, divided by two
			vDist_half = vDist / 2,  // the extent of the plane along v, divided by two
			offset = constructee.vertices.length;

		if ( ( u === 'x' && v === 'y' ) || ( u === 'y' && v === 'x' ) ) {

			w = 'z';

		} else if ( ( u === 'x' && v === 'z' ) || ( u === 'z' && v === 'x' ) ) {

			w = 'y';
			segV = constructee.depthSegments;

		} else if ( ( u === 'z' && v === 'y' ) || ( u === 'y' && v === 'z' ) ) {

			w = 'x';
			segU = constructee.depthSegments;

		}

		var segUi = segU + 1,  // i = inc = incremented (by one)
			segVi = segV + 1,  // i = inc = incremented (by one)
			segmentDist_u = uDist / segU,
			segmentDist_v = vDist / segV,
			normal = new THREE.Vector3();

		normal[ w ] = wDist_half > 0 ? 1 : -1;

		for ( iv = 0; iv < segVi; iv++ ) {

			for ( iu = 0; iu < segUi; iu++ ) {

				var vertex = new THREE.Vector3();
				vertex[ u ] = ( iu * segmentDist_u - uDist_half ) * uDir;
				vertex[ v ] = ( iv * segmentDist_v - vDist_half ) * vDir;
				vertex[ w ] = wDist_half;

				constructee.vertices.push( vertex );

			}

		}

		for ( iv = 0; iv < segV; iv++ ) {

			for ( iu = 0; iu < segU; iu++ ) {

				var a = iu         + segUi *   iv;
				var b = iu         + segUi * ( iv + 1 );
				var c = ( iu + 1 ) + segUi * ( iv + 1 );
				var d = ( iu + 1 ) + segUi *   iv;

				var uva = new THREE.Vector2(   iu       / segU, 1 -   iv       / segV );
				var uvb = new THREE.Vector2(   iu       / segU, 1 - ( iv + 1 ) / segV );
				var uvc = new THREE.Vector2( ( iu + 1 ) / segU, 1 - ( iv + 1 ) / segV );
				var uvd = new THREE.Vector2( ( iu + 1 ) / segU, 1 -   iv       / segV );

				var face1 = new THREE.Face3( a + offset, b + offset, d + offset );
				face1.normal.copy( normal );
				face1.vertexNormals.push( normal.clone(), normal.clone(), normal.clone() );
				face1.materialIndex = materialIndex;

				constructee.faces.push( face1 );
				constructee.faceVertexUvs[ 0 ].push( [ uva, uvb, uvd ] );

				var face2 = new THREE.Face3( b + offset, c + offset, d + offset );
				face2.normal.copy( normal );
				face2.vertexNormals.push( normal.clone(), normal.clone(), normal.clone() );
				face2.materialIndex = materialIndex;

				constructee.faces.push( face2 );
				constructee.faceVertexUvs[ 0 ].push( [ uvb.clone(), uvc, uvd.clone() ] );

			}

		}

	}

	this.mergeVertices();
};
THREE.Box2Geometry.prototype = Object.create( THREE.Geometry.prototype );
&#13;
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
  </head>
  <body>
    <script src="https://raw.githubusercontent.com/mrdoob/three.js/master/build/three.js"></script>
    <script src="main2.js"></script>
  </body>
</html>
&#13;
&#13;
&#13;

3 个答案:

答案 0 :(得分:2)

错误控制台告诉它是另一个CORS问题:

  

DOMException [SecurityError:“操作不安全。”

将CrossOrigin属性设置为空:

var loader = new THREE.TextureLoader();
loader.crossOrigin = "";
loader.load("http://mrdoob.github.io/three.js/examples/textures/crate.gif",
    function( texture ) {
        //...
    },
    function () {},  // onProgress function
    function ( error ) { console.log( error ) } // onError function
);

答案 1 :(得分:2)

因此,代码结果包含三个错误,每个错误由Falk Thiele2pha / gaitat指出:

  1. &#39;跨域资源共享&#39; (CORS)问题,在Firebug中提出以下错误:

    SecurityError: The operation is insecure.
    gl.texImage2D.apply( gl, arguments );
    

    Falk Thiele引用此错误是通过将CrossOrigin属性设置为空来修复的:

    var loader = new THREE.TextureLoader();
    loader.crossOrigin = "";
    loader.load(
        "http://mrdoob.github.io/three.js/examples/textures/crate.gif",
        function( texture ) {
            //...
        },
        function () {},  // onProgress function
        function ( error ) { console.log( error ) } // onError function
    );
    

    奇怪的是,在本地加载crate.gif纹理时,也会出现CORS错误(在Chrome中)。如果包含loader.crossOrigin = "";行,则会发生这种情况。因此,如果确定原点确实来自跨站点原点,则该行似乎只应

  2. scene仅渲染一次,这一次渲染在纹理加载之前发生。这是因为TextureLoader.load()调用异步工作,因此在调用renderer.render( scene, camera );之前执行后面的代码行load

  3. 该脚本无法在Chrome中运行,原因有二:首先是上述CORS问题,其次是脚本由于某种原因未能加载THREE库(Uncaught ReferenceError: THREE is not defined)。我不知道为什么THREE无法在Chrome中加载,但在纠错后的代码中(见下文,以及here)错误不再出现,所以目前原因仍然未知。

  4. 最后,我做了JS fiddle demonstrating the running code

    以下是错误更正的代码段,错误1,2和3不再存在:

    &#13;
    &#13;
    "use strict";
    
    // make DOM elements:
    var container = document.createElement( 'div' );
    document.body.appendChild( container );
    var info = document.createElement( 'div' );
    container.appendChild( info );
    
    // a 'Box2' geometry instance:  (see geometry implementation below)
    var myBox2geom = new THREE.BoxGeometry( 100, 100, 100, 10, 10, 10 );  // args: x,y,z-dimensions and width of their segments
    
    // create scene:
    var scene = new THREE.Scene();
    
    // make a corresponding 'Box2' mesh:
    var loader = new THREE.TextureLoader();
    loader.crossOrigin = "";
    loader.load("http://mrdoob.github.io/three.js/examples/textures/crate.gif",
    	function ( texture ) {
    		texture.minFilter = THREE.NearestFilter;
    		var material = new THREE.MeshLambertMaterial( { map: texture, side: THREE.DoubleSide } );
    		var myBox2mesh = new THREE.Mesh(myBox2geom, material);
    		// add mesh to scene:
    		scene.add( myBox2mesh );
    	},
    	function () {},  // onProgress function
    	function ( error ) { console.log( error ) }  // no error gets logged
    );
    
    // make light:
    var light = new THREE.PointLight( 0xffffff );
    light.position.set(100, 200, 300);
    light.lookAt( new THREE.Vector3( 0, 0, 0 ) );
    scene.add( light );
    
    // make camera:
    var camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 10000 );
    camera.position.x = 100;
    camera.position.y = 200;
    camera.position.z = 300;
    camera.lookAt( new THREE.Vector3( 0, 0, 0 ) );
    scene.add( camera );
    
    // make renderer:
    var renderer = new THREE.WebGLRenderer();
    renderer.setSize( window.innerWidth, window.innerHeight );
    container.appendChild( renderer.domElement );
    
    // aaaand render, continuously!
    function animate() {
    	requestAnimationFrame( animate );
    	renderer.render( scene, camera );
    }
    animate();
    
    
    
    THREE.Box2Geometry = function ( width, height, depth, widthSegments, heightSegments, depthSegments ) {
    
    	THREE.Geometry.call( this );
    
    	this.parameters = {
    		width: width,
    		height: height,
    		depth: depth,
    		widthSegments: widthSegments,
    		heightSegments: heightSegments,
    		depthSegments: depthSegments
    	};
    
    	this.widthSegments = widthSegments || 1;
    	this.heightSegments = heightSegments || 1;
    	this.depthSegments = depthSegments || 1;
    
    	var constructee = this;  // constructee = the instance currently being constructed by the Box2Geometry constructor
    
    	var width_half = width / 2;    // width  = the distance along x in the absolute 3D space
    	var height_half = height / 2;  // height = the distance along y in the absolute 3D space
    	var depth_half = depth / 2;    // depth  = the distance along z in the absolute 3D space
    
    	buildPlane( 'z', 'y', -1, -1, depth, height, width_half, 0 ); // px
    	buildPlane( 'z', 'y',  1, -1, depth, height, -width_half, 1 ); // nx
    	buildPlane( 'x', 'z',  1,  1, width, depth, height_half, 2 ); // py
    	buildPlane( 'x', 'z',  1, -1, width, depth, -height_half, 3 ); // ny
    	buildPlane( 'x', 'y',  1, -1, width, height, depth_half, 4 ); // pz
    	buildPlane( 'x', 'y', -1, -1, width, height, -depth_half, 5 ); // nz
    
    	function buildPlane( u, v, uDir, vDir, uDist, vDist, wDist_half, materialIndex ) {
    
    		var w, iu, iv,
    			segU = constructee.widthSegments,  // number of segments along u   // width  = x
    			segV = constructee.heightSegments, // number of segments along v   // height = y
    			uDist_half = uDist / 2,  // the extent of the plane along u, divided by two
    			vDist_half = vDist / 2,  // the extent of the plane along v, divided by two
    			offset = constructee.vertices.length;
    
    		if ( ( u === 'x' && v === 'y' ) || ( u === 'y' && v === 'x' ) ) {
    
    			w = 'z';
    
    		} else if ( ( u === 'x' && v === 'z' ) || ( u === 'z' && v === 'x' ) ) {
    
    			w = 'y';
    			segV = constructee.depthSegments;
    
    		} else if ( ( u === 'z' && v === 'y' ) || ( u === 'y' && v === 'z' ) ) {
    
    			w = 'x';
    			segU = constructee.depthSegments;
    
    		}
    
    		var segUi = segU + 1,  // i = inc = incremented (by one)
    			segVi = segV + 1,  // i = inc = incremented (by one)
    			segmentDist_u = uDist / segU,
    			segmentDist_v = vDist / segV,
    			normal = new THREE.Vector3();
    
    		normal[ w ] = wDist_half > 0 ? 1 : -1;
    
    		for ( iv = 0; iv < segVi; iv++ ) {
    
    			for ( iu = 0; iu < segUi; iu++ ) {
    
    				var vertex = new THREE.Vector3();
    				vertex[ u ] = ( iu * segmentDist_u - uDist_half ) * uDir;
    				vertex[ v ] = ( iv * segmentDist_v - vDist_half ) * vDir;
    				vertex[ w ] = wDist_half;
    
    				constructee.vertices.push( vertex );
    
    			}
    
    		}
    
    		for ( iv = 0; iv < segV; iv++ ) {
    
    			for ( iu = 0; iu < segU; iu++ ) {
    
    				var a = iu         + segUi *   iv;
    				var b = iu         + segUi * ( iv + 1 );
    				var c = ( iu + 1 ) + segUi * ( iv + 1 );
    				var d = ( iu + 1 ) + segUi *   iv;
    
    				var uva = new THREE.Vector2(   iu       / segU, 1 -   iv       / segV );
    				var uvb = new THREE.Vector2(   iu       / segU, 1 - ( iv + 1 ) / segV );
    				var uvc = new THREE.Vector2( ( iu + 1 ) / segU, 1 - ( iv + 1 ) / segV );
    				var uvd = new THREE.Vector2( ( iu + 1 ) / segU, 1 -   iv       / segV );
    
    				var face1 = new THREE.Face3( a + offset, b + offset, d + offset );
    				face1.normal.copy( normal );
    				face1.vertexNormals.push( normal.clone(), normal.clone(), normal.clone() );
    				face1.materialIndex = materialIndex;
    
    				constructee.faces.push( face1 );
    				constructee.faceVertexUvs[ 0 ].push( [ uva, uvb, uvd ] );
    
    				var face2 = new THREE.Face3( b + offset, c + offset, d + offset );
    				face2.normal.copy( normal );
    				face2.vertexNormals.push( normal.clone(), normal.clone(), normal.clone() );
    				face2.materialIndex = materialIndex;
    
    				constructee.faces.push( face2 );
    				constructee.faceVertexUvs[ 0 ].push( [ uvb.clone(), uvc, uvd.clone() ] );
    
    			}
    
    		}
    
    	}
    
    	this.mergeVertices();
    };
    THREE.Box2Geometry.prototype = Object.create( THREE.Geometry.prototype );
    &#13;
    <!doctype html>
    <html>
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
      </head>
      <body>
        <script src="https://raw.githubusercontent.com/mrdoob/three.js/master/build/three.js"></script>
        <script src="main3.js"></script>
      </body>
    </html>
    &#13;
    &#13;
    &#13;

    编辑:第四种类型的错误,可以导致纹理变白(如果它本身是自发光)或变黑(如果它不是),如果没有灯光,或灯光不是& #39; t被添加到场景中,或者指示灯指向错误的方向(提示:使用light.lookAt())或者灯光离网格太远。

    编辑2:第五个原因是面部法线不是从几何体向外指向。有关详细信息,请参阅问题three.js: custom geometry wont be textured

答案 2 :(得分:0)

我对不同的原因有类似的效果:我在透明背景上写了黑色文字,结果是一个完全黑色的立方体。我通过给纹理png文件一个颜色而不是让它透明来解决了这个问题。