【问题标题】:Geometry instancing with one shader but multiple textures使用一个着色器但有多个纹理的几何实例化
【发布时间】:2020-04-15 20:13:54
【问题描述】:

我想使用本示例提供的着色器/技术向着色器添加第二个板条箱纹理:

https://threejs.org/examples/#webgl_buffergeometry_instancing_dynamic

我想我可以穿上另一套制服来添加第二张地图。

crateMaterial = new THREE.RawShaderMaterial( {
        uniforms: {
          map: { value: new THREE.TextureLoader().load( './img/textures/crate/crate.gif' ), 
          map2: { value: new THREE.TextureLoader().load( './img/textures/crate2/crate2.gif' ) }
};

但是,由于我在 GLSL 方面的经验和技能非常有限,因此我正在努力弄清楚如何“标记”特定的 crate,然后使用着色器绘制具有正确纹理的顶点。

我可以传入另一个由(顶点)索引组成的统一体来指定着色器应该在哪里应用第二个纹理吗?即:

crateMaterial.uniforms.cratesTexturemap = [];
for(i=0;i<cratesToRender;i++) {
/* set position */
...

this._instancePositions.push( position.x, position.y, position.z );

if (drawCrate2) {
crateMaterial.uniforms.cratesTexturemap.push(i); /* correlates to (vertex) position index */
crateMaterial.uniforms.cratesTexturemap.push(i+1);
crateMaterial.uniforms.cratesTexturemap.push(i+2);
}
...
}

在性能/内存方面,将(动态)纹理数组传递给着色器更好还是逐个传递它们(如上每个纹理的统一值)更有利?

示例着色器代码供参考:

<script id="vertexShader" type="x-shader/x-vertex">
        precision highp float;
        uniform mat4 modelViewMatrix;
        uniform mat4 projectionMatrix;
        attribute vec3 position;
        attribute vec3 offset;
        attribute vec2 uv;
        attribute vec4 orientation;
        varying vec2 vUv;
        // http://www.geeks3d.com/20141201/how-to-rotate-a-vertex-by-a-quaternion-in-glsl/
        vec3 applyQuaternionToVector( vec4 q, vec3 v ){
            return v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );
        }
        void main() {
            vec3 vPosition = applyQuaternionToVector( orientation, position );
            vUv = uv;
            gl_Position = projectionMatrix * modelViewMatrix * vec4( offset + vPosition, 1.0 );
        }
    </script>

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

【问题讨论】:

  • 使用额外的实例化缓冲区属性,其中包含要用于特定 crate 的纹理的索引。

标签: three.js glsl shader textures instance


【解决方案1】:

你不能只传递一个纹理数组,然后使用由 int 统一传递的索引来选择要应用的纹理吗? 所以对于每一个你可以做的箱子

crate.material.uniforms.index = 2

选择数组中的第三个纹理

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多