【发布时间】: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