Unityファーシェーダーファーシェーダー
Unity Fur Shader Fur Shader
Github倉庫の住所: github.com/Sorumi/UnityFurShader
元のブログ投稿: sorumi.xyz/posts/unity-fur-shader/
ベーシックファー0.1ベーシック
まず、髪のモデルを作成します。
モデルによると、レイヤーを使用して髪の長さをレンダリングします。 Unity Shaderでは、各パスはレイヤーを表します。
各レイヤーをレンダリングするときは、法線を使用してモデルサーフェスから頂点位置を「押し出し」、次に対応するピクセル位置の式を使用します。
float3 P = v.vertex.xyz + v.normal * _FurLength * FURSTEP
FURSTEP
現在のレイヤー数/レイヤー総数を示します。レイヤーの数を増やすと、より細い髪を作成できます。
次に、ノイズテクスチャを各ピクセルのアルファ値として使用して、ピクセルがヘアポイントに属しているかどうかを判断します。
照明モデルは、アンビエントライト、拡散照明、スペキュラーライトを使用し、ピクセルごとのカラーリングを使用します。 (パフォーマンスを考慮すると、頂点彩色に変更できます。)
n個のレイヤーを設定する場合、サブシェーダーにファーに関係なくサーフェスのみをレンダリングする1つのパスと、ファーをレンダリングするn個のパス(合計n + 1パス)が必要です。
毛沢東のコード:
struct v2f { float4 pos: SV_POSITION half4 uv: TEXCOORD0 float3 worldNormal: TEXCOORD1 float3 worldPos: TEXCOORD2 } v2f vert_base(appdata_base v) { v2f o float3 P = v.vertex.xyz + v.normal * _FurLength * FURSTEP o.pos = UnityObjectToClipPos(float4(P, 1.0)) o.uv.xy = TRANSFORM_TEX(v.texcoord, _MainTex) o.uv.zw = TRANSFORM_TEX(v.texcoord, _FurTex) o.worldNormal = UnityObjectToWorldNormal(v.normal) o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz return o } fixed4 frag_base(v2f i): SV_Target { fixed3 worldNormal = normalize(i.worldNormal) fixed3 worldLight = normalize(_WorldSpaceLightPos0.xyz) fixed3 worldView = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz) fixed3 worldReflect = normalize(reflect(-worldView, worldNormal)) fixed3 albedo = tex2D(_MainTex, i.uv.xy).rgb * _Color fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo fixed3 diffuse = _LightColor0.rgb * albedo * saturate(dot(worldNormal, worldLight)) fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(worldReflect, worldView)), _Shininess) fixed3 color = ambient + diffuse + specular fixed alpha = tex2D(_FurTex, i.uv.zw).rgb return fixed4(color, alpha) }
効果:
ファーの属性0.2属性
毛皮の密度を上げる
髪の毛が尻尾に向かって細くなることを示すために使用されます。ノイズグレースケールサンプリングに従ってピクセルの各レイヤーの透明度を調整し、フラグメントシェーダーのアルファ計算方法を変更します
alpha = clamp(noise - (FURSTEP * FURSTEP) * _EdgeFade, 0, 1)
毛皮の薄さを増やす
それは本質的にノイズテクスチャを変更するタイルです
fixed3 noise = tex2D(_FurTex, i.uv.zw * _FurThinnesss).rgb
ファーシェーディングを増やす
ルートに近いピクセルは色が濃くなります
albedo -= (pow(1 - FURSTEP, 3)) * _FurShading
または補間を使用します
float shadow = lerp(1, FURSTEP, _FurShading)
albedo *= shadow
2つの方法の効果を比較すると、より階層化されているように感じます。
効果:
外力を増やす0.3力
これは、世界に対する力(グローバルな力)とオブジェクトに対する力(ローカルな力)に分けられます。頂点シェーダーで頂点位置Pを変更します。オフセット方向の制約を実行するには、clamp(x、-1、1)関数を使用します。
P += clamp(mul(unity_WorldToObject, _ForceGlobal).xyz + _ForceLocal.xyz, -1, 1) * pow(FURSTEP, 3) * _FurLength
効果:
リムカラー0.4リムカラー
エッジの髪の色が光の影響をわずかに受けることを考慮して、リムの色(リムの色)を増やします。
half rim = 1.0 - saturate(dot(worldView, worldNormal))
albedo += fixed4(_RimColor.rgb * pow(rim, _RimPower), 1.0)
効果: