当前位置:网站首页>Unity shader: realize diffuse reflection and specular reflection
Unity shader: realize diffuse reflection and specular reflection
2022-07-24 06:14:00 【A small EZ】
Recent research Unity Of Shader To write , Feng Lele 《UnityShader Introduction to topic 》 It's interesting to find out .
Here is to realize the basic Shader. The author's Unity The version is 2019.4.19f1. Compared with 《UnityShader Introduction to topic 》 Some writing methods and functions in have been updated .
Standard illumination model
There are many kinds of lighting models in game engines , But in early game engines, only one lighting model was often used , This model is called the standard illumination model .
Its basic method is , Divide the light entering the camera into 4 Parts of , Each part uses a method to calculate its contribution . this 4 The parts are as follows
- Spontaneous light
- The ambient light
- Full reflection
- Specular reflection
Ambient light
In the standard lighting model , We use a part called ambient light to approximate indirect illumination ( It can be understood as the illumination of the overall environment ). The calculation of ambient light is very simple , It is usually a global variable , That is, all objects in the scene use this ambient light .
stay Unity in The ambient light is obtained by using the following code :
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
Diffuse reflection
For the introduction of diffuse reflection, see Diffuse reflection _ Baidu Encyclopedia .
In diffuse reflection , The position of the perspective is not important , Because the reflection is completely random , Therefore, it can be considered that the distribution in any reflection direction is the same . however , The angle of incident light is important .
The diffuse reflection formula is as follows :
C diffuse by Diffuse color
C light by The color of the light source
M diffuse by The diffuse reflection coefficient of the material
vector n Is the normal direction
vector l Is the direction of the light source
In order to prevent the dot product of normal and light direction from being negative , So use the function that takes the maximum value to intercept it to 0.
It doesn't matter if you don't understand the formula here . Practice makes perfect . With the deepening of research , Will slowly understand .
Code up
Shader "Custom/DiffuseShader"
{
Properties
{
_Diffuse("Diffuse", Color) = (1, 1, 1, 1)
}
SubShader
{
Pass
{
Tags {
"LightMode" = "ForwardBase" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
fixed4 _Diffuse;
struct appdata
{
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct v2f
{
float4 vertex : SV_POSITION;
float3 worldNormal : TEXCOORD0;
};
v2f vert(appdata v)
{
v2f o;
// Transform from model space to crop space
o.vertex = UnityObjectToClipPos(v.vertex);
// From model space to world space
o.worldNormal = UnityObjectToWorldNormal(v.normal);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
fixed3 worldLight = normalize(_WorldSpaceLightPos0.xyz);
fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(i.worldNormal, worldLight));
fixed3 color = ambient + diffuse;
return fixed4(color, 1);
}
ENDCG
}
}
// Above SubShader Used for callback after all failures Unity Shader
FallBack "Diffuse"
}
Create a new one Image Effect Shader, Open to overwrite this code . Create a new material choice Custom/DiffuseShader , Drag the material onto the object .
Code parsing :
Shader “Custom/DiffuseShader” It specifies Shader The path of .
stay Properties It is stipulated in Inspector Properties edited in . Here we specify the default diffuse coefficient of the material ( Formula M diffuse).
stay SubShader Of Pass in , We have designated Pass in LightMode by ForwardBase. The Pass Accounting for ambient light 、 Main directional light 、 The vertices /SH Light source and Lightmaps The light map .
At the same time Pass The input of vertex and fragment shaders is specified in .
In the vertex shader , The vertex coordinates and vertex normals in model space are obtained . Then transform the vertex coordinates into the clipping space . Transform normals to world coordinates . The normal is the vector in the formula n .
In the fragment shader ambient by The ambient light
worldLight Is the vector in the formula l
_LightColor0.rgb Is C light
Finally, we get the result of the segment color .
Finally designated Fallback), If all SubShader Cannot run on this hardware , Will use the default Diffuse.
The result is zero 
Specular reflection
Specular reflection is used to calculate the light reflected in the direction of full specular reflection , This makes the object look shiny , For example, metal materials .
But the specular reflection here is an empirical model , in other words , It doesn't exactly match the specular reflection phenomenon in the real world .
Formula for 
C specular by Specular color
C light by The color of the light source
M specular by Material specular reflection coefficient
vector v Is the angle of view
vector l Is the reflection direction
Code up
Shader "Custom/SpecularShader"
{
Properties
{
_Diffuse("Diffuse", Color) = (1, 1, 1, 1)
_Specular("Specular", Color) = (1, 1, 1, 1)
_Gloss("Gloss", Range(8.0, 256)) = 20
}
SubShader
{
Pass
{
Tags {
"LightMode" = "ForwardBase" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
//#include "UnityCG.cginc"
#include "Lighting.cginc"
fixed4 _Diffuse;
fixed4 _Specular;
float _Gloss;
struct a2v
{
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct v2f
{
float4 vertex : SV_POSITION;
float3 worldNormal : TEXCOORD0;
float3 worldPos : TEXCOORD1;
};
v2f vert(a2v v)
{
v2f o;
// Transform from model space to crop space
o.vertex = UnityObjectToClipPos(v.vertex);
// Normals are transformed from model space to world space
o.worldNormal = UnityObjectToWorldNormal(v.normal);
// Vertex transformation from model space to world space
o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
return o;
}
fixed4 frag(v2f i) : SV_Target
{
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
fixed3 worldNormal = normalize(i.worldNormal);
fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
// Calculate diffuse reflection
fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal, worldLightDir));
// Get the reflection direction
fixed3 reflectDir = normalize(reflect(-worldLightDir, worldNormal));
// Get the perspective direction
fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);
// Calculate specular reflections
fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(reflectDir, viewDir)), _Gloss);
return fixed4(ambient + diffuse + specular, 1.0);
}
ENDCG
}
}
FallBack "Specular"
}
stay Pass The vertex coordinates in world space are calculated in the vertex shader of , The calculation of specular reflection has been added to the clip shader , Finally, the ambient light Diffuse reflection And the result of specular reflection , Get the final result .
It also specifies FallBack Is the default Specular
Create a new one Image Effect Shader, Open to overwrite this code . Create a new material choice Custom/SpecularShader , Drag the material onto the object .
The result is zero .
You can see the specular reflection Shader More metallic , At the same time, in the material Inspector Panel adjustment Gloss Value ,Gloss The bigger the value is. , The smaller the light spot reflected by the highlight .
边栏推荐
- Dameng database_ Logical architecture foundation
- QT novice entry level calculator addition, subtraction, multiplication, division, application
- MySQL download and installation environment settings
- unity2D横版游戏跳跃实时响应
- How to solve the problem of large distribution gap between training set and test set
- 使用Keras实现 基于注意力机制(Attention)的 LSTM 时间序列预测
- MySQL基础---约束
- day6-jvm
- Kernel pwn 基础教程之 Heap Overflow
- Accessing a one-dimensional array with a pointer
猜你喜欢

Using keras to realize LSTM time series prediction based on attention mechanism

Unity(二) 更多API和物理引擎

day6-jvm

Hit the wall record (continuously updated)
![[principles of database system] Chapter 5 algebra and logic query language: package, extension operator, relational logic, relational algebra and datalog](/img/6a/c30b139823208a2e021135a4bf8d58.png)
[principles of database system] Chapter 5 algebra and logic query language: package, extension operator, relational logic, relational algebra and datalog

JUC并发编程基础(8)--读写锁

QT novice entry level calculator addition, subtraction, multiplication, division, application

Machine learning & deep learning introduction information sharing summary

JUC并发编程基础(6)--Lock锁

unity2D游戏之让人物动起来-上
随机推荐
通道注意力与空间注意力模块
JUC并发编程基础(7)--多线程锁
What is monotone stack
Statistical analysis of catering data --- Teddy cloud course homework
Dameng database_ Supported table types, usage, characteristics
[principles of database system] Chapter 4 advanced database model: Unified Modeling Language UML, object definition language ODL
Detailed explanation of KMP code distribution
Dameng database_ Common initialization parameters
配置固定的远程桌面地址【内网穿透、无需公网IP】
Unity 3D帧率统计脚本
Calculation steps of principal component analysis
Dameng database_ Trigger, view, materialized view, sequence, synonym, auto increment, external link and other basic operations
JVM系统学习
What is monotonic queue
Lua基础
Use QT to connect to MySQL and create table numbers, write data, and delete data
Find the number with the most occurrences in the array
HoloLens 2 开发:开发环境部署
Yolov5 learning summary (continuously updated)
Headlong platform operation