zoukankan      html  css  js  c++  java
  • three中的着色器示例

    其实在3D引擎/库的帮助下,我们做webgl开发的难度已经很大大地降低了,熟悉相关API的话,开发一个简单的3D程序可以说是很轻松的事情。

    在我看来,webgl的核心就是着色器(顶点着色器、片元着色器),这两者决定了如何在屏幕上绘制出我们想要的效果。所以,无论你是刚入门的3D开发者(我也是刚刚探索3D领域)还是该领域的资深老鸟,对着色器的了解都是至关重要的。

    我们一般的软件开发(例如一些管理系统、商城小程序),诸如这些业务逻辑性非常强的程序,都是依靠CPU的高速运算,而做WebGL(3D开发),我们写的程序代码是要跑在GPU上的,因为对于绘图能力来说,GPU是远远高于CPU的,所以,我们做的就是GPU编程了。

    今天,就以一个demo来体会一下,three.js中如何编写自定义的着色器并运用到mesh材质上的。

    (首先默认大家都已经学会three.js的一些基本操作,例如将一个three.js内置的面板PlaneGeometry放到场景中)

    一、添加plane

        function addplane(){
            var planeGeometry = new THREE.PlaneGeometry(300,150)
            var meshMaterial = new THREE.MeshPhongMaterial({
                color: 0xfff000 * Math.random()
            });
            var plane = new THREE.Mesh(planeGeometry,meshMaterial);
            scene.add(plane);
        }

    这个函数将会往场景中添加一个Plane,效果如下:

    ok,这就是一个plane了。

    二、着色器代码

    <!-- 顶点着色器 -->
    <script id="vertex-shader" type="x-shader/x-vertex">
    void main(){ gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0); } </script>
    <!-- 顶点着色器 -->
    <script id="fragment-shader-3" type="x-shader/x-fragment">
        uniform vec2 resolution;
          uniform float scale;
    
    
        vec2 rand(vec2 pos){
            return fract( 0.00005 * (pow(pos+2.0, pos.yx + 1.0) * 22222.0));
        }
    vec2 rand2(vec2 pos){
    return rand(rand(pos)); } float softnoise(vec2 pos, float scale){ vec2 smplpos = pos * scale; float c0 = rand2((floor(smplpos) + vec2(0.0, 0.0)) / scale).x; float c1 = rand2((floor(smplpos) + vec2(1.0, 0.0)) / scale).x; float c2 = rand2((floor(smplpos) + vec2(0.0, 1.0)) / scale).x; float c3 = rand2((floor(smplpos) + vec2(1.0, 1.0)) / scale).x; vec2 a = fract(smplpos); return mix( mix(c0, c1, smoothstep(0.0, 1.0, a.x)), mix(c2, c3, smoothstep(0.0, 1.0, a.x)), smoothstep(0.0, 1.0, a.y)
    ); }
    void main(void){ vec2 pos = gl_FragCoord.xy / resolution.y; pos.x += time * 0.1; float color = 0.0; float s = 1.0; for(int i = 0; i < 8; i++){ color += softnoise(pos+vec2(i)*0.02, s * 4.0) / s / 2.0; s *= 2.0; } gl_FragColor = vec4(color); } </script>

    顶点着色器中,进行了一系列的矩阵变换,将图形的顶点转换为屏幕上的像素点;

    模型矩阵: 将顶点从局部坐标系转换到世界坐标系中;

    视图矩阵: 将顶点从世界坐标转化到视图坐标系下;

    投影矩阵: 将顶点从视图坐标系转换到规范立方体中(即屏幕中);

    局部坐标系(模型/物体本身)----->世界坐标系----->视图坐标系----->屏幕。

    片元着色器中,因为片元着色器是针对顶点着色器输出的顶点数据 (gl_Position)进行逐点绘制的,所以该着色器就是对每个点赋予一个颜色值,针对上面的片元着色器,他接受外界赋予的变量(uniform类型)。

    三、着色器材质

    下面我们就用两种着色器来生成一个材质。

        //创建ShaderMaterial纹理的函数
        function createMaterial(vertexShader, fragmentShader) {
            var vertShader = document.getElementById(vertexShader).innerHTML; //获取顶点着色器的代码
            var fragShader = document.getElementById(fragmentShader).innerHTML; //获取片元着色器的代码
    
            //配置着色器里面的attribute变量的值
            var attributes = {};
            //配置着色器里面的uniform变量的值
            var uniforms = {
                scale: {type: 'f', value: 10},
                resolution: {type: "v2", value: new THREE.Vector2(window.innerWidth, window.innerHeight)}
            };
            var meshMaterial = new THREE.ShaderMaterial({
                uniforms: uniforms,
                defaultAttributeValues : attributes,
                vertexShader: vertShader,
                fragmentShader: fragShader,
                transparent: true
            });
            return meshMaterial;
        }

    四、利用shader材质重新绘制plane

        function addplane(){
            var planeGeometry = new THREE.PlaneGeometry(300,150)
            var meshMaterial = createMaterial("vertex-shader", "fragment-shader-3");
            var plane = new THREE.Mesh(planeGeometry,meshMaterial);
            scene.add(plane);
        }

    效果:

     五、其他着色器效果示例

  • 相关阅读:
    测试工具知识大集合
    滴滴,好未来,百度,快手,头条测试&测试开发岗面经(附面试题)
    做数据必知的十本书,你读过几本?
    如何有效延长假期?
    当程序猿第那几年!
    自动化测试中的那些误解和偏见
    北京VS上海:“活着为了工作”还是“工作为了生活”?
    程序员国庆相亲图鉴
    有赞精准测试实践
    IE中的文档兼容性
  • 原文地址:https://www.cnblogs.com/eco-just/p/11181210.html
Copyright © 2011-2022 走看看