272 lines
9.7 KiB
HLSL
272 lines
9.7 KiB
HLSL
/*
|
||
* The MIT License
|
||
*
|
||
* Copyright 2018-2021 whiteflare.
|
||
*
|
||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||
* to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||
*
|
||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||
*
|
||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||
*/
|
||
|
||
#ifndef INC_UNLIT_WF_UNTOON
|
||
#define INC_UNLIT_WF_UNTOON
|
||
|
||
////////////////////////////
|
||
// uniform variable
|
||
////////////////////////////
|
||
|
||
#include "WF_INPUT_UnToon.cginc"
|
||
|
||
////////////////////////////
|
||
// main structure
|
||
////////////////////////////
|
||
|
||
struct appdata {
|
||
float4 vertex : POSITION;
|
||
#ifdef _VC_ENABLE
|
||
float4 vertex_color : COLOR0;
|
||
#endif
|
||
float2 uv : TEXCOORD0;
|
||
float2 uv_lmap : TEXCOORD1;
|
||
float3 normal : NORMAL;
|
||
#ifdef _NM_ENABLE
|
||
float4 tangent : TANGENT;
|
||
#endif
|
||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||
};
|
||
|
||
struct v2f {
|
||
float4 vs_vertex : SV_POSITION;
|
||
#ifdef _VC_ENABLE
|
||
float4 vertex_color : COLOR0;
|
||
#endif
|
||
float3 light_color : COLOR1;
|
||
#ifdef _TS_ENABLE
|
||
float shadow_power : COLOR2;
|
||
#endif
|
||
float2 uv : TEXCOORD0;
|
||
float2 uv_lmap : TEXCOORD1;
|
||
float3 ws_vertex : TEXCOORD2;
|
||
float4 ws_light_dir : TEXCOORD3;
|
||
float3 normal : TEXCOORD4; // world space
|
||
#ifdef _NM_ENABLE
|
||
float3 tangent : TEXCOORD5; // world space
|
||
float3 bitangent : TEXCOORD6; // world space
|
||
#endif
|
||
UNITY_FOG_COORDS(7)
|
||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||
UNITY_VERTEX_OUTPUT_STEREO
|
||
};
|
||
|
||
////////////////////////////
|
||
// UnToon function
|
||
////////////////////////////
|
||
|
||
#include "WF_UnToon_Function.cginc"
|
||
|
||
////////////////////////////
|
||
// vertex&fragment shader
|
||
////////////////////////////
|
||
|
||
v2f vert(in appdata v) {
|
||
v2f o;
|
||
|
||
UNITY_SETUP_INSTANCE_ID(v);
|
||
UNITY_INITIALIZE_OUTPUT(v2f, o);
|
||
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
|
||
|
||
o.ws_vertex = UnityObjectToWorldPos(v.vertex.xyz);
|
||
#ifndef _WF_MAIN_Z_SHIFT
|
||
o.vs_vertex = UnityObjectToClipPos(v.vertex.xyz); // 通常の ToClipPos を使う
|
||
#else
|
||
o.vs_vertex = shiftDepthVertex(o.ws_vertex, _WF_MAIN_Z_SHIFT); // Zシフトした値を使う
|
||
#endif
|
||
#ifdef _VC_ENABLE
|
||
o.vertex_color = v.vertex_color;
|
||
#endif
|
||
o.uv = v.uv;
|
||
o.uv_lmap = v.uv_lmap;
|
||
o.ws_light_dir = calcWorldSpaceLightDir(o.ws_vertex);
|
||
|
||
#ifdef _NM_ENABLE
|
||
localNormalToWorldTangentSpace(v.normal, v.tangent, o.normal, o.tangent, o.bitangent, _NM_FlipMirror & 1, _NM_FlipMirror & 2);
|
||
#else
|
||
localNormalToWorldTangentSpace(v.normal, o.normal);
|
||
#endif
|
||
|
||
// 環境光取得
|
||
float3 ambientColor = calcAmbientColorVertex(v.uv_lmap);
|
||
// 影コントラスト
|
||
calcToonShadeContrast(o.ws_vertex, o.ws_light_dir, ambientColor, o.shadow_power);
|
||
// Anti-Glare とライト色ブレンドを同時に計算
|
||
o.light_color = calcLightColorVertex(o.ws_vertex, ambientColor);
|
||
|
||
UNITY_TRANSFER_INSTANCE_ID(v, o);
|
||
UNITY_TRANSFER_FOG(o, o.vs_vertex);
|
||
return o;
|
||
}
|
||
|
||
float4 frag(v2f i, uint facing: SV_IsFrontFace) : SV_Target {
|
||
UNITY_SETUP_INSTANCE_ID(i);
|
||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
|
||
|
||
float4 color;
|
||
float2 uv_main;
|
||
|
||
// メイン
|
||
affectBaseColor(i.uv, facing, uv_main, color);
|
||
// 頂点カラー
|
||
affectVertexColor(i.vertex_color, color);
|
||
|
||
// カラーマスク
|
||
affect3chColorMask(uv_main, color);
|
||
// アルファマスク適用
|
||
affectAlphaMask(uv_main, color);
|
||
|
||
// 色変換
|
||
affectColorChange(color);
|
||
// BumpMap
|
||
float3 ws_normal = i.normal;
|
||
float3 ws_bump_normal;
|
||
affectBumpNormal(i, uv_main, ws_bump_normal, color);
|
||
|
||
// ビューポイントへの方向
|
||
float3 ws_view_dir = worldSpaceViewPointDir(i.ws_vertex);
|
||
// カメラへの方向
|
||
float3 ws_camera_dir = worldSpaceCameraDir(i.ws_vertex);
|
||
// カメラとライトの位置関係: -1(逆光) ~ +1(順光)
|
||
float angle_light_camera = calcAngleLightCamera(i.ws_vertex, i.ws_light_dir.xyz);
|
||
|
||
// matcapベクトルの配列
|
||
float4x4 matcapVector = calcMatcapVectorArray(ws_view_dir, ws_camera_dir, ws_normal, ws_bump_normal);
|
||
|
||
// メタリック
|
||
affectMetallic(i, ws_camera_dir, uv_main, ws_normal, ws_bump_normal, color);
|
||
// Highlight
|
||
affectMatcapColor(calcMatcapVector(matcapVector, _HL_BlendNormal, _HL_Parallax).xy, uv_main, color);
|
||
// ラメ
|
||
affectLame(i, uv_main, ws_normal, color);
|
||
// 階調影
|
||
affectToonShade(i, uv_main, ws_normal, ws_bump_normal, angle_light_camera, color);
|
||
// リムライト
|
||
affectRimLight(i, uv_main, calcMatcapVector(matcapVector, _TR_BlendNormal, 0), angle_light_camera, color);
|
||
// Decal
|
||
affectOverlayTexture(i, uv_main, calcMatcapVector(matcapVector, 1, 0.5), color);
|
||
// Outline
|
||
affectOutline(uv_main, color);
|
||
|
||
// Anti-Glare とライト色ブレンドを同時に計算
|
||
color.rgb *= i.light_color;
|
||
// Ambient Occlusion
|
||
affectOcclusion(i, uv_main, color);
|
||
|
||
// EmissiveScroll
|
||
affectEmissiveScroll(i.ws_vertex, uv_main, color);
|
||
// ToonFog
|
||
affectToonFog(i, ws_view_dir, color);
|
||
|
||
// フレネル
|
||
affectFresnelAlpha(uv_main, ws_normal, ws_view_dir, color);
|
||
// Alpha は 0-1 にクランプ
|
||
color.a = saturate(color.a);
|
||
|
||
// fog
|
||
UNITY_APPLY_FOG(i.fogCoord, color);
|
||
|
||
return color;
|
||
}
|
||
|
||
////////////////////////////
|
||
// アウトライン用 vertex&fragment shader
|
||
////////////////////////////
|
||
|
||
float4 shiftOutlineVertex(inout v2f o, float width, float shift) {
|
||
return shiftOutlineVertex(o.ws_vertex, o.normal, width, shift);
|
||
}
|
||
|
||
float4 shiftOutlineVertex(inout v2f o) {
|
||
#ifdef _TL_ENABLE
|
||
return shiftOutlineVertex(o, getOutlineShiftWidth(TRANSFORM_TEX(o.uv, _MainTex)), -_TL_Z_Shift);
|
||
#else
|
||
return UnityObjectToClipPos( ZERO_VEC3 );
|
||
#endif
|
||
}
|
||
|
||
// vertex シェーダでアウトラインメッシュを張るタイプ。NORMALのみサポートする。
|
||
v2f vert_outline(appdata v) {
|
||
// 通常の vert を使う
|
||
v2f o = vert(v);
|
||
// SV_POSITION を上書き
|
||
o.vs_vertex = shiftOutlineVertex(o);
|
||
|
||
return o;
|
||
}
|
||
|
||
// geometry シェーダでアウトラインメッシュを張るタイプ。NORMALとEDGEをどちらもサポートする。
|
||
#if SHADER_TARGET >= 40
|
||
[maxvertexcount(15)]
|
||
void geom_outline(triangle v2f v[3], inout TriangleStream<v2f> triStream) {
|
||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(v[0]);
|
||
|
||
#ifdef _TL_ENABLE
|
||
#ifdef _WF_LEGACY_FEATURE_SWITCH
|
||
if (TGL_ON(_TL_Enable)) {
|
||
#endif
|
||
float width0 = getOutlineShiftWidth(TRANSFORM_TEX(v[0].uv, _MainTex));
|
||
float width1 = getOutlineShiftWidth(TRANSFORM_TEX(v[1].uv, _MainTex));
|
||
float width2 = getOutlineShiftWidth(TRANSFORM_TEX(v[2].uv, _MainTex));
|
||
float shift0 = -_TL_Z_Shift - (TGL_ON(_TL_LineType) ? width0 * 10 : 0);
|
||
float shift1 = -_TL_Z_Shift - (TGL_ON(_TL_LineType) ? width1 * 10 : 0);
|
||
float shift2 = -_TL_Z_Shift - (TGL_ON(_TL_LineType) ? width2 * 10 : 0);
|
||
|
||
// NORMAL
|
||
v2f p0 = v[0];
|
||
v2f p1 = v[1];
|
||
v2f p2 = v[2];
|
||
p0.vs_vertex = shiftOutlineVertex(p0, width0, shift0);
|
||
p1.vs_vertex = shiftOutlineVertex(p1, width1, shift1);
|
||
p2.vs_vertex = shiftOutlineVertex(p2, width2, shift2);
|
||
triStream.Append(p0);
|
||
triStream.Append(p1);
|
||
triStream.Append(p2);
|
||
|
||
// EDGE
|
||
if (TGL_ON(_TL_LineType)) {
|
||
v2f n0 = v[0];
|
||
v2f n1 = v[1];
|
||
v2f n2 = v[2];
|
||
n0.vs_vertex = shiftOutlineVertex(n0, -width0, shift0);
|
||
n1.vs_vertex = shiftOutlineVertex(n1, -width1, shift1);
|
||
n2.vs_vertex = shiftOutlineVertex(n2, -width2, shift2);
|
||
triStream.Append(n2);
|
||
triStream.Append(p0);
|
||
triStream.Append(n0);
|
||
triStream.Append(p1);
|
||
triStream.Append(n1);
|
||
triStream.Append(p2);
|
||
triStream.Append(n2);
|
||
// 折り返すことで裏面まで描画する
|
||
triStream.Append(p1);
|
||
triStream.Append(n1);
|
||
triStream.Append(p0);
|
||
triStream.Append(n0);
|
||
triStream.Append(p2);
|
||
}
|
||
|
||
triStream.RestartStrip();
|
||
#ifdef _WF_LEGACY_FEATURE_SWITCH
|
||
}
|
||
#endif
|
||
#endif
|
||
}
|
||
#endif
|
||
|
||
#endif
|