(轉)基本光照模型公式

轉載請註明出處: http://blog.csdn.net/tianhai110

 

光照模型

3D渲染中, 物體表面的光照計算公式爲:

環境光(Iambient) + 漫反射光(Idiffuse) + 鏡面高光(Ispecular);

 

其中,環境光(ambient)計算公式爲:

Iambient = Aintensity * Acolor ;             (Aintensity表示環境光強度,Acolor表示環境光顏色)

 

漫反射光(diffuse)計算公式爲:

Idiffuse = Dintensity*Dcolor*N.L ;                   (Dintensity表示漫反射強度,Dcolor表示漫反射光顏色,N爲該點的法向量,L爲光源向量)

 

鏡面光照(specular)計算公式爲:

Ispecular = Sintensity*Scolor*(R.V);         (Sintensity表示鏡面光照強度,Scolor表示鏡面光顏色,R爲光的反射向量,V爲觀察者向量)

 

綜上所得:整個光照公式爲:

I = Aintensity * Acolor + Dintensity*Dcolor*N.L + Sintensity*Scolor*(R.V)n ;

將一些值合併,並使用白色作爲光照顏色,則上述公式可簡化爲:

I = A + D*N.L + (R.V)n

 

 

環境光照:

1.      打開RenderMonkey, 右擊WorkSpaceEffect WorkSpace結點,選擇Add Default Effect->DirectX->DirectX;

2.      這樣建立的效果就是一個環境光照效果,可以雙擊pixel shader, 修改自己喜歡的顏色作爲環境光

 

效果如下圖:

 

 

 

 

 

漫反射光照:

1.      打開RenderMonkey, 右擊WorkSpaceEffect WorkSpace結點,選擇Add Default Effect->DirectX->DirectX;

2.      添加物體位置矩陣:右擊Effect節點 選擇 Add Variable->Matrix->PreDefined->matWorld

 

3.      添加光源向量右擊Effect節點 選擇Add Variable->float->float4;  修改名稱爲vecLightDir, 雙擊設置其值

 

4.      修改stream Mapping; 添加一個法向量形式

 

5.       編寫Vertex Shader:

  1. float4x4 matViewProjection;  
  2.   
  3. float4x4 matWorld;  
  4.   
  5. float4   vecLightDir;  
  6.   
  7.    
  8.   
  9. struct VS_INPUT   
  10.   
  11. {  
  12.   
  13.    float4 Position : POSITION0;  
  14.   
  15.    float3 Norm     : NORMAL0;  
  16.   
  17. };  
  18.   
  19.    
  20.   
  21. struct VS_OUTPUT   
  22.   
  23. {  
  24.   
  25.    float4 Position : POSITION0;  
  26.   
  27.    float3 Light    : TEXCOORD0;  
  28.   
  29.    float3 Norm     : TEXCOORD1;  
  30.   
  31. };  
  32.   
  33.    
  34.   
  35. VS_OUTPUT vs_main( VS_INPUT Input )  
  36.   
  37. {  
  38.   
  39.    VS_OUTPUT Output;  
  40.   
  41.    
  42.   
  43.    Output.Position = mul( Input.Position, matViewProjection );  
  44.   
  45.    Output.Light    = normalize(vecLightDir);  
  46.   
  47.    Output.Norm     = normalize(mul(Input.Norm, matWorld));  
  48.   
  49.      
  50.   
  51.    return( Output );  
  52.   
  53.      
  54.   
  55. }  
  

 

6.       編寫Pixel Shader:

 

  1. float4 ps_main( float3 Light:TEXCOORD0, float3 Norm:TEXCOORD1) : COLOR0  
  2. {     
  3.     float4 diffuse = { 1.0f, 1.0f, 1.0f, 1.0f};  
  4.     float4 ambient = { 0.3, 0.2, 0.1, 1.0};  
  5.       
  6.     return ambient + diffuse * saturate(dot(Light, Norm));  
  7. }  

 

7.       編譯預覽效果:

 

鏡面反射光照:

鏡面光照在漫反射基礎上,還需要添加一個視口位置;

1.      打開RenderMonkey, 添加一個渲染節點;Add Default Effect->DirectX->DirectX

2.      添加攝像機矩陣,Add Variable->Matrix->Predefined->matView;

3.      添加光源方向 Add Variable->float->float4; 改名爲vecLightDir,並設值

 

4.      添加視點位置 Add Variable->float->float4; 改名爲vecEye; 並設值(00-101);

5.      添加紋理 Add Texture->Add 2D Texture->2D Texture; 隨便選擇一張紋理;

6.      右鍵pass0,添加一個紋理對象; Add Texture Object->my2DTexture;  並改名爲baseMap;

7.      修改steam mapping 如下

 

8.       編寫vertex shader;

 

  1. float4x4 matViewProjection;  
  2. float4x4 matView;  
  3. float4   vecLightDir;  
  4. float4   vecEye;  
  5.   
  6. struct VS_INPUT   
  7. {  
  8.    float4 Position : POSITION0;  
  9.    float3 Normal   : NORMAL0;  
  10.    float2 Texcoord : TEXCOORD0;  
  11. };  
  12.   
  13. struct VS_OUTPUT   
  14. {  
  15.    float4 Position : POSITION0;  
  16.    float2 Texc     : TEXCOORD0;  
  17.    float3 Light    : TEXCOORD1;  
  18.    float3 Norm     : TEXCOORD2;  
  19.    float3 View     : TEXCOORD3;  
  20.     
  21. };  
  22.   
  23. VS_OUTPUT vs_main( VS_INPUT Input )  
  24. {  
  25.    VS_OUTPUT Output;  
  26.   
  27.    Output.Position = mul( Input.Position, matViewProjection );  
  28.    Output.Light      = vecLightDir;  
  29.      
  30.    float3 posWorld = normalize(mul(Input.Position, matView));  
  31.    Output.View = vecEye - posWorld;  
  32.    Output.Norm = mul(Input.Normal, matView);  
  33.    Output.Texc = Input.Texcoord;  
  34.    return( Output );  
  35.      
  36. }  
 

 

9.       編寫 pixel shader;

 

  1. sampler2D baseMap;  
  2. float4 ps_main( float2 Texc:TEXCOORD0, float3 Light:TEXCOORD1,  
  3.           float3 Norm:TEXCOORD2, float3 View:TEXCOORD3) : COLOR0  
  4. {     
  5.    float4 ambient = { 0.3686f, 0.3686f, 0.3686f, 1.0f};  
  6.    float4 diffuse = { 0.88f, 0.88f, 0.88f, 1.0f};  
  7.      
  8.    float3 Normal = normalize( Norm);  
  9.    float3 LightDir = normalize( Light);  
  10.    float3 ViewDir = normalize( View);  
  11.    float4 diff = saturate( dot( Normal, LightDir));  
  12.      
  13.    float3 Reflect = normalize( 2 * diff * Normal - LightDir);  
  14.    float4 specular = pow(saturate(dot(Reflect, ViewDir)), 8);  
  15.      
  16.    float4 fvBaseColor      = tex2D( baseMap, Texc );  
  17.    float4 fvTotalAmbient   = ambient * fvBaseColor;   
  18.    float4 fvTotalDiffuse   = diffuse * diff * fvBaseColor;   
  19.   
  20.         
  21.    return fvTotalAmbient + fvTotalDiffuse + specular;  
  22.      
  23. }  
 

 

10.   運行結果:

 

 

 

該實例可通過Add Default Effect->DirectX->TexturedPhong 自動生成;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章