Skip to content

Instantly share code, notes, and snippets.

@rngtm
Created June 4, 2023 12:30
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rngtm/b4a50de08eab6b46140456f73ef2ea62 to your computer and use it in GitHub Desktop.
Save rngtm/b4a50de08eab6b46140456f73ef2ea62 to your computer and use it in GitHub Desktop.
透ける眉のシェーダー
Shader "Zenn/Character-Body"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
[Header(Stencil)]
[Space]
_StencilRef("Stencil Ref", Int) = 0
[Enum(UnityEngine.Rendering.CompareFunction)]_StencilComp("Stencil Comp", Int) = 0
[Enum(UnityEngine.Rendering.StencilOp)]_StencilPassOp("Stencil Pass", Int) = 0
[Enum(UnityEngine.Rendering.StencilOp)]_StencilFailOp("Stencil Fail", Int) = 0
[Enum(UnityEngine.Rendering.StencilOp)]_StencilZFailOp("Stenci ZFail", Int) = 0
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
Name "Body"
Stencil
{
Ref [_StencilRef]
Comp [_StencilComp]
Pass [_StencilPassOp]
Fail [_StencilFailOp]
ZFail [_StencilZFailOp]
}
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "CharacterPass.hlsl"
ENDHLSL
}
}
}
Shader "Zenn/Character-Face"
{
Properties
{
_EyeBrowColor ("Eyebrow Color", Color) = (1, 1, 1, 0.5)
_MainTex ("Main Texture", 2D) = "white" {}
_EyeMaskTex ("Eye Mask Texture", 2D) = "black" {}
_EyeMaskEdge1 ("Eye Mask Edge 1", Range(0, 1)) = 0.4 // フェードがかかりはじめる角度 (角度ではなく、cosの値を指定)
_EyeMaskEdge2 ("Eye Mask Edge 2", Range(0, 1)) = 0.0 // フェードがかかり終わる角度 (角度ではなく、cosの値を指定)
[Header(EyeBrow Stencil)]
[Space]
_StencilRef("Stencil Ref", Int) = 1
[Enum(UnityEngine.Rendering.CompareFunction)]_StencilComp("Stencil Comp", Int) = 0
[Enum(UnityEngine.Rendering.StencilOp)]_StencilPassOp("Stencil Pass", Int) = 0
[Enum(UnityEngine.Rendering.StencilOp)]_StencilFailOp("Stencil Fail", Int) = 0
[Enum(UnityEngine.Rendering.StencilOp)]_StencilZFailOp("Stenci ZFail", Int) = 0
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
Name "Base"
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "CharacterPass.hlsl"
ENDHLSL
}
Pass
{
Name "EyeBrow"
Tags { "LightMode"="EyeBrow" }
Stencil
{
Ref [_StencilRef]
Comp [_StencilComp]
Pass [_StencilPassOp]
Fail [_StencilFailOp]
ZFail [_StencilZFailOp]
}
Blend SrcAlpha OneMinusSrcAlpha
ZTest Off
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#define CHARACTER_EYEBROW_PASS
#include "CharacterPass.hlsl"
ENDHLSL
}
}
}
Shader "Zenn/Character-Hair"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
[Header(Stencil)]
[Space]
_StencilRef("Stencil Ref", Int) = 0
[Enum(UnityEngine.Rendering.CompareFunction)]_StencilComp("Stencil Comp", Int) = 0
[Enum(UnityEngine.Rendering.StencilOp)]_StencilPassOp("Stencil Pass", Int) = 0
[Enum(UnityEngine.Rendering.StencilOp)]_StencilFailOp("Stencil Fail", Int) = 0
[Enum(UnityEngine.Rendering.StencilOp)]_StencilZFailOp("Stenci ZFail", Int) = 0
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
Name "Hair"
Stencil
{
Ref [_StencilRef]
Comp [_StencilComp]
Pass [_StencilPassOp]
Fail [_StencilFailOp]
ZFail [_StencilZFailOp]
}
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "CharacterPass.hlsl"
ENDHLSL
}
}
}
#ifndef CHARACTER_PASS_INCLUDED
#define CHARACTER_PASS_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
CBUFFER_START(UnityPerMaterial)
sampler2D _MainTex; // ベースカラーテクスチャ
sampler2D _EyeMaskTex; // 眉をくり抜くマスクテクスチャ
half4 _EyeBrowColor; // 眉の色
float3 _CharacterFaceFront; // キャラクターの顔の正面
half _EyeMaskEdge1; // フェードがかかり始める角度 (cosの値を指定)
half _EyeMaskEdge2; // フェードがかかり終わる角度 (cosの値を指定)
CBUFFER_END
float cross2d(float2 a, float2 b)
{
return (a.x * b.y - a.y * b.x);
}
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
float eyeMask : TEXCOORD1; // 目じりをくり抜くマスク値
};
float remap(float x, float a, float b, float c, float d)
{
return saturate((x - a) / (b - a)) * (d - c) + c;
}
v2f vert (appdata v)
{
v2f o;
o.vertex = TransformObjectToHClip(v.vertex);
o.uv = v.uv;
float3 camFront = -UNITY_MATRIX_V[2];
float2 camFrontXZ = -UNITY_MATRIX_V[2].xz;
float2 faceFrontXZ = _CharacterFaceFront.xz;
float isRightSide = step(0.0, cross2d(camFrontXZ, faceFrontXZ));
o.eyeMask = lerp(step(0, v.vertex.x), step(v.vertex.x, 0), isRightSide);
half dotFaceCamera = dot(_CharacterFaceFront, -camFront);
o.eyeMask *= remap(dotFaceCamera, _EyeMaskEdge1, _EyeMaskEdge2, 0.0, 1.0);
o.eyeMask *= saturate(dotFaceCamera);
return o;
}
half4 frag (v2f i) : SV_Target
{
// カラーテクスチャのサンプリング
half4 col = tex2D(_MainTex, i.uv);
#ifdef CHARACTER_EYEBROW_PASS
half4 mask = tex2D(_EyeMaskTex, i.uv);
clip(mask.r - 0.001); // マスクが黒いところをくり抜く
col *= _EyeBrowColor;
col.a *= i.eyeMask;
#endif
return col;
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment