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.1基本

ファーの属性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.2属性

外力を増やす0.3力

これは、世界に対する力(グローバルな力)とオブジェクトに対する力(ローカルな力)に分けられます。頂点シェーダーで頂点位置Pを変更します。オフセット方向の制約を実行するには、clamp(x、-1、1)関数を使用します。

P += clamp(mul(unity_WorldToObject, _ForceGlobal).xyz + _ForceLocal.xyz, -1, 1) * pow(FURSTEP, 3) * _FurLength

効果:
0.3力

リムカラー0.4リムカラー

エッジの髪の色が光の影響をわずかに受けることを考慮して、リムの色(リムの色)を増やします。

half rim = 1.0 - saturate(dot(worldView, worldNormal))
albedo += fixed4(_RimColor.rgb * pow(rim, _RimPower), 1.0)

効果:
0.4リムカラー


参照リンク

毛皮の効果-テディ、猫、髪…。
ファーシェーダー-シェーダーラボ