(转)基本光照模型公式

来源:互联网 发布:淘宝学生春秋外套 编辑:程序博客网 时间:2024/04/27 23:06

转载请注明出处: 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:

view plaincopy to clipboardprint?
  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:

 

view plaincopy to clipboardprint?
  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;

 

view plaincopy to clipboardprint?
  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;

 

view plaincopy to clipboardprint?
  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 自动生成;

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 大同同煤集团三供一业人员怎么办 小孩被猫咪抓了怎么办 长得特别丑的人怎么办 锅巴放的不脆了怎么办 淘宝买到假货了怎么办 单位不给解约函怎么办 安卓个人热点打不开怎么办 密码忘记无法进入主机怎么办 流放之路w10闪退怎么办 电脑网站被劫持了怎么办 苹果手机浏览器被劫持怎么办 苹果手机网站被劫持怎么办 a37手机网站被劫持怎么办 耳朵被震的耳鸣怎么办 液晶电视怎么办断屏坏还是逻辑板 门保险拧坏了怎么办 锁的保险坏了怎么办 鞋子里面长霉了怎么办 塑料瓶盖滑丝了怎么办? 塑料杯盖滑丝了怎么办 洗衣机上的订子很难扭出来怎么办 滚筒洗衣机坏了打不开门怎么办 海尔滚筒洗衣机打不开门怎么办 格兰仕滚筒洗衣机门打不开怎么办? lg洗衣机洗完衣服门打不开怎么办 lg洗衣机不能冼衣服怎么办 vivo账户密码忘记了怎么办 oppo账户密码忘记了怎么办 74160从1开始计数怎么办 微信录音声音小怎么办 word文档已停止工作怎么办 怀孕30天不想要怎么办 一楼墙体起碱怎么办 农村平房顶四墙面渗水怎么办 被蝎子精蛰了怎么办 小娃头摔包要怎么办抹个什么 老人死了银行钱存死期怎么办 飙酷车神2一进画面就闪退怎么办 电脑开机键盘鼠标没反应怎么办 玩gta4自由城卡怎么办 gta5游戏服务当前不可用怎么办