OpenGL ES 光照模型之——漫反射光(RenderMonkey測試,地球日出效果)

概述及目錄(版權全部,請勿轉載 http://www.cnblogs.com/feng-sc)

  本文在上一篇(OpenGL ES 光照模型之——環境光照(RenderMonkey測試))環境光基礎上,增長漫反射光照。咱們主要使用漫反射光模擬太陽光,實現以下兩種效果:函數

    一、地球自傳,太陽光固定的日出效果;測試

    二、地球靜止,太陽光圍繞地球旋轉的效果。spa

  本文主要包括以下方面內容:code

    一、漫反射光模型簡介;orm

    二、地球自轉日出效果Shader實現;blog

    三、地球靜止,太陽光圍繞地球旋轉Shader實現。ci

 

漫反射光照模型簡介

  漫反射光的定義網上有各類說法,在此就不描述了,下面經過兩個圖形來表示:it

  

 (平行光)io

(「散」射光)編譯

  如上兩個圖中,有人把第一個圖的平行光當作漫反射光,也有人把第二個圖的模型當作慢反射光。是的,若是第二個圖中光遠點T無限遠,那麼兩個光照模型的效果實際上是同樣的,但模型2更像是沒有衰減係數的點光源。

  模型公式以下:

     

  其中:

     IDifuse爲漫反射光照強度;

     Id爲光源顏色;

     Kd能夠理解爲漫反射光照輸入強度;

     cosθ爲光線與發現的夾角;

  咱們下面經過介紹的是使用第一種模型實現的效果。

地球自轉日出效果Shader實現

  本段內容咱們先來看下利用RenderMonkey實現的OpenGL ES Shader日出模型的最終效果圖,以下圖所示:

(日出模型效果圖)

  OK,咱們如今來具體看看如何使用RenderMonkey實現如上的效果。

  咱們在上一篇(OpenGL ES 光照模型之——環境光照(RenderMonkey測試))的基礎上,在RenderMonkey工程中加入三個變量:gDiffStrength、time和angles。具體操做以下:

  

  其中:

  gDiffStrength爲模型公式中的Kd,是一個float類型的數據;

  time和angles均爲RenderMonkey與設置的float類型數據,且數據會在每一幀中會隨時間從0至2π變化。

  GPU的Vertex Shader代碼實現以下:

//漫反射光照模型vertex shader示例代碼 1.0 http://www.cnblogs.com/feng-sc/
uniform   mat4 matViewProjection;
attribute vec4 rm_Vertex;
attribute vec2 rm_TexCoord0;
attribute vec3 rm_Normal; //法線輸入
varying vec2 rm_Texcoord; varying vec3 fNormal; uniform
float angles; mat4 rotate(mat4 matrix, float a,vec3 v ) //矩陣旋轉函數shader實現 { float c = cos(a); float s = sin(a); vec3 axis = normalize(v); vec3 temp = (1.0 - c) * axis; matrix[0][0] = c + temp[0] * axis[0]; matrix[0][1] = temp[0] * axis[1] + s * axis[2]; matrix[0][2] = temp[0] * axis[2] - s * axis[1]; matrix[0][3] = 0.0; matrix[1][0] = temp[1] * axis[0] - s * axis[2]; matrix[1][1] = c + temp[1] * axis[1]; matrix[1][2] = temp[1] * axis[2] + s * axis[0]; matrix[1][3] = 0.0; matrix[2][0] = temp[2] * axis[0] + s * axis[1]; matrix[2][1] = temp[2] * axis[1] - s * axis[0]; matrix[2][2] = c + temp[2] * axis[2]; matrix[2][3] = 0.0; matrix[3][0] = 0.0; matrix[3][1] = 0.0; matrix[3][2] = 0.0; matrix[3][3] = 1.0; return matrix; } void main( void ) { mat4 maxtrixWorld = mat4(1.0); maxtrixWorld = rotate(maxtrixWorld,angles * 10.0 ,vec3(0.0,1.0,0.0)); //定義模型矩陣,並使其圍繞y軸旋轉 gl_Position = (matViewProjection * maxtrixWorld * rm_Vertex); rm_Texcoord = rm_TexCoord0.xy; fNormal = (maxtrixWorld * vec4(rm_Normal,1.0)).xyz; //法線輸出,必須與定點同樣,通過模型矩陣變化 }

  GPU的Fragment Shader實現代碼以下:

//漫反射光照模型fragment shader示例代碼 1.0 http://www.cnblogs.com/feng-sc/
#ifdef GL_FRAGMENT_PRECISION_HIGH
   // Default precision
   precision highp float;
#else
   precision mediump float;
#endif
uniform sampler2D baseMap;
uniform vec4 gAnbientColor;
uniform float gAmbientStrength;
uniform float gDiffStrength;
uniform float time;
varying vec2 rm_Texcoord;
varying vec3 fNormal;

vec4 AmbientColor() //計算環境光
{
   return gAnbientColor * gAmbientStrength;
}

vec4 DiffuseColor() //計算漫反射光
{
   //float diffFactor = max(dot(normalize(fNormal),normalize(vec3(sin(time * 10.0),0.0,cos(time * 10.0))) - vec3(0,0,0)),0.0);
   float diffFactor = max(dot(normalize(fNormal),vec3(0.0,0.0,1.0)),0.0); //定義光照方向爲vec3(0.0,0.0,1.0),與法線求點積 return gAnbientColor * diffFactor * gDiffStrength;
}

void main( void )
{
   vec4 color = texture2D(baseMap,rm_Texcoord);
   vec4 ambientcolor = AmbientColor();
   vec4 diffusecolor = DiffuseColor();
   gl_FragColor = color * (ambientcolor + diffusecolor); //最後輸出顏色爲環境光顏色和漫反射光顏色相加,在與文理顏色作乘法混合
    
}

  編譯如上兩段shader代碼後,RenderMonkey場景中最終能夠獲得咱們剛開始是的顯示效果圖。

地球靜止,太陽光圍繞地球旋轉Shader實現

  一樣,本段內容咱們先來看下利用RenderMonkey實現的OpenGL ES Shader太陽圍繞地球旋轉的效果圖:

(太陽圍繞地球旋轉的效果圖)

 

  GPU的Vertex Shader實現代碼以下,與上一段落 (地球自轉日出效果Shader實現)的Vertex Shader區別在於屏蔽掉了以下第8行地球自轉的代碼:

 1 //漫反射光照模型,太陽圍繞地球轉 vertex shader示例代碼 1.0 http://www.cnblogs.com/feng-sc/
 2 ……
 3 ……
 4 ……
 5 void main( void )
 6 {
 7     mat4 maxtrixWorld = mat4(1.0);
 8    // maxtrixWorld = rotate(maxtrixWorld,angles * 10.0 ,vec3(0.0,1.0,0.0)); //定義模型矩陣,並使其圍繞y軸旋轉
 9     gl_Position = (matViewProjection * maxtrixWorld * rm_Vertex);
10     rm_Texcoord    = rm_TexCoord0.xy;
11     fNormal = (maxtrixWorld * vec4(rm_Normal,1.0)).xyz; //法線輸出,必須與定點同樣,通過模型矩陣變化
12 }

 

  GPU的Fragment Shader實現代碼以下,與上一段落 (地球自轉日出效果Shader實現)的Fragment Shader區別在於屏蔽掉了以下第8行漫反射光照代碼,而增長第7行。

  第7行中的vec3(sin(time * 10.0),0.0,cos(time * 10.0)),根據time計算光源方向,time的變化範圍爲0至2π,所以,讓光源方向圍繞xz平面旋轉,得:

  x = sin(time)

  y = 0

  z = cos(time)

  注:代碼中的time*10中10沒有特別意義,只是讓光源方向移動得更快。

 1 //漫反射光照模型,太陽圍繞地球轉 fragment shader示例代碼 1.0 http://www.cnblogs.com/feng-sc/
 2 ……
 3 ……
 4 ……
 5 vec4 DiffuseColor() //計算漫反射光
 6 {
 7    float diffFactor = max(dot(normalize(fNormal),normalize(vec3(sin(time * 10.0),0.0,cos(time * 10.0))) - vec3(0,0,0)),0.0);
 8    //float diffFactor = max(dot(normalize(fNormal),vec3(0.0,0.0,1.0)),0.0); //定義光照方向爲vec3(0.0,0.0,1.0),與法線求點積
 9    return gAnbientColor * diffFactor * gDiffStrength;
10 }
11 
12 ……
13 ……
14 …… 
相關文章
相關標籤/搜索