天天看點

cesium three性能比較_用three.js調試簡單的shader

目的是示範在WebGL上跑自制shader(着色器)。 架構使用three.js, 搭建hello world參見:

  • three.js

注意,WebGL 1.0使用的shader隻支援GLSL 1.0.17, 這是因為WebGL是基于OpenGL ES 2.0的,是給相對于桌上型電腦性能較低的手持裝置用的。 是以如果在網上找到的GLSL的例子,在WebGL上可能不管用,要注意版本。 GLSL 1.0與現行最高的4版本比起差別還是比較多的,比如老版本裡叫attribute, varying的變量到高版本裡叫in, out了。 具體WebGL學習參見:

  • Learn WebGL

先上代碼: Github: demaxism/

shader-threejs

使用: git clone代碼後進入檔案夾, 啟動web server, 比如我用node:

http-server .
           

浏覽器打開

http://127.0.0.1:8080/

後,點選Simple Shader按鈕。

cesium three性能比較_用three.js調試簡單的shader

代碼解釋: v_shader和f_shader是我們要加載的vertex shader和fragment shader,以字元串形式儲存。 vertex shader的工作比較好了解,是對單個頂點的處理,頂點就是三維模型資料裡的頂點。 built-in uniform和attribute有:

uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;

attribute vec3 position;
attribute vec3 normal;
attribute vec2 uv;
           

還有些其他内置變量,詳見:

  • WebGL Program Doc

v_shader裡, position是頂點的local坐标(Model坐标),以下這步把local坐标轉換成camera坐标:

vec4 modelViewPosition = modelViewMatrix * vec4(position, 1.0);
           

也可以拆解成: Model坐标 X ModelMatrix = World坐标;World坐标 X ViewMatrix = Camera坐标。

接下來這步把camera坐标轉換成投影坐标

gl_Position = projectionMatrix * modelViewPosition;
           

詳見:

  • Opengl-tutorial Basic/Matrices
varying vec3 localPos;
...
localPos = position;
           

這裡我把Model坐标以varying的形式傳給fragment shader.

在fragment shader裡,接受了來自vertex shader的localPos, 還有個uniform變量time。它在每幀(每次渲染完成)内是全局不變的。 gl_FragColor是fragment shader唯一的輸出。 所有的處理都服務于它。

在vertex shader處理完後, polygon被栅格化(rasterized)成一個個fragment, fragment和pixel的差別開始有些難了解,其實可以了解成fragment是pixel的candidate。 比如有多個polygon在垂直于螢幕方向疊在一起,這些polygon都會産生fragment,但有些會因為深度靠後而被丢棄。

varying vec3 localPos在fragment shader裡是被線性補間的。 在vertex shader裡隻輸出了模型的各頂點到localPos, 每個polygon隻有三個localPos, 但由于這個polygon會被栅格化成許多小fragment,于是各個fragment拿到的localPos是補間生成的。

最後three的init()裡不要忘了加上:

this.animate = this.animate.bind(this);
           

不然的話在回調調用這個animate時,内部的this會失效(不再指向自己),是以這裡就把this綁定給自己。