着色器应用贴图纹理并修改顶点实现“平地起丘陵”
来张效果图先:
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
推荐阅读
- Docker应用:容器间通信与Mariadb数据库主从复制
- JS中的各种宽高度定义及其应用
- 人生感悟记#环境仪器宋庆国成长记#072
- 标签、语法规范、内联框架、超链接、CSS的编写位置、CSS语法、开发工具、块和内联、常用选择器、后代元素选择器、伪类、伪元素。
- 视频转换器哪种好用()
- NeuVector 会是下一个爆款云原生安全神器吗()
- 操作系统|[译]从内部了解现代浏览器(1)
- 探索免费开源服务器tomcat的魅力
- java之static、static|java之static、static final、final的区别与应用
- Android7.0|Android7.0 第三方应用无法访问私有库