three.js 着色器(08)

一、什么是着色器(shader)

  • 从3D图形学历史的角度来讲,他的确曾经扮演过和它名字一样的角色,即二进制码。
  • 在进一步理解,如果将three.js比作粗语言的话,那么着色器就是汇编语言,显然c语言的实现最终都是由汇编语言完成的。
  • 所以着色器有比three,js更强大的功能,虽然three.js的功能已经很强大了。

二、着色器的分类

无论是在OpenGL、openes,还是dx中,着色器都分为 顶点着色器片元着色器

  1. 顶点着色器 :就是对顶点进行操作。例如改变顶点的位置和顶点的大小。
  2. 片元着色器 :通俗讲就是用来定义屏幕中显示的各个点的颜色。

注:每一个图元都会先执行顶点着色器 然后再执行片元着色器。

三、着色器CPU和GPU之间的关系

(1)CPU和GPU的比较

  • 计算机的CPU在运行代码额的时候,是一条一条代码顺序执行的。
  • CPU的串行运算方式能够满足日常中大多数的串行工作,但是在图形领域却速度非常慢。
  • GPU是并行的。

(2)总结

我们的shader程序就是在显卡中运行的,针对每一个顶点或者片元(像素),显卡将运行一次shader程序。每个顶点或者片元的shader程序在显卡中都是并行运行的,所以速度极快。

四、着色器的设备坐标系

  • 一旦你的顶点坐标已经在顶点着色器中处理过,他们就应该是标准化设备坐标了
  • 标准化设备坐标是一个x、y、z值在-1.0到1.0的一小段空间。
  • 任何落在范围外的坐标都会被丢弃/裁剪,不会显示在你的屏幕上。
  • z坐标至今尚未标准化。
    在这里插入图片描述

五、着色器的一些语法

1、着色器中的变量

​ JavaScript向着色器传递数据由变量来完成。根据变量的作用范围和修改频率分为 属性变量一致变量和易变变量

变量的作用是在JavaScript和shader之间传递数据

  • 属性变量:(attributes变量)一般用来保存每一个顶点独有的数据,如每一个顶点的位置。

    • attribute vec3 pos;  //定义
      
  • 一致变量:(uniform变量)在一个帧渲染的过程中保持不变的变量,例如光的照射方向,它是所有顶点都共有的数据,所以才叫一致变量。

    • uniform vec3 a;
      
  • 易变变量:(varying变量):就是比较容易变化的变量,一般用来在顶点着色器和片元着色器之间传递数据。

    • varying vec3 a;
      

在这里插入图片描述

六、一个栗子

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>着色器</title>
    <style>
        body{
     
     
            color: white;
            text-align:center;
            background-color: black;
            margin: 0;
            overflow: hidden;
        }
        #info{
     
     
            position: absolute;
            top: 0px;
            width: 100%;
            padding:5px;
        }
        a{
     
     
            color: #ffffff;
        }
        #oldie a{
     
     
            color: #da0;
        }
    </style>
    <script src="../three.js"></script>
    <script src="../lib/stats.min.js"></script>
    <script src="../lib/Detector.js"></script>
    <!-- 定义着色器 -->
        <!-- 顶点着色器 -->
    <script type="x-shader/x-vertex" id="vertexShader">
        void main(){
     
     
            //输出的值是在-1.0-1.0之间
            gl_Position = vec4(position,1.0);

        }
    </script>
        <!-- 片元着色器 -->
    <script type="x-shader/x-fragment" id="fragmentShader">
        void main(){
     
     
            gl_FragColor = vec4(1.0,0.6,0.9,1.0);
        }
    </script>
</head>
<body>
    <div id="container"></div>
    <div id="info">shader</div>

    <!-- js的一些代码 -->
    <script>
        if(!Detector.webgl) Detector.addGetGLMessage();
        var container,stats;
        var camera,scene,renderer;
        var uniforms,material,mesh;
        var mouseX = 0,mouseY = 0,lat = 0,lon = 0,phy=0,theta=0;

        var windowHalfX = window.innerWidth/2;
        var windowHalfY = window.innerHeight/2;

        init();
        animate();

        function init(){
     
     
            container = document.getElementById("container");
            camera = new THREE.OrthographicCamera(-1,1,1,-1,0,1);
            camera.position.z =0.3;
            scene = new THREE.Scene();

            material = new THREE.ShaderMaterial( {
     
     
                vertexShader: document.getElementById( 'vertexShader' ).textContent,
                fragmentShader: document.getElementById( 'fragmentShader' ).textContent
 
            } );
 
            mesh = new THREE.Mesh( new THREE.PlaneGeometry( 1.0, 1.0 ), material );
            scene.add( mesh );
 
            renderer = new THREE.WebGLRenderer();
            container.appendChild( renderer.domElement );
 
            stats = new Stats();
            stats.domElement.style.position = 'absolute';
            stats.domElement.style.top = '0px';
            container.appendChild( stats.domElement );
 
            onWindowResize();
 
            window.addEventListener( 'resize', onWindowResize, false );

        }

        function onWindowResize( event ) {
     
     
 
            renderer.setSize( window.innerWidth, window.innerHeight );
 
        }
 
        //
 
        function animate() {
     
     
 
            requestAnimationFrame( animate );
 
            render();
            stats.update();
 
        }
 
        function render() {
     
     
            renderer.render( scene, camera );
        }
 
    </script>
</body>
</html>

猜你喜欢

转载自blog.csdn.net/weixin_48931875/article/details/114585456