当前位置:网站首页>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_WorldToObject
You 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);
边栏推荐
- idea里使用module项目的一个bug
- About using CDN based on Kangle and EP panel
- NCS Chengdu Xindian interview experience
- Rapid integration of authentication services - harmonyos platform
- Goldbach conjecture C language
- leetcode134. gas station
- 調用華為遊戲多媒體服務的創建引擎接口返回錯誤碼1002,錯誤信息:the params is error
- Image segmentation in opencv
- Greenplum6.x搭建_安装
- LeetCode 715. Range 模块
猜你喜欢
Greenplum 6.x build_ Environment configuration
[Yugong series] February 2022 U3D full stack class 007 - production and setting skybox resources
硬核分享:硬件工程师常用工具包
Novice entry SCM must understand those things
Calf problem
Nanjing commercial housing sales enabled electronic contracts, and Junzi sign assisted in the online signing and filing of housing transactions
平台化,强链补链的一个支点
2022-06-30 Unity核心8——模型导入
opencv之图像分割
Greenplum6.x重新初始化
随机推荐
模拟卷Leetcode【普通】1706. 球会落何处
数字三角形模型 AcWing 275. 传纸条
Oracle makes it clear at one time that a field with multiple separators will be split into multiple rows, and then multiple rows and columns. Multiple separators will be split into multiple rows, and
Shell script for changing the current folder and the file date under the folder
cmake命令行使用
为什么要选择云原生数据库
With an annual salary of 50W, Alibaba P8 will come out in person to teach you how to advance from testing
Greenplum 6.x build_ Environment configuration
idea里使用module项目的一个bug
数字三角形模型 AcWing 1027. 方格取数
Markdown编辑器Editor.md插件的使用
JS的操作
How to integrate app linking services in harmonyos applications
年薪50w阿里P8亲自下场,教你如何从测试进阶
年薪50w阿裏P8親自下場,教你如何從測試進階
oracle一次性说清楚,多种分隔符的一个字段拆分多行,再多行多列多种分隔符拆多行,最终处理超亿亿。。亿级别数据量
为不同类型设备构建应用的三大更新 | 2022 I/O 重点回顾
Analysis of abnormal channel number information before and after AGC re signature service
Count sort (diagram)
Interpolation lookup (two methods)