three.js如何使纹理“生成”纹理坐标,就像搅拌器循环一样

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了three.js如何使纹理“生成”纹理坐标,就像搅拌器循环一样相关的知识,希望对你有一定的参考价值。

我正试图在THREE.js中的圆柱体上显示一个纹理,我想纹理显示在一个井中的圆柱体上......没有那么扭曲的方式,现在它的样子如下:enter image description here

这只是基于这个简单的纹理:enter image description here

我不希望它沿着圆柱体的边缘扭曲/拉伸,我希望它看起来像搅拌机循环中的“生成”纹理坐标:enter image description here

(注意图像纹理中的“框”设置)

SOOO我不知道如何在THREE.js中设置纹理坐标......?

编辑:::有一个实际源代码的请求,所以在这里(即使它很复杂):

var COBY = new (function() {
 this.p = Processing;
 this.t=THREE;
 this.mouseX = 0;
 this.mouseY = 0;
  this.Keyboard = new (function() {
   this.keysDown = [];
   for(var i = 0; i < 200; i++) {
     this.keysDown[i] = false;
   }
   this.RIGHT = 39;
   this.LEFT = 37;
   this.UP = 38;
   this.DOWN = 40;
   this.setKeyDown = function(key) {
     COBY.Keyboard.keysDown[key] = true;
   };
   this.setKeyUp = function(key) {
     COBY.Keyboard.keysDown[key] = false;
   };
   this.isKeyDown = function(key) {
     return COBY.Keyboard.keysDown[key];
   };
 });
  document.body.onkeydown = function(e) {
   COBY.Keyboard.setKeyDown(e.keyCode);


 };
  document.body.onkeyup = function(e) {
   COBY.Keyboard.setKeyUp(e.keyCode);
 };
 document.body.onmousemove = function(e) {
   COBY.mouseX = e.x;
   COBY.mouseY = e.y;
 };
 this.shapes = {
   cube:new THREE.BoxGeometry(1,1,1),
   cylinder: new THREE.CylinderGeometry(0.5, 0.5, 1),
   plane: new THREE.PlaneBufferGeometry(1,1),
 };
 this.textures = {
   white:new THREE.MeshLambertMaterial({color:"white"}),
   red:new THREE.MeshLambertMaterial({color:"red"}),
   purple:new THREE.MeshLambertMaterial({color:"purple"}),
   blue:new THREE.MeshLambertMaterial({color:"blue"}),
   pink:new THREE.MeshLambertMaterial({color:"pink"}),
   gray:new THREE.MeshLambertMaterial({color:"gray"}),
   yellow:new THREE.MeshLambertMaterial({color:"yellow"}),
   green:new THREE.MeshLambertMaterial({color:"green"})
 };

this.loadTexture = function(name, path) {
  COBY.textures[name] = new THREE.MeshBasicMaterial({
        map: THREE.ImageUtils.loadTexture(path)
      });
  console.log(COBY.textures);
};

this.GUIContainer = function(obj) {
    this.div = document.createElement("div");
    this.div.style.position="absolute";
    this.div.style.left=(obj.x || 0) + "px";
    this.div.style.top=(obj.y || 0) + "px";
    this.div.style.background=obj.color || "white";
    this.div.style.width = (obj.width || 100) + "px";
    this.div.style.height = (obj.height || 100) + "px";
    this.div.style.display = obj.invisible ? "none" : "block";
    var that = this;
    this.add = function(g) {
        that.div.appendChild(g.div);
    };
    if(document.body) {
        document.body.appendChild(this.div);
    }
};

this.GUIObject = function(obj) {
    this.div = document.createElement("div");
    this.div.style.position="absolute";
    this.div.style.left=(obj.x || 0) + "px";
    this.div.style.top=(obj.y || 0) + "px";
    this.div.style.background=obj.color || "white";
    this.div.style.width = (obj.width || 100) + "px";
    this.div.style.height = (obj.height || 100) + "px";
    if(obj.text) {
        this.div.innerhtml = "<p class='gTxt'>" + obj.text + "</p>";
    }
    if(obj.type === "button") {
        this.div.className = "btn";
    } 
};

this.Cobject = function(obj,world) {
 this.width=obj.width||1;
 this.height=obj.height||1;
 this.depth=obj.depth||1;
 this.position = new THREE.Vector3();
 this.rotation = {x:0,y:0,z:0};
 this.forReference = obj.forReference;
 if(obj.position) {
this.position.x = obj.position.x || 0;
this.position.y = obj.position.y || 0;
this.position.z = obj.position.z || 0;
 }
 if(obj.rotation) {
 this.rotation.x = obj.rotation.x || 0;
 this.rotation.y = obj.rotation.y || 0;
 this.rotation.z = obj.rotation.z || 0;
 }
 this.worldParent = world || false;
 this.followMouse = obj.followMouse || false;
 this.update=obj.update||function(c){};
 this.start = obj.start || function(){};
 this.texture = COBY.textures[obj.texture];
 //this.texture.wrapS = this.texture.wrapT = THREE.MirroredRepeatWrapping;

 this.mesh=new THREE.Mesh(COBY.shapes[obj.shape],this.texture);
 var self = this;

 this.updateTexture = function(path) {
    self.mesh.material.map.image.src = path;
    self.mesh.material.needsUpdate = true;
 }

 this.superUpdate = function(cob) {
   self.mesh.scale.set(self.width,self.height,self.depth);
   self.mesh.position.copy(self.position);
   self.mesh.rotation.set(self.rotation.x,self.rotation.y,self.rotation.z);
   self.update(cob);
 };


};
function webglAvailable() {
        try {
            var canvas = document.createElement( 'canvas' );
            return !!( window.WebGLRenderingContext && (
                canvas.getContext( 'webgl' ) ||
                canvas.getContext( 'experimental-webgl' ) )
            );
        } catch ( e ) {
            return false;
        }
    }
this.World=function (obj) {
   this.width = window.innerWidth;
   this.height = window.innerHeight;
   this.loadTextures = function(texts) {
     for(var i = 0; i < texts.length; i++) {
       COBY.loadTexture(texts[i].name, texts[i].path);
     }
   };

   if(obj) {
   this.width=obj.width || window.innerWidth;
   this.height=obj.height || window.innerHeight;
   if(obj.textures) {
     this.loadTextures(obj.textures);
   }
   }

   this.scene=new THREE.Scene();
   this.camera = new THREE.PerspectiveCamera( 75, this.width   / this.height, 0.1, 10000 );
   this.camera.name = "camera";
//if ( webglAvailable() ) {
        this.renderer = new THREE.WebGLRenderer({alpha:true});
//  } else {
    //  this.renderer = new THREE.CanvasRenderer();
//  }

this.renderer.setSize(this.width,this.height);
this.renderer.setClearColor(0x000000, 0);

this.renderer.domElement.style.position="absolute";
this.renderer.domElement.style.left="0";
this.renderer.domElement.style.top="0";

this.camera.position.z=5;

this.cobs = [];
this.meshes=[];
var that=this;
this.light = function(x,y,z,inten) {
    var directionalLight1=new THREE.DirectionalLight(0xffffff);
    directionalLight1.position.set(x,y,z,inten || 1);
    directionalLight1.name == "light";
    that.scene.add(directionalLight1);
};
this.lights = function() {
  var ambientLight = new THREE.AmbientLight( 0x606060 );
                that.scene.add( ambientLight );

                var directionalLight = new THREE.DirectionalLight( 0xffffff );
                directionalLight.position.set( 1, 0.75, -0.5 ).normalize();
                that.scene.add( directionalLight );
};
  this.lights();
this.add=function(obj){
   if(!obj.forReference) {
   if(obj.mesh) {
   that.scene.add(obj.mesh);
   that.meshes.push(obj.mesh);
   that.cobs.push(obj);
   } else {
    that.scene.add(obj);
   }



   }
   obj.start(obj);
};

this.cob = function(c) {
    that.add(new COBY.Cobject(c,that));
};

this.addCobjects = function(cobs) {
  for(var i = 0; i < cobs.length; i++) {
    that.add(new COBY.Cobject(cobs[i],that));
  }
};

this.empty = function() {
    that.meshes = [];
    that.cobs = [];
    for(var i = that.scene.children.length - 1; i >= 0; i--) {
            that.scene.remove(that.scene.children[i]);
    }
    that.scene.add(that.camera);
    that.lights();
  console.log("just actually emptied..feels good");
};

this.update=function (){
  // noprotect
   for(var i=0;i<that.cobs.length;i++) {
    that.cobs[i].superUpdate(that.cobs[i]);
   }
   that.loop();
   that.renderer.render(that.scene, that.camera);
};
this.loop=function(){

};
this.canvas=this.renderer.domElement;


this.start = function(div) {
  if(!div)
    document.body.appendChild(this.canvas);
  else
    div.appendChild(this.canvas);
  function sketchProc(proc) {
    // noprotect
      proc.draw=function(){    
         that.update();
      };
   }
   var procInst=new Processing(document.createElement("canvas"),sketchProc);
};
};
})();
答案

THREE.CylinderGeometry()THREE.CylinderBufferGeometry()都按预期工作:

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.setScalar(10);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x404040);
document.body.appendChild(renderer.domElement);

var controls = new THREE.OrbitControls(camera, renderer.domElement);

//var cylGeom = new THREE.CylinderGeometry(5, 5, 1, 8);
var cylGeom = new THREE.CylinderBufferGeometry(5, 5, 1, 8);

var texLoader = new THREE.TextureLoader();
var texEnd = texLoader.load("https://threejs.org/examples/textures/UV_Grid_Sm.jpg");
texEnd.wrapS = THREE.RepeatWrapping;
texEnd.wrapT = THREE.RepeatWrapping;
texEnd.repeat.set(1, 1);
var texSide = texLoader.load("https://threejs.org/examples/textures/UV_Grid_Sm.jpg");
texSide.wrapS = THREE.RepeatWrapping;
texSide.wrapT = THREE.RepeatWrapping;
texSide.repeat.set(1, 1 / (cylGeom.parameters.radiusTop * cylGeom.parameters.radiusBottom));

var cylMatEnd = new THREE.MeshBasicMaterial({
  map: texEnd
});
var cylMatSide = new THREE.MeshBasicMaterial({
  map: texSide
});
var cyl = new THREE.Mesh(cylGeom, [cylMatSide, cylMatEnd, cylMatEnd]);
scene.add(cyl);

render();

function render() {
  requestAnimationFrame(render);
  renderer.render(scene, camera);
}
body {
  overflow: hidden;
  margin: 0;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

以上是关于three.js如何使纹理“生成”纹理坐标,就像搅拌器循环一样的主要内容,如果未能解决你的问题,请参考以下文章

如何使用Three.js获取纹理尺寸

如何从 GLTF 模型动态覆盖纹理 - Three.js

如何禁用three.js以以2的幂调整图像大小?

如何在three.js中为.fbx模型应用纹理?

【Three.js】请问如何显示带纹理的三维模型?

如何使用 THREE.js 向 collada 文件 (.dae) 添加纹理?