当前位置:网站首页>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);
边栏推荐
- 【踩坑】nacos注册一直连接localhost:8848,no available server
- Interpolation lookup (two methods)
- PPT模板、素材下载网站(纯干货,建议收藏)
- [Nanjing University] - [software analysis] course learning notes (I) -introduction
- [Yugong series] February 2022 U3D full stack class 007 - production and setting skybox resources
- 年薪50w阿里P8亲自下场,教你如何从测试进阶
- Data analysis methodology and previous experience summary 2 [notes dry goods]
- How to realize sliding operation component in fast application
- channel. Detailed explanation of queuedeclare parameters
- Other 7 features of TCP [sliding window mechanism ▲]
猜你喜欢

【Istio Network CRD VirtualService、Envoyfilter】
![Upload an e-office V9 arbitrary file [vulnerability recurrence practice]](/img/e7/278193cbc2a2f562270f99634225bc.jpg)
Upload an e-office V9 arbitrary file [vulnerability recurrence practice]

【MySQL】数据库进阶之触发器内容详解

The longest ascending subsequence model acwing 1017 Strange thief Kidd's glider

平台化,强链补链的一个支点

LED模拟与数字调光

NCS Chengdu Xindian interview experience
![Data analysis methodology and previous experience summary 2 [notes dry goods]](/img/e1/643e847a777e1effcbd39f8b009e2b.png)
Data analysis methodology and previous experience summary 2 [notes dry goods]

A bug using module project in idea

面板显示技术:LCD与OLED
随机推荐
模拟卷Leetcode【普通】1705. 吃苹果的最大数目
What are the advantages of commas in conditional statements- What is the advantage of commas in a conditional statement?
Enterprise manager cannot connect to the database instance
Three usage scenarios of annotation @configurationproperties
Unity Shader入门精要初级篇(一)-- 基础光照笔记
Digital triangle model acwing 275 Pass a note
[Nanjing University] - [software analysis] course learning notes (I) -introduction
OpenGL帧缓冲
面板显示技术:LCD与OLED
[Yugong series] February 2022 U3D full stack class 006 unity toolbar
Frequently Asked Coding Problems
ESP32-ULP协处理器低功耗模式RTC GPIO中断唤醒
[MySQL] detailed explanation of trigger content of database advanced
RuntimeError: Calculated padded input size per channel: (1 x 1). Kernel size: (5 x 5). Kernel size c
let const
opencv之图像分割
LeetCode 715. Range module
Several methods of calculating the average value of two numbers
Greenplum 6.x common statements
求有符号数的原码、反码和补码【C语言】