(转)基本光照模型公式

转载请注明出处: 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 自动生成;

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