threejs: как визуализировать текстуру с помощью пользовательских шейдеров, ВКЛЮЧАЯ текстуры смещения UV - PullRequest
0 голосов
/ 05 сентября 2018

Я хочу визуализировать текстуру на плоскости с помощью пользовательских шейдеров. Эта текстура имеет набор свойств offset, который работает правильно, когда я использую стандартный материал Threejs. Однако я не могу понять, как получить доступ к этим смещениям в моем пользовательском фрагментном шейдере. Он просто отображает всю текстуру по всей плоскости:

шейдеры:

<script id="vertex_shader" type="x-shader/x-vertex">
    varying vec2 vUv;

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

    </script>

    <script id="fragment_shader" type="x-shader/x-fragment">

    uniform sampler2D texture1;
    varying vec2 vUv;

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

    </script>

если бы я мог как-то сказать что-то вроде:

gl_FragColor = texture2D(texture1, vUv + texture1.offset); 

? Может быть, это сработает. Но очевидно, что это выдает ошибку.

UPDATE: поэтому я отправил смещение текстуры как форму, и это работает. Не знаю, почему я об этом не подумал.

1 Ответ

0 голосов
/ 05 сентября 2018

Если я правильно понимаю ваш вопрос, то ответом будет добавление и использование формы uniform mat3 uvTransform; для вашего фрагментного шейдера.

THREE будет искать и заполнять эту форму преобразованием текстуры (которое включает в себя texture1.offset) при рендеринге текстуры в вашу геометрию.

Вы должны иметь возможность доступа и извлечения данных, переданных в texture1.offset, чтобы компенсировать выборку текстур следующим образом:

<script id="vertex_shader" type="x-shader/x-vertex">
varying vec2 vUv;

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

</script>

<script id="fragment_shader" type="x-shader/x-fragment">

    // [UPDATE] The uv offset uniform we defined below
    uniform vec2 uvOffset;
    // [UPDATE] The texture uniform we defined below
    uniform sampler2D texture;

    varying vec2 vUv;

    void main()
    {
        // [UPDATE] Apply offset to texture lookup
        gl_FragColor = texture2D(texture, vUv + uvOffset); 
    }

</script>

Затем вы сопровождали бы вершинный и фрагментный шейдеры, приведенные выше, со следующим THREE.ShaderMaterial:

<script>
  var material = new THREE.ShaderMaterial({
  uniforms: THREE.UniformsUtils.merge([
    {
      //Declare texture uniform in shader
      texture: { type: 't', value: null }, 
      //Declare texture offset in shader
      uvOffset : { type : 'v', value : new THREE.Vector2(0,0) } 
    }
  ]),
  vertexShader: 
  document.getElementById('vertexshader').textContent,
  fragmentShader: 
  document.getElementById('fragmentshader').textContent
});

// Shader uniforms can be updated like so
material.uniforms.map.value = yourTexture;
material.uniforms.uvOffset.value = yourTextureOffsetVector2;
</script>
...