Three.js-Vertex Shader UV变量仅返回0,0 [英] Three.js - Vertex Shader UV variable return only 0,0

查看:77
本文介绍了Three.js-Vertex Shader UV变量仅返回0,0的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用OBJLoader加载了一个对象.我想使用带有纹理的着色器材质.我将纹理传递给材质的统一参数. 我将UV变量从顶点着色器传递到片段着色器.

I loaded an object with OBJLoader. I want to use a Shader Material with a texture. I pass my texture to the uniforms parameters of the material. I pass the UV variable from the vertex shader to the fragment shader.

但是当我使用uv坐标来映射我的纹理时,我总是得到0,0或至少这是它的样子.整个对象都带有纹理的左下角像素.

But when I use the uv coordinate for mapping my texture I get always 0,0 or at least this is what it looks like. The whole object is coloured with the bottom left pixel of the texture.

这是我的着色器:

  <script type='x-shader/x-vertex' id='vertex-shader'>
    uniform float u_time;
    varying vec2 vUv;
    void main() {
      vUv = uv;
      vec4 pos = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
      gl_Position = pos;
    }
  </script>
  <script type='x-shader/x-fragment' id='fragment-shader'>
    precision highp float;
    uniform float u_time;
    uniform vec2 u_resolution;
    uniform sampler2D texture;
    varying vec2 vUv;
    void main(){
      vec2 st = vUv;
      vec4 tex = texture2D(texture, st);
      gl_FragColor = tex;
     }
  </script>

这是我如何加载对象并分配材料的方法

And here is how I load the object and assign the material

var loader = new THREE.OBJLoader();
loader.load(
    'assets/standing.obj',
    function (object){

    main.man = object;
    main.man.position.set(0,-600,400);

    main.texture = new THREE.TextureLoader().load( 'assets/na_00004c.jpg' );

    main.texture_needsUpdate = true;
    var uniforms = {
      u_time:{type:'f', value:0.0},
      u_mouse:{type:'v2', value: new THREE.Vector2()},
      u_resolution: {type: 'v2', value: {x:2048.,y:1024.}},
      texture: {type: 't', value: main.texture}
    }

    main.material = new THREE.ShaderMaterial({  
      uniforms: uniforms,
      vertexShader: document.getElementById('vertex-shader').textContent,
      fragmentShader: document.getElementById('fragment-shader').textContent,
      transparent: true
    });

    main.material.needsUpdate = true;
    main.material.side = THREE.DoubleSide;

    main.man.traverse(function(child){
      if(child instanceof THREE.Mesh){
        child.material = main.material;
        child.material.needsUpdate = true;
        child.geometry = new THREE.Geometry().fromBufferGeometry( child.geometry );  
        child.geometry.computeVertexNormals();
        child.geometry.elementsNeedUpdate = true;
        child.geometry.mergeVertices(); 
        child.verticesNeedUpdate = true;
        child.normalsNeedUpdate = true;
        child.uvsNeedUpdate = true;
        child.material.flatShading = THREE.SmoothShading;
      } 
    });

        main.scene.add(main.man);

    },
    function (xhr){
        console.log((xhr.loaded/xhr.total*100)+'% loaded');
    },
    function (error){
        console.log(error,'An error happened');
    }
);

这里有完整的例子 http://cmt.re/dev/na/

这是我要用作纹理的图像 http://cmt.re/dev/na/assets/na_00004c.jpg

This is the image that I want to use as a texture http://cmt.re/dev/na/assets/na_00004c.jpg

有人知道为什么会这样吗?

Does somebody know why this is happening?

非常感谢.

推荐答案

您的代码可以正常工作,但是您的*.obj文件不包含任何纹理坐标. Wavefront OBJ 文件(.obj文件)是文本文件,纹理坐标是带有以下内容的条目键vt,如果缺少此条目,则网格没有任何纹理坐标.

Your code works fine, but your *.obj file doesn't contain any texture coordinates. The Wavefront OBJ file (.obj file) is a text file, texture coordinates are the entries with the key vt, if this entries are missing, the mesh doesn't have any texture coordinates.

您的代码运行良好,请参见示例,其中我将您的原始代码与一个简单模型一起使用:

Your code works fine, see the example, where I used your original code with a simple model:

var main = new function(){
  
  this.init = function(){
    
    this.initThree();
    
  }
  
  this.initThree = function(){
    
    main.scene = new THREE.Scene();
    main.scene.background = new THREE.Color(0xCCCCCC);
    
    var aspectRatio = window.innerWidth / window.innerHeight;
    main.camera = new THREE.PerspectiveCamera(75, aspectRatio, 0.1, 100000);
    //main.camera.position.set(-40, 0, 512);
    main.camera.position.set(1,2,0);
    
    main.renderer = new THREE.WebGLRenderer({antialias: true});
    main.renderer.setPixelRatio(window.devicePixelRatio);
    main.renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(main.renderer.domElement);

    main.controls = new THREE.OrbitControls(main.camera, main.renderer.domElement);
    main.controls.enableDamping = true;
    main.controls.dampingFactor = 0.1;
    main.controls.screenSpacePanning = false;

    var helper = new THREE.GridHelper(2000, 100);
    helper.material.opacity = 0.25;
    helper.material.transparent = true;
    main.scene.add(helper);

    var axis = new THREE.AxesHelper();
    main.scene.add(axis);
    
    makeTextFile = function (text) {
      var data = new Blob([text], {type: 'text/plain'});
      var textFile = window.URL.createObjectURL(data);
      return textFile;   
    }
    var textbox_obj = document.getElementById('plane_obj');
    var obj_url = makeTextFile(textbox_obj.value);

    var loader = new THREE.OBJLoader();
    loader.load(
    	obj_url,
    	function (object){
        
        main.man = object;
        //main.man.position.set(0,-600,400);
        main.man.position.set(0,0,0);
        
        main.texture = new THREE.TextureLoader().load( 'https://raw.githubusercontent.com/Rabbid76/graphics-snippets/master/resource/texture/Gominolas.png' );
        
        main.texture_needsUpdate = true;
        var uniforms = {
          u_time:{type:'f', value:0.0},
          u_mouse:{type:'v2', value: new THREE.Vector2()},
          u_resolution: {type: 'v2', value: {x:2048.,y:1024.}},
          texture: {type: 't', value: main.texture}
        }
        
        main.material = new THREE.ShaderMaterial({  
          uniforms: uniforms,
          vertexShader: document.getElementById('vertex-shader').textContent,
          fragmentShader: document.getElementById('fragment-shader').textContent,
          transparent: true
        });
        
        main.material.needsUpdate = true;
        main.material.side = THREE.DoubleSide;
        
        // main.material = new THREE.MeshNormalMaterial();
        
        main.man.traverse(function(child){
          if(child instanceof THREE.Mesh){
            child.material = main.material;
            child.material.needsUpdate = true;
            child.geometry = new THREE.Geometry().fromBufferGeometry( child.geometry );  
            child.geometry.computeVertexNormals();
            child.geometry.elementsNeedUpdate = true;
            child.geometry.mergeVertices(); 
            child.verticesNeedUpdate = true;
            child.normalsNeedUpdate = true;
            child.uvsNeedUpdate = true;
            child.material.flatShading = THREE.SmoothShading;
          } 
        });
        
    		main.scene.add(main.man);
        
    	},
    	function (xhr){
    		console.log((xhr.loaded/xhr.total*100)+'% loaded');
    	},
    	function (error){
    		console.log(error,'An error happened');
    	}
    );
    
    window.onresize = main.onResize;

    this.render();
    
  }
  
  this.render = function(){

    var time = Date.now();
    main.controls.update();
    requestAnimationFrame(main.render);
    main.renderer.render(main.scene, main.camera);
    
  }
  
  this.onResize = function(event) {
    
    main.renderer.setSize(window.innerWidth, window.innerHeight);
    main.camera.aspect = window.innerWidth / window.innerHeight;
    main.camera.updateProjectionMatrix();
    
  }

}

 main.init();

<script src="https://cdn.jsdelivr.net/npm/three@0.115/build/three.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.115/examples/js/controls/OrbitControls.js"></script>
<script src="https://rawgit.com/mrdoob/three.js/dev/examples/js/loaders/OBJLoader.js"></script>

<textarea id="plane_obj" style="display:none;">
    v -1.000000 0.000000 1.000000
    v 1.000000 0.000000 1.000000
    v -1.000000 0.000000 -1.000000
    v 1.000000 0.000000 -1.000000
    
    vt 0.000000 0.000000
    vt 1.000000 0.000000
    vt 0.000000 1.000000
    vt 1.000000 1.000000
    
    vn 0.0000 1.0000 0.0000
    
    f 1/1/1 2/2/1 4/4/1 3/3/1
</textarea>

<script type='x-shader/x-vertex' id='vertex-shader'>
uniform float u_time;
varying vec2 vUv;
void main() {
    vUv = uv;
    vec4 pos = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    gl_Position = pos;
}
</script>

<script type='x-shader/x-fragment' id='fragment-shader'>
precision highp float;
uniform float u_time;
uniform vec2 u_resolution;
uniform sampler2D texture;
varying vec2 vUv;
void main(){
    vec2 st = vUv;
    vec4 tex = texture2D(texture, st);
    gl_FragColor = tex;
}
</script>

这篇关于Three.js-Vertex Shader UV变量仅返回0,0的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆