当前位置:网站首页>Unity shader beginner's Essentials (I) -- basic lighting notes
Unity shader beginner's Essentials (I) -- basic lighting notes
2022-07-07 08:54:00 【Zero if】
A personal Shader note , Mainly through analysis Shader Code to summarize several lighting models .
0. Standard illumination model
The standard model is mainly divided into four parts , Spontaneous light + Specular reflection + Diffuse reflection + The ambient light
According to different lighting models , Calculate different rays and add them
Per vertex and per pixel
There are two main types of model illumination calculation , Per pixel and per vertex , namely Grouraud Shading and Phone Shading
per-vertex
Calculate illumination at each vertex , Linear interpolation is performed inside the rendering entity , Finally, output the imager color
shortcoming : Vertices are interpolated within the calculated illumination , The interior of an entity is always darker than the highest color value at the vertex , And there will be edges and corners
But it also tells us , Lighting is calculated in vertex shaders
Pixel by pixel
On a per pixel basis , Get his normal , ( It can be vertex normal interpolation , You can sample from the normal texture ), Perform illumination calculation
therefore , Illumination is calculated in the slice shader
1. Diffuse reflection model
Lambert Basis of diffuse reflection model , The main thing is to satisfy Lambert The laws of : That is, the intensity of the reflected light is directly proportional to the cosine of the angle between the surface normal and the direction of the light source
The formula is :
Cdiffuse = ( Clight · mdiffuse )max (0, n · l)
Clight : The color of the light source
mdiffuse: Material diffuse color
n : The surface normals
l : Point to the light source unit vector
1.1 Diffuse per vertex
mdiffuse Definition of diffuse color of material , Colors can be found in unity Take from oneself
Properties
{
_Diffuse("Diffuse", Color) = (1, 1, 1, 1)
}
Namely a2v and v2f, namely application to vertex shader and vertex shader To fragment shader The definition of .
Calculate lighting in vertex shaders , So you need to a2v Access to vertices and normals ; To transfer the light color in the vertex shader to the slice shader , therefore ,v2f You need to convert vertices into clipping space and store color value
struct a2v
{
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct v2f
{
float4 pos : SV_POSITION;
float3 worldNormal : TEXCOORD0;
};
This is the specific calculation in vertex shader .Clight and mdiffuse One is directly obtained, and the other is defined before , What needs to be solved is n · l . You need to convert these two values to world space for dot multiplication .
Normal in world coordinates :unity Built in
unity_WorldToObjectYou can convert from world coordinates to local coordinates , Then use the inverse operation of matrix , Get the world coordinates of the normal .
Others are brought into the formula
v2f vert(a2v v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
fixed3 worldNormal = normalize(mul(v.normal,(float3x3)unity_WorldToObject));
fixed3 worldLight = normalize(_WorldSpaceLightPos0.xyz);
fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb *saturate(dot(worldNormal,worldLight));
o.color = ambient + diffuse;
return o;
}
Just output directly from the slice shader
fixed4 frag(v2f i) : SV_TARGET
{
return fixed4(i.color, 1.0);
}
1.2 Per pixel diffuse
The main reason is that the contents of calculation in the two shaders are different .
In the vertex shader , There is no need to calculate the illumination , Just pass the vertices and normals in world space to the slice shader .
v2f vert(a2v v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.worldNormal = mul(v.normal, (float3x3)unity_WorldToObject);
return o;
}
The key point is to calculate the illumination in the slice shader ., The ideas are the same , Pay attention to the unitization of various vectors .
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);
}
2. Specular reflection model
Specular reflection model points Phone and Blinn Phone Two kinds of
The former model is , Specular reflection and Viewing angle direction and reflection direction Is related to the dot multiplication value of , The latter believes that it is the normal direction and the viewing angle direction Point multiplication value of half range vector and normal relevant .
Phone Highlight model :
Cspecular = (Clight · mspecular) max(0, v, r)mgloss
Clight : The color and intensity of the incident light
mspecular: The specular reflection coefficient of the material
v: Direction of view
r : Direction of reflection
mgloss: Glossiness , Reflectance
Blinn Phone Highlight model :
Cspecular = (Clight · mspecular) max(0, n, h)mgloss
n : normal ,h It's a half range vector
The others are roughly the same
2.1 per-vertex Phone Specular reflection
Diffuse color , Specular reflection coefficient and gloss are customized as follows
Properties
{
_Diffuse("Diffuse", Color) = (1, 1, 1, 1)
_Specular("Specular", Color) = (1, 1, 1, 1)
_Gloss ("Gloss", Range(8.0, 256)) = 20
}
Calculating lighting in vertex shaders , Mainly calculate highlights , So we get the ambient light directly . The calculation method of diffuse reflection is not much written , Highlight into the formula of a meal calculation , Plus ambient light return
reflectDir Directly through built-in functions , Write the ray incidence direction and vertex normal direction to get the exit direction
viewDir Through the world position of the camera - The world position of the vertex gets the field of view vector
v2f vert(a2v v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
fixed3 worldNormal = normalize(mul(v.normal, (float3x3)unity_WorldToObject));
fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal, worldLightDir));
fixed3 reflectDir = normalize(reflect(-worldLightDir, worldNormal));
fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - mul(unity_ObjectToWorld, v.vertex).xyz);
fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(reflectDir, viewDir)), _Gloss);
o.color = ambient + diffuse + specular;
return o;
Finally, just output the color directly in the slice shader , Consistent with the above .
2.2 Pixel by pixel Phone Specular reflection
Obviously, the illumination is calculated in the slice shader , Think the same way . In the vertex shader , Just calculate the world coordinates of the vertex and the position under the world of the normal
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 reflectDir = normalize(reflect(-worldLightDir, worldNormal));
fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);
fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(reflectDir, viewDir)), _Gloss);
return fixed4(ambient + diffuse + specular, 1.0);
}
2.3 Pixel by pixel Blinn Phone Highlight model
Roughly the same , The main thing is to calculate the illumination of the slice , One more half way vector calculation and use
fixed3 halfDir = normalize(worldLightDir + viewDir);
fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0, dot(reflectDir, viewDir)), _Gloss);
边栏推荐
- 最长上升子序列模型 AcWing 1017. 怪盗基德的滑翔翼
- Synchronized underlying principle, volatile keyword analysis
- PPT模板、素材下载网站(纯干货,建议收藏)
- 如何在图片的目标中添加目标的mask
- [step on the pit] Nacos registration has been connected to localhost:8848, no available server
- MySQL主从延迟的解决方案
- Redis fault handling "can't save in background: fork: cannot allocate memory“
- 年薪50w阿裏P8親自下場,教你如何從測試進階
- 数字三角形模型 AcWing 1027. 方格取数
- Pointer advanced, string function
猜你喜欢

A bug using module project in idea

How to integrate app linking services in harmonyos applications

2022-06-30 Unity核心8——模型导入
![[Yugong series] February 2022 U3D full stack class 006 unity toolbar](/img/2e/3a7d71a0b5a6aff294a0bd2f8515f8.jpg)
[Yugong series] February 2022 U3D full stack class 006 unity toolbar

Digital triangle model acwing 275 Pass a note

数据分片介绍

Greenplum 6.x build_ install

Output all composite numbers between 6 and 1000

Greenplum 6.x monitoring software setup

面板显示技术:LCD与OLED
随机推荐
Introduction to data fragmentation
模拟卷Leetcode【普通】1705. 吃苹果的最大数目
opencv之图像分割
Markdown editor Use of MD plug-in
Interpolation lookup (two methods)
cmake命令行使用
IP地址的类别
Database storage - table partition
uniapp 微信小程序监测网络
Image segmentation in opencv
How to integrate app linking services in harmonyos applications
Output all composite numbers between 6 and 1000
对API接口或H5接口做签名认证
Test pits - what test points should be paid attention to when adding fields to existing interfaces (or database tables)?
Selenium automation integration, eight years of testing experience, soft test engineer, an article to teach you
Un salaire annuel de 50 W Ali P8 vous montrera comment passer du test
数字三角形模型 AcWing 275. 传纸条
[Yugong series] February 2022 U3D full stack class 005 unity engine view
模拟卷Leetcode【普通】1557. 可以到达所有点的最少点数目
使用Typora编辑markdown上传CSDN时图片大小调整麻烦问题