blinn-phong高光:

H=normalize(V+L);


specular=pow(saturate(dot(N,H)),shiness);

会遇到如下问题:

图中光源在surface背面,但却仍然产生高光。(可以验证,不使用半角向量h,而使用反射向量r的原始phong高光也存在类似问题。)

此问题的一种简单解决办法,是判断出光源在surface背面则令specular为0,即:

H=normalize(V+L);


specular=pow(saturate(dot(N,H)),shiness);

if(dot(N,L)<0){

  specular=0;

}

这样确实能避面背光面产生高光,但是在背光面和受光面之间高光突然截断会产生过硬的明暗交界线。

也见过有算法是用specular直接乘以一下diffuse,从而获得柔和过度,但往往会过于柔和。

为了使交界线处过度柔和且柔和程度可控,可以采用如下技巧:

首先不难看出上面代码等价于:

H=normalize(V+L);


specular=pow(saturate(dot(N,H)),shiness);

specular*=step(0,dot(N,L));

为使过度平滑,只需用smoothstep代替step,即:

H=normalize(V+L);


specular=pow(saturate(dot(N,H)),shiness);

specular*=smoothstep(0,0.12,dot(N,L));

这样就ok了。

注:smoothstep(0,0.12,dot(N,L))的含义就是:当dot(N,L)<0时,取0;当dot(N,L)>0.12时取1,当dot(N,L)介于0与0.12之间时平滑插值。

blinn-phong高光反向穿透问题的更多相关文章

  1. 用DirectX12实现Blinn Phong

    这次我们来用DirectX12实现一下基本的Blinn Phong光照模型.让我们再把这个光照模型的概念过一遍:一个物体的颜色由三个因素决定:ambient, diffuse, specular.am ...

  2. Unity-Shader-镜面高光Phong&BlinnPhong-油腻的师姐在哪里

    [旧博客转移 - 2016年4月4日 13:13 ] 油腻的师姐: 以前玩过一款很火热的端游<剑灵>,剑灵刚出来的时候,某网页游戏广告视频中有句台词:"我不断的在寻找,有你的世界 ...

  3. Unity3D ShaderLab 使用BlinnPhong高光类型

    Unity3D shaderLab 使用BlinnPhong高光类型 上一篇我们实现了自定义高光类型,这一篇,我们说Blinn高光,它是另一种计算和估算高光更高效的方式,它是通过视线防线和光线方向,所 ...

  4. Unity3D ShaderLab 创建自定义高光类型

    Unity3D ShaderLab 创建自定义高光类型 在上一篇,我们认识了Unity基础的高光实现,本次主要是研究如何对Phong高光类型进行顶点操作,以及在表面着色器中使用Input结构体的新参数 ...

  5. 基础知识:Q&A

    1.点乘几何意义? >0,a,b同向,=1时,方向完全相同 =0,垂直 <0,反向,=-1时,方向完全相反 2.叉乘几何意义?叉乘得到的向量的方向怎么确定? aXb ,可以得到 同时垂直于 ...

  6. Opengles 管线编程介绍

      OpenGL ES 2.0可编程管道 上图橙色部分(Vertex Shader和Fragment Shader)为此管道的可编程部分.整个管道包含以下两个规范: 1)         OpenGL ...

  7. 【Aladdin Unity3D Shader编程】之三 光照模型(二)

    高光反射模型 Specular=直射光*pow(cosθ,高光的参数) θ:是反射光和视野方向的夹角 编写高光反射Shader Shader "AladdinShader/07 Specul ...

  8. 【Unity Shader】(六) ------ 复杂的光照(上)

    笔者使用的是 Unity 2018.2.0f2 + VS2017,建议读者使用与 Unity 2018 相近的版本,避免一些因为版本不一致而出现的问题.              [Unity Sha ...

  9. 三种光照模型的shader实现

    1.Lambert模型,公式为I=Kd*Il(N*L): Shader "Custom/Lambert_A" { Properties { _Diffuse(,,,) } SubS ...

随机推荐

  1. java中关于重载与重写的区别

    1.重载 允许多个同名但是形式参数个数或参数类型不同的方法存在同一个类中,在调用时根据形式参数列表来调用对应的方法. 2.判断 (1):方法名必须相同. (2):形式参数个数不同或者参数类型不同(满足 ...

  2. Linux 之 Makefile 报错

    1. 在make命令后出现这种错误提示,是提示第4行没有分隔符. 例如: 1 target:prerequisites ...... 4 command …… 改为: 1 target:prerequ ...

  3. 解决Ubuntu无法进行SSH连接的问题(以及如何使用SSH)

    我们在VM中安装好Ubuntu 虚拟机后,经常需要使用Xshell.ssh等工具进行远程连接,方便我们在两个操作系统中进行文件的复制与移动,但是有时候会出现无法连接的问题,原因可能是Ubuntu中默认 ...

  4. Flutter常用组件(Widget)解析-Image

    显示图片的组件 以下是几种加载图片路径方式: Image.asset 加载asset项目资源中的文件 Image.network 加载网络资源图片,通过url加载 Image.file 加载本地文件中 ...

  5. go语言学习-结构体

    结构体 go语言中的结构体,是一种复合类型,有一组属性构成,这些属性被称为字段.结构体也是值类型,可以使用new来创建. 定义: type name struct { field1 type1 fie ...

  6. IdentityServer4-介绍

    一.总体介绍 大多数现代应用或多或少是这样的: 通常,每个层(前端.中间层和后端)都必须保护资源并实现身份验证和/或授权——通常针对相同的用户存储. 将这些基本的安全功能外包给安全令牌服务,可以防止在 ...

  7. 洛谷.1486.[NOI2004]郁闷的出纳员(Splay)

    题目链接 /* BZOJ1503: 3164kb 792ms/824ms(新建节点) 洛谷 : 3.06mb 320ms/308ms(前一个要慢wtf 其实都差不多,但前者好写) 四种操作: A:所有 ...

  8. 潭州课堂25班:Ph201805201 并发(协程) 第十五课 (课堂笔记)

    #斐波那契 def fid(n): res = [] indx = 0 a = 0 b = 1 while indx < n : res.append(b) a,b = b,a+b indx + ...

  9. [USACO09OPEN]捉迷藏Hide and Seek

    OJ题号:洛谷2951 思路:Dijkstra+堆优化.注意是无向图,所以加边时要正反各加一遍. #include<cstdio> #include<vector> #incl ...

  10. 使用time模块,转化时间格式

    import time ''' 时间戳:表示1970年开始计算的偏移量.我们运用type(时间戳)是float类型 结构化时间:9个元素组成的数组 格式化时间字符串 ''' '''获取当前时间戳''' ...