zoukankan      html  css  js  c++  java
  • 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);

    }






















  • 相关阅读:
    第一个EJB示例
    Visual Studio/Eclipse调用 JBoss5中的WebService
    TomEE
    eclipse 启动时使用指定的jdk
    Haskell示例
    安装VS2010 SP1后,再安装mvc3
    Mysql报错为1366的错误的时候
    Java8-如何将List转变为逗号分隔的字符串
    IDEA连接mysql又报错!Server returns invalid timezone. Go to 'Advanced' tab and set 'serverTimezone' prope
    he last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
  • 原文地址:https://www.cnblogs.com/liyonghelpme/p/4273790.html
Copyright © 2011-2022 走看看