【问题标题】:threejs: how to render a texture with custom shaders INCLUDING the textures UV offsetsthreejs:如何使用自定义着色器渲染纹理,包​​括纹理 UV 偏移
【发布时间】:2019-02-10 02:06:09
【问题描述】:

我想使用自定义着色器将纹理渲染到平面。这个纹理有一个“偏移”属性集,当我使用标准的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); 

?也许那会奏效。但显然这会引发错误。

更新: 所以我将纹理偏移作为制服发送,并且有效。不知道为什么我没有想到。

【问题讨论】:

  • 是的。我在问题的标题中写了“threejs”。

标签: three.js shader uv-mapping


【解决方案1】:

如果我正确理解您的问题,那么答案应该是在片段着色器中添加和使用 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>

【讨论】:

  • 看起来很棒!虽然它对我不起作用,但它没有效果。我找不到任何关于自动传递给着色器的“uvTransform”的文档。是否有将矩阵应用于纹理的标准方法?
  • 你是如何加载着色器的?通过 THREE.Shader 或 THREE.RawShader ?
  • var 材质 = 新的 THREE.ShaderMaterial。如果有更好、更标准的方法来实现简单的 UV 映射自定义着色器,我很乐意在某处找到示例
  • 您可能需要将实际偏移量应用到制服上,例如myMaterial.uniforms.uvOffset.value = myTexture.transformMatrix 或其他任何名称。这将是一个 mat3,因此您必须将它相乘,仅对于偏移量,您可能会做一个 @ 987654328@myMateria.uniforms.uOffset.value = myTexture.offset
  • @korrbit 刚刚更新了答案 - 希望这会有所帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-04
  • 1970-01-01
  • 2018-02-17
  • 2019-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多