1

我正在尝试在 2pha 制作的 ThreeJS 中测试一个简单的点着色器:https ://2pha.com/demos/threejs/shaders/simple_dots.html

使用 Marching Cubes 的元球似乎无法正常工作:https ://threejs.org/examples/webgl_marchingcubes.html 。这是UV坐标问题吗?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" )
}
4

1 回答 1

0

是的。您的点着色器正在使用 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;
    }
于 2018-07-01T07:45:47.627 回答