《The Complete Effect and HLSL Guide》翻译连载(十二)

《The Complete Effect and HLSL Guide》翻译连载(一)                    哦~~~~。好久没有更新了,决定把近期写的一点东西贴上来。工作了三个月之后终于辞职了,找个理想的工作怎么就那么难呢??       我的demo进展缓慢,数学、数学、数学,天啊,总是在细节出错!!!       怀念昆明温暖的天气,呼呼 ^o^ The Complete Effect and HLSL Guide--Sebastien St-Lau 阅读详情

The Complete Effect and HLSL Guide(十二) 

  本文版权归原作者所有,仅供个人学习使用,请勿转载,勿用于任何商业用途。
由于本人水平有限,难免出错,不清楚的地方请大家以原著为准。欢迎大家和我多多交流。
翻译:clayman
Blog:
http://blog.youkuaiyun.com/soilwork
clayman_joe@yahoo.com.cn 
 

   我们已经有了个一个漫反射点光源着色器,现在应该考虑光照方程中的高光部分了。和漫反射相比,镜面高光最大的区别就是光照亮度不但与光线到表面的角度有关,还和观察者的角度有关。

       为了计算高光,我们需要一个称为中间(half)矢量的值。这个矢量其实是观察矢量和灯光矢量的中间值。为了计算观察矢量需要把观察点变换到模型空间。我们假设观察点的位置位于( 0,0,10)。把它变换到模型空间之后,加上顶点位置,就是最终的观察矢量:

 

       EyeVector = -normal(mul ( inv_view_matrix, float4(0,0,10,1) + inPos);

 

       把EyeVector与光源矢量混合到一起,然后进行标准化,就是中间矢量。由于EyeVector和LightDir都是标准矢量,所以中间矢量相当于二者的均值(A + B)/ 2。

 

       HalfVect = normalize ( LightDir – EyeVetor);

       (译注:更直观的做法是在世界坐标下计算EyeVector,然后用LightDir + EyeVetor计算HalfVect)

       有了中间矢量,把它和表面法线的点积进行m次幂运算,就能算出光源基于角度的光线强度。幂运算时的指数相当于物体的镜面指数,值越大,高光区域就越小也越明亮。下面的代码假设镜面指数为32。

 

struct VS_OUTPUT

{

       float4 Pos:      POSITION;

       float2 texCoord: TEXCOORD0;

       float2 Color: COLOR;

};

 

float4 Light_PointSpecular( float3 VertPos, float3 VertNorm,float3 LightPos,

              float4 LightColor, float4 Lightattenuation, float3 EyeDir)

{

       //Determine the Distance from the light to the vertex and the direction

       float3 LightDir = LightPos - VertPos;

       float Dis = length(lightDir);

       LightDir = LightDir / Dist;   

       //Computer half vector

       float3 HalfVect = normalize( LightDir = EyeDir);     

       //Compute distance based attenuation. this is defined as:

       //Attenuation = 1/(LA.x + LA.y * Dist + LA * Dist * Dist)

       float DistAttn = saturate( 1 / ( LightAttenuation.x + LightAttenuation.y * Dist +

                     LightAttenuation.z * Dist * Dist));

       float SpecularAttn = pow(saturate ( dot(VertNorm,HalfVect)),32);      

       //Compute finfal lighting

       return LightColor * DistAttn * SpecularAttn;

}

 

VS_OUTPUT vs_main( float4 inPos:POSITION,float3 inNormal: NORMAL ,float2 inTxr:TEXCOORD0)

{

       VS_OUTPUT Out;

       //compute the projected positon and send out the texture coordinates

       Out.Pos = mul(View_proj_matrix,inPos);

       Out.TexCoord = inTxr;      

       //Output the ambient Color

       float4 Color = Light_Ambient;

       //Determine the eye vector

       float3 EyeVector = -normlaize(mul(inv_view_matrix,float4(0,0,10,1)) + inPos);      

       //computer the light contribution

       Color = Light_PointSpecular(inPos,inNormal,Light1_Position,Light1_Color,Lihgt_Attenuation,

              EyeVector);     

       //Output Final Color

       Out.Color = Color;

       return Out

}

 

       当考虑光照时,大部分人都认为逐顶点的光照足够好了。对于镶嵌度较高的模型来说是这样,但对某些复杂或的精度模型来说却不一定。出现这种效果的原因是顶点间颜色插值的方式。

       当逐顶点照亮对象时,将为每个顶点计算一次光照颜色,然后在通过顶点在多边形所覆盖的区域对像素颜色进行线形插值。现实中,光照值取决于光线角度,表面法线,和观察点(对于镜面高光来说)。与逐像素对所有光照元素进行单独插值,再计算光照相比,直接对顶点颜色进行插值所得的结果通常不够精确,特别是对面积较大的多边形来说。

(左图为per-pixel lighting,右图为per-vertex)

      

       上图显示了逐像素和逐顶点光照的差别。当处理高精度多边形模型时,由于每个多边形所覆盖的区域很小,因此插值之后每个像素的误差也很小,所以逐顶点光照可以工作的很好。而当处理低模时,这种误差就变的很大了。

       使用逐像素光照的另一个好处是可以在渲染时添加并不存在的表面细节。通过bump map或normal map,可以在像素级别让原本平坦的表面表现出近似的凹凸效果。

       再回过头来看看漫反射光线,你需要决定哪些光照元素可以插值之后传送到像素着色器,哪些元素必须逐像素计算。从头到尾,决定漫反射光照的就是表面法线和光线矢量的点积。

       这个点积定义了光照的强度,但是对它进行插值的结果通常不正确。因此这一步计算应该移动到像素着色器中,进行逐像素计算。

       表面法线和光矢量是计算点积的要素。通常矢量间的插值是正确的。因此可以在顶点着色器计算他们的值,并传递到像素着色器中,然后进行最终的点积计算。

 

注意


虽然对法线的插值是正确的,但是插值之后的向量将不再是标准向量。为了对此进行校正,需要在像素着色器中对法线重新进行标准化,可以使用内建的normalize函数。

      

       为了把光照计算移动到像素着色器中,需要先添加两个变量到顶点着色器的输出结构中。可以使用TEXCOORD1和TEXCOORD2语义把这些值传递到像素着色器。代码如下:

 

struct VS_OUTPUT

{

        float4 Pos : POSITION;

        float2 TexCoord: TEXCOORD0;

        float3 Normal : TEXCOORD1;

        float3 LightDir: TEXCOORD2;

}

 

       接下来修改顶点着色器代码。目前我们只考虑单光源光照的情况,所以先删除原先的光照函数把其中的代码复制到vs_main函数中。记住,我们后面回讨论多光源的情况。

       你可能已经注意到我们还没有讨论基于距离的衰减值应该在哪里计算。虽然对距离的插值结果不是完全正确,但由于光线的变化有足够容差范围,距离上的微小差别并不会给结果带来明显变化,所以不需要逐像素计算。

       衰减值只是一个标量,为了把它传递给像素着色器,而又不浪费一个额外的寄存器来传值,可以把LightDir改为一个float4的矢量,把衰减值作为这个矢量的w分量。修改后的顶点着色器如下:

 

VS_OUTPUT vs_main(float4 inPos:POSITION,float3 inNormal: NORMAL ,

       float2 inTxr: TEXCOORD0)

{

       VS_OUTPUT Out; 

       Out.Pos = mul( view_proj_matrix, inPos);

       Out.TexCoord = inTxr;

       Out.Normal = inNormal;   

       //Computer and move the light direction to the pixel shader

       float4 LightDir;

       LightDir.xyz = Light1_Position - inPosition;

       float Dist = length(LightDir.xyz);

       LightDir.xyz = LightDir.xyz / Dist;    

       LightDir.w = saturate( 1 / ( LightAttenuation.x + LightAttenuation.y * Dist +

                     LightAttenuation.y * Dist*Dist));  

       //Output the light direction

       Out.LightDir = lightDir;

       return Out;

}

 

       在像素着色器中,只需要接收参数,计算点击和颜色就可以了。为了方便,把光照计算单独放到一个名为Light_PointDiffuse的函数中。本质上来说,这里计算光照的方法和在顶点着色器中是一样的。

 

float4 Light_PointDiffuse(float4 LightDir, float3 Normal ,Float4 LightColor)

{

       //compute dot product of N and L

       float AngleAttn = saturate(dot( Normal ,LightDir.xyz));

       //compute final lighting

       return LightColor * LightDir.w * AngleAttn;

}

 

float4 ps_main(float3 inNormal:TEXCOORD1,

       float4 inLightDir : TEXCOORD2) : COLOR

{

       //Compter the lighting contribution for this single light

       return Light_PointDiffuse(inLightDir,inNormal,Light_Color);

}

 

       很简单,对吧!接下来编写镜面高光像素着色器。整个步骤基本上和我们刚才编写漫反射像素着色器的方法差不多。这一个shader的核心是法线和中间矢量的点积,需要把它们移动到像素着色器中。这意味着需要在顶点着色器中计算光照矢量,中间矢量。先修改顶点着色器的输出结构。

 

struct VS_OUTPUT

{

       float4 pos: POSITION;

       float2 TexCoord: TEXCOORD0;

       float3 Normal : TEXCOORD1;

       float4 LightDir: TEXCOORD2;

       float3 HalfVect: TEXCOORD3;

}

 

       在顶点着色器中,需要计算以下值:表面法线,光照矢量,中间矢量和基于距离的衰减值。只需要把先前编写的镜面高光着色器代码稍作修改就行了。

VS_OUTPUT vs_main(float4 inPos:POSITION,float3 inNormal: NORMAL ,

              float2 inTxr: TEXCOORD0)

{

       VS_OUT Out;
   
   Out.Pos = mul(view_proj_matrix, inPos);
       Out.TexCoord = inTxr;
       float4 LightDir;

 

       LightDir.xyz = Light1_Position - inPos;

       flaot Dist = length(LightDir.xyz);

       LightDir.xyz = LightDir.xyz / Dist;

 

       LightDir.w = saturate( 1 / ( LightAttenuation.x + LightAttenuation.y * Dist +  LightAttenuation.y * Dist*Dist));    

       //computer eye vector and the half vector

       float3 EyeVector = -normalize(mul(inv_view_matrix,float4(0,0,10,1))+inPos);

       Out.HalfVect = normalize(LightDir - EyeVector);    

       //Output normal and light direction

       Out.Normal = inNormal;

       Out.LightDir = LightDir; 

       return Out;

}

 

       对像素着色器来说,同样把计算高光的代码作为一个单独的函数:

 

float4 Light_PointSpecular(float3 Normal ,flaot3 HalfVect,float4 LightDir,float4 LightColor)

{

       float SpecularAttn = pow(saturate(dot( Normal ,HalfVect)),32);

       return LightColor * LightDir.w * SpecularAttn;

}

 

float4 ps_main(float3 inNormal:TEXCOORD1,float4 LightDir:TEXCOORD2,

              float3 HalfVect:TEXCOORD3):COLOR

{

       //simply route teh vertex color to the output

       return Light_PointSpecular(inNormal,HalfVect,LightDir,Light1_Color);

}

~~~~~~~~未完待续~~~~~~~~~~~~~~~~

 

《The Complete Effect and HLSL Guide》翻译连载(十一)  The Complete Effect and HLSL Guide(十一) 本文版权归原作者所有,仅供个人学习使用,请勿转载,勿用于任何商业用途。由于本人水平有限,难免出错,不清楚的地方请大家以原著为准。欢迎大家和我多多交流。翻译:claymanBlog:http://blog.youkuaiyun.com/soilworkclayman_joe@yahoo.com.cn  第四章 Shader示 阅读详情

相关推荐

《The Complete Effect and HLSL Guide》翻译连载(二)

The Complete Effect and HLSL Guide(二)本文版权归原作者所有,仅供个人学习使用,请勿转载,勿用于任何商业用途。由于本人水平有限,难免出错,不清楚的地方请大家以原著为准。欢迎大家和我多多交流。翻译:claymanBlog:http://blog.youkuaiyun.com/soilworkclayman_joe@yahoo.com.cn 一点点历史….  

Clayman的专栏 1万+

《The Complete Effect and HLSL Guide》翻译连载(七)

The Complete Effect and HLSL Guide(七) 本文版权归原作者所有,仅供个人学习使用,请勿转载,勿用于任何商业用途。由于本人水平有限,难免出错,不清楚的地方请大家以原著为准。欢迎大家和我多多交流。翻译:claymanBlog:http://blog.youkuaiyun.com/soilworkclayman_joe@yahoo.com.cn 分量访问和重组 

Clayman的专栏 5386

The Complete Effect and HLSL Guide

不是英文的原版,我花了几周的时间都没有找到,只是中文的前三章。 绝不是有意而为,上传的太多东西,有点糊涂了。 整理的时间和上传的时间间隔有些远,记不太清楚的缘故。 不好意思。

《The Complete Effect and HLSL Guide》翻译连载(六)

The Complete Effect and HLSL Guide(六) 本文版权归原作者所有,仅供个人学习使用,请勿转载,勿用于任何商业用途。由于本人水平有限,难免出错,不清楚的地方请大家以原著为准。欢迎大家和我多多交流。翻译:claymanBlog:http://blog.youkuaiyun.com/soilworkclayman_joe@yahoo.com.cn  第二章 HLSL着色语

Clayman的专栏 8863

产业园区如何高效对接企业技术需求与高校科研成果?.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

国央企创新负责人如何快速掌握本地科技资源分布与匹配情况?.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

《The Complete Effect and HLSL Guide》翻译连载(八)

The Complete Effect and HLSL Guide(八) 本文版权归原作者所有,仅供个人学习使用,请勿转载,勿用于任何商业用途。由于本人水平有限,难免出错,不清楚的地方请大家以原著为准。欢迎大家和我多多交流。翻译:claymanBlog:http://blog.youkuaiyun.com/soilworkclayman_joe@yahoo.com.cn定义变量 

Clayman的专栏 8456

基于Simulink的二相混合式步进电机驱动器快速建模与仿真实践

本文详细介绍了如何利用Simulink对二相混合式步进电机驱动器进行快速建模与仿真。通过从零搭建电机数学模型、设计H桥控制逻辑,并集成步进时序,手把手指导读者创建可运行的仿真模型文件。该方法能有效验证控制策略,避免硬件调试风险,是学习与实践电机驱动开发的理想途径。

weixin_29171087的博客 148

《The Complete Effect and HLSL Guide》翻译连载(五)

The Complete Effect and HLSL Guide(五) 本文版权归原作者所有,仅供个人学习使用,请勿转载,勿用于任何商业用途。由于本人水平有限,难免出错,不清楚的地方请大家以原著为准。欢迎大家和我多多交流。翻译:claymanBlog:http://blog.youkuaiyun.com/soilworkclayman_joe@yahoo.com.cn词汇约定       

Clayman的专栏 5687

在win10-wsl2(ubuntu)中安装jlink

在 官方下载linux版本的deb包拷贝到ubuntu的/home目录下(其他目录也可以),进行安装然后提示很多依赖缺失的错误,此时执行自动安装需要的依赖包再次重新安装就可以啦查看是否安装成功,输入JLink 再按下两次Table键,是否如下所示这样表示安装成功了。

yaq_30401的博客 3140

HC32F460的GPIO重映射实战:如何用3步搞定SPI引脚冲突问题

本文详细介绍了HC32F460的GPIO重映射功能,通过三步操作解决SPI引脚冲突问题。文章解析了HC32F460的FuncGroup功能分组机制,提供了具体的寄存器配置步骤和验证技巧,并对比了与传统方案的性能优势,帮助工程师灵活配置引脚,优化硬件设计。

t4y5u6i7o的博客 918

《The Complete Effect and HLSL Guide》翻译连载(九)

The Complete Effect and HLSL Guide(九) 本文版权归原作者所有,仅供个人学习使用,请勿转载,勿用于任何商业用途。由于本人水平有限,难免出错,不清楚的地方请大家以原著为准。欢迎大家和我多多交流。翻译:claymanBlog:http://blog.youkuaiyun.com/soilworkclayman_joe@yahoo.com.cn  第三章 函数,

Clayman的专栏 6267

点云工具CloudCompare下载、安装与汉化

打开软件后,是英文界面,找到菜单栏【Display】-【Language Translation】,选择简体中文。进入官网后,点击菜单栏【Download】提示需要重启软件才能生效,点OK即可。重启软件后,已经是中文了。选择合适系统进行下载。常规软件安装流程即可。

sagima_sdu的博客 1万+

《The Complete Effect and HLSL Guide》翻译连载(三)

The Complete Effect and HLSL Guide(三)本文版权归原作者所有,仅供个人学习使用,请勿转载,勿用于任何商业用途。由于本人水平有限,难免出错,不清楚的地方请大家以原著为准。欢迎大家和我多多交流。翻译:claymanBlog:http://blog.youkuaiyun.com/soilworkclayman_joe@yahoo.com.cn   

Clayman的专栏 1万+

AI 测试工程师 — 6 个月学习计划表

AI 转型测试工程师 —— 6 个月学习计划表

weixin_46453070的博客 1068

用一张分析型 CDS Query 看清争议案件新增与结案节奏:C_OpenClosedDisputeCase 深度解读

应收账款争议管理中的关键CDS视图分析 摘要:C_OpenClosedDisputeCase是SAP系统中用于监控应收账款争议案件的重要CDS视图,提供三个时间窗口(当日、近5天、当月)的新增与结案数据。该视图通过"创建vs解决"的净变化指标,帮助财务团队实时掌握争议管理趋势,特别适用于多币种跨国企业的现金流管理。其核心价值在于将争议管理从被动"救火"转变为可量化运营,通过统一汇率换算和关键日期参数,为管理层提供标准化的运营仪表盘。视图采用特权访问模式,需通过上层应用

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 122

《The Complete Effect and HLSL Guide》翻译连载(十)

 The Complete Effect and HLSL Guide(十) 本文版权归原作者所有,仅供个人学习使用,请勿转载,勿用于任何商业用途。由于本人水平有限,难免出错,不清楚的地方请大家以原著为准。欢迎大家和我多多交流。翻译:claymanBlog:http://blog.youkuaiyun.com/soilworkclayman_joe@yahoo.com.cn 自定义函数  

Clayman的专栏 5081

硬方案——几种实用的恒流源电路设计方案,敬请收藏(运放、三极管在手,让你玩出多种花样)

0 引言 我们在信号测量、供电等应用场景时常会涉及到使用恒流源,以前觉得恒流源挺神奇的,研究了下实现方案,其实也没有多么高深(这里讨论的仅限于用在信号测量中的小电流恒流源设计),这里给出几个实用的恒流源电路设计方案。 1 恒流源电路设计 (1)使用三极管搭建的恒流源 (2)使用运放搭建的恒流源 (3)使用恒流二极管搭建的恒流源 pt100恒流源测温电路图_电子技术_电工之家 ...

数字世界 万物互联 9524

《The Complete Effect and HLSL Guide》翻译连载(四)

The Complete Effect and HLSL Guide(四) 本文版权归原作者所有,仅供个人学习使用,请勿转载,勿用于任何商业用途。由于本人水平有限,难免出错,不清楚的地方请大家以原著为准。欢迎大家和我多多交流。翻译:claymanBlog:http://blog.youkuaiyun.com/soilworkclayman_joe@yahoo.com.cn~~~~~~~~~~~

Clayman的专栏 8467

【VTKExamples::PolyData】第十六期 GradientFilter

本文分享VTK样例GradientFilter,并解析接口vtkGradientFilter & vtkAssignAttribute,希望对各位小伙伴有所帮助!

qq_40041064的博客 319

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

搬家了,新地址http://www.cnblogs.com/clayman/

   终于决定搬家,难用都还可以勉强忍受,可是最近居然开始乱封blog了,怕怕。可惜那么多文章带不走,手动把部份我觉得比较有价值的文章搬过去了。呵呵,欢迎大家有空过去看看:)。 此blog将不再更新...........

Clayman的专栏 18万+

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Effect & HLSL Guide – Semantics(十三)

Effect & HLSL Guide – Semantics(十三) 本文版权归我所有,仅供个人学习使用,请勿转载,勿用于任何商业用途。由于本人水平有限,难免出错,欢迎大家和我交流。作者:claymanBlog:http://blog.youkuaiyun.com/soilworkclayman_joe@yahoo.com.cn           介绍HLSL或者DirectX / X

Clayman的专栏 6296

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

上一篇: 值类型属性??
下一篇: content pipeline without volume texture support???!!!
soilwork
博客等级 码龄23年 290粉丝 116原创
评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值