我想使用此示例提供的着色器/技术向着色器添加第二个板条纹理:
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方面的经验和技能非常有限,因此我很难弄清楚如何“标记”特定的板条箱,然后使用着色器绘制具有正确纹理的顶点。
我是否可以传入由(顶点)索引组成的另一种制服,以指定着色器应在何处应用第二个纹理?即:
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>
难道不能只传递一个纹理数组,然后使用由int统一传递的索引来选择应用哪个纹理?因此,您可以对每个板条箱进行操作
crate.material.uniforms.index = 2
选择数组中的第三个纹理