此篇文章参考 Hair Rendering and Shading
相关链接:Redirecting
在Unity中实现高质量的发丝渲染通常需要结合多种技术,包括Shader编写、几何处理、光照模型等。
1. 准备发丝模型
首先,你需要一个高质量的发丝模型。通常,发丝模型由多个细长的三角形条带组成,模拟头发的形状。可以使用3D建模软件(如Maya、Blender)创建,或者使用头发生成工具(如HairWorks、Ornatrix)生成。
2 编写Shader
技术实现:
Shader "Custom/HairShader"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Color ("Color", Color) = (1,1,1,1)
_Specular ("Specular", Color) = (1,1,1,1)
_Gloss ("Gloss", Range(0,1)) = 0.5
_Anisotropic ("Anisotropic", Range(0,1)) = 0.5
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 200
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 normal : NORMAL;
float4 tangent : TANGENT;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 pos : SV_POSITION;
float3 worldNormal : NORMAL;
float3 worldTangent : TANGENT;
float3 worldBinormal : BINORMAL;
};
sampler2D _MainTex;
float4 _Color;
float4 _Specular;
float _Gloss;
float _Anisotropic;
v2f vert (appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
o.worldNormal = UnityObjectToWorldNormal(v.normal);
o.worldTangent = UnityObjectToWorldDir(v.tangent.xyz);
o.worldBinormal = cross(o.worldNormal, o.worldTangent) * v.tangent.w;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
float3 worldNormal = normalize(i.worldNormal);
float3 worldTangent = normalize(i.worldTangent);
float3 worldBinormal = normalize(i.worldBinormal);
// Anisotropic lighting
float3 viewDir = normalize(_WorldSpaceCameraPos - i.pos);
float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
float3 halfDir = normalize(lightDir + viewDir);
float NdotL = dot(worldNormal, lightDir);
float TdotH = dot(worldTangent, halfDir);
float BdotH = dot(worldBinormal, halfDir);
float anisotropy = _Anisotropic;
float specular = exp(-(TdotH * TdotH + anisotropy * BdotH * BdotH) / (1.0 + _Gloss));
fixed4 texColor = tex2D(_MainTex, i.uv);
fixed4 finalColor = texColor * _Color + _Specular * specular;
return finalColor;
}
ENDCG
}
}
FallBack "Diffuse"
}
3. 光照设置
发丝渲染对光照非常敏感,建议使用HDRP(High Definition Render Pipeline)或URP(Universal Render Pipeline)来获得更好的光照效果。
-
HDRP:支持更复杂的光照模型和后期处理效果,适合高质量的发丝渲染。
-
URP:性能较好,适合移动端或性能要求较高的项目。
4. 后期处理
为了进一步增强发丝的真实感,可以添加一些后期处理效果:
-
抗锯齿:使用TAA(Temporal Anti-Aliasing)来减少发丝的锯齿。
-
景深:模拟相机焦点外的模糊效果,增加真实感。
-
Bloom:增强发丝的高光效果。
相关技术支持:
5. 优化
发丝渲染通常对性能有较高要求,尤其是在移动设备上。以下是一些优化建议:
-
LOD(Level of Detail):根据距离调整发丝的细节层次。
-
GPU Instancing:对相同的发丝模型使用GPU Instancing来减少Draw Call。
-
Culling:使用视锥剔除和遮挡剔除来减少不必要的渲染。
6.结语
效果:
对于半透明的物体,需要从后向前渲染保证渲染的正确性
对于有头发的头,这和头发从内向外渲染很相似。这个可以在制作模型的时候,内部的顶点坐标往前放,外部的顶点坐标向后放,主要是索引的顺序要正确。
按照下面的顺序去渲染,分4个pass (深度写入,不透明,半透明背面,半透明正面)
第一个pass,使用alphaTest剔除半透明像素,禁用背面剔除,写入深度,深度检测为less,不需要渲染颜色,只需要写入深度。
第二个pass,进行完整的头发像素渲染,禁用背面剔除,禁用深度写入,深度检测为 Equal,用来绘制不透明部分的表面。
第三个pass,用于绘制半透明背面,剔除正面渲染,不写入深度,深度检测为less。
第四个pass,半透明正面渲染,剔除背面,深度写入,深度检测为less,启用深度写入可以防止不正确的深度顺序。
综上便可实现头发渲染,动手试试吧!