最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • webgl初章:进入3D世界

    正文概述 掘金(yancy__)   2020-12-25   421

    终于要进入到webgl的世界了。还真是有点小激动。在之前的文章里,跟大家详细分享了下 canvas 的相关内容。下面会有这几篇文章的链接,有兴趣的小伙伴可以自行查阅。

    canvas入门篇 一

    canvas入门篇 二

    canvas实战篇

    准备好了吗?接下来让我们开启奇幻旅程,进入 3D 的世界。

    1. 认识3D

    首先我们要介绍的是几个概念,这是我们要进入到 3D 不可或缺的内容。认识一下它们吧。

    1.1 视点,视线,目标点,上方向

    这几个概念在webgl中属于最常见的内容。

    • 视点:可以简易的理解为眼睛,也叫观察点
    • 目标点:可以理解为我们要看的物体(任何物体)
    • 上方向:头顶的方向。

    实际生活中,我们的目光总是以我们的眼睛为起始点,到达我们想要看到的物体,同时,我们观察的角度不同,物体也会呈现不一样的形态。以一张图说明吧。

    webgl初章:进入3D世界

    如此几个内容,创建出了3D世界的基本显示模型,由此可见其重要程度。后面我们也会说到如何在 webgl 中设定这几个内容。也会有的小伙伴把视点称为相机目标点称为画布。其实是一样的道理。按照自己的理解记忆就好。

    1.2 可视范围

    可视范围指的是我们所能看到的最大范围。如:一般情况下我们看不到自己身后的事物。

    众所周知,三维物体具有深度的概念。在我们的理解中,深度就是 z 轴。

    虽然我们可以将物体放置在三维空间中的任何位置,但是在webgl中,可视范围之外的物体是不被绘制的,这也是为了节省开销。

    1.3 可视空间

    水平视角、垂直视角、可视深度 定义了可视空间的概念。

    可视空间分为两种。

    • 正射投影:与物体的远近无关,通常用在建筑设计和建模上。

    webgl初章:进入3D世界

    • 透视投影:我们平时观察的真实世界都是透视投影。更有深度的感觉。

    webgl初章:进入3D世界

    1.3 着色器

    如果想渲染 3d 图形,就需要经过一系列的步骤,这些步骤称为渲染管线。在开发 webgl 程序时,我们就需要通过着色器语言跟GPU进行沟通,用来设定我们需要渲染和显示的图形。

    由此可见:着色器是编写webgl时最重要的一点(没有之一)。我们之所以能生成并操作3d图像,都是因为着色器在起作用。webgl中着色器分为两种。顶点着色器和片元着色器

    1.3.1 顶点着色器

    这里的顶点代表的是组成物体的每一个点。

    顶点着色器的功能主要是将位置数据经过矩阵变换、计算光照之后生成顶点颜色、变换纹理坐标。并将生成的数据输出到片元着色器。

    1.3.2 片元着色器

    片元着色器的作用是将光栅化阶段生成的每个片元,计算出每个片元的最终元素。

    注:

    由于着色器内容比较重要,这里我们先引入这两个概念,先简单理解就可以,后面专门对着色器进行分享。

    2. 绘制图形

    2.1 获取绘图上下文

    了解了第一小节的内容之后,我们开始进入到webgl开发实战中。

    还记得canvas中第一步需要干什么吗?

    没错,需要获取 canvas 元素和绘图上下文。webgl 开发也不例外,也需要首先获取元素和绘图上下文。形如下方代码所示:

    // <canvas id="canvas"></canvas>  canvas的dom结构
    
    // 获取canvas元素
    const ctx = document.getElementById('canvas') 
    
    // 获取绘图上下文
    const gl = ctx.getContext('webgl')
    

    2.2 初始化着色器

    1. 编写着色器代码

    获取到绘图上下文之后,我们需要初始化webgl 的着色器了,着色器代码是以字符串的形式嵌入到渲染程序中,所以我们需要编写两个着色器的字符串。

    // 顶点着色器
    const VERTEX_SHADER = '' +
          'void main(){' +
          ' gl_Position = vec4(0.0,0.0,0.0,1.0);' +
          ' gl_PointSize = 15.0;' +
          '}' +
          ''
    // 片元着色器
    const FRAGMENT_SHADER = '' +
          'void main() {' +
          ' gl_FragColor = vec4(1.0,0.0,0.0,1.0);' +
          '}' +
          ''
    

    两个着色器代码都是以字符串的形式存在,并在执行渲染时嵌入到渲染流程内。

    说明:

    • void main() {}: 创建一个主函数。
    • gl_Position: 指定绘制的坐标,接收一个拥有4个浮点分量的vec4数据。分别代表 x,y,z,w数据
    • gl_PointSize: 表示要绘制图形的尺寸大小。
    • gl_FragColor: 定义图形颜色,1.0 0.0 0.0 1.0 分别代表r g b a
    2. 创建着色器

    当然,只是编写完着色器代码依然不能完成渲染工作,接下来我们就需要将着色器添加到渲染流程内

    // 首先创建顶点和片元着色器
    
    // 创建顶点着色器
    const vertexShader = gl.createShader(gl.VERTEX_SHADER);
    
    // 创建片元着色器
    const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    
    3. 着色器编译

    完成上述两步之后,我们就需要将着色器代码添加到着色器中。看下例子。

    // 将顶点着色器代码添加到顶点着色器中
    gl.shaderSource(vertexShader, VERTEX_SHADER);
    
    // 将片元着色器代码添加到片元着色器中
    gl.shaderSource(fragmentShader, FRAGMENT_SHADER);
    
    // 添加完成后,需要编译着色器
    gl.compileShader(vertexShader);
    gl.compileShader(fragmentShader);
    
    4. 创建 program

    完成编译之后,我们需要将着色器添加到渲染程序中。

    const program = gl.createProgram();
    
    // 将着色器添加到程序中
    gl.attachShader(program, vertexShader);
    gl.attachShader(program, fragmentShader);
    
    // 关联program
    gl.linkProgram(program);
    
    // 使用program
    gl.useProgram(program);
    
    5. 绘制图形

    完成上述步骤之后,就可以绘制我们的图形了。这里我们以一个点为例。在画布上绘制一个点出来。

    gl.drawArrays(gl.POINTS, 0, 1);
    

    此时就可以打开页面,看到我们绘制的这个点了。

    总结代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>webgl初章:进入3D世界</title>
    </head>
    <body>
    
    <canvas id="canvas"></canvas>
    
    <script>
      const ctx = document.getElementById('canvas');
    
      const gl = ctx.getContext('webgl');
    
      // 顶点着色器
      const VERTEX_SHADER = '' +
        'void main(){' +
        ' gl_Position = vec4(0.0,0.0,0.0,1.0);' +
        ' gl_PointSize = 15.0;' +
        '}' +
        ''
    
      // 顶点着色器
      const FRAGMENT_SHADER = '' +
        'void main() {' +
        ' gl_FragColor = vec4(1.0,0.0,0.0,1.0);' +
        '}' +
        ''
    
      // 创建顶点和片元着色器
      const vertexShader = gl.createShader(gl.VERTEX_SHADER);
      const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    
      // 将顶点着色器代码添加到顶点着色器中
      gl.shaderSource(vertexShader, VERTEX_SHADER);
    
      // 将片元着色器代码添加到片元着色器中
      gl.shaderSource(fragmentShader, FRAGMENT_SHADER);
    
      // 添加完成后,需要编译着色器
      gl.compileShader(vertexShader);
      gl.compileShader(fragmentShader);
    
      const program = gl.createProgram();
    
      // 将着色器添加到程序中
      gl.attachShader(program, vertexShader);
      gl.attachShader(program, fragmentShader);
    
      // 关联program
      gl.linkProgram(program);
      // 使用program
      gl.useProgram(program);
    
      // 绘制一个点
      gl.drawArrays(gl.POINTS, 0, 1);
    
    </script>
    </body>
    </html>
    

    由于是初章,内容会比较少。今天的内容就先分享到这里,Bye~


    起源地下载网 » webgl初章:进入3D世界

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元