首页 > 其他 > 详细

着色器应用贴图纹理并修改顶点实现“平地起丘陵”

时间:2019-08-14 01:07:31      阅读:108      评论:0      收藏:0      [点我收藏+]

来张效果图先:

技术分享图片

    var plane;
    function addpanel(){
        var axesHelper = new THREE.AxesHelper( 400 );
        scene.add( axesHelper );
        var geometry = new THREE.PlaneBufferGeometry( 200,200,400, 400);1
        var material = createMaterial("vertex-shader-2", "fragment-shader-2");
        material.uniforms.texture_grass={
            type:t, 
            value:new THREE.TextureLoader().load("../texture/tile_aqua.png"),
        }
        material.uniforms.texture_grass.value.wrapS = THREE.RepeatWrapping;2
        material.uniforms.texture_grass.value.wrapT = THREE.RepeatWrapping;
        var displacement = new Float32Array(200000);3
        for(var i = 0; i < 200000; i++){
            displacement[i]=0;
        }
        //丘陵
        displacement = addmoutain(displacement,50,170,30,30);
        displacement = addmoutain(displacement,100,30,30,30);
        displacement = addmoutain(displacement,150,270,30,30);
        displacement = addmoutain(displacement,200,30,30,30);
        displacement = addmoutain(displacement,250,170,30,30);
        displacement = addmoutain(displacement,300,30,30,30);
        
        geometry.addAttribute(displacement, new THREE.BufferAttribute(displacement, 1));4
        plane = new THREE.Mesh( geometry, material );
        plane.rotation.x = -1;
        scene.add( plane );
    }

1.利用PlaneBufferGeometry起了一块尺寸200X200的面板,后面的400,400是x轴y轴细分的三角形个数

技术分享图片

2.为着色器材质提供贴图纹理,并设置repeat(贴图尺寸必须为2的n次幂)

3.因为plane被细分了(400 x 400,实际可能不是160000个顶点,就像两个三角形4个顶点,4个三角形却只有6个顶点,因为共用的问题)产生n个顶点,所以我们要提供相对应数量的数据供顶点使用;

其实这些数据是后面要传给着色器,替换position.z的,addmoutain函数的作用是以第m个点为中心,周围radius半径内的点按一定规则升降(距离中心点越近,那么高度越高,即值越大)

该函数如下:

    function addmoutain(arr,row,col,radius,height){
        var colstart = (col-radius+1)>0?(col-radius+1):1;
        var colend = (col+radius)>400?400:(col+radius);
        var rowstart = (row -radius + 1)>0?(row -radius + 1):1;
        var rowend = (row+radius)>400?400:(row+radius);
        for(var i = rowstart;i<=rowend;i++){
            for(var j = colstart;j<=colend;j++){
                var distance = Math.sqrt(Math.pow((row-i),2) + Math.pow((col-j),2));
                if(distance < radius){
                    var percent = (radius - distance)/radius;
                    var h = Math.sin(percent * Math.PI/2) * height/2;
                    arr[(i-1)*400+j-1] = h;
                }
            }
        }
        return arr;
    }

4.将写好的顶点z轴数据值传给geometry。

下面来看两个着色器:

vs:

<script id="vertex-shader-2" type="x-shader/x-vertex">
    attribute float displacement;
    varying vec2 vUv;
    varying float pt;
    void main(){
        vUv = uv * 4.0; 
        pt = displacement;
        gl_Position = projectionMatrix * modelViewMatrix * vec4(position.xy,displacement, 1);
    }
</script>

通过uv * 4.0 实现贴图repeat,position.z值用displacement代替,pt(varying类型)用于后续fs计算透明度的依据

fs:

<script id="fragment-shader-2" type="x-shader/x-fragment">
    uniform sampler2D texture_grass;
    varying vec2 vUv;
    varying float pt;

    void main(){
        vec4 color = texture2D(texture_grass, vUv);
        float percent = 1.0;
        if(pt > 0.5){
            percent = pt / 15.0;
        }
        gl_FragColor = color * percent;
    }
</script>

因为最高的高度为15.0;所以pt/15.0实现的山丘的颜色透明过渡。

 

这样,就写完了,后续考虑利用该种方法画一个围棋盘,敬请期待!

 

着色器应用贴图纹理并修改顶点实现“平地起丘陵”

原文:https://www.cnblogs.com/eco-just/p/11349480.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!