トゥーンシェーダ―作ってみる
トゥーンシェーダ―作りたい
シェーダーの色々な知見が出来たので少しずつメモ
中野シスターズ
まず 中野シスターズをダウンロードしてくる
詳細は省略するが、ダウンロードして UNITYにインポートしシーンに配置する
暗いので、今後色々と遊ぶので ポイントライトを4-5個つけてみる
調整はまたこんど
ちなみに Forwardレンダリングだと
DrawCall 74
Deferredレンダリングだと
DrawCall 41
ライトが多いと圧倒的に Deferredのメリットが出てくる
シェーダーをコピー
中野シスターズは Standardシェーダ(Unityのビルトインシェーダ)を使っている
UNITYの公式ページより ビルトインシェーダをダウンロードすれば中身を見れる
UNITYエディタで Create->Shaderで シェーダを作り、Standardをコピーしよう
シェーダー名は 今回は Yuki/Standard にした
// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt) Shader "Yuki/Standard" { Properties { _Color("Color", Color) = (1,1,1,1) _MainTex("Albedo", 2D) = "white" {} _Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5 _Glossiness("Smoothness", Range(0.0, 1.0)) = 0.5 _GlossMapScale("Smoothness Scale", Range(0.0, 1.0)) = 1.0 [Enum(Metallic Alpha,0,Albedo Alpha,1)] _SmoothnessTextureChannel("Smoothness texture channel", Float) = 0 [Gamma] _Metallic("Metallic", Range(0.0, 1.0)) = 0.0 _MetallicGlossMap("Metallic", 2D) = "white" {} [ToggleOff] _SpecularHighlights("Specular Highlights", Float) = 1.0 [ToggleOff] _GlossyReflections("Glossy Reflections", Float) = 1.0 _BumpScale("Scale", Float) = 1.0 _BumpMap("Normal Map", 2D) = "bump" {} _Parallax("Height Scale", Range(0.005, 0.08)) = 0.02 _ParallaxMap("Height Map", 2D) = "black" {} _OcclusionStrength("Strength", Range(0.0, 1.0)) = 1.0 _OcclusionMap("Occlusion", 2D) = "white" {} _EmissionColor("Color", Color) = (0,0,0) _EmissionMap("Emission", 2D) = "white" {} _DetailMask("Detail Mask", 2D) = "white" {} _DetailAlbedoMap("Detail Albedo x2", 2D) = "grey" {} _DetailNormalMapScale("Scale", Float) = 1.0 _DetailNormalMap("Normal Map", 2D) = "bump" {} [Enum(UV0,0,UV1,1)] _UVSec("UV Set for secondary textures", Float) = 0 // Blending state [HideInInspector] _Mode("__mode", Float) = 0.0 [HideInInspector] _SrcBlend("__src", Float) = 1.0 [HideInInspector] _DstBlend("__dst", Float) = 0.0 [HideInInspector] _ZWrite("__zw", Float) = 1.0 } CGINCLUDE #define UNITY_SETUP_BRDF_INPUT MetallicSetup ENDCG SubShader { Tags{ "RenderType" = "Opaque" "PerformanceChecks" = "False" } LOD 300 // ------------------------------------------------------------------ // Base forward pass (directional light, emission, lightmaps, ...) Pass { Name "FORWARD" Tags{ "LightMode" = "ForwardBase" } Blend[_SrcBlend][_DstBlend] ZWrite[_ZWrite] CGPROGRAM #pragma target 3.0 // ------------------------------------- #pragma shader_feature _NORMALMAP #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON #pragma shader_feature _EMISSION #pragma shader_feature _METALLICGLOSSMAP #pragma shader_feature ___ _DETAIL_MULX2 #pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A #pragma shader_feature _ _SPECULARHIGHLIGHTS_OFF #pragma shader_feature _ _GLOSSYREFLECTIONS_OFF #pragma shader_feature _PARALLAXMAP #pragma multi_compile_fwdbase #pragma multi_compile_fog #pragma multi_compile_instancing // Uncomment the following line to enable dithering LOD crossfade. Note: there are more in the file to uncomment for other passes. //#pragma multi_compile _ LOD_FADE_CROSSFADE #pragma vertex vertBase #pragma fragment fragBase #include "UnityStandardCoreForward.cginc" ENDCG } // ------------------------------------------------------------------ // Additive forward pass (one light per pass) Pass { Name "FORWARD_DELTA" Tags{ "LightMode" = "ForwardAdd" } Blend[_SrcBlend] One Fog{ Color(0,0,0,0) } // in additive pass fog should be black ZWrite Off ZTest LEqual CGPROGRAM #pragma target 3.0 // ------------------------------------- #pragma shader_feature _NORMALMAP #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON #pragma shader_feature _METALLICGLOSSMAP #pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A #pragma shader_feature _ _SPECULARHIGHLIGHTS_OFF #pragma shader_feature ___ _DETAIL_MULX2 #pragma shader_feature _PARALLAXMAP #pragma multi_compile_fwdadd_fullshadows #pragma multi_compile_fog // Uncomment the following line to enable dithering LOD crossfade. Note: there are more in the file to uncomment for other passes. //#pragma multi_compile _ LOD_FADE_CROSSFADE #pragma vertex vertAdd #pragma fragment fragAdd #include "UnityStandardCoreForward.cginc" ENDCG } // ------------------------------------------------------------------ // Shadow rendering pass Pass{ Name "ShadowCaster" Tags{ "LightMode" = "ShadowCaster" } ZWrite On ZTest LEqual CGPROGRAM #pragma target 3.0 // ------------------------------------- #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON #pragma shader_feature _METALLICGLOSSMAP #pragma shader_feature _PARALLAXMAP #pragma multi_compile_shadowcaster #pragma multi_compile_instancing // Uncomment the following line to enable dithering LOD crossfade. Note: there are more in the file to uncomment for other passes. //#pragma multi_compile _ LOD_FADE_CROSSFADE #pragma vertex vertShadowCaster #pragma fragment fragShadowCaster #include "UnityStandardShadow.cginc" ENDCG } // ------------------------------------------------------------------ // Deferred pass Pass { Name "DEFERRED" Tags{ "LightMode" = "Deferred" } CGPROGRAM #pragma target 3.0 #pragma exclude_renderers nomrt // ------------------------------------- #pragma shader_feature _NORMALMAP #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON #pragma shader_feature _EMISSION #pragma shader_feature _METALLICGLOSSMAP #pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A #pragma shader_feature _ _SPECULARHIGHLIGHTS_OFF #pragma shader_feature ___ _DETAIL_MULX2 #pragma shader_feature _PARALLAXMAP #pragma multi_compile_prepassfinal #pragma multi_compile_instancing // Uncomment the following line to enable dithering LOD crossfade. Note: there are more in the file to uncomment for other passes. //#pragma multi_compile _ LOD_FADE_CROSSFADE #pragma vertex vertDeferred #pragma fragment fragDeferred #include "UnityStandardCore.cginc" ENDCG } // ------------------------------------------------------------------ // Extracts information for lightmapping, GI (emission, albedo, ...) // This pass it not used during regular rendering. Pass { Name "META" Tags{ "LightMode" = "Meta" } Cull Off CGPROGRAM #pragma vertex vert_meta #pragma fragment frag_meta #pragma shader_feature _EMISSION #pragma shader_feature _METALLICGLOSSMAP #pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A #pragma shader_feature ___ _DETAIL_MULX2 #pragma shader_feature EDITOR_VISUALIZATION #include "UnityStandardMeta.cginc" ENDCG } } SubShader { Tags{ "RenderType" = "Opaque" "PerformanceChecks" = "False" } LOD 150 // ------------------------------------------------------------------ // Base forward pass (directional light, emission, lightmaps, ...) Pass { Name "FORWARD" Tags{ "LightMode" = "ForwardBase" } Blend[_SrcBlend][_DstBlend] ZWrite[_ZWrite] CGPROGRAM #pragma target 2.0 #pragma shader_feature _NORMALMAP #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON #pragma shader_feature _EMISSION #pragma shader_feature _METALLICGLOSSMAP #pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A #pragma shader_feature _ _SPECULARHIGHLIGHTS_OFF #pragma shader_feature _ _GLOSSYREFLECTIONS_OFF // SM2.0: NOT SUPPORTED shader_feature ___ _DETAIL_MULX2 // SM2.0: NOT SUPPORTED shader_feature _PARALLAXMAP #pragma skip_variants SHADOWS_SOFT DIRLIGHTMAP_COMBINED #pragma multi_compile_fwdbase #pragma multi_compile_fog #pragma vertex vertBase #pragma fragment fragBase #include "UnityStandardCoreForward.cginc" ENDCG } // ------------------------------------------------------------------ // Additive forward pass (one light per pass) Pass { Name "FORWARD_DELTA" Tags{ "LightMode" = "ForwardAdd" } Blend[_SrcBlend] One Fog{ Color(0,0,0,0) } // in additive pass fog should be black ZWrite Off ZTest LEqual CGPROGRAM #pragma target 2.0 #pragma shader_feature _NORMALMAP #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON #pragma shader_feature _METALLICGLOSSMAP #pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A #pragma shader_feature _ _SPECULARHIGHLIGHTS_OFF #pragma shader_feature ___ _DETAIL_MULX2 // SM2.0: NOT SUPPORTED shader_feature _PARALLAXMAP #pragma skip_variants SHADOWS_SOFT #pragma multi_compile_fwdadd_fullshadows #pragma multi_compile_fog #pragma vertex vertAdd #pragma fragment fragAdd #include "UnityStandardCoreForward.cginc" ENDCG } // ------------------------------------------------------------------ // Shadow rendering pass Pass{ Name "ShadowCaster" Tags{ "LightMode" = "ShadowCaster" } ZWrite On ZTest LEqual CGPROGRAM #pragma target 2.0 #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON #pragma shader_feature _METALLICGLOSSMAP #pragma skip_variants SHADOWS_SOFT #pragma multi_compile_shadowcaster #pragma vertex vertShadowCaster #pragma fragment fragShadowCaster #include "UnityStandardShadow.cginc" ENDCG } // ------------------------------------------------------------------ // Extracts information for lightmapping, GI (emission, albedo, ...) // This pass it not used during regular rendering. Pass { Name "META" Tags{ "LightMode" = "Meta" } Cull Off CGPROGRAM #pragma vertex vert_meta #pragma fragment frag_meta #pragma shader_feature _EMISSION #pragma shader_feature _METALLICGLOSSMAP #pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A #pragma shader_feature ___ _DETAIL_MULX2 #pragma shader_feature EDITOR_VISUALIZATION #include "UnityStandardMeta.cginc" ENDCG } } FallBack "VertexLit" CustomEditor "StandardShaderGUI" }
各メッシュのシェーダを Standardから Yuki/Standardに変更
Passというのが シェーダのパスで
Tags{ “LightMode” = “ForwardBase” }
となっている部分が、レンダリングモード
Forwardレンダリング時は
メインライトのパスが ForwardBase
その他のライトがライト毎に ForwardAdd
Deferredレンダリング時は
Deferredパスが呼ばれる
また影の計算時に
ShadowCasterパスが呼ばれる
輪郭線を付ける
今回は単純な オブジェクトの裏側を法線方向に拡大して表示する
アウトラインのパスを作る
先ほどのシェーダーに輪郭線パスを増やす
StandardはLODにより2個あるので 出来れば2つのSubshaderに書くほうが良い
Pass{ Name "Outline" Tags{ "LightMode" = "ForwardBase" } Cull Front CGPROGRAM #pragma vertex vert #pragma fragment frag #define _GLOSSYENV 1 #include "UnityCG.cginc" #pragma fragmentoption ARB_precision_hint_fastest #pragma multi_compile_shadowcaster #pragma multi_compile_fog #pragma only_renderers d3d9 d3d11 glcore gles #pragma target 5.0 struct VertexInput { float4 vertex : POSITION; float3 normal : NORMAL; }; struct VertexOutput { float4 pos : SV_POSITION; UNITY_FOG_COORDS(1) }; VertexOutput vert(VertexInput v) { VertexOutput o = (VertexOutput)0; float width = 1; o.pos = UnityObjectToClipPos(float4(v.vertex.xyz + v.normal*(width*0.01),1)); UNITY_TRANSFER_FOG(o,o.pos); return o; } float4 frag(VertexOutput i, float facing : VFACE) : COLOR{ float isFrontFace = (facing >= 0 ? 1 : 0); float faceSign = (facing >= 0 ? 1 : -1); float4 outlineColor = float4(0,0,0,1); return fixed4(outlineColor); } ENDCG }
上記はForwardパスなので Deferredパスにも同じものを追加すると Deferredでも輪郭線がつく
具体的には上記の
Tags{ “LightMode” = “ForwardBase” }
を
Tags{ “LightMode” = “Deferred” }
にしたものを書けばいい
Forward
Deferred
DeferredではMSAAが使えないため、画質が悪い。
Deferredでは他の方法で アンチエイリアスを考える必要がある