shader篇-漫反射


  • shader篇-漫反射
  • 背景
  • 逐顶点光照
  • 逐像素光照
  • 半兰伯特光照模型

之前只是草草看了书,隔了一两个月回头看,很多都忘了,学习方法不对啊,希望利用写博客加深对知识的理解吧。

背景

渲染包含两大部分:像素可见性和光照计算。
今天就是介绍如何利用shader仿真现实世界中的漫反射。
漫反射计算公式如下

Cdiffuse=(Clight∗Mdiffuse)∗max(0,n⃗ ∗l⃗ )

C_{diffuse}=(C_{light}*M_{diffuse})*max(0,\vec{n}*\vec{l})
计算漫反射需要四个参数,入射光颜色,强度

Clight

C_{light},材质反射系数

Mdiffuse

M_{diffuse},表面法线n和光源方向l

逐顶点光照

 Shader "Test Shader/VertexLevel"{
Properties
{_Diffuse ("DiffuseName",Color)=(1,1,1,1)
}
SubShader
{Pass{Tags{"LightMode"="ForwardBase"}CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"#include "Lighting.cginc"fixed4 _Diffuse;struct a2v{//模型空间的顶点坐标float4 vertex:POSITION;//模型空间的法线方向float3 normal:NORMAL;};struct v2f{//输出的是裁剪空间的顶点坐标float4 pos:SV_POSITION;float3 color:COLOR;};v2f vert(a2v v){v2f o;//利用unity内置的模型-观察-投影矩阵将顶点坐标转换到裁剪空间o.pos=UnityObjectToClipPos(v.vertex);//通过内置变量获取环境光fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.xyz;//法线转换到世界坐标//unity_WorldToObject为模型空间到世界空间的变换矩阵的逆矩阵fixed3 worldNormal=normalize(mul(v.normal,(float3x3)unity_WorldToObject));//获取光源方向fixed3 worldLight=normalize(_WorldSpaceLightPos0.xyz);//利用漫反射光照公式计算漫反射fixed3 diffuse=_LightColor0.rgb*_Diffuse.rgb*max(0,dot(worldNormal,worldLight));//漫反射和环境光相加得到最终的光照结构o.color=ambient+diffuse;return o;}fixed4 frag(v2f i):SV_Target{return fixed4(i.color,1.0);}ENDCG}
}
FallBack "DiffuseFallBack"

把这个shader文件添加给某个材质,再把该材质添加到角色中,就能得到简单的漫反射效果
不过这样的漫反射会出现一些视觉问题,背光面和光面交界处有锯齿

逐像素光照

Shader "Test Shader/DiffusePixelLevel"{
Properties
{_Diffuse ("DiffuseName",Color)=(1,1,1,1)
}
SubShader
{Pass{Tags{"LightMode"="ForwardBase"}CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"#include "Lighting.cginc"fixed4 _Diffuse;struct a2v{//模型空间的顶点坐标float4 vertex:POSITION;//模型空间的法线方向float3 normal:NORMAL;};struct v2f{//输出的是裁剪空间的顶点坐标float4 pos:SV_POSITION;float3 worldNormal:TEXCOORD0 ;};v2f vert(a2v v){v2f o;//利用unity内置的模型-观察-投影矩阵将顶点坐标转换到裁剪空间o.pos=UnityObjectToClipPos(v.vertex);//法线转换到世界坐标//unity_WorldToObject为模型空间到世界空间的变换矩阵的逆矩阵o.worldNormal=mul(v.normal,(float3x3)unity_WorldToObject);return o;}fixed4 frag(v2f i):SV_Target{//通过内置变量获取环境光fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.xyz;fixed3 worldNormal=normalize(i.worldNormal);//获取光源方向fixed3 worldLight=normalize(_WorldSpaceLightPos0.xyz);//利用漫反射光照公式计算漫反射//saturate(x)和max(0,x)能达到同样的效果,他的作用是把x截取到[0,1]范围内fixed3 diffuse=_LightColor0.rgb*_Diffuse.rgb*saturate(dot(worldNormal,worldLight));fixed3 color=ambient+diffuse;return fixed4(color,1.0);}ENDCG}
}
FallBack "DiffuseFallBack"}

把计算挪到片元着色器中完成了逐像素光照,逐像素光照更平滑
不过这2种着色效果造成模型外观呈黑,
我们用半兰伯特光照模型解决这一问题

半兰伯特光照模型

Cdiffuse=(Clight∗Mdiffuse)∗(α∗(n⃗ ∗l⃗ )+β)

C_{diffuse}=(C_{light}*M_{diffuse})*(\alpha*(\vec{n}*\vec{l})+\beta)
这里并没有使用max操作防止n,l点积为负值,而是对结果进行了一个a倍的缩放加上一个B大小的偏移,大多数情况下,a和b值为0.5

Cdiffuse=(Clight∗Mdiffuse)∗(0.5∗(n⃗ ∗l⃗ )+0.5)

C_{diffuse}=(C_{light}*M_{diffuse})*(0.5*(\vec{n}*\vec{l})+0.5)

Shader "Test Shader/HalfLambert"{
Properties
{_Diffuse ("DiffuseName",Color)=(1,1,1,1)
}
SubShader
{Pass{Tags{"LightMode"="ForwardBase"}CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"#include "Lighting.cginc"fixed4 _Diffuse;struct a2v{//模型空间的顶点坐标float4 vertex:POSITION;//模型空间的法线方向float3 normal:NORMAL;};struct v2f{//输出的是裁剪空间的顶点坐标float4 pos:SV_POSITION;float3 worldNormal:TEXCOORD0 ;};v2f vert(a2v v){v2f o;//利用unity内置的模型-观察-投影矩阵将顶点坐标转换到裁剪空间o.pos=UnityObjectToClipPos(v.vertex);//法线转换到世界坐标//unity_WorldToObject为模型空间到世界空间的变换矩阵的逆矩阵o.worldNormal=mul(v.normal,(float3x3)unity_WorldToObject);return o;}fixed4 frag(v2f i):SV_Target{//通过内置变量获取环境光fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.xyz;fixed3 worldNormal=normalize(i.worldNormal);//获取光源方向fixed3 worldLight=normalize(_WorldSpaceLightPos0.xyz);fixed3 halflambert=dot(worldNormal,worldLight)*0.5+0.5;//利用漫反射光照公式计算漫反射fixed3 diffuse=_LightColor0.rgb*_Diffuse.rgb*halflambert;fixed3 color=ambient+diffuse;return fixed4(color,1.0);}ENDCG}
}
FallBack "DiffuseFallBack"}

我在下面的代码里使用半兰特伯模型取代了原来的半兰特伯模型

    fixed3 halflambert=dot(worldNormal,worldLight)*0.5+0.5;//利用漫反射光照公式计算漫反射fixed3 diffuse=_LightColor0.rgb*_Diffuse.rgb*halflambert;fixed3 color=ambient+diffuse;return fixed4(color,1.0);

这是最终的效果,从左到右是逐顶点光照,逐像素光照,半兰特伯模型

shader篇-漫反射相关推荐

  1. UI优化策略-Shader篇

    原文:https://zhuanlan.zhihu.com/p/33458843 前言 优化本身是一件琐碎且耗神的事情,需要经历问题定位.原因探查.优化方案设计和实现.效果验证.资源修改多个步骤,也会 ...

  2. Unity shader学习-漫反射-兰伯特光照模型和半兰伯特光照模型

    兰伯特漫反射公式:Diffuse = 直射光颜色 *物体颜色* max(0,cos夹角(光和法线的夹角) ) 下面给出顶点漫反射代码:   Shader "Unlit/005" { ...

  3. 深入URP之Shader篇5: SimpleLit Shader分析(1)

    SimpleLit.shader 本篇开始分析simple lit shader.我们通过分析unlit shader了解了URP shader的结构,以及一些基础功能.而simple lit sha ...

  4. 深入URP之Shader篇3: Unlit Shader分析[下]

    Unlit shader 上篇中我们分析了Unlit shader的Properties在ShaderGUI中的处理,接下来看Sub Shader. SubShader unlit shader以及其 ...

  5. 深入URP之Shader篇8: SimpleLit Shader分析(4)

    Simple Lit Forward Pass 本篇继续 Fragment shader 函数 InitializeInputData InputData inputData; InitializeI ...

  6. Unity Shader知识点(二)写一个基础漫反射Shader

    前言 我们刚学习Shader时,往往会被计算机图形学相关复杂的数学.物理知识所困扰,并在学习过程中丧失兴趣.个人以为,在代码以外,学习Shader应当有本科线性代数课程基础的概念框架,在这一基础上,完 ...

  7. Android绘图Canvas十八般武器之Shader详解及实战篇(下)

    前言 上一篇<Android绘图Canvas十八般武器之Shader篇(上)> 我们知道了Bitmap的用法,及TileMode的详细情况.接下来,这一篇作为整个知识体系的下半部要讲的是S ...

  8. Unity Shader知识点(三)高光反射Shader

    前言 此文及专栏系是以Shader入门精要为基础整理的Unity Shader学习笔记,尽量以初学者视角还原(其实半年前我就是初学者),错误还需指正. 本篇是实操部分的第三个Shader,即高光反射S ...

  9. 【Unity Shader】 Fog

    一.介绍Fog Fog,即雾化.本质是离屏幕越远的物体,就越趋向某种颜色.通常是远处,即离屏幕远的地方,趋向于白色或浅灰色. 二.Unity 灯光的Fog选项 1. Color 雾的颜色 2. Mod ...

  10. Cocos技术派 | 导入FBX模型实现真3d效果

    文章目录 前言 工程介绍 导入模型 源码 前言 Cocos Creator一直以来都是一个2D游戏引擎,并且致力于H5游戏开发领域.很多同学不满足于开发2D游戏,想尽办法搞一些3D效果,比如自己接入t ...

最新文章

  1. AtCoder Regular Contest 092 Two Sequences AtCoder - 3943 (二进制+二分)
  2. vue中的props对象
  3. 日志规范之阿里巴巴开发手册中的其它规范讲解
  4. 恭喜了!5 月逼自己学下这项技能,年薪 35 万起
  5. 产品经理最重要的3个能力
  6. 照片浏览器_2020护考报名失败!只因照片太大瞎忙乎三小时...
  7. 解读今年的 Google IO 2017
  8. 思科 mds 虚拟服务器,Cisco MDS系列交换机VSAN功能简介
  9. JavaCV 第一个JavaCV程序
  10. 基于KNN的手写数字识别
  11. 机器学习笔记——14 矩阵谱分解与奇异值分解及其背后的线性算子理论 (实战项目:利用SVD进行图像压缩)
  12. Foxmail 设置自动落款签名
  13. 地震勘探原理(五)之地震勘探的野外工作
  14. android6支持内存卡,2020年拥有可扩展存储的最佳Android手机
  15. python驱动级模拟按键 检测_py库: pyautogui (自动测试模块,模拟鼠标、键盘动作)...
  16. .axf文件_Keil开发环境如何生成BIN文件
  17. 惠普电脑锁屏快捷键怎么设置?
  18. oracle 客户端 sqlplus 命令行 问号 乱码
  19. ​在商还得言商 | 【常垒·常识】
  20. centos 安装kermit

热门文章

  1. ABC Amber CHM Converter:CHM转换PDF
  2. [数学建模] 大数据建模五步法
  3. (html)音乐之原生js简单的歌词滚动hah
  4. DEVC++实现街头篮球(爷青回)(1.01版)
  5. cad2006激活未找到html文件,[转载]AutoCAD2006启动时提示“许可证系统出现问题”解决方法...
  6. ERP、SCM、CRM的区别和联系
  7. 华为手机Root方法(推荐)
  8. Unity将相机内容输出成图片
  9. MSF-Evasion模块免杀
  10. java服务端性能优化_记我的一次 Java 服务性能优化