Files
2025-01-07 18:54:46 +02:00

423 lines
13 KiB
Plaintext

Shader "Hair/Hair Mark 9"
{
Properties
{
_Color("Color", Color) = (1,1,1,1)
_MainTex ("Texture", 2D) = "white" {}
_Cutoff ("Alpha cutoff", Range(0,1)) = 0.4
_CutoffOffset ("Alpha cutoff shadows", Range(0,1)) = 0.4
_MipScale ("Mip Level Alpha Scale", Range(0,1)) = 0.25
_MipScaleOffset ("Shadow Scale", Range(0,3)) = 1.5
_ShadowScaleOffset ("Shadow Scale Offset", float) = -0.001
_Spec("Spec Color", Color) = (1,1,1,1)
_Gloss("Gloss", float) = 1.0
_AnisoOffset("Aniso Offset", float) = 1.0
_Flatness("Flatness", float) = 0.5
_Smoother("Lighting Smoother", float) = 4
_RimPower("Rim Lighting", Range(0,2)) = 0
_RimAngle("Rim Angle", Range(0,20)) = 1
_AnisoTwo("Aniso", float) = 1.0
_AnisoThree("Strandiness", float) = 1.0
_AnisoFour("Strand Highlight Cutoff", float) = 1.0
_AnisoDir("Aniso Dir", Vector) = (0.5,0.5,1.0,1.0)
_BlueNoiseCrossfade("Blue Noise Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderQueue"="AlphaTest" "RenderType"="TransparentCutout" }
Cull Off
Pass
{
Tags { "LightMode"="ForwardBase" }
//AlphaToMask On
ZWrite On
ColorMask RGB
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdbase
#include "UnityCG.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc"
#include "DitherFunctions.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
half3 normal : NORMAL;
};
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
half3 worldNormal : NORMAL;
half3 viewDir : TEXCOORD1;
float4 screenPos : TEXCOORD2;
LIGHTING_COORDS(3,4)
};
sampler2D _MainTex;
float4 _MainTex_ST;
float4 _MainTex_TexelSize;
fixed _Cutoff;
half _MipScale;
fixed _Gloss;
fixed4 _Spec;
half _AnisoOffset;
half _Flatness;
fixed4 _Color;
float4 _AnisoDir;
float _AnisoTwo;
float _AnisoThree;
float _AnisoFour;
float _Smoother;
float CalcMipLevel(float2 texture_coord)
{
float2 dx = ddx(texture_coord);
float2 dy = ddy(texture_coord);
float delta_max_sqr = max(dot(dx, dx), dot(dy, dy));
return max(0.0, 0.5 * log2(delta_max_sqr));
}
v2f vert (appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
o.viewDir = ObjSpaceViewDir(v.vertex);
o.screenPos = ComputeScreenPos(UnityObjectToClipPos(v.vertex));
TRANSFER_VERTEX_TO_FRAGMENT(o);
return o;
}
float _RimAngle;
float _RimPower;
inline fixed4 CalculateLighting(v2f i, fixed facing : VFACE, fixed4 albedo) {
float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
float3 worldNormal = i.worldNormal * facing;
fixed3 h = normalize(normalize(lightDir) + normalize(i.viewDir));
float d = max(dot(lightDir, worldNormal), dot(lightDir, worldNormal * -1));
float NdotL = saturate(d * _Smoother + _Flatness);
fixed HdotA = dot(normalize(worldNormal + _AnisoDir.rgb), h);
float aniso = max(0, sin(radians((HdotA + _AnisoOffset) * 180)));
float specX = saturate(dot(worldNormal, h));
float rim = saturate(pow(max(dot(i.worldNormal * facing, i.viewDir), dot(i.worldNormal * facing, i.viewDir)), _RimAngle)) * _RimPower;
float3 spec = saturate((pow(lerp(specX, aniso, _AnisoTwo), _Gloss * 128) + rim) * _Spec);
float maxAlbedo = max(max(albedo.r, albedo.g), albedo.b);
spec = lerp(spec, spec*saturate(((maxAlbedo - _AnisoFour)*(1.0 / _AnisoFour))), _AnisoThree);
fixed4 c;
half3 sh9 = ShadeSH9(float4(worldNormal.rgb,1.0));
c.rgb = ((albedo * _LightColor0.rgb * NdotL * 0.5) + (_LightColor0.rgb * spec * maxAlbedo))
* (LIGHT_ATTENUATION(i) * 2)
+ (sh9 * albedo);
c.a = albedo.a;
//clip(albedo.Alpha - _Cutoff);
return c;
}
fixed4 frag (v2f i, fixed facing : VFACE) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv) * _Color;
// rescale alpha by mip level (if not using preserved coverage mip maps)
col.a *= 1 + max(0, CalcMipLevel(i.uv * _MainTex_TexelSize.zw)) * _MipScale;
// rescale alpha by partial derivative
col.a = (col.a - _Cutoff) / max(fwidth(col.a), 0.0001) + 0.5;
half3 worldNormal = normalize(i.worldNormal * facing);
col = CalculateLighting(i, facing, col);
//col.rg = (i.screenPos.xy / i.screenPos.w);
ditherClip(i.screenPos.xy / i.screenPos.w, col.a, _Cutoff);
return col;
}
ENDCG
}
Pass
{
Tags { "LightMode"="ForwardBase" }
AlphaToMask Off
ZWrite Off
ZTest Less
Cull Off
ColorMask RGB
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdbase
#include "UnityCG.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc"
#include "DitherFunctions.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
half3 normal : NORMAL;
};
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
half3 worldNormal : NORMAL;
half3 viewDir : TEXCOORD1;
float4 screenPos : TEXCOORD2;
LIGHTING_COORDS(3,4)
};
sampler2D _MainTex;
float4 _MainTex_ST;
float4 _MainTex_TexelSize;
fixed _Cutoff;
half _MipScale;
fixed _Gloss;
fixed4 _Spec;
half _AnisoOffset;
half _Flatness;
fixed4 _Color;
float4 _AnisoDir;
float _AnisoTwo;
float _AnisoThree;
float _AnisoFour;
float _Smoother;
float CalcMipLevel(float2 texture_coord)
{
float2 dx = ddx(texture_coord);
float2 dy = ddy(texture_coord);
float delta_max_sqr = max(dot(dx, dx), dot(dy, dy));
return max(0.0, 0.5 * log2(delta_max_sqr));
}
v2f vert (appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
o.viewDir = ObjSpaceViewDir(v.vertex);
o.screenPos = ComputeScreenPos(UnityObjectToClipPos(v.vertex));
TRANSFER_VERTEX_TO_FRAGMENT(o);
return o;
}
float _RimAngle;
float _RimPower;
inline fixed4 CalculateLighting(v2f i, fixed facing : VFACE, fixed4 albedo) {
float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
float3 worldNormal = i.worldNormal * facing;
fixed3 h = normalize(normalize(lightDir) + normalize(i.viewDir));
float d = max(dot(lightDir, worldNormal), dot(lightDir, worldNormal * -1));
float NdotL = saturate(d * _Smoother + _Flatness);
fixed HdotA = dot(normalize(worldNormal + _AnisoDir.rgb), h);
float aniso = max(0, sin(radians((HdotA + _AnisoOffset) * 180)));
float specX = saturate(dot(worldNormal, h));
float rim = saturate(pow(max(dot(i.worldNormal * facing, i.viewDir), dot(i.worldNormal * facing, i.viewDir)), _RimAngle)) * _RimPower;
float3 spec = saturate((pow(lerp(specX, aniso, _AnisoTwo), _Gloss * 128) + rim) * _Spec);
float maxAlbedo = max(max(albedo.r, albedo.g), albedo.b);
spec = lerp(spec, spec*saturate(((maxAlbedo - _AnisoFour)*(1.0 / _AnisoFour))), _AnisoThree);
fixed4 c;
half3 sh9 = ShadeSH9(float4(worldNormal.rgb,1.0));
c.rgb = ((albedo * _LightColor0.rgb * NdotL * 0.5) + (_LightColor0.rgb * spec * maxAlbedo))
* (LIGHT_ATTENUATION(i) * 2)
+ (sh9 * albedo);
c.a = albedo.a;
//clip(albedo.Alpha - _Cutoff);
return c;
}
fixed4 frag (v2f i, fixed facing : VFACE) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv) * _Color;
// rescale alpha by mip level (if not using preserved coverage mip maps)
//col.a *= 1 + max(0, CalcMipLevel(i.uv * _MainTex_TexelSize.zw)) * _MipScale;
// rescale alpha by partial derivative
//col.a = (col.a - _Cutoff) / max(fwidth(col.a), 0.0001) + 0.5;
half3 worldNormal = normalize(i.worldNormal * facing);
col = CalculateLighting(i, facing, col);
//ditherClip(i.screenPos.xy / i.screenPos.w, 1.0 - col.a, _Cutoff);
col.a = saturate(col.a * (1/_Cutoff));
return col;
}
ENDCG
}
/*
Pass {
Name "CASTER"
Tags { "LIGHTMODE"="SHADOWCASTER" "QUEUE"="AlphaTest" "IGNOREPROJECTOR"="true" "SHADOWSUPPORT"="true" "RenderType"="TransparentCutout" }
//AlphaToMask On
Cull Off
ZWrite On
CGPROGRAM
#include "HLSLSupport.cginc"
#include "UnityShaderVariables.cginc"
#include "UnityShaderUtilities.cginc"
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#pragma multi_compile_shadowcaster
#pragma multi_compile_instancing // allow instanced shadow pass for most of the shaders
#include "UnityCG.cginc"
struct v2f {
V2F_SHADOW_CASTER;
float2 uv : TEXCOORD1;
UNITY_VERTEX_OUTPUT_STEREO
};
uniform float4 _MainTex_ST;
float _ShadowScaleOffset;
v2f vert( appdata_base v )
{
v2f o;
v.vertex.xyz += v.normal.xyz * _ShadowScaleOffset;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
TRANSFER_SHADOW_CASTER_NORMALOFFSET(o)
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
return o;
}
uniform sampler2D _MainTex;
float4 _MainTex_TexelSize;
uniform fixed _CutoffOffset;
uniform fixed4 _Color;
half _MipScaleOffset;
float CalcMipLevel(float2 texture_coord)
{
float2 dx = ddx(texture_coord);
float2 dy = ddy(texture_coord);
float delta_max_sqr = max(dot(dx, dx), dot(dy, dy));
return max(0.0, 0.5 * log2(delta_max_sqr));
}
float4 frag( v2f i ) : SV_Target
{
fixed4 col = tex2D( _MainTex, i.uv );
//col.a *= 1 + max(0, CalcMipLevel(i.uv * _MainTex_TexelSize.zw)) * _MipScaleOffset;
//col.a -= _CutoffOffset + 0.1;
//col.a = (col.a - _CutoffOffset) / max(fwidth(col.a), 0.0) + 0.5;
clip( col.a - _CutoffOffset);
SHADOW_CASTER_FRAGMENT(i)
}
ENDCG
}
*/
Pass
{
Name "CASTER"
Tags { "LIGHTMODE"="SHADOWCASTER" "QUEUE"="AlphaTest" "IGNOREPROJECTOR"="true" "SHADOWSUPPORT"="true" "RenderType"="TransparentCutout" }
CGPROGRAM
#include "UnityCG.cginc"
#include "DitherFunctions.cginc"
#pragma vertex vert
#pragma fragment frag
float4 _Color;
float4 _MainTex_ST; // For the Main Tex UV transform
sampler2D _MainTex; // Texture used for the line
float _MipScaleOffset;
float _CutoffOffset;
struct v2f
{
float4 pos : POSITION;
float2 uv : TEXCOORD0;
float4 screenPos : TEXCOORD1;
};
v2f vert(appdata_base v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
o.screenPos = ComputeScreenPos(UnityObjectToClipPos(v.vertex));
return o;
}
float4 frag(v2f i) : COLOR
{
float4 col = _Color * tex2D(_MainTex, i.uv);
ditherClip(i.screenPos.xy / i.screenPos.w, col.a * _MipScaleOffset, _CutoffOffset);
return float4(0,0,0,0);
}
ENDCG
}
}
FallBack "Transparent/Cutout/Specular"
}