我正在尝试在 2pha 制作的 ThreeJS 中测试一个简单的点着色器:https://2pha.com/demos/threejs/shaders/simple_dots.html
它似乎不能正常工作,用于使用行进立方体的元球:https://threejs.org/examples/webgl_marchingcubes.html。 这是紫外线坐标问题吗?ThreeJS版本有一个enableUvs
标志,但似乎还不够。
在这里,着色器传递给了ShaderMaterial
'polkadots' : {
uniforms: {
"amount":{type: "f",value: 5.},
"radius1":{type: "f",value: 0.3},
"radius2":{type: "f",value: 0.32},
"color1":{type:"c",value: new THREE.Color(0xffffff)},
"color2":{type:"c",value: new THREE.Color(0x000000)},
},
vertexShader: [
"varying vec2 vUv;",
"void main() {",
"vUv = uv;",
"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
"gl_Position = projectionMatrix * mvPosition;",
"}",
].join( "n" ),
fragmentShader: [
"uniform vec3 color1;",
"uniform vec3 color2;",
"uniform float radius1;",
"uniform float radius2;",
"uniform float amount;",
"varying vec2 vUv;",
"void main(void){",
"float p = smoothstep(radius1, radius2, length(fract(amount*vUv)-0.5));",
"vec3 col = mix(color1,color2,vec3(p));",
"gl_FragColor = vec4(col,1.0);",
"}",
].join( "n" )
}
是的。您的点着色器正在使用 UV 来确定在何处绘制点...如果你的行进立方体算法没有设置 UV,你必须自己合成一些...... 你可以做一个盒子展开。. 这不是太复杂,但弄清楚很有趣。 你循环穿过几何体的面...找出三角形位于哪个平面上,并将顶点投影到该UV平面上。我冒昧地为你写了它:
function boxUnwrapUVs(geometry) {
for (var i = 0; i < geometry.faces.length; i++) {
var face = geometry.faces[i];
var faceUVs = geometry.faceVertexUvs[0][i]
var va = geometry.vertices[geometry.faces[i].a]
var vb = geometry.vertices[geometry.faces[i].b]
var vc = geometry.vertices[geometry.faces[i].c]
var vab = new THREE.Vector3().copy(vb).sub(va)
var vac = new THREE.Vector3().copy(vc).sub(va)
//now we have 2 vectors to get the cross product of...
var vcross = new THREE.Vector3().copy(vab).cross(vac);
//Find the largest axis of the plane normal...
vcross.set(Math.abs(vcross.x), Math.abs(vcross.y), Math.abs(vcross.z))
var majorAxis = vcross.x > vcross.y ? (vcross.x > vcross.z ? 'x' : vcross.y > vcross.z ? 'y' : vcross.y > vcross.z) : vcross.y > vcross.z ? 'y' : 'z'
//Take the other two axis from the largest axis
var uAxis = majorAxis == 'x' ? 'y' : majorAxis == 'y' ? 'x' : 'x';
var vAxis = majorAxis == 'x' ? 'z' : majorAxis == 'y' ? 'z' : 'y';
faceUVs[0].set(va[uAxis], va[vAxis])
faceUVs[1].set(vb[uAxis], vb[vAxis])
faceUVs[2].set(vc[uAxis], vc[vAxis])
}
//Tell THREE that our modifications need to be uploaded to the GPU
geometry.elementsNeedUpdate = geometry.verticesNeedUpdate = true;
}