首页 > 其他分享 >《UnityShader入门精要》 漫反射部分代码及详细注释

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

时间:2022-12-06 16:26:29浏览次数:65  
标签:漫反射 fixed3 diffuse UnityShader v2f worldNormal 精要 Diffuse

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

标签:漫反射,fixed3,diffuse,UnityShader,v2f,worldNormal,精要,Diffuse
From: https://www.cnblogs.com/zhuzhu-BizarreAdventure/p/16955610.html

相关文章

  • unityshader学习笔记5
    Unity中的光照:光源光是由光源发射出来的,实时渲染中,通常把光源当成一个没有体积的点,用L来表示它的方向.在光学里,用辐照度来量化光.对于平行光来说,它的辐照度可通......
  • unityshader学习笔记4
    顶点/片元着色器的基本结构:Shader"Custom/SimpleShader"{  SubShader{    Pass{      CGPROGRAM      #pragmavertexve......
  • Unity Shader入门精要第七章 基础纹理之遮罩纹理
    Unity系列文章目录文章目录​​Unity系列文章目录​​​​前言​​​​一、实践​​​​参考​​前言遮罩纹理(masktexture)是本章要介绍的最后一种纹理,它非常有用,在很多商业......
  • 手把手教你:轻松打造沉浸感十足的动态漫反射全局光照
    一个沉浸感十足的游戏,其场景中的全局光照效果一定功不可没。动态漫反射全局光照(DDGI)带来的光影变化,是细腻延展的视觉语言,让场景中每种颜色都有了“五彩斑斓”的诠释,场景布......
  • 读UnityShader入门精要第六章-Unity中的基础光照
    1.我们如何看到这个世界1.1 光源光是由光源发出的,在实时渲染中,光源被当成一个没有体积的点.在光学中,使用辐照度(irradiance)来量化光.当光打在一个平面上......
  • unityshader_01
    第一章渲染流水线1.1渲染流水线1.1.1现实中流水线在工业上,流水线被广泛应用在装配线上。假设,老王有一个生产洋娃娃的工厂,一个洋娃娃的生产流程可以分为4个步骤:在流水线......