首页 > [原]three.js 地形纹理混合

[原]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);



}















































作者:liyong748 发表于2012/9/17 21:58:21 原文链接
阅读:786 评论:0 查看评论

转载于:https://www.cnblogs.com/liyonghelpme/archive/2012/09/17/4273567.html

更多相关:

  • 2020.2.5 疫情持续蔓延,在家无聊便解决标题所述问题。 若纹理加载是initializeGL()中,而在QtOpenGL的initializeGL()在程序运行时只运行一次,如果我的图像是通过上一步得到而不保存在本地,那么更换纹理变成了一个棘手的问题。 我曾尝试用extern、static等方法在类与类之间传递数据,但是依然...

  • 为了能够把纹理映射(Map)到三角形上,我们需要指定三角形的每个顶点各自对应纹理的哪个部分。这样每个顶点就会关联着一个纹理坐标(Texture Coordinate),用来标明该从纹理图像的哪个部分采样(译注:采集片段颜色)。之后在图形的其它片段上进行片段插值(Fragment Interpolation)。 纹理坐标在x和y轴上,...

  • Blender纹理基础学习视频教程 CGCookie – Fundamentals of Texturing in Blender Blender纹理基础学习视频教程 CGCookie – Fundamentals of Texturing in Blender Blender纹理基础学习视频教程 CGCookie –...

  •  风格化手绘纹理包 CGTrader – Stylized Mix Vol. 41 – Hand Painted Texture Pack CGTrader–风格化混合第41卷–手绘纹理包 大小解压后:343M 信息: 7种风格化材料的包装。格式:. png .uproject .unitypackage 特点: 7种独特...