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

镜面反射光照公式: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. Spring技术揭幕----DispatcherServlet

    Spring MVC是一个MVC模式的实现.在Spring MVC的使用中,需要在web.xml中配置DispatcherServlet,也就是说其核心是一个Servlet,这个DispatcherS ...

  2. android StringBuffer类的使用

    参考 http://www.cnblogs.com/springcsc/archive/2009/12/03/1616330.html StringBuffer类和String一样,也用来代表字符串, ...

  3. EBS R12重启后无法进入登录页面

    应用启动正常,但无法进入登录页面: The webpage cannot be found HTTP 404 ... No known changes had been made and the Mi ...

  4. 七、context command

    context command是用来新建自己的工具,可以调用OPENGL,获取鼠标操作函数,在view窗口画自己想画的东西.(我是这麽理解的,可以以后再确定一下) 下面是一个context comma ...

  5. 伪静态URLRewrite学习笔记

    UrlRewrite: UrlRewrite就是我们通常说的地址重写,用户得到的全部都是经过处理后的URL地址,类似于Apache的mod_rewrite.将我们的动态网页地址转化为静态的地址,如ht ...

  6. 洛谷P3374 【模板】树状数组 1

    P3374 [模板]树状数组 1 140通过 232提交 题目提供者HansBug 标签 难度普及/提高- 提交  讨论  题解 最新讨论 题目描述有误 题目描述 如题,已知一个数列,你需要进行下面两 ...

  7. jQuery图片渐变特效的简单实现

    (document).ready(function() {(document).ready(function() {("div.baba").mouseleave(function ...

  8. ssh IP打通,hadoop启动失败

    ssh ip 无密码打通,hadoop启动失败 报错为:host'主机名' can't be established. 纠结了接近一个多小时 之后必须ssh 主机名 , yes一下,发现hadoop能 ...

  9. Excel_常用快捷键

    Ctrl+B        粗体Ctrl+U         下划线Ctrl+I         斜体Ctrl+5      删除线Ctrl+9      隐藏选中的行Ctrl+0      隐藏选中 ...

  10. vbs获取命令行里的参数

    var args1=WScript.Arguments.Item(0) var args2=WScript.Arguments.Item(1)