<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[用webgl来绘制二维点云吧]]></title><description><![CDATA[<p dir="auto">做图形化程序web是非常方便的。最近做了一个项目就是用webgl来绘制二维点云，运行效果还是不错的。下面简单介绍一下webgl的使用方法和二维点云的绘制方法。</p>
<p dir="auto">首先什么是webgl？opengl大家一定都知道，就是 open graphic library. webgl 就相当于web中的opengl实现。利用webgl就可以充分利用显卡的性能绘制出很好的图形效果。</p>
<p dir="auto">webgl的基本概念<br />
三维图形在opengl中都是分割成三角形进行渲染的。比如一个正方形可以分成上下两个三角形。</p>
<p dir="auto"><img src="/uploads/files/1467023411858-screenshot-from-2016-06-27-18-29-44.png" alt="0_1467023401352_Screenshot from 2016-06-27 18:29:44.png" class=" img-responsive img-markdown" /></p>
<p dir="auto">这样一个正方形就有六个定点去确定下来。要利用webgl取画图就要指定两点就可以了，一个是所绘图形的所有定点，另一个是每个三角形的贴图。在webgl中这个是用 script type="x-shader/x-fragment"去指定的。<br />
下面就是画一个正方形的顶点计算script</p>
<pre><code>&lt;script id="2d-vertex-shader" type="x-shader/x-vertex"&gt;
attribute vec2 a_position;

uniform vec2 u_resolution;
uniform vec2 u_translation;
uniform vec2 u_rotation;
uniform vec2 u_scale;

void main() {
  // Scale the positon
  vec2 scaledPosition = a_position * u_scale;

  // Rotate the position
  vec2 rotatedPosition = vec2(
     scaledPosition.x * u_rotation.y + scaledPosition.y * u_rotation.x,
     scaledPosition.y * u_rotation.y - scaledPosition.x * u_rotation.x);

  // Add in the translation.
  vec2 position = rotatedPosition + u_translation;

  // convert the position from pixels to 0.0 to 1.0
  vec2 zeroToOne = position / u_resolution;

  // convert from 0-&gt;1 to 0-&gt;2
  vec2 zeroToTwo = zeroToOne * 2.0;

  // convert from 0-&gt;2 to -1-&gt;+1 (clipspace)
  vec2 clipSpace = zeroToTwo - 1.0;

  gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);
}
&lt;/script&gt;
</code></pre>
<p dir="auto">首先定义了几个变量，然后根据转动，平移等坐标变换去计算应该绘制的坐标。gl_Position就是最后计算得出的坐标。整个计算过程由GPU去完成，因此运行效率也是很高的。</p>
<p dir="auto">定义贴图的script如下</p>
<pre><code>&lt;script id="2d-fragment-shader" type="x-shader/x-fragment"&gt;
precision mediump float;

uniform vec4 u_color;

void main() {
   gl_FragColor = u_color;
}
&lt;/script&gt;
</code></pre>
<p dir="auto">这个脚本只是设置了填充的颜色，当然也可以填充图片之类的。</p>
<p dir="auto">变量的计算方式已经有了，怎么给这些变量设值呢？opengl提供了一些方法</p>
<pre><code>  gl = canvas.getContext("webgl");
  if (!gl) {
    return;
  }

  // setup GLSL program
  var program = glUtils.createProgramFromScripts(gl, ["2d-vertex-shader", "2d-fragment-shader"]);
  gl.useProgram(program);

  // lookup uniforms
  resolutionLocation = gl.getUniformLocation(program, "u_resolution"); // 获取GPU中变量的地址
  colorLocation = gl.getUniformLocation(program, "u_color");
  translationLocation = gl.getUniformLocation(program, "u_translation");
  rotationLocation = gl.getUniformLocation(program, "u_rotation");
  scaleLocation = gl.getUniformLocation(program, "u_scale");

  var positionLocation = gl.getAttribLocation(program, "a_position");
  translation = [0, 0];
  rotation = [0, 1];
  scale = [1, 1];
  // set the resolution
  gl.uniform2f(resolutionLocation, canvas.width, canvas.height);  // 给GPU中的变量赋值
  // Set the translation.
  gl.uniform2fv(translationLocation, translation);
  // Set the rotation.
  gl.uniform2fv(rotationLocation, rotation);
  // Set the scale.
  gl.uniform2fv(scaleLocation, scale);
</code></pre>
<p dir="auto">执行 <code>uniform2f</code> 之后就会更改GPU内对应数据的值。</p>
<p dir="auto">通过</p>
<pre><code>gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
     x1, y1,
     x2, y1,
     x1, y2,
     x1, y2,
     x2, y1,
     x2, y2]), gl.STATIC_DRAW);
</code></pre>
<p dir="auto">去设置所绘图形的端点坐标，这里是绘制正方形，所以是六个顶点。</p>
<pre><code>    gl.drawArrays(gl.TRIANGLES, 0, 6);
</code></pre>
<p dir="auto">执行上面这句就可以开始绘图了，这里的参数指明了采用三角形进行绘图，共绘制六个顶点。这样我们就能看到一个正方形了<br />
<a href="http://webglfundamentals.org/webgl/webgl-fundamentals.html" target="_blank" rel="noopener noreferrer">完整的代码执行例子, 不涉及到坐标的计算</a><br />
<a href="http://webglfundamentals.org/webgl/webgl-2d-geometry-scale.html" target="_blank" rel="noopener noreferrer">完整的有坐标计算和拉伸的例子</a><br />
推荐一个学习webgl的好<a href="http://webglfundamentals.org/" target="_blank" rel="noopener noreferrer">网站</a></p>
<p dir="auto">对于我们所要绘制的点云，只有画正方形是不够的。还有图像的放大，缩小，平移等等。这些就可以通过改变计算顶点坐标时的参数来实现。具体算起来会比较复杂，但是原理上就是如此。每个点就是一个非常小的正方形。</p>
<p dir="auto">来一个软件的最终效果图吧。</p>
<p dir="auto"><img src="/uploads/files/1467025063738-screenshot-from-2016-06-27-18-57-02.png" alt="0_1467025052651_Screenshot from 2016-06-27 18:57:02.png" class=" img-responsive img-markdown" /></p>
<p dir="auto">放大后的点云图<br />
<img src="/uploads/files/1467025094903-screenshot-from-2016-06-27-18-57-17.png" alt="0_1467025084561_Screenshot from 2016-06-27 18:57:17.png" class=" img-responsive img-markdown" /></p>
]]></description><link>http://community.bwbot.org/topic/54/用webgl来绘制二维点云吧</link><generator>RSS for Node</generator><lastBuildDate>Fri, 07 Aug 2026 19:30:09 GMT</lastBuildDate><atom:link href="http://community.bwbot.org/topic/54.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 27 Jun 2016 11:00:04 GMT</pubDate><ttl>60</ttl></channel></rss>