当前位置:网站首页>Character shader exercise
Character shader exercise
2022-07-29 07:57:00 【TingQiaoQiao】
Follow the train of thought of Zhuang Tong Dota Character material
1.1 Handle the map
The map inside has the problem of upside down or left-right reverse , So you need to first process the image into the same position as the color map and normal map , And then the others RampTexture To put WrapMode Set to Clamp Pattern .
Untreated black spots will appear

After processing RampTexture It will show normal effect

1.2 View design documents , Analyze the lighting model and mapping effect
Because considering that the color reflected by diffuse reflection and specular reflection of metal and non-metal is different , So first calculate the different colors produced by specular reflection and specular reflection , Later, multiply the color into the calculated lighting model .
float3 diffuseColor = lerp(var_MainTexture,float3(0.0,0.0,0.0), var_Metellic);
float3 specularColor = lerp(var_MainTexture, float3(0.4, 0.4, 0.4), var_TintMaskTexture) * var_SpecIntTexture; 1.3 Illumination model
1.3.1 Diffuse reflection
// Diffuse reflection of main light source
float halfLambert =ldotn * 0.5 + 0.5;
float3 lambertColor = tex2D(_DiffuseColor,float2(halfLambert,0.5));
float3 lightDiffuseColor = _LightColor * lambertColor * diffuseColor * _LightDiffuseStrength;
// Ambient light diffuse
float maskUp = max(0,nDirWS.g);
float maskDown = max(0, -nDirWS.g) ;
float maskMiddle = 1 - maskUp - maskDown;
float3 ambiendDiffuseColor =( maskUp * _AmbientDiffuseColor_Up + maskDown * _AmbientDiffuseColor_Down + _AmbientDiffuseColor_Middle * maskMiddle ) * diffuseColor * _AmbientDiffuseStrength;Diffuse reflection of main light source

Diffuse reflection of ambient light

1.3.2 Specular reflection
// Main light source specular
float Phong = pow(max(0, lrdotv), var_SpecPowTexture * _LightSpecularPow);
float specular = Phong * halfLambert;
float FresnelSpecular = lerp(var_FresnelSpecular,0.0, var_Metellic);
//float specular_Fresnel = tex2D(_FresnelSpecular, float2(specular, 0.5));// It doesn't seem to be able to sample like that , There is a very magical effect
float specular_Fresnel = max(specular, FresnelSpecular) * _LightSpecularStrength;
float3 lightSpecularColor = _LightColor * specular_Fresnel * specularColor;
// Ambient light specular
float reflect = max(var_Metellic, FresnelSpecular) * var_SpecIntTexture;
float3 envSpecularColor = reflect * specularColor * var_CubeMap * _EnvSpecularStength;Specular reflection of the main light source

Specular reflection of ambient light

If you use ramptexture Use highlights as samples , It will produce an effect similar to that the whole is metal

Because Fresnel effect usually appears only with some smooth materials , So we should use the metal range mask to control the Fresnel ramptexture Conduct lerp once
var_FresnelRim No, lerp once

After processing

1.3.3 Contour light and self illumination
// Contour light
float FresnelRim = lerp(var_FresnelRim, 0.0, var_Metellic);
float3 rimLight = var_RimIntTexture * FresnelRim * max(0, nDirWS.g) * _RimStrength * _RimColor;
// Spontaneous light
float3 emission = diffuseColor * var_EmissionTexture * _EmissionStrength;
1.3.4 Mix lighting and output

1.4 Code
notes : Because it is more intuitive and can not think about the conversion between parameters , So I didn't synthesize multiple maps into one map , You can see that each map is sampled once , Then all parameter types are used uniformly float, Some can be used half perhaps fixed To replace .
Shader "Unlit/Body Shader"
{
Properties{
// Open attribute control
[Header(Texture)]
_MainTexture(" Main map ",2D) = "white"{}
_OpacityTexture(" Transparency maps ",2D) = "white"{}
_NormalTexture(" Normal map ",2D) = "bump"{}
_SpecIntTexture(" Highlight intensity map ",2D) = "white"{}
_RimIntTexture(" Edge light intensity map ",2D) = "white"{}
_TintMaskTexture(" Dye mask map ",2D) = "white"{}
_SpecPowTexture(" Highlight power map ",2D) = "white"{}
_CubeMap(" Environmental ball ",cube) = "_skybox"{}
_DiffuseColor(" Diffuse color map ",2D) = "grey"{}
_FresnelRim(" Fresnel edge light map ",2D) = "white"{}
_FresnelSpecular(" Fresnel highlight map ",2D) = "white"{}
_Metellic(" Metal range mask ",2D) = "grey"{}
_EmissionTexture(" irradiance map ",2D) = "white"{}
[Header(Slider)]
_Cutoff(" Transparency map threshold ",Range(0,1)) = 0.5
_LightDiffuseStrength(" Diffuse reflection intensity of main light ",Range(0,5)) = 2
_LightSpecularStrength(" Highlight reflection intensity of main light ", Range(0,5)) = 2
_LightSpecularPow(" Highlight power of main light ", Range(0,10)) = 5
_AmbientDiffuseStrength(" Ambient diffuse intensity ",Range(0,1)) = 0.8
_EnvSpecularStength(" Specular intensity of ambient light ",Range(1,10)) = 5
_RimStrength(" Edge light intensity ",Range(0,5)) = 2
_EmissionStrength(" Self luminous intensity ",Range(0,5)) = 2
[Header(Color)]
_LightColor(" The color of the light ", color) = (1.0,1.0,1.0,1.0)
_AmbientDiffuseColor_Up(" Ambient light diffuses the upper light ",color) = (1.0,1.0,1.0,1.0)
_AmbientDiffuseColor_Middle(" Ambient diffuse mid light ",color) = (1.0,1.0,1.0,1.0)
_AmbientDiffuseColor_Down(" Ambient diffuse lower light ",color) = (1.0,1.0,1.0,1.0)
_RimColor(" Edge light color ",color) = (1.0,1.0,0.0,1.0)
}
SubShader{
Tags {
"RenderType" = "Opaque"
}
Pass {
Name "FORWARD"
Tags {
"LightMode" = "ForwardBase"
}
Cull Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "AutoLight.cginc"
#include "UnityCG.cginc"
#include "Lighting.cginc"
#pragma multi_compile_fwdbase_fullshadows
#pragma target 3.0
// Defining attributes
uniform sampler2D _MainTexture;
uniform sampler2D _OpacityTexture;
uniform float _Cutoff;
uniform sampler2D _NormalTexture;
uniform float _LightDiffuseStrength;
uniform sampler2D _SpecIntTexture;
uniform sampler2D _RimIntTexture;
uniform sampler2D _TintMaskTexture;
uniform sampler2D _SpecPowTexture;
uniform samplerCUBE _CubeMap;
uniform sampler2D _FresnelRim;
uniform sampler2D _FresnelSpecular;
uniform sampler2D _Metellic;
uniform sampler2D _DiffuseColor;
uniform float3 _LightColor;
uniform float3 _AmbientDiffuseColor_Up;
uniform float3 _AmbientDiffuseColor_Middle;
uniform float3 _AmbientDiffuseColor_Down;
uniform float _AmbientDiffuseStrength;
uniform float _LightSpecularPow;
uniform float _LightSpecularStrength;
uniform float _EnvSpecularStength;
uniform float3 _RimColor;
uniform float _RimStrength;
uniform sampler2D _EmissionTexture;
uniform float _EmissionStrength;
// Input structure
struct VertexInput {
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 tangent : TANGENT;
float2 uv0 : TEXCOORD0;
};
// Output structure
struct VertexOutput {
float4 pos : SV_POSITION;
float3 posWS : TEXCOORD0;
float2 uv0 : TEXCOORD1;
float3 nDirWS : TEXCOORD2;
float3 tDirWS : TEXCOORD3;
float3 bDirWS : TEXCOORD4;
LIGHTING_COORDS(5, 6)
};
// Pixels shader
VertexOutput vert(VertexInput v) {
VertexOutput o = (VertexOutput)0;
o.pos = UnityObjectToClipPos(v.vertex);
o.posWS = mul(unity_ObjectToWorld, v.vertex);
o.uv0 = v.uv0;
o.nDirWS = UnityObjectToWorldNormal(v.normal);
o.tDirWS = normalize(mul(unity_ObjectToWorld, float4(v.tangent.xyz, 0.0)).xyz);
o.bDirWS = normalize(cross(o.nDirWS, o.tDirWS) * v.tangent.w);
TRANSFER_VERTEX_TO_FRAGMENT(o)
return o;
}
// The vertices shader
float4 frag(VertexOutput i) : COLOR {
// Vector preparation
float3 nDirTS = UnpackNormal(tex2D(_NormalTexture,i.uv0)).rgb; // Get normal information
float3x3 TBN = float3x3(i.tDirWS,i.bDirWS,i.nDirWS);
float3 nDirWS = normalize(mul(nDirTS, TBN));
float3 lDirWS = _WorldSpaceLightPos0.xyz;
float3 lrDirWS = reflect(lDirWS,nDirWS);
float3 vDirWS = normalize(_WorldSpaceCameraPos.xyz - i.posWS.xyz);
float3 vrDirWS = normalize(reflect(-vDirWS, nDirWS));
// Intermediate quantity preparation
float ldotn = dot(lDirWS,nDirWS); // The dot multiplier required by half Lambert
float lrdotv = dot(lrDirWS, vDirWS); //Phong Required dot multiplication
float ndotv = (nDirWS,vDirWS); // Point multiplier required by contour light
// Texture sampling
float3 var_MainTexture = tex2D(_MainTexture, i.uv0); // Sample color texture
float var_OpacityTexture = tex2D(_OpacityTexture, i.uv0);// Transparent map sampling
float var_SpecIntTexture = tex2D(_SpecIntTexture, i.uv0); // Sample highlight texture , As a highlight, you need to increase the intensity
float var_RimIntTexture = tex2D(_RimIntTexture, i.uv0); // Edge light texture , As a mask, judge where to highlight
float var_TintMaskTexture = tex2D(_TintMaskTexture, i.uv0); // Dye mask texture , As
float var_SpecPowTexture = tex2D(_SpecPowTexture, i.uv0); // Sampling highlight power , Use it as a template to control the roughness
float var_FresnelRim = tex2D(_FresnelRim, i.uv0); // Fresnel edge light ramptexture
float var_FresnelSpecular = tex2D(_FresnelSpecular, i.uv0); // Fresnel highlights ramptexture
float3 var_CubeMap = texCUBElod(_CubeMap, float4(vrDirWS, lerp(7.0, 0.0, var_SpecIntTexture))).rgb;
float var_Metellic = tex2D(_Metellic, i.uv0);
float var_EmissionTexture = tex2D(_EmissionTexture, i.uv0);
// shadow
float shadow = LIGHT_ATTENUATION(i);
// Illumination model
// Because the colors of specular reflection and diffuse reflection are different , In specular reflection, the metal will show its true color , Nonmetals will appear black and white ; In diffuse reflection, metal diffuse reflection is less , Darker map
float3 diffuseColor = lerp(var_MainTexture,float3(0.0,0.0,0.0), var_Metellic); // use lerp Interpolation , If matellic by 0 The place will reflect its primary color , If it is 1 The reaction is black ,matellic=0.5 Ooh, other decimals are interpolated to calculate the weight of their offset
float3 specularColor = lerp(var_MainTexture, float3(0.4, 0.4, 0.4), var_TintMaskTexture) * var_SpecIntTexture; // Interpolation calculation is carried out through the metal reflective mask , And multiply it by the map with highlights , So as to imitate its reflection color under the light source
// Diffuse reflection of main light source
float halfLambert =ldotn * 0.5 + 0.5; // Half Lambert effect is much better than Lambert effect , Lambert effect is a little terrible
float3 lambertColor = tex2D(_DiffuseColor,float2(halfLambert,0.5));
float3 lightDiffuseColor = _LightColor * lambertColor * diffuseColor * _LightDiffuseStrength;
// Ambient light diffuse
float maskUp = max(0,nDirWS.g);
float maskDown = max(0, -nDirWS.g) ;
float maskMiddle = 1 - maskUp - maskDown;
float3 ambiendDiffuseColor =( maskUp * _AmbientDiffuseColor_Up + maskDown * _AmbientDiffuseColor_Down + _AmbientDiffuseColor_Middle * maskMiddle ) * diffuseColor * _AmbientDiffuseStrength;
// Main light source specular
float Phong = pow(max(0, lrdotv), var_SpecPowTexture * _LightSpecularPow);
float specular = Phong * halfLambert;
float FresnelSpecular = lerp(var_FresnelSpecular,0.0, var_Metellic);
//float specular_Fresnel = tex2D(_FresnelSpecular, float2(specular, 0.5));// It doesn't seem to be able to sample like that , There is a very magical effect
float specular_Fresnel = max(specular, FresnelSpecular) * _LightSpecularStrength;
float3 lightSpecularColor = _LightColor * specular_Fresnel * specularColor;
// Ambient light specular
float reflect = max(var_Metellic, FresnelSpecular) * var_SpecIntTexture;
float3 envSpecularColor = reflect * specularColor * var_CubeMap * _EnvSpecularStength;
// Contour light
float FresnelRim = lerp(var_FresnelRim, 0.0, var_Metellic);
float3 rimLight = var_RimIntTexture * FresnelRim * max(0, nDirWS.g) * _RimStrength * _RimColor;
// Spontaneous light
float3 emission = diffuseColor * var_EmissionTexture * _EmissionStrength;
// Mixed light source
float3 finalColor = (lightDiffuseColor + lightSpecularColor) * shadow + envSpecularColor + envSpecularColor + rimLight + emission;
// Transparent shear
clip(var_OpacityTexture - _Cutoff);
return fixed4(finalColor,1);
}
ENDCG
}
}
FallBack "Legacy Shaders/Transparent/Cutout/VertexLit"
}
边栏推荐
- 佳木斯市场监管局开展防疫防虫害专题食品安全网络培训
- Jiamusi Market Supervision Bureau carried out special food safety network training on epidemic and insect prevention
- 20 hacker artifacts
- What are the principles and methods of implementing functional automation testing?
- [freeze electron microscope] analysis of the source code of the subtomogram alignment function of relion4.0 (for self use)
- [dry goods memo] 50 kinds of Matplotlib scientific research paper drawing collection, including code implementation
- FLink CDC 的mysql connector中,mysql的字段是varbinary, 官方
- Output 1234 three digits without repetition
- UPC little C's King Canyon
- Matrix decomposition and gradient descent
猜你喜欢

Amaze UI 图标查询

JVM garbage collection mechanism (GC)

The new colleague wrote a few pieces of code, broke the system, and was blasted by the boss!

Excellent urban design ~ good! Design # visualization radio station will be broadcast soon
![[deep learning] data preparation -pytorch custom image segmentation data set loading](/img/7d/61be445febc140027b5d9d16db8d2e.png)
[deep learning] data preparation -pytorch custom image segmentation data set loading

Effective learning of medical image segmentation annotation based on noise pseudo tags and adversarial learning

Compare three clock circuit schemes of single chip microcomputer

Solving linear programming problems based on MATLAB

Monitor the bottom button of page scrolling position positioning (including the solution that page initialization positioning does not take effect on mouse sliding)

Data unit: bit, byte, word, word length
随机推荐
Data unit: bit, byte, word, word length
Solving linear programming problems based on MATLAB
cs61abc分享会(六)程序的输入输出详解 - 标准输入输出,文件,设备,EOF,命令行参数
[experience] relevant configuration of remote connection to intranet server through springboard machine
《nlp入门+实战:第五章:使用pytorch中的API实现线性回归》
UPC little C's King Canyon
MapReduce各阶段步骤
Dynamic thresholds buffer management in a shared buffer packet switch paper summary
工业互联网行至深水区,落地的路要怎么走?
Measured waveform of boot capacitor short circuit and open circuit of buck circuit
The software package is set to - > Yum source
[lecture notes] how to do in-depth learning in poor data?
Embroidery of little D
The beauty of do end usage
Excellent urban design ~ good! Design # visualization radio station will be broadcast soon
Amaze UI icon query
MySQL 45 讲 | 07 行锁功过:怎么减少行锁对性能的影响?
Dynamic Thresholds Buffer Management in a Shared Buffer Packet Switch论文总结
IonIcons图标大全
[skill accumulation] common expressions when writing emails