【JS】GPU计算

https://www.worldlink.com.cn/osdir/gpu-js.html

<script src="gpu-browser.js"></script>
<script>
function mul(a,b){
	var l1=a.length
	var l2=a[0].length
	var l3=b.length
	var l4=b[0].length
	if(l2!=l3)return false
                var f= new GPU().createKernel(function(a, b,l2) {
        		let sum = 0;
        		for (let i = 0; i <l2; i++) 
            			sum += a[this.thread.y][i] * b[i][this.thread.x];
        		return sum;
    	}).setOutput([l4, l1]);
	return f(a, b,l2)
}
var a=[
	[1,0],
	[1,0],
	[0,2]]
var b=[
	[2,0],
	[0,1]]
var c = mul(a, b);
console.log("a",a)
console.log("b",b)
console.log("c",c)
</script>

用GPU实现视锥剔除

class Culling{
	X,Y,Z,R,//包围球
	camera,
	models,
	sizeGPU,
	constructor (opt){
		this.camera=opt.camera
		this.models=opt.models
		this.#init_GPU_culling()
	}
    #init_GPU_culling(){
    	var b=this.models.length
        this.sizeGPU=Math.ceil(Math.pow(n,0.5));
        //#GPU_culling是利用GPU进行视锥遮挡计算的方法
        this.GPU_culling= new GPU().createKernel(function (p0,p1,p2,p3,p4,p5,X,Y,Z,R,sizeGPU) {
            //p0,p1,p2,p3,p4,p5 视锥体的6个平面 //每个平面包含四个参数信息
            //X,Y,Z,R 包围球   sizeGPU
            var k=this.thread.y*sizeGPU+this.thread.x;
            return   intersectsSphere(p0,p1,p2,p3,p4,p5,X[k],Y[k],Z[k],R[k])
            function intersectsSphere(p0,p1,p2,p3,p4,p5,x,y,z,r) {
                function distanceToPoint(plane,point) {
                    return plane[0]* point[0] + plane[1]* point[1] + plane[2]* point[2] + plane[3];
                }

                if ( distanceToPoint(p0, [x,y,z] ) < -1*r ) return 0;//不相交
                if ( distanceToPoint(p1, [x,y,z] ) < -1*r ) return 0;//不相交
                if ( distanceToPoint(p2, [x,y,z] ) < -1*r ) return 0;//不相交
                if ( distanceToPoint(p3, [x,y,z] ) < -1*r ) return 0;//不相交
                if ( distanceToPoint(p4, [x,y,z] ) < -1*r ) return 0;//不相交
                if ( distanceToPoint(p5, [x,y,z] ) < -1*r ) return 0;//不相交

                return 1;
            }
        }).setOutput([this.sizeGPU, this.sizeGPU])

        var X=[],Y=[],Z=[],R=[];
        var k=0;
        for(var i=0;i<this.sizeGPU;i++)
            for(var j=0;j<this.sizeGPU;j++){
                if(k<this.models.length){
                    X.push(this.models[k].boundingSphere.x);
                    Y.push(this.models[k].boundingSphere.y);
                    Z.push(this.models[k].boundingSphere.z);
                    R.push(this.models[k].boundingSphere.r);
                    k++;
                }else{
                    X.push(0);
                    Y.push(0);
                    Z.push(0);
                    R.push(0);
                }
            }
        this.X=X;this.Y=Y;this.Z=Z;this.R=R;
    }
    update=function(){//判断哪些资源在视锥内
            var frustum=scope.#getFrustum();
            var out=scope.GPU_culling(
                frustum[0], frustum[1], frustum[2], frustum[3], frustum[4], frustum[5],//视锥体
                scope.X,scope.Y,scope.Z,scope.R,//包围球
                scope.sizeGPU
            )

            var kk=0;
            for(var i=0;i<scope.sizeGPU;i++)
                for(var j=0;j<scope.sizeGPU;j++)
                   if(kk<scope.models.length)
                          scope.models[kk++].visible=(out[i][j]===1);
    }
    #getFrustum=function () {
        var frustum=new THREE.Frustum();
        frustum.setFromProjectionMatrix(
                new THREE.Matrix4().multiplyMatrices(
                    this.camera.projectionMatrix,
                    this.camera.matrixWorldInverse
                )
            );
        const planes = frustum.planes;
        var plane0=planes[0];
        var plane1=planes[1];
        var plane2=planes[2];
        var plane3=planes[3];
        var plane4=planes[4];
        var plane5=planes[5];

        return [
            [plane0.normal.x,plane0.normal.y,plane0.normal.z,plane0.constant],
            [plane1.normal.x,plane1.normal.y,plane1.normal.z,plane1.constant],
            [plane2.normal.x,plane2.normal.y,plane2.normal.z,plane2.constant],
            [plane3.normal.x,plane3.normal.y,plane3.normal.z,plane3.constant],
            [plane4.normal.x,plane4.normal.y,plane4.normal.z,plane4.constant],
            [plane5.normal.x,plane5.normal.y,plane5.normal.z,plane5.constant],
        ];
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值