mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-05-14 14:29:52 -05:00
add outline pass
This commit is contained in:
parent
598e3d7013
commit
c81e4c275a
|
|
@ -62,6 +62,7 @@ Shader "Hidden/VRM10/vrmc_materials_mtoon"
|
|||
_M_DebugMode ("_DebugMode", Float) = 0.0
|
||||
}
|
||||
|
||||
// Shader Model 3.0
|
||||
SubShader
|
||||
{
|
||||
Tags { "RenderType" = "Opaque" "Queue" = "Geometry" }
|
||||
|
|
@ -77,7 +78,7 @@ Shader "Hidden/VRM10/vrmc_materials_mtoon"
|
|||
ZWrite [_M_ZWrite]
|
||||
ZTest LEqual
|
||||
BlendOp Add, Max
|
||||
AlphaToMask Off
|
||||
AlphaToMask [_M_AlphaToMask]
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma target 3.0
|
||||
|
|
@ -99,6 +100,42 @@ Shader "Hidden/VRM10/vrmc_materials_mtoon"
|
|||
ENDHLSL
|
||||
}
|
||||
|
||||
// Built-in Forward Base Pass: OUTLINE
|
||||
Pass
|
||||
{
|
||||
Name "FORWARD_BASE_OUTLINE"
|
||||
Tags { "LightMode" = "ForwardBase" }
|
||||
|
||||
Cull Front
|
||||
Blend [_M_SrcBlend] [_M_DstBlend]
|
||||
ZWrite [_M_ZWrite]
|
||||
ZTest LEqual
|
||||
BlendOp Add, Max
|
||||
AlphaToMask [_M_AlphaToMask]
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma target 3.0
|
||||
|
||||
// Unity defined keywords
|
||||
#pragma multi_compile_fwdbase
|
||||
#pragma multi_compile_fog
|
||||
#pragma multi_compile_instancing
|
||||
|
||||
#pragma multi_compile_local __ _ALPHATEST_ON _ALPHABLEND_ON
|
||||
#pragma multi_compile_local __ _NORMALMAP
|
||||
#pragma multi_compile_local __ _UVANIMATION
|
||||
|
||||
#define MTOON_PASS_OUTLINE
|
||||
#define MTOON_OUTLINE_WIDTH_WORLD
|
||||
|
||||
#pragma vertex MToonVertex
|
||||
#pragma fragment MToonFragment
|
||||
|
||||
#include "./vrmc_materials_mtoon_forward_vertex.hlsl"
|
||||
#include "./vrmc_materials_mtoon_forward_fragment.hlsl"
|
||||
ENDHLSL
|
||||
}
|
||||
|
||||
// Built-in Forward Add Pass
|
||||
Pass
|
||||
{
|
||||
|
|
|
|||
|
|
@ -25,8 +25,9 @@ struct Varyings
|
|||
half4 tangentWS : TEXCOORD3;
|
||||
#endif
|
||||
float3 viewDirWS : TEXCOORD4;
|
||||
UNITY_FOG_COORDS(5)
|
||||
UNITY_LIGHTING_COORDS(6,7)
|
||||
half outlineFactor : TEXCOORD5;
|
||||
UNITY_FOG_COORDS(6)
|
||||
UNITY_LIGHTING_COORDS(7,8)
|
||||
float4 pos : SV_POSITION; // UnityCG macro specified name. Accurately "positionCS"
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
UNITY_VERTEX_OUTPUT_STEREO
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
#ifndef VRMC_MATERIALS_MTOON_DEFINE_INCLUDED
|
||||
#define VRMC_MATERIALS_MTOON_DEFINE_INCLUDED
|
||||
|
||||
#ifndef UNITY_SAMPLE_TEX2D_LOD
|
||||
#define UNITY_SAMPLE_TEX2D_LOD(tex,coord,lod) tex.SampleLevel (sampler##tex,coord,lod)
|
||||
#endif
|
||||
|
||||
// Compile-time constant
|
||||
inline bool MToon_IsForwardBasePass()
|
||||
{
|
||||
|
|
@ -14,6 +18,16 @@ inline bool MToon_IsForwardBasePass()
|
|||
#endif
|
||||
}
|
||||
|
||||
// Compile-time constant
|
||||
inline bool MToon_IsOutlinePass()
|
||||
{
|
||||
#if defined(MTOON_PASS_OUTLINE)
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Compile-time constant
|
||||
inline bool MToon_IsUvAnimationOn()
|
||||
{
|
||||
|
|
@ -34,4 +48,24 @@ inline bool MToon_IsNormalMapOn()
|
|||
#endif
|
||||
}
|
||||
|
||||
// Compile-time constant
|
||||
inline bool MToon_IsOutlineModeWorldCoordinates()
|
||||
{
|
||||
#if defined(MTOON_OUTLINE_WIDTH_WORLD)
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Compile-time constant
|
||||
inline bool MToon_IsOutlineModeScreenCoordinates()
|
||||
{
|
||||
#if defined(MTOON_OUTLINE_WIDTH_SCREEN)
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ half4 MToonFragment(const Varyings input) : SV_Target
|
|||
mtoonInput.viewDirWS = input.viewDirWS;
|
||||
mtoonInput.litColor = litColor.rgb;
|
||||
mtoonInput.alpha = alpha;
|
||||
mtoonInput.outlineFactor = input.outlineFactor;
|
||||
const half4 col = GetMToonLighting(unityLighting, mtoonInput);
|
||||
|
||||
UNITY_APPLY_FOG(i.fogCoord, col);
|
||||
|
|
|
|||
|
|
@ -3,9 +3,11 @@
|
|||
|
||||
#include <UnityCG.cginc>
|
||||
#include <AutoLight.cginc>
|
||||
#include "./vrmc_materials_mtoon_define.hlsl"
|
||||
#include "./vrmc_materials_mtoon_utility.hlsl"
|
||||
#include "./vrmc_materials_mtoon_input.hlsl"
|
||||
#include "./vrmc_materials_mtoon_attribute.hlsl"
|
||||
#include "./vrmc_materials_mtoon_geometry_vertex.hlsl"
|
||||
|
||||
Varyings MToonVertex(const Attributes v) // v is UnityCG macro specified name.
|
||||
{
|
||||
|
|
@ -15,18 +17,31 @@ Varyings MToonVertex(const Attributes v) // v is UnityCG macro specified name.
|
|||
UNITY_TRANSFER_INSTANCE_ID(v, output);
|
||||
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
|
||||
|
||||
output.pos = UnityObjectToClipPos(v.vertex);
|
||||
output.positionWS = mul(unity_ObjectToWorld, v.vertex);
|
||||
output.uv = TRANSFORM_TEX(v.texcoord0, _MainTex);
|
||||
output.viewDirWS = MToon_GetWorldSpaceNormalizedViewDir(output.positionWS);
|
||||
|
||||
if (MToon_IsOutlinePass())
|
||||
{
|
||||
output.normalWS = UnityObjectToWorldNormal(-v.normalOS);
|
||||
const VertexPositionInfo position = MToon_GetOutlineVertex(v.vertex.xyz, normalize(v.normalOS), output.uv);
|
||||
output.pos = position.positionCS;
|
||||
output.positionWS = position.positionWS;
|
||||
output.outlineFactor = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
output.normalWS = UnityObjectToWorldNormal(v.normalOS);
|
||||
const VertexPositionInfo position = MToon_GetVertex(v.vertex.xyz);
|
||||
output.pos = position.positionCS;
|
||||
output.positionWS = position.positionWS;
|
||||
output.outlineFactor = 0;
|
||||
}
|
||||
|
||||
output.normalWS = UnityObjectToWorldNormal(v.normalOS);
|
||||
#if defined(_NORMALMAP)
|
||||
const half tangentSign = v.tangentOS.w * unity_WorldTransformParams.w;
|
||||
output.tangentWS = half4(UnityObjectToWorldDir(v.tangentOS), tangentSign);
|
||||
#endif
|
||||
|
||||
output.viewDirWS = MToon_GetWorldSpaceNormalizedViewDir(output.positionWS);
|
||||
|
||||
UNITY_TRANSFER_FOG(output, output.positionWS);
|
||||
UNITY_TRANSFER_LIGHTING(output, v.texcoord1.xy);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
#ifndef VRMC_MATERIALS_MTOON_GEOMETRY_VERTEX_INCLUDED
|
||||
#define VRMC_MATERIALS_MTOON_GEOMETRY_VERTEX_INCLUDED
|
||||
|
||||
#include <UnityCG.cginc>
|
||||
#include "./vrmc_materials_mtoon_define.hlsl"
|
||||
#include "./vrmc_materials_mtoon_utility.hlsl"
|
||||
#include "./vrmc_materials_mtoon_input.hlsl"
|
||||
|
||||
struct VertexPositionInfo
|
||||
{
|
||||
float4 positionWS;
|
||||
float4 positionCS;
|
||||
};
|
||||
|
||||
inline VertexPositionInfo MToon_GetOutlineVertex(const float3 positionOS, const half3 normalOS, const float2 uv)
|
||||
{
|
||||
if (MToon_IsOutlineModeWorldCoordinates())
|
||||
{
|
||||
const float3 positionWS = mul(unity_ObjectToWorld, float4(positionOS, 1)).xyz;
|
||||
const half outlineWidth = _OutlineWidth * UNITY_SAMPLE_TEX2D_LOD(_OutlineWidthTex, uv, 0);
|
||||
const half3 normalWS = UnityObjectToWorldNormal(normalOS);
|
||||
|
||||
VertexPositionInfo output;
|
||||
output.positionWS = float4(positionWS + normalWS * outlineWidth, 1);
|
||||
output.positionCS = UnityWorldToClipPos(output.positionWS);
|
||||
return output;
|
||||
}
|
||||
else if (MToon_IsOutlineModeScreenCoordinates())
|
||||
{
|
||||
const float3 positionWS = mul(unity_ObjectToWorld, float4(positionOS, 1)).xyz;
|
||||
const half outlineWidth = _OutlineWidth * UNITY_SAMPLE_TEX2D_LOD(_OutlineWidthTex, uv, 0);
|
||||
|
||||
const float4 nearUpperRight = mul(unity_CameraInvProjection, float4(1, 1, UNITY_NEAR_CLIP_VALUE, _ProjectionParams.y));
|
||||
const half aspect = abs(nearUpperRight.y / nearUpperRight.x);
|
||||
|
||||
float4 positionCS = UnityObjectToClipPos(positionOS);
|
||||
const half3 normalVS = MToon_GetObjectToViewNormal(normalOS);
|
||||
const half3 normalCS = TransformViewToProjection(normalVS.xyz);
|
||||
half2 normalProjectedCS = normalize(normalCS.xy);
|
||||
normalProjectedCS *= positionCS.w;
|
||||
normalProjectedCS.x *= aspect;
|
||||
positionCS.xy += outlineWidth * normalProjectedCS.xy * saturate(1 - abs(normalVS.z)); // ignore offset when normal toward camera
|
||||
|
||||
VertexPositionInfo output;
|
||||
output.positionWS = float4(positionWS, 1);
|
||||
output.positionCS = positionCS;
|
||||
return output;
|
||||
}
|
||||
else
|
||||
{
|
||||
VertexPositionInfo output;
|
||||
output.positionWS = mul(unity_ObjectToWorld, float4(positionOS, 1));
|
||||
output.positionCS = UnityWorldToClipPos(output.positionWS);
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
inline VertexPositionInfo MToon_GetVertex(const float3 positionOS)
|
||||
{
|
||||
VertexPositionInfo output;
|
||||
output.positionWS = mul(unity_ObjectToWorld, float4(positionOS, 1));
|
||||
output.positionCS = UnityWorldToClipPos(output.positionWS);
|
||||
return output;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 92e89e208e604f28acdce8a142d1e241
|
||||
timeCreated: 1622805067
|
||||
|
|
@ -14,6 +14,7 @@ struct MToonInput
|
|||
half3 viewDirWS;
|
||||
half3 litColor;
|
||||
half alpha;
|
||||
half outlineFactor;
|
||||
};
|
||||
|
||||
inline half GetMToonLighting_Reflectance(const UnityLighting lighting, const MToonInput input)
|
||||
|
|
@ -91,12 +92,13 @@ half4 GetMToonLighting(const UnityLighting unityLight, const MToonInput input)
|
|||
const half3 direct = GetMToonLighting_DirectLighting(unityLight, input, reflectance);
|
||||
const half3 indirect = GetMToonLighting_GlobalIllumination(unityLight, input);
|
||||
const half3 lighting = direct + indirect;
|
||||
|
||||
const half3 emissive = GetMToonLighting_Emissive(input);
|
||||
|
||||
const half3 rim = GetMToonLighting_Rim(input, lighting);
|
||||
|
||||
const half3 col = lighting + emissive + rim;
|
||||
const half3 baseCol = lighting + emissive + rim;
|
||||
const half3 outlineCol = _OutlineColor.rgb * lerp(half3(1, 1, 1), baseCol, _OutlineLightingMix);
|
||||
|
||||
const half3 col = lerp(baseCol, outlineCol, input.outlineFactor);
|
||||
|
||||
return half4(col, input.alpha);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,4 +39,9 @@ inline half3x3 MToon_GetTangentToWorld(const half3 normalWS, const half4 tangent
|
|||
return half3x3(normalizedTangentWS, normalizedBitangentWS, normalizedNormalWS);
|
||||
}
|
||||
|
||||
inline half3 MToon_GetObjectToViewNormal(const half3 normalOS)
|
||||
{
|
||||
return normalize(mul((half3x3)UNITY_MATRIX_IT_MV, normalOS));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user