当前位置: 首页 >  网站大师 >  《UnityShader入门精要》 漫反射部分代码及详细注释

《UnityShader入门精要》 漫反射部分代码及详细注释

导读:漫反射.漫反射计算公式 : C diffuse = (C light · M diffuse ) max(0 , n · l ).C light :入射光线的强度和颜色.M diffuse : 材质的漫反射系数 物体本色.n : 法线单位向量.l : 光源单位向量.逐顶点漫反射代

漫反射
漫反射计算公式 : C diffuse = (C light · M diffuse ) max(0 , n · l )
C light :入射光线的强度和颜色
M diffuse : 材质的漫反射系数 物体本色
n : 法线单位向量
l : 光源单位向量
逐顶点漫反射代码 :
效果图:

Shader "DiffuseVertex"
{
Properties
{
_Diffuse ("Diffuse",Color)=(1,1,1,1)
}
SubShader
{

Pass{
Tags{"LightMode" = "ForwardBase"}

CGPROGRAM

#pragma vertex vert
#pragma fragment frag

#include "Lighting.cginc"

fixed4 _Diffuse;//获取反漫射颜色(既上面设置的物体自身颜色)

struct a2v{
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct v2f{
float4 pos : SV_POSITION;
fixed3 color : COLOR;
};
//逐顶点漫反射
v2f vert(a2v v){
v2f o;

o.pos = UnityObjectToClipPos(v.vertex);

fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;//环境光

//由于下方法线光线两个向量点乘必须处于 同一坐标系下 所以此处将此处的顶点转换到
//通过矩阵坐标空间转换 以及 单位转换 算出单位法线向量
//unity_WorldToObject 既 _World2Object 变换矩阵 可将模型空间转换到世界空间
//通过调换顺序已达到此矩阵的转置矩阵 注意 mul 乘法公式从左到右
//由于法线向量是个三维矢量 将变换矩阵通过 float3x3 转成3x3矩阵
fixed3 worldNormal = normalize(mul(v.normal,(float3x3)unity_WorldToObject));

// 取得光线的单位向量
fixed3 worldLight = normalize(_WorldSpaceLightPos0.xyz); // normalize 单位化 归一化

//通过点乘 获得 法线与光线的夹角 saturate 只截取[0,1]范围内 防止为负数 s
//光线的颜色*漫反射的颜色(物体本色)*光线与法线的夹角 光线照射的角度
fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal,worldLight));

//环境光与漫反射相加 得到最终的颜色
o.color = ambient + diffuse;

return o;
}
//片元着色器直接输出
fixed4 frag(v2f i) : SV_Target{
return fixed4(i.color,1.0);
}


ENDCG
}
}
FallBack "Diffuse"
}

逐片元(像素)漫反射代码 :
效果图:

Shader "DiffusePixel"
{
Properties
{
_Diffuse ("Diffuse",Color)=(1,1,1,1)
}
SubShader
{

Pass{
Tags{"LightMode" = "ForwardBase"}

CGPROGRAM

#pragma vertex vert
#pragma fragment frag

#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;

//投影矩阵 将模型空间转换为裁切空间
o.pos = UnityObjectToClipPos(v.vertex);

//空间转换
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 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);

//漫反射计算主体
fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal,worldLightDir));

//颜色叠加计算出最后的颜色
fixed3 color = ambient + diffuse;

//返回
return fixed4(color,1.0);



}


ENDCG
}
}
FallBack "Diffuse"
}

半兰伯特公式 像素漫反射:
效果图:

Shader "HalfLambert"
{
Properties
{
_Diffuse ("Diffuse",Color)=(1,1,1,1)
}
SubShader
{

Pass{
Tags{"LightMode" = "ForwardBase"}

CGPROGRAM

#pragma vertex vert
#pragma fragment frag

#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;

//投影矩阵 将模型空间转换为裁切空间
o.pos = UnityObjectToClipPos(v.vertex);

//空间转换
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 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);

//漫反射计算主体
//fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal,worldLightDir));
//利用半兰伯特公示计算 原理是将原来的max控制最低值的方法给取消
//取代为将值变为原来的一半 原[-1,1] 乘上0.5得 [-0.5,0.5] 最后加上0.5 得 [0,1] 因此称为半兰伯特
//通过这种方法 能够使背光面也会有光线明暗过渡 而不是如同一张纸一样呈现出一个颜色
fixed halfLambert = dot(worldNormal,worldLightDir) * 0.5 + 0.5;

fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * halfLambert;



//颜色叠加计算出最后的颜色
fixed3 color = ambient + diffuse;

//返回
return fixed4(color,1.0);
}
ENDCG
}
}
FallBack "Diffuse"
}

三种类型的漫反射反射:

TRANSLATE with x

English

Arabic Hebrew Polish
Bulgarian Hindi Portuguese
Catalan Hmong Daw Romanian
Chinese Simplified Hungarian Russian
Chinese Traditional Indonesian Slovak
Czech Italian Slovenian
Danish Japanese Spanish
Dutch Klingon Swedish
English Korean Thai
Estonian Latvian Turkish
Finnish Lithuanian Ukrainian
French Malay Urdu
German Maltese Vietnamese
Greek Norwegian Welsh
Haitian Creole Persian

TRANSLATE with

COPY THE URL BELOW

Back

EMBED THE SNIPPET BELOW IN YOUR SITE

Enable collaborative features and customize widget: Bing Webmaster Portal

Back

此页面的语言为中文(简体)

翻译为

  • 中文(简体)
  • 中文(繁体)
  • 丹麦语
  • 乌克兰语
  • 乌尔都语
  • 亚美尼亚语
  • 俄语
  • 保加利亚语
  • 克罗地亚语
  • 冰岛语
  • 加泰罗尼亚语
  • 匈牙利语
  • 卡纳达语
  • 印地语
  • 印尼语
  • 古吉拉特语
  • 哈萨克语
  • 土耳其语
  • 威尔士语
  • 孟加拉语
  • 尼泊尔语
  • 布尔语(南非荷兰语)
  • 希伯来语
  • 希腊语
  • 库尔德语
  • 德语
  • 意大利语
  • 拉脱维亚语
  • 挪威语
  • 捷克语
  • 斯洛伐克语
  • 斯洛文尼亚语
  • 旁遮普语
  • 日语
  • 普什图语
  • 毛利语
  • 法语
  • 波兰语
  • 波斯语
  • 泰卢固语
  • 泰米尔语
  • 泰语
  • 海地克里奥尔语
  • 爱沙尼亚语
  • 瑞典语
  • 立陶宛语
  • 缅甸语
  • 罗马尼亚语
  • 老挝语
  • 芬兰语
  • 英语
  • 荷兰语
  • 萨摩亚语
  • 葡萄牙语
  • 西班牙语
  • 越南语
  • 阿塞拜疆语
  • 阿姆哈拉语
  • 阿尔巴尼亚语
  • 阿拉伯语
  • 韩语
  • 马尔加什语
  • 马拉地语
  • 马拉雅拉姆语
  • 马来语
  • 马耳他语
  • 高棉语

随时将中文(简体)翻译为PRO
一律不翻译中文(简体)
一律不翻译i.cnblogs.com

内容
  • Docker的Portainer认识、安装、使用
    Docker的Portainer
    2023-12-08
    一、认识.docker的图形化界面.Portainer 是一个轻量级的容器管理界面,可以让用户更轻松地管理 Docker
  • misc刷题
    misc刷题
    2023-12-04
    lsb隐写.引用一段百度内容.> LSB隐写就是修改RGB颜色分量的最低二进制位也就是最低有效位(LSB),而人类的眼睛
  • 虹科案例 | 丝芙兰xDomo:全球美妆巨头商业智能新玩法
    虹科案例 | 丝芙兰xDomo:
    2023-12-05
    全球美妆行业的佼佼者丝芙兰,其走向成功绝非仅依靠品牌知名度和营销手段。身为数据驱动型企业,2018年以来,丝芙兰就率先在
  • 密评相关要求介绍
    密评相关要求介绍
    2023-12-04
    密评相关要求介绍.项目建设单位需从物理和环境安全、网络和通信安全、设备和计算安全、应用和数据安全等四个层面采用密码技术措
  • SonarQube系列-通过配置扫描分析范围,聚焦关键问题
    SonarQube系列-通过配置
    2023-12-04
    在许多情况下,你可能不希望分析项目中每个源文件的各个方面。例如,项目可能包含生成的代码、库中的源代码或有意复制的代码。在
  • SublimeText实现Markdown快速预览
    SublimeText实现Mar
    2023-12-07
    SublimeText是什么?.SublimeText是一个文本编辑器,同时也是一个先进的代码编辑器。SublimeTe