今天学习的是镜面的反射光照,其实一般在场景中基本环境光和漫反射光照已经可以表现出一个不错的照明了,今天的镜面反射光照其实仅仅适合于需要在表面添加抛光或者闪耀的物体上,例如金属、玻璃等等,同时也是基于之前的环境光和漫反射光的基础之上的,先来看看镜面反射光照的公式吧。

镜面反射光照公式:I=AiAc+Di*Dc*N.L+Si*Sc*(R.V)^n

      公式说明:其中,AiAc+Di*Dc*N.L是前一节的公式,即环境光+漫反射光,Si和Sc分别为镜面反射光照的强度和颜色,R=2*(N.L)*N-L表示反射向量。

      V:为从相机的位置指向观察目标的向量,即V=cameraPosition-mul(position,world)也就是高光的部分始终面向相机可以被看到。

      相机的位置:通常在Game中定义视角矩阵ViewMatrix的第一个参数,即:ViewMatrix=Matrix.CreateLookAt(CameraPosition,CameraTarget,VectorUp)中的CameraPosition

      观察目标:即为POSITION0中存储的物体位置,当然这是模型空间的坐标,需要利用World转换为世界空间中的坐标。

      n:表示光泽属性,n越大,表明物体表面越光滑,反光越强。

     参照公式修改上一节中的部分代码即可完成效果,当然最好是新建一个项目,自己从头到尾按部就班的写代码,温故而知新......下面贴出变动的代码:

            #region 镜面反射光照
effect.CurrentTechnique = effect.Techniques["SpecularLight"];
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Apply();
foreach (ModelMesh mesh in model.Meshes)
{
foreach (ModelMeshPart part in mesh.MeshParts)
{
effect.Parameters["World"].SetValue(modelTransform[mesh.ParentBone.Index] * Matrix.CreateScale(30.0f) * Matrix.CreateRotationX(rotateAngle) * Matrix.CreateRotationY(rotateAngle));
effect.Parameters["View"].SetValue(viewMatrix);
effect.Parameters["Projection"].SetValue(projectMatrix); //环境光参数
effect.Parameters["AmbientColor"].SetValue(new Vector4(0.1f, 0.2f, 0f, 0.2f));
effect.Parameters["AmbientIntensity"].SetValue(0.5f); //漫反射光参数
effect.Parameters["DiffuseIntensity"].SetValue(0.5f);
effect.Parameters["DiffuseColor"].SetValue(new Vector4(1.0f, 0.0f, 0.5f, ));
effect.Parameters["LightDirection"].SetValue(new Vector4(, , 1.0f, 1.0f)); //镜面高光参数
effect.Parameters["VecEye"].SetValue(new Vector4(camPosition, ));
effect.Parameters["SpecularIntensity"].SetValue(1f);
effect.Parameters["SpecularColor"].SetValue(new Vector4(1.0f, 0.0f, 0.5f, 0.5f)); graphics.GraphicsDevice.SetVertexBuffer(part.VertexBuffer);
graphics.GraphicsDevice.Indices = part.IndexBuffer; graphics.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, part.VertexOffset, , part.NumVertices, part.StartIndex, part.PrimitiveCount);
}
}
}
#endregion

接下来看看fx里面的代码:

float4x4 World;
float4x4 View;
float4x4 Projection; //Ambient
float4 AmbientColor;
float AmbientIntensity; //Diffuse
float4 DiffuseColor;
float DiffuseIntensity;
float4 LightDirection; //Specular
float4 VecEye;
float SpecularIntensity;
float4 SpecularColor; struct VertexShaderOutput
{
float4 Position : POSITION0;
float3 Normal:TEXCOORD0;
float4 VecEye:TEXCOORD1;
float4 Light:TEXCOORD2;
}; VertexShaderOutput VertexShaderFunction(float4 Position:POSITION0,float3 Normal:NORMAL)
{
VertexShaderOutput output; float4 worldPosition = mul(Position, World);
float4 viewPosition = mul(worldPosition, View);
output.Position = mul(viewPosition, Projection); output.Normal =normalize(mul(Normal,World)); output.VecEye = normalize(VecEye-mul(Position,World)); output.Light = normalize(LightDirection); return output;
} float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
float4 vAmbient = AmbientIntensity*AmbientColor;//环境光 float4 vDiffuse = DiffuseIntensity*DiffuseColor*saturate(dot(input.Normal,input.Light));//漫反射光 float4 vSpecular = SpecularIntensity*SpecularColor*pow(saturate(dot(normalize(*saturate(dot(input.Normal,input.Light))*input.Normal-input.Light),input.VecEye)),);//镜面高光 return vAmbient+vDiffuse+vSpecular;
} technique SpecularLight
{
pass Pass0
{
VertexShader = compile vs_2_0 VertexShaderFunction();
PixelShader = compile ps_2_0 PixelShaderFunction();
}
}

fx中的代码为了更好的展示各个光照的公式效果,代码上没有简化,其次需要注意光照方向Light,相机指向物体的位置VecEye,以及物体表面的法线这几个向量一定要记得单位化,利用fx里面自带的normalize方法,最后看看效果图:

感觉效果挺好的,也领略到了HLSL的魅力,继续学习.......

HLSL之镜面反射光照的更多相关文章

  1. HLSL之漫反射光

    整整忙了一个月了,总算清闲下来了,从上次写完环境光后又过了这么长时间,继续学习......加油!!今天整理下漫反射光并记录下来,那就直接进入主题吧,开始漫反射光的学习. 漫反射光是在环境光的基础上添加 ...

  2. [图形学] Chp17 OpenGL光照和表面绘制函数

    这章学了基本光照模型,物体的显示受到以下效果影响:全局环境光,点光源(环境光漫反射分量,点光源漫反射分量,点光源镜面反射分量),材质系数(漫反射系数,镜面反射系数),自身发光,雾气效果等.其中点光源有 ...

  3. [CG编程] 基本光照模型的实现与拓展以及常见光照模型解析

    0.前言 这篇文章写于去年的暑假.大二的假期时间多,小组便开发一个手机游戏的项目,开发过程中忙里偷闲地了解了Unity的shader编写,而CG又与shaderLab相似,所以又阅读了<CG教程 ...

  4. 西川善司【神秘海域(Uncharted)】的图形分析

          本文是为传播0月8日发售的[神秘海域 合集]魅力而短篇连载的第2回,这次主要集中在神秘海域系列的图形的技术方面.原文链接在 http://weekly.ascii.jp/elem/000/ ...

  5. RenderMonkey 练习 第二天 【opengl 光照模型】

    光照模型 3D渲染中, 物体表面的光照计算公式为: I = 环境光(Iambient) + 漫反射光(Idiffuse) + 镜面高光(Ispecular); 其中,环境光(ambient)计算公式为 ...

  6. Elays'Blog

    文章导航 阴影的重要意义 阴影是光线被阻挡的结果,它能够使场景看起来真实很多,可以让观察者获得物体之间的空间位置关系.如下图所示: 图1 可以看到,有阴影的时候能够更容易的看出立方体是悬浮在地板上的. ...

  7. CSharpGL(39)GLSL光照示例:鼠标拖动太阳(光源)观察平行光的漫反射和镜面反射效果

    CSharpGL(39)GLSL光照示例:鼠标拖动太阳(光源)观察平行光的漫反射和镜面反射效果 开始 一图抵千言.首先来看鼠标拖动太阳(光源)的情形. 然后是鼠标拖拽旋转模型的情形. 然后我们移动摄像 ...

  8. DirectX11 With Windows SDK--07 添加光照与常用几何模型

    前言 对于3D游戏来说,合理的光照可以让游戏显得更加真实.接下来会介绍光照的各种分量,以及常见的光照模型.除此之外,该项目还用到了多个常量缓冲区,因此还会提及HLSL的常量缓冲区打包规则以及如何设置多 ...

  9. Obj模型功能完善(物体材质,光照,法线贴图).Cg着色语言+OpenTK+F#实现.

    这篇文章给大家讲Obj模型里一些基本功能的完善,包含Cg着色语言,矩阵转换,光照,多重纹理,法线贴图的运用. 在上篇中,我们用GLSL实现了基本的phong光照,这里用Cg着色语言来实现另一钟Blin ...

随机推荐

  1. [家里蹲大学数学杂志]第056期Tikhonov 泛函的变分

    设 $\scrX$, $\scrY$ 是 Hilbert 空间, $T\in \scrL(\scrX,\scrY)$, $y_0\in\scrY$, $\alpha>0$. 则 Tikhonov ...

  2. XE6移动开发环境搭建之IOS篇(5):解决Windows和虚拟机下Mac OSX的共享问题(有图有真相)

    网上能找到的关于Delphi XE系列的移动开发环境的相关文章甚少,本文尽量以详细的图文内容.傻瓜式的表达来告诉你想要的答案. 原创作品,请尊重作者劳动成果,转载请注明出处!!! 在安装XE6 PAS ...

  3. Quartus II中FPGA的管脚分配保存方法

    一.摘要 将Quartus II中FPGA管脚的分配及保存方法做一个汇总. 二.管脚分配方法 FPGA 的管脚分配,除了在QII软件中,选择“Assignments ->Pin”标签(或者点击按 ...

  4. Django views 中的 shortcut function

    shortcut function都在django.shortcuts这个包中,主要包含有:render(), render_to_response(), redirect(), get_object ...

  5. oracle 常见恢复

    author by :shawnloong 环境:windows 2008 r2 sp1 db:oracle 11g r2 做之前记得做个完整备份 ONFIGURE RETENTION POLICY ...

  6. 使用JDBC处理MySQL大数据

    一.基本概念 大数据也称之为LOB(Large Objects),LOB又分为:clob和blob,clob用于存储大文本,blob用于存储二进制数据,例如图像.声音.二进制文等. 在实际开发中,有时 ...

  7. Opera放弃自家内核转投WebKit的背后(转)

    Opera在2月13日宣布用户突破3亿,并且带着这3亿用户投入WebKit阵营,自家的Presto内核将会走入历史.Opera为什么选择在现在这个时间点放弃自有内核?之前Opera的坚持自主研发一直被 ...

  8. MySQL 常用命令(持续更新)

    停止启动MySQL服务 停止:net stop mysql启动:net start mysql 查看正在运行的线程 SHOW PROCESSLIST SHOW FULL PROCESSLIST 杀死线 ...

  9. c++ primer 5th 练习3.43

    #include <iostream> using namespace std; int main() { ][]={,,,,,,,,,,,}; /* for(int (&i)[4 ...

  10. ajax XML

    <script src="jquery-1.11.2.min.js"></script> </head> <body> <se ...