shader篇-漫反射
shader篇-漫反射
- shader篇-漫反射
- 背景
- 逐顶点光照
- 逐像素光照
- 半兰伯特光照模型
之前只是草草看了书,隔了一两个月回头看,很多都忘了,学习方法不对啊,希望利用写博客加深对知识的理解吧。
背景
渲染包含两大部分:像素可见性和光照计算。
今天就是介绍如何利用shader仿真现实世界中的漫反射。
漫反射计算公式如下
C_{diffuse}=(C_{light}*M_{diffuse})*max(0,\vec{n}*\vec{l})
计算漫反射需要四个参数,入射光颜色,强度
C_{light},材质反射系数
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种着色效果造成模型外观呈黑,
我们用半兰伯特光照模型解决这一问题
半兰伯特光照模型
C_{diffuse}=(C_{light}*M_{diffuse})*(\alpha*(\vec{n}*\vec{l})+\beta)
这里并没有使用max操作防止n,l点积为负值,而是对结果进行了一个a倍的缩放加上一个B大小的偏移,大多数情况下,a和b值为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篇-漫反射相关推荐
- UI优化策略-Shader篇
原文:https://zhuanlan.zhihu.com/p/33458843 前言 优化本身是一件琐碎且耗神的事情,需要经历问题定位.原因探查.优化方案设计和实现.效果验证.资源修改多个步骤,也会 ...
- Unity shader学习-漫反射-兰伯特光照模型和半兰伯特光照模型
兰伯特漫反射公式:Diffuse = 直射光颜色 *物体颜色* max(0,cos夹角(光和法线的夹角) ) 下面给出顶点漫反射代码: Shader "Unlit/005" { ...
- 深入URP之Shader篇5: SimpleLit Shader分析(1)
SimpleLit.shader 本篇开始分析simple lit shader.我们通过分析unlit shader了解了URP shader的结构,以及一些基础功能.而simple lit sha ...
- 深入URP之Shader篇3: Unlit Shader分析[下]
Unlit shader 上篇中我们分析了Unlit shader的Properties在ShaderGUI中的处理,接下来看Sub Shader. SubShader unlit shader以及其 ...
- 深入URP之Shader篇8: SimpleLit Shader分析(4)
Simple Lit Forward Pass 本篇继续 Fragment shader 函数 InitializeInputData InputData inputData; InitializeI ...
- Unity Shader知识点(二)写一个基础漫反射Shader
前言 我们刚学习Shader时,往往会被计算机图形学相关复杂的数学.物理知识所困扰,并在学习过程中丧失兴趣.个人以为,在代码以外,学习Shader应当有本科线性代数课程基础的概念框架,在这一基础上,完 ...
- Android绘图Canvas十八般武器之Shader详解及实战篇(下)
前言 上一篇<Android绘图Canvas十八般武器之Shader篇(上)> 我们知道了Bitmap的用法,及TileMode的详细情况.接下来,这一篇作为整个知识体系的下半部要讲的是S ...
- Unity Shader知识点(三)高光反射Shader
前言 此文及专栏系是以Shader入门精要为基础整理的Unity Shader学习笔记,尽量以初学者视角还原(其实半年前我就是初学者),错误还需指正. 本篇是实操部分的第三个Shader,即高光反射S ...
- 【Unity Shader】 Fog
一.介绍Fog Fog,即雾化.本质是离屏幕越远的物体,就越趋向某种颜色.通常是远处,即离屏幕远的地方,趋向于白色或浅灰色. 二.Unity 灯光的Fog选项 1. Color 雾的颜色 2. Mod ...
- Cocos技术派 | 导入FBX模型实现真3d效果
文章目录 前言 工程介绍 导入模型 源码 前言 Cocos Creator一直以来都是一个2D游戏引擎,并且致力于H5游戏开发领域.很多同学不满足于开发2D游戏,想尽办法搞一些3D效果,比如自己接入t ...
最新文章
- AtCoder Regular Contest 092 Two Sequences AtCoder - 3943 (二进制+二分)
- vue中的props对象
- 日志规范之阿里巴巴开发手册中的其它规范讲解
- 恭喜了!5 月逼自己学下这项技能,年薪 35 万起
- 产品经理最重要的3个能力
- 照片浏览器_2020护考报名失败!只因照片太大瞎忙乎三小时...
- 解读今年的 Google IO 2017
- 思科 mds 虚拟服务器,Cisco MDS系列交换机VSAN功能简介
- JavaCV 第一个JavaCV程序
- 基于KNN的手写数字识别
- 机器学习笔记——14 矩阵谱分解与奇异值分解及其背后的线性算子理论 (实战项目:利用SVD进行图像压缩)
- Foxmail 设置自动落款签名
- 地震勘探原理(五)之地震勘探的野外工作
- android6支持内存卡,2020年拥有可扩展存储的最佳Android手机
- python驱动级模拟按键 检测_py库: pyautogui (自动测试模块,模拟鼠标、键盘动作)...
- .axf文件_Keil开发环境如何生成BIN文件
- 惠普电脑锁屏快捷键怎么设置?
- oracle 客户端 sqlplus 命令行 问号 乱码
- ​在商还得言商 | 【常垒·常识】
- centos 安装kermit
热门文章
- ABC Amber CHM Converter:CHM转换PDF
- [数学建模] 大数据建模五步法
- (html)音乐之原生js简单的歌词滚动hah
- DEVC++实现街头篮球(爷青回)(1.01版)
- cad2006激活未找到html文件,[转载]AutoCAD2006启动时提示“许可证系统出现问题”解决方法...
- ERP、SCM、CRM的区别和联系
- 华为手机Root方法(推荐)
- Unity将相机内容输出成图片
- MSF-Evasion模块免杀
- java服务端性能优化_记我的一次 Java 服务性能优化