没有几何着色器如何做出面片飞散的效果?

类似于这种https://www.e-learn.cn/topic/3184608,求教大佬思路

替楼主补个效果图,同时也想知道怎么用 cocos 实现?

前排收藏关注一下,我也想学习

俺也想学习

插个眼,俺也一样~

简单说下自己的思路吧,就是把模型网格切割成若干个三角面生成新的网格数据再拼成原来的样子然后进行移动。因为基本都是js完成的,所以性能低下只能看看,没啥实用性。


start () {

        // [3]

        let r = utils.readMesh(this.node.getComponent(MeshRenderer)!.mesh!);

        let faceArr = this.division(r);

        for (let i = 0; i < faceArr.length; i++) {

            let node = instantiate(this.pre);

            node.getComponent(MeshRenderer)!.mesh = utils.createMesh(faceArr[i].r);

            node.getComponent(Move)!.point = faceArr[i].pos;

            this.node.parent?.addChild(node);

            node.setPosition(this.node.position);

        }

        this.node.destroy();

    }

    division (r: primitives.IGeometry) {

        let positionsArr = [];

        for (let i = 0; i < r.positions.length / 3; i++) {

            let t = i * 3;

            positionsArr.push(v3(r.positions[t], r.positions[t + 1], r.positions[t + 2]));

        }

        let normalsArr = [];

        for (let i = 0; i < r.normals!.length / 3; i++) {

            let t = i *3;

            normalsArr.push(v3(r.normals![t], r.normals![t + 1], r.normals![t + 2]));

        }

        let uvsArr = [];

        for (let i = 0; i < r.uvs!.length / 2; i++) {

            let t = i * 2;

            uvsArr.push(v2(r.uvs![t], r.uvs![t + 1]));

        }

        let posArr = [];

        for (let i = 0; i < r.indices!.length; i++) {

            posArr.push({pos: positionsArr[r.indices![i]], normal: normalsArr[r.indices![i]], uvs: uvsArr[r.indices![i]]});

        }

        let faceArr = [];

        for (let i = 0; i < posArr.length / 3; i++) {

            let t = i * 3;

            let a = v3(posArr[t].pos).subtract(posArr[t + 1].pos);

            let b = v3(posArr[t + 2].pos).subtract(posArr[t + 1].pos);

            let normal = b.cross(a).normalize();

            faceArr.push({normal: normal, face: [posArr[t].pos, posArr[t + 1].pos, posArr[t + 2].pos], faceNormals: [posArr[t].normal, posArr[t + 1].normal, posArr[t + 2].normal], faceUvs: [posArr[t].uvs, posArr[t + 1].uvs, posArr[t + 2].uvs]});

        }

        r.positions = [];

        r.normals = [];

        r.indices = [];

        r.uvs = [];

        let rArr = [];

        for (let i = 0; i < faceArr.length; i++) {

            let temp = faceArr[i];

            let rTemp = instantiate(r);

            let pos = temp.face;

            for (let j = 0; j < temp.face.length; j++) {

                let tempPos = temp.face[j];

                rTemp.positions.push(tempPos.x, tempPos.y, tempPos.z);

            }

            for (let j = 0; j < temp.faceNormals.length; j++) {

                let tempNor = temp.faceNormals[j];

                rTemp.normals!.push(tempNor.x, tempNor.y, tempNor.z);

            }

            for (let j = 0; j < temp.faceUvs.length; j++) {

                let tempUvs = temp.faceUvs[j];

                rTemp.uvs!.push(tempUvs.x, tempUvs.y);

            }

            rTemp.indices = [0, 1, 2];

            rArr.push({r: rTemp, pos: pos});

        }

        return rArr;

        // let tP = [], tN = [], tI = [], tUvs = [];

        // for (let i = 0; i < posArr.length; i++) {

        //     const element = posArr[i];

        //     tP.push(element.pos.x);

        //     tP.push(element.pos.y);

        //     tP.push(element.pos.z);

        //     tN.push(element.normal.x);

        //     tN.push(element.normal.y);

        //     tN.push(element.normal.z);

        //     tI.push(i);

        //     tUvs.push(element.uvs.x);

        //     tUvs.push(element.uvs.y);

        // }

        // r.positions = tP;

        // r.normals = tN;

        // r.indices = tI;

        // r.uvs = tUvs;

        // return faceArr;

    }

希望大佬们有更好的思路可以指点一二

4赞

学到了,学到了

mark~

战略插眼~

这个计算相当于把模型“炸开”,如果直接在3dmax里把模型炸开处理就变“实用”了 :blush:

试了下,不太行,虽然渲染消耗降低了,但是因为要不断更新网格数据逻辑消耗上去了

模型已经每个三角面独立了,为啥还要更新网格?

炸开后模型的网格不还是一个吗,只是顶点连接的面分开了吧

是这样的,所以模型本身已经不要写JS进行重新组装了,直接提交给渲染管线。
shader里要做的事情和原来一样。

shader里拿不到整个面的数据,只能改顶点,实在没想出如何将整个面进行移动

你们这些人为什么这么优秀??

说个思路,首先模型的顶点得分开,也就是顶点数是面数的三倍。然后添加自定义顶点属性,分别是同一个面的另外两个顶点的位置和法线。然后在顶点着色器里面就可以计算按整个面移动的数据来修改当前的顶点,效果肯定是和几何着色器一样的,效率就不知道怎么样了

难点是怎么添加另外两个顶点呢

createMesh用到的结构里有customattributes,这你应该看过了,模型原来的postions, normals这些不动,再加一些自定义的例如postions1,normals1这样的进去。自定义属性还没用过,之前只试过顶点颜色里面传些信息进去,不过应该是可以的,普通模型还好,带骨骼动画的模型怎么修改可能有点麻烦。

感谢指点,性能没话说