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

来张效果图先:

var plane; function addpanel(){ var axesHelper = new THREE.AxesHelper( 400 ); scene.add( axesHelper ); var geometry = new THREE.PlaneBufferGeometry( 200,200,400, 400); 1var 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); 3for(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:

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

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

【着色器应用贴图纹理并修改顶点实现“平地起丘陵”】这样,就写完了,后续考虑利用该种方法画一个围棋盘,敬请期待!

转载于:https://www.cnblogs.com/eco-just/p/11349480.html

    推荐阅读