three.js 地形纹理混合

地形生成一般使用高度图, 而高度图的生成能够使用绘图工具,或者经过分形算法生成,例如square-diamond,  fbm方法。 这里采用简单求平均值+随机波动的方法。 对于一个2^n+1  *  2^n+1 的网格, 中心点的高度是四角点的平均值加随机偏移, 边上中点的高度值是边两端点的平均值加随机偏移。 接着将偏移的幅度缩小, 计算四个较小方块的顶点的高度值。 这样随机生成了高度。 接着构造地形, 地形分割成2^n * 2^n 块, 这样顶点就有 2^n+1  *  2^n+1 个      var geo = new THREE.PlaneGeometry(3, 3, WIDTH-1, HEIGHT-1); 上面生成了每一个顶点的高度, 须要将高度值传入shader中, 能够直接修改geo中的全部顶点的z值,来修改高度。 咱们能够根据地形的高度来混合纹理,例如比较高的位置为石块, 而低洼处为草地, 这个纹理的混合。 c2 = mix(c0, c1, (height-minHeight)/(maxHeight-minHeight)) c0是第一张纹理获取的颜色, c1是第二张纹理获取的颜色, 而minHeight maxHeight 是整个地形高度的方位, height是当前高度。 c2 就是混合后的颜色。 shader以下,两张纹理, 顶点在平面坐标中的位置,  纹理坐标采用顶点的x, y 坐标的小数部分。     uniform sampler2D texture_grass;     uniform sampler2D texture_rock;     uniform float maxHeight;     uniform float minHeight;     varying vec3 pos; void main( void ) {         vec2 uv0;                  uv0.x = fract(pos.x);         uv0.y = fract(pos.y);                  vec4 c0 = texture2D(texture_grass, uv2);         vec4 c1 = texture2D(texture_rock, uv2);         vec4 c2 = mix(c0, c1, (pos.z-minHeight)/(maxHeight-minHeight));         gl_FragColor = c2;       } 而材质:     var pmat = new THREE.ShaderMaterial({         uniforms:{             texture_grass:{type:'t', value:0, texture:THREE.ImageUtils.loadTexture("grassa512.bmp")},             texture_rock:{type:'t', value:1, texture:THREE.ImageUtils.loadTexture("dirt512.bmp")},                    maxHeight:{type:'f', value:0},             minHeight:{type:'f', value:1},         },         attributes:{         },         vertexShader: document.getElementById("vert").textContent,         fragmentShader: document.getElementById("frag").textContent,         //wireframe:true,          }); 其中纹理的值 0, 1 表示GPU内部的纹理编号, 这个数量受硬件限制。 顶点shader     varying vec3 pos; void main( void ) {         pos = position.xyz;         gl_Position = projectionMatrix * modelViewMatrix * vec4(position.xyz, 1); }
相关文章
相关标签/搜索