一、 使用一个材质
利用材质的OnBeforeCompile
, 例如 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| extrudeMeshMat.onBeforeCompile = function(shader) { shader.fragmentShader = shader.fragmentShader.replace( '#include <dithering_fragment>', ` #ifdef OPAQUE diffuseColor.a = 1.0; #endif #ifdef USE_TRANSMISSION diffuseColor.a *= material.transmissionAlpha + 0.1; #endif if ( gl_FrontFacing ) { \ gl_FragColor = vec4( 1.0, 0.0, 0.0, diffuseColor.a ); \ } else { \ gl_FragColor = vec4( 0.0, 1.0, 0.0, diffuseColor.a ); \ } ` ) };
|
着色器参数diffuseColor
对应的是material.color设置的颜色,gl_FragColor对应的是最终渲染的颜色,gl_FrontFacing表示正面还是反面,在适当的位置,将gl_FragColor的初始化根据gl_FrontFacing对gl_FragColor进行不同的操作就可以得正反面颜色不同的效果
二、 使用材质数组
1. 创建材质数组,例如
1 2 3
| const material1 = new THREE.MeshBasicMaterial({color: 0xff0000}); const material2 = new THREE.MeshBasicMaterial({color: 0x00ff00}); const materials = [material1, material2]
|
2.
如果有顶点索引,则遍历顶点索引,再添加反面的顶点索引;如果没有顶点索引,则遍历顶点,创建正面和反面的顶点索引。使用setIndex函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| const finalVertices = <THREE.Vector3[]>[...] // 几何体的顶点 const geo = new THREE.BufferGeometry() geo.setFromPoints(finalVertices) // ! 计算法向量要在只有一个面的时候计算 geo.computeVertexNormals() const newIndexes = <number[]>[] const count = finalVertices.length for(let i = 0; i < count; i += 3) { newIndexes.push(i, i + 1, i + 2) } for(let i = 0; i < count; i += 3) { newIndexes.push(i, i + 2, i + 1) } geo.setIndex(newIndexes)
|
3.
使用setGroup函数,将当前几何体分割成组进行渲染
1 2
| geo.addGroup(0, count, 0) geo.addGroup(count, count, 1)
|
demo