原文地址:WebGL展示3D房屋內景
由於生活和工作上的原因,從年前開始一直到處奔波,沒有太多的時間去關注和學習WebGL圖形學相關的技術, 不過陸陸續續都有學習使用blender進行3D建模, 而這篇文章涉及到的房屋內景3D建模就是我這段時間以來的學習成果,現在展示出來.
檔案模型比較大,頁面載入比較慢,請耐心等候,例項為: 餐廳 dinning hall 3D
動畫效果如下:
Blender
Blender是開源的建模和動畫製作軟體,功能雖然沒有3dmax和maya強大,但它精簡,易學易用,而且還是開源的, 非常適合像我這樣的入門級新手.如果你也想做模型和特效,建立自己心目中的3D世界,Blender值得你去嘗試.
入門教程推薦臺灣大神的blender教程全集
模型檔案
在blender製作好模型之後,接著就是匯出obj檔案,接著就是使用js讀取obj檔案,之後就開始涉及到WebGL,具體的步驟可以參考我之前的文章 WebGL學習(3) - 3D模型
著色器
著色器程式碼實現的是WebGL最基本的功能,使用了一個平行光源,光照部分有環境光,漫反射,馮氏高光鏡面反射.程式碼詳情如下:
頂點著色器
attribute vec4 a_position;//頂點位置
attribute vec4 a_color;//頂點顏色
attribute vec4 a_scolor;//頂點高光顏色
attribute vec4 a_normal;//法向量
uniform mat4 u_MvpMatrix;//mvp矩陣
uniform mat4 u_ModelMatrix;//模型矩陣
uniform mat4 u_NormalMatrix;
varying vec4 v_Color;
varying vec4 v_Scolor;
varying vec3 v_Normal;
varying vec3 v_Position;
void main() {
gl_Position = u_MvpMatrix * a_position;
// 計算頂點在世界座標系的位置,以便計算點光源在頂點處點位置
v_Position = vec3(u_ModelMatrix * a_position);
// 計算變換後的法向量
v_Normal = vec3(u_NormalMatrix * a_normal);
v_Color = a_color;
v_Scolor = a_scolor;
}
片段著色器
#ifdef GL_ES
precision mediump float;
#endif
uniform vec3 u_LightPosition;//光源位置
uniform vec3 u_diffuseColor;//漫反射光顏色
uniform vec3 u_AmbientColor;//環境光顏色
uniform vec3 u_specularColor;//鏡面反射光顏色
uniform float u_Shininess;// 鏡面反射光澤度
uniform vec3 u_viewPosition;// 視點位置
varying vec3 v_Normal;//法向量
varying vec3 v_Position;//頂點位置
varying vec4 v_Color;//頂點顏色
varying vec4 v_Scolor;//頂點高光顏色
void main() {
vec3 normal = normalize(v_Normal);
// 平行光
vec3 lightDirection = normalize(u_LightPosition);
// 計算光線方向和法向量點積
float nDotL = max(dot(lightDirection, normal), 0.0);
// 漫反射光亮度
vec3 diffuse = u_diffuseColor * nDotL * v_Color.rgb;
// 環境光亮度
vec3 ambient = u_AmbientColor * v_Color.rgb;
// gl_FragColor = vec4(diffuse + ambient, v_Color.a);
// 觀察方向的單位向量V
vec3 eyeDirection = normalize(u_viewPosition - v_Position.xyz);// 反射方向
// 反射方向
vec3 reflectionDirection = reflect(-lightDirection, normal);
// 鏡面反射亮度權重
float specularWeighting = pow(max(dot(reflectionDirection, eyeDirection), 0.0), u_Shininess);
vec3 specular = u_specularColor.rgb * specularWeighting;
gl_FragColor = vec4(ambient + diffuse + specular, v_Color.a);
}
模型變換
模型變換同樣可參考我之前的文章 WebGL多模型光照綜合例項
總結
這個例項最困難和花費時間最多的其實是3D建模部分,而開發所使用到的WebGL知識點由於比較基礎,反而沒多大難度.總之要做出酷炫逼真的特效和模型,還得繼續深入學習3D建模.