ADS光照模型實例(GLSL實現)

ADS光照模型實例(GLSL實現)

來自專欄技術美術19 人贊了文章

keywords:ambient diffuse specular、Phong Shading、Phong reflection model

公式概述

ADS光照模型又稱為「馮氏反射模型」(Phong reflection model),為什麼叫馮氏:

裴祥風(Bùi T??ng Phong音譯, 1942年—1975年),美國電腦CG研究學者,于越南出生。他於1973年在尤他大學取得哲學博士學位,並發明了Phong反射模型及Phong著色法,並廣為CG界採用。1975死於白血病。

ADS光照模型公式縮寫:

LightIntensity = Ambient + Diffuse + Specular;

參數說明:

  • Ambient 環境光
  • Diffuse 漫反射
  • Specular 全反射光 / 鏡面光

三個參數渲染效果示例:

三個參數拆解如下:

Ambient = La * Ka;Diffuse = Ld * Kd * max( dot(s, n), 0.0 );Specular = Ls * Ks * pow( max( dot(r, v), 0.0 ), f );

參數說明:

  • La 環境光強度(Ambient light intensity)
  • Ka 材質環境光反射率 / 材質環境光反射係數(Ambient reflectivity)
  • Ld 漫射光強度 / 散射光強度(Diffuse light intensity)
  • Kd 材質漫反射率 / 材質漫反射係數(Diffuse reflectivity)
  • s 頂點 / 曲面點 到光源方向的單位向量(Direction from the surface point to the light source)
  • n 頂點 / 曲面點 的法線單位向量(Normal vector at the surface point)
  • Ls 鏡面光強度 / 全反射光強度(Specular light intensity)
  • Ks 材質鏡面反射率 / 材質鏡面反射係數(Specular reflectivity)
  • r 完全反射向量( the vector of perfect reflection)
  • v 頂點 / 曲面點 到攝像機方向的向量( the vector towards the viewer)
  • f 鏡面高光(specular highlights),值範圍在1到200之間,值越小,鏡面亮點越大

光源出射強度 / 出射光強度(Intensity of the outgoing light )I的完整計算公式如下:

渲染實例

OpenGL API 版本為4.1。

假設不考慮環境光和鏡面光,只考慮漫射光,渲染效果:

shader 代碼:

diffuse.vert

#version 410layout (location = 0) in vec3 VertexPosition;layout (location = 1) in vec3 VertexNormal;out vec3 LightIntensity;uniform vec4 LightPosition; // Light position in eye coords.uniform vec3 Kd; // Diffuse reflectivityuniform vec3 Ld; // Diffuse light intensityuniform mat4 ModelViewMatrix;uniform mat3 NormalMatrix;uniform mat4 ProjectionMatrix;uniform mat4 MVP;voidmain(){ vec3 tnorm = normalize( NormalMatrix * VertexNormal); vec4 eyeCoords = ModelViewMatrix * vec4(VertexPosition,1.0); vec3 s = normalize(vec3(LightPosition - eyeCoords)); LightIntensity = Ld * Kd * max( dot( s, tnorm ), 0.0 ); gl_Position = MVP * vec4(VertexPosition,1.0);}

diffuse.frag

#version 410in vec3 LightIntensity;layout( location = 0 ) out vec4 FragColor;void main() { FragColor = vec4(LightIntensity, 1.0);}

同時計算環境光、漫反射、鏡面反射的渲染效果:

shader 代碼:

phong.vert

#version 410layout (location = 0) in vec3 VertexPosition;layout (location = 1) in vec3 VertexNormal;out vec3 LightIntensity;struct LightInfo { vec4 Position; // Light position in eye coords. vec3 La; // Ambient light intensity vec3 Ld; // Diffuse light intensity vec3 Ls; // Specular light intensity};uniform LightInfo Light;struct MaterialInfo { vec3 Ka; // Ambient reflectivity vec3 Kd; // Diffuse reflectivity vec3 Ks; // Specular reflectivity float Shininess; // Specular shininess factor};uniform MaterialInfo Material;uniform mat4 ModelViewMatrix;uniform mat3 NormalMatrix;uniform mat4 ProjectionMatrix;uniform mat4 MVP;void main(){ vec3 tnorm = normalize( NormalMatrix * VertexNormal); vec4 eyeCoords = ModelViewMatrix * vec4(VertexPosition,1.0); vec3 s = normalize(vec3(Light.Position - eyeCoords)); vec3 v = normalize(-eyeCoords.xyz); vec3 r = reflect( -s, tnorm ); float sDotN = max( dot(s,tnorm), 0.0 ); vec3 ambient = Light.La * Material.Ka; vec3 diffuse = Light.Ld * Material.Kd * sDotN; vec3 spec = vec3(0.0); if( sDotN > 0.0 ) spec = Light.Ls * Material.Ks * pow( max( dot(r,v), 0.0 ), Material.Shininess ); LightIntensity = ambient + diffuse + spec; gl_Position = MVP * vec4(VertexPosition,1.0);}

phong.frag

#version 410in vec3 LightIntensity;layout( location = 0 ) out vec4 FragColor;void main() { FragColor = vec4(LightIntensity, 1.0);}

demo完整代碼:

github.com/dawnarc/Shad


推薦閱讀:

ue4卡通渲染的概念及技巧
第1章 引擎的紛爭 (感謝大食堂對本章的校驗)
第十一章 場景管理 Part4(11.5 To 11.7)
[Siggraph15] GPU-Driven Rendering Pipelines
遊戲引擎列表

TAG:遊戲引擎 | shader | OpenGL |