threejs_着色器语言

简介: threejs的着色器语言

WebGL绘制一个点

  • 超文本语言HTML
  • 脚本语言Javascript
  • Canvas画布
  • 着色器语言GLSL ES
  • WebGL API
    绘制点像素点的html
   <!DOCTYPE html>
   <html lang="en">
   <head>
       <meta charset="UTF-8">
       <title>使用WebGL绘制一个点</title>
    </head>
   <body>
    <!--canvas标签创建一个宽高均为500像素,背景为蓝色的矩形画布-->
   <canvas id="webgl" width="500" height="500" style="background-color: blue"></canvas>


  <script>
     //通过getElementById()方法获取canvas画布
      var canvas=document.getElementById('webgl');
     //通过方法getContext()获取WebGL上下文
     var gl=canvas.getContext('webgl');

     //顶点着色器源码
      var vertexShaderSource = '' +
         'void main(){' +
         //给内置变量gl_PointSize赋值像素大小
        '   gl_PointSize=50.0;' +
        //顶点位置,位于坐标原点
         '   gl_Position =vec4(0.0,0.0,0.0,1.0);' +
        '}';

     //片元着色器源码
   var fragShaderSource = '' +
         'void main(){' +
        //定义片元颜色
        '   gl_FragColor = vec4(1.0,0.0,0.0,1.0);' +
         '}';

      //初始化着色器
    var program = initShader(gl,vertexShaderSource,fragShaderSource);
     //开始绘制,显示器显示结果
    gl.drawArrays(gl.POINTS,0,1);

     //声明初始化着色器函数
     function initShader(gl,vertexShaderSource,fragmentShaderSource){
   
   
          //创建顶点着色器对象
          var vertexShader = gl.createShader(gl.VERTEX_SHADER);
           //创建片元着色器对象
          var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
         //引入顶点、片元着色器源代码
          gl.shaderSource(vertexShader,vertexShaderSource);
          gl.shaderSource(fragmentShader,fragmentShaderSource);
         //编译顶点、片元着色器
          gl.compileShader(vertexShader);
          gl.compileShader(fragmentShader);

          //创建程序对象program
          var program = gl.createProgram();
          //附着顶点着色器和片元着色器到program
         gl.attachShader(program,vertexShader);
         gl.attachShader(program,fragmentShader);
         //链接program
         gl.linkProgram(program);
        //使用program
         gl.useProgram(program);
        //返回程序program对象
         return program;
      }
  </script>
  </body>
  </html>

演示效果
image.png

创建Canvas画布

Canvas画布,显示WebGL的渲染结果,canvas元素和div等元素一样是HTML的一个元素,只是Canvas画布具有2D和3D绘图功能

<!--canvas标签创建一个宽高均为500像素,背景为蓝色的矩形画布-->
<canvas id="webgl" width="500" height="500" style="background-color: blue"></canvas>

通过JavaScript获取上面创建的Canvas元素返回一个Canvas对象。

//通过getElementById()方法获取canvas画布对象
var canvas= document.getElementById('webgl')

canvas对象也可以不通过<canvas>标签创建,然后id方式获取,也可以通过DOM直接创建

//通过getElementById()方法获取canvas画布对象
var canvas = document.createElement('canvas');

Canvas对象方法.getContext()

HTML的Canvas元素提供了2D和3D绘图两种功能,平时程序员之间交流所说的Canvas一词就是指Canvas的2D绘图功能,通过Canvas元素实现的3D绘图功能,也就是所谓的WebGL,或者说WebGL依赖于Canvas元素实现。
执行canvas.getContext('2d')返回对象具有一系列绘制二维图形的方法,比如绘制直线、圆弧等API。

//通过方法getContext()获取Canvas 2D绘图上下文
var gl=canvas.getContext('2d');
c.moveTo(0,0);//直线起点坐标
c.lineTo(50,50);//直线第2个点坐标
c.lineTo(0,100);//直线第3个点坐标
c.stroke();//把点连成直线绘制出来

执行canvas.getContext('webgl');返回对象具有一系列绘制渲染三维场景的方法,也就是WebGL API

//通过方法getContext()获取WebGL上下文
var gl=canvas.getContext('webgl');
...
//调用WebGL API绘制渲染方法drawArrays
gl.drawArrays(gl.POINTS,0,1);

着色器语言GLSL ES

//顶点着色器源码
var vertexShaderSource = '' +
    'void main(){' +
    //给内置变量gl_PointSize赋值像素大小
    '   gl_PointSize=20.0;' +
    //顶点位置,位于坐标原点
    '   gl_Position =vec4(0.0,0.0,0.0,1.0);' +
    '}';

片元着色器定义了点的渲染结果像素的颜色值

//片元着色器源码
var fragShaderSource = '' +
    'void main(){' +
    //定义片元颜色
    '   gl_FragColor = vec4(1.0,0.0,0.0,1.0);' +
    '}';

gl_PointSize、gl_Position、gl_FragColor都是内置变量

通过程序可以看出来顶点着色器源码vertexShaderSource、片元着色器源码fragShaderSource,都是只有一个主函数main,也就是入口函数。

给内置变量gl_Position赋值vec4(0.0,0.0,0.0,1.0),也就是设置顶点位置坐标,vec4代表的是一种数据类型, 在这里可以理解为vec4()是一个可以构造出vec4类型数据的构造函数,前三个参数表示顶点坐标值xyz。

给内置变量gl_FragColor赋值vec4(1.0,0.0,0.0,1.0),也就是设置会在屏幕上显示的像素的颜色,vec4()构造函数 前三个参数,表示颜色RGB值,最后一个参数是透明度A。在WebGL着色器中颜色值使用[0,1]区间表示。

你可以通过改变WebGL着色器代码内置变量gl_PointSize、gl_Position、gl_FragColor测试WebGL渲染效果的变化。

  1. gl_PointSize=50.0改为gl_PointSize=10.0,观察屏幕点的大小变化
    image.png

image.png

  1. gl_Position =vec4(0.5,0.5,0.0,1.0)改为gl_Position =vec4(0.5,-0.8,0.0,1.0),观察屏幕点的位置变化
    image.png

image.png

  1. gl_FragColor=vec4(0.0,1.0,1.0,1.0)更改为gl_FragColor = vec4(0.0,0.0,1.0,1.0)

image.png

image.png

理解gl_FragColor=vec4(r,g,b,alpha)

WebGL API

WebGL API指的就是gl=canvas.getContext('webgl')返回对象gl的一系列绘制渲染方法,通过WebGL API可以把一个三维场景绘制渲染出来。比如上面代码中gl.createShader()、gl.shaderSource()、gl.drawArrays()等方法就是WebGl API

初始化着色器函数initShader()

//声明初始化着色器函数
function initShader(gl,vertexShaderSource,fragmentShaderSource){
   
   
    //创建顶点着色器对象
    var vertexShader = gl.createShader(gl.VERTEX_SHADER);
    //创建片元着色器对象
    var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    //引入顶点、片元着色器源代码
    gl.shaderSource(vertexShader,vertexShaderSource);
    gl.shaderSource(fragmentShader,fragmentShaderSource);
    //编译顶点、片元着色器
    gl.compileShader(vertexShader);
    gl.compileShader(fragmentShader);

    //创建程序对象program
    var program = gl.createProgram();
    //附着顶点着色器和片元着色器到program
    gl.attachShader(program,vertexShader);
    gl.attachShader(program,fragmentShader);
    //链接program
    gl.linkProgram(program);
    //使用program
    gl.useProgram(program);
    //返回程序program对象
    return program;
}

绘制方法gl.drawArrays()

gl.drawArrays()方法的作用就是通知GPU执行着色器代码,然后根据着色器代码在Canvas画布上进行渲染绘制。

着色器代码放在script标签中

<!-- 顶点着色器源码 -->
<script id="vertexShader" type="x-shader/x-vertex">
  void main() {
   
   
    //给内置变量gl_PointSize赋值像素大小
    gl_PointSize=20.0;
    //顶点位置,位于坐标原点
    gl_Position =vec4(0.0,0.0,0.0,1.0);
  }
</script>
<!-- 片元着色器源码 -->
<script id="fragmentShader" type="x-shader/x-fragment">
  void main() {
   
   
    gl_FragColor = vec4(1.0,0.0,0.0,1.0);
  }
</script>
//顶点着色器源码
var vertexShaderSource = document.getElementById('vertexShader').innerText;
//片元着色器源码
var fragShaderSource = document.getElementById('fragmentShader').innerText;
//初始化着色器
var program = initShader(gl,vertexShaderSource,fragShaderSource);
目录
相关文章
|
7月前
|
API C语言 图形学
webgl学习笔记4_初识着色器语言ES GLSL
webgl学习笔记4_初识着色器语言ES GLSL
54 0
|
存储 编译器 图形学
使用Unity在材质球上实现绘画:详细解释每一行Shader代码!
使用Unity在材质球上实现绘画:详细解释每一行Shader代码!
192 0
|
C# C语言 计算机视觉
WPF开发:高阶着色器语言(HLSL)
WPF开发:高阶着色器语言(HLSL)
237 0
着色器,头文件在“纹理””那节随笔中
着色器,头文件在“纹理””那节随笔中
|
小程序 编译器 C语言
OpenGL学习笔记(十):深入学习和理解着色器
OpenGL学习笔记(十):深入学习和理解着色器
OpenGL学习笔记(十):深入学习和理解着色器
|
存储 图形学
【Aladdin Unity3D Shader编程】之四 贴图纹理
关于纹理贴图介绍 纹理坐标也叫UV坐标,UV坐标都是0~1,并不是我们所理解的像素坐标,相当于是一个百分比。 编写shader映射纹理 将纹理的颜色取代漫反射的颜色 Shader "AladdinShader/11 Single Texture Shader" ...
1757 0
|
图形学
【Aladdin Unity3D Shader编程】之三 光照模型(二)
高光反射模型 Specular=直射光*pow(cosθ,高光的参数) θ:是反射光和视野方向的夹角 编写高光反射Shader Shader "AladdinShader/07 Specular Vertex Shader" { Prop...
1590 0
|
图形学
【Aladdin Unity3D Shader编程】之二 光照模型(一)
光照模型 光照模型就是一个公式,使用这个公式来计算在某个点的光照效果。 在标准光照模型里面,我们把进入摄像机的光分为下面四个部分: * 自发光 类似生活中的萤火虫等自己能够发光 * 高光反射 类似生活中的镜子,近似认为百分百反射出去 * 漫反射 类似生活中的光照射到墙壁上、桌子上的反光不会百分百反射出去,各个方向都会反射。
1776 0
《OpenGL编程指南(原书第9版)》——第2章 2.0着色器基础
本节书摘来自华章计算机《OpenGL编程指南(原书第9版)》一书中的第2章,第2.1节,作者:(美)约翰·克赛尼希(John Kessenich)著, 更多章节内容可以访问云栖社区“华章计算机”公众号查看。
1340 0