WebGL展示3D房屋內景

Jeff.Zhong發表於2018-05-31

  原文地址:WebGL展示3D房屋內景
  由於生活和工作上的原因,從年前開始一直到處奔波,沒有太多的時間去關注和學習WebGL圖形學相關的技術, 不過陸陸續續都有學習使用blender進行3D建模, 而這篇文章涉及到的房屋內景3D建模就是我這段時間以來的學習成果,現在展示出來.
  檔案模型比較大,頁面載入比較慢,請耐心等候,例項為: 餐廳 dinning hall 3D
  動畫效果如下:
WebGL展示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建模.

相關文章