Как я могу отобразить изображение текстуры на геометрию шейдера? - PullRequest
0 голосов
/ 02 января 2019

У меня есть 2 сцены, в одной из которых я сопоставил изображение текстуры с геометрией плоскости, и я просто рендерил его, в другой сцене у меня есть куб с материалом шейдера, теперь я хочу, чтобы изображение текстуры отображалось в hte.первая сцена, которая должна быть отображена на поверхность куба, но я не знаю, как я могу это сделать, кто-нибудь может помочь?

на самом деле не хватает документации на то, что я хочу сделать, и я как-то плохо знаком с тремя.js, так что я понятия не имею, что мне делать в вершинном и фрагментном шейдерах моего HTML-файла, я сделал только то, что упомянул ранее.

Вот мое изображение текстуры и геометрия плоскости в первой сцене и куб вдругие, а также мой фрагмент и вершинный шейдер:

this.vertShader = document.getElementById('vertexShader').innerHTML;
this.fragShader = document.getElementById('fragmentShader').innerHTML;
var geometry = new THREE.BoxGeometry( 0.5, 0.5 );

var material = new THREE.MeshLambertMaterial( { color: "blue", wireframe: 
true} );
this.mesh = new THREE.Mesh( geometry, material );
this.scene.add( this.mesh );

var texture = new THREE.TextureLoader().load ('js/textures/earth.jpg');
var texMaterial = new THREE.MeshBasicMaterial( { map: texture } );
var texGeometry = new THREE.PlaneGeometry(1, 1);
this.texmesh = new THREE.Mesh(texGeometry, texMaterial);
this.texmesh.position.set(0,0,0);
this.texScene.add(this.texmesh);

вершинный шейдер: меняющийся vec2 vUv;

void main() {
    vUv = uv;

    gl_Position =   projectionMatrix * modelViewMatrix * 
vec4(position,1.0);
 }

фрагментный шейдер: унифицированная текстура sampler2D;

varying vec2 vUv;

void main() {
    gl_FragColor = texture2D(texture, vUv);
}

Мне нравится куб, который будет покрыт изображением текстуры.

1 Ответ

0 голосов
/ 02 января 2019

В фрагментном шейдере необходимо объявить стандартную переменную типа sampler2D:

Vertex Shader :

varying vec2 vUv;

void main() {
    vUv = uv;
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}

Фрагментный шейдер :

precision highp float;

uniform sampler2D u_texture; // <---------------------------------- texture sampler uniform

varying vec2 vUv;

void main(){
    gl_FragColor = texture2D(u_texture, vUv);
}

С помощью шейдеров можно создать THREE.ShaderMaterial.

Сначала загрузите текстуру:

var texture = new THREE.TextureLoader().load ('js/textures/earth.jpg');

Затем укажите набор Uniform s (в данном случае это только текстурная форма):

var uniforms = {
    u_texture: {type: 't', value: texture}
};

Наконец, создайте материал:

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

Материал можно использовать так же, как и любой другой материал, см. Пример:

(function onLoad() {
  var loader, camera, scene, renderer, orbitControls;
  
  init();
  animate();

  function createModel() {

    var texture = new THREE.TextureLoader().load( 'https://raw.githubusercontent.com/Rabbid76/graphics-snippets/master/resource/texture/Gominolas.png' );

    var uniforms = {
        u_texture: {type: 't', value: texture}
    };
        
    var material = new THREE.ShaderMaterial({  
          uniforms: uniforms,
          vertexShader: document.getElementById('vertex-shader').textContent,
          fragmentShader: document.getElementById('fragment-shader').textContent
    });

    var geometry = new THREE.BoxGeometry( 1, 1, 1 );
    var mesh = new THREE.Mesh(geometry, material);

    scene.add(mesh);
  }

  function init() {
    renderer = new THREE.WebGLRenderer({
      antialias: true,
      alpha: true
    });
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.shadowMap.enabled = true;
    document.body.appendChild(renderer.domElement);

    camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 100);
    camera.position.set(0, 1, -2);

    loader = new THREE.TextureLoader();
    loader.setCrossOrigin("");

    scene = new THREE.Scene();
    scene.background = new THREE.Color(0xffffff);
    scene.add(camera);
    window.onresize = resize;
    
    orbitControls = new THREE.OrbitControls(camera);
    
    addGridHelper();
    createModel();
  }

  function addGridHelper() {
    
    var helper = new THREE.GridHelper(100, 100);
    helper.material.opacity = 0.25;
    helper.material.transparent = true;
    scene.add(helper);

    var axis = new THREE.AxesHelper(1000);
    scene.add(axis);
  }

  function resize() {
    
    var aspect = window.innerWidth / window.innerHeight;
    renderer.setSize(window.innerWidth, window.innerHeight);
    camera.aspect = aspect;
    camera.updateProjectionMatrix();
  }

  function animate() {
    requestAnimationFrame(animate);
    orbitControls.update();
    render();
  }

  function render() {
    renderer.render(scene, camera);
  }
})();
<script type='x-shader/x-vertex' id='vertex-shader'>
varying vec2 vUv;
void main() {
    vUv = uv;
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
</script>

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

<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
...