Three.js 浅尝:基础3D渲染(一)

照例在开头终归得感慨一番“白驹过隙”“日月如梭”种种,平日忙着为实验室打杂、看书、放羊,回过头来距离上一篇博客也过去了半年时光。
趁着当下手头的项目暂告一段落还是抓紧时间多写几篇罢。

博客后续内容链接:Three.js 浅尝:基础3D渲染(二)

引言

Three.js 在其官网上提供了完备的使用文档以及丰富的使用实例,若是仅仅拿来搬砖,官方所提供的资料也足以应付了,但对于好奇其中内部原理、实现细节的家伙们,这些个资料还远远不够。
以 r110 版本为例,Three.js 源码大约 56000 行(另有 11000 余行的 TypeScript 声明代码)。这样的代码,若是想要通读,想来得花费不少时间,同时也不可避免的陷入其中诸多的细枝末节当中去。比起如无头苍蝇般的乱撞,还是通过具体的例子来探究 Three.js 中某一部分功能的相关实现,并逐步延伸开来理解一些细节来的有效。
本篇是我关于 Three.js 源码阅读的第一篇博客,其本身也是我阅读源码所做笔记的一个记录。事实上我也才在最近抽出时间开始阅读其中源码,再加上我关于 WebGL 以及图形学相关知识的掌握也不过是个初学者,博文中难免出现诸多纰漏、不当之处,还望读者赏脸指出。

从一个简单的例子开始

在一头扎进 Three.js 源码之前,不妨让我们先关注一个最简单的例子:渲染一个单色的 Cube。

Three.js 的例子

在 Three.js 的世界中,渲染一个 Cube 是十分简单的,只消不到 20 行代码就能构建一个 cube 的单帧渲染:

const canvas = document.querySelector('#canvas');
const renderer = new THREE.WebGLRenderer({
   canvas});

const camera = new THREE.PerspectiveCamera();
camera.position.z = 2;

const scene = new THREE.Scene();

const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({
   color: 0xffffff});
const cube = new THREE.Mesh(geometry, material);
cube.rotation.x = 2;
cube.rotation.z = -1;

scene.add(cube);

renderer.render(scene, camera);

其绘制结果如下图所示:
Three.js 绘制简单 cube
上述代码中包含了简单的通过 BoxGeometry 构造了一个一个纯色的 cube 并通过 WebGLRenderer 渲染出来。
例子程序中没有添加任何光源,并且简单的使用了 MeshBasicMaterial 类的材质,因此绘制出的 cube 上没有明暗的变化缺乏了立体感。但这一做法时为了使得整个例子更为简洁,减少后续涉及的细节,至于绘制的效果还是由读者用心去感受吧。

WebGL 的例子

借助 Three.js 所提供的便捷,我们能够快速的构建 3d 渲染程序。那么,同样的渲染换用原生的 WebGL 来实现是怎么样的呢?
以下是来自《WebGL Programming Guide: Interactive 3D Graphics Programming with WebGL》的一个简单例子(该书所涉及内容较浅,略微涉及了图形学的一些基础知识,如果仅想学习 WebGL ,该书也可作为一个不错的入门读物):

// HelloCube.js (c) 2012 matsuda
// Vertex shader program
var VSHADER_SOURCE =
  'attribute vec4 a_Position;\n' +
  'attribute vec4 a_Color;\n' +
  'uniform mat4 u_MvpMatrix;\n' +
  'varying vec4 v_Color;\n' +
  'void main() {\n' +
  '  gl_Position = u_MvpMatrix * a_Position;\n' +
  '  v_Color = a_Color;\n' +
  '}\n';

// Fragment shader program
var FSHADER_SOURCE =
  '#ifdef GL_ES\n' +
  'precision mediump float;\n' +
  '#endif\n' +
  'varying vec4 v_Color;\n' +
  'void main() {\n' +
  '  gl_FragColor = v_Color;\n' +
  '}\n';

function main() {
   
  // Retrieve <canvas> element
  var canvas = document.getElementById('webgl');

  // Get the rendering context for WebGL
  var gl = getWebGLContext(canvas);
  if (!gl) {
   
    console.log('Failed to get the rendering context for WebGL');
    return;
  }

  // Initialize shaders
  if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
   
    console.log('Failed to intialize shaders.');
    return;
  }

  // Set the vertex coordinates and color
  var n = initVertexBuffers(gl);
  if (n < 0) {
   
    console.log('Failed to set the vertex information');
    return;
  }

  // Set clear color and enable hidden surface removal
  gl.clearColor(0.0, 0.0, 0.0, 1.0);
  gl.enable(gl.DEPTH_TEST);

  // Get the storage location of u_MvpMatrix
  var u_MvpMatrix = gl.getUniformLocation(gl.program, 'u_MvpMatrix');
  if (!u_MvpMatrix) {
    
    console.log('Failed to get the storage location of u_MvpMatrix');
    return;
  }

  // Set the eye point and the viewing volume
  
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值