夜風のMixedReality

xRと出会って変わった人生と出会った技術を書き残すためのGeekなHoloRangerの居場所

ゼロから始めるUnityShader開発 第六章 セルルックなライティングを行う その③ハイライトの実装

本日はShader枠です。

現在はライティングについてのシェーダー構築をステップアップで見ています。

前回はShadowColorを追加して影の色を任意に変更できるようにしました。

redhologerbera.hatenablog.com

redhologerbera.hatenablog.com

今回はハイライトを実装します。

〇ハイライトの実装

ハイライトとは光が物体にあたるときにできる明るい部分を指します。

これは光源からの光が直接物体に反射して強調される光を指します。

毎度ですが、Shaderで光の当たり方の計算はNdotLです。

 float strength = dot(lt.direction, i.normalWS);

これは通常であれば1~0のグラデーションとして返されます。

ここでstep関数を使用して閾値をもとに0,1で振り分けたものがセルルックなシェーディングの影です。

                float shadow =step(0.3,strength);

この閾値を上げることで光が当たっているエリアを絞ることができます。

ここでは新たなパラメータhighlightとhightkightColorを定義し以下のように実装しました。

            float4 frag (v2f i) : SV_Target
            {
                float4 col = _MainColor;
                //Light.hlslで提供されるUnityのライトを取得する関数
                Light lt = GetMainLight();

                //ライトの向きを計算
                float strength = dot(lt.direction, i.normalWS);
                float shadow =step(0.3,strength);
                float highlight = step(0.95,strength);
                float4 lightColor = float4(lt.color, 1)*shadow;
                float4 shadowColor = _ShadowColor * (1-shadow);
                float4 hightlightColor = _HightlightColor * highlight;
                return col* (shadowColor + lightColor)+hightlightColor;
            }

 ここでhightlightColorは最終的に加算処理をしています。

この理由として加算を行うことで発光の効果が期待できるためです。 

https://redhologerbera.hatenablog.com/entry/2022/11/16/220437

今回はハイライトの閾値を0.95にしていますが、もっと上げることもできます。

最終的に以下のようにハイライトが付くようになります。

〇コード全文

Shader "Unlit/TutorialShader"
{
    Properties
    {
     //   _MainTex ("Texture", 2D) = "white" {}
        _MainColor("Color" ,color) = (1,1,1,1)
        _ShadowColor("ShadowColor",color) = (0,0,0,1)
        _HightlightColor("HightlightColor",color) = (1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
            #include  "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
            
            struct appdata
            {
                float4 vertex : POSITION;
                half3 normal: NORMAL;
            };

            struct v2f
            {
            float4 vertex : SV_POSITION;
            float3 normalWS : TEXCOORD1;
            };


            float4 _MainColor;
            float4 _ShadowColor;
            float4 _HightlightColor;
            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = TransformObjectToHClip(v.vertex);
                //面の法線を取得、ライトの当たる向きを計算
                VertexNormalInputs normal = GetVertexNormalInputs(v.normal);
                o.normalWS = normal.normalWS;
                return o;
            }

            float4 frag (v2f i) : SV_Target
            {
                float4 col = _MainColor;
                //Light.hlslで提供されるUnityのライトを取得する関数
                Light lt = GetMainLight();

                //ライトの向きを計算
                float strength = dot(lt.direction, i.normalWS);
                float shadow =step(0.3,strength);
                float highlight = step(0.95,strength);
                float4 lightColor = float4(lt.color, 1)*shadow;
                float4 shadowColor = _ShadowColor * (1-shadow);
                float4 hightlightColor = _HightlightColor * highlight;
                return col* (shadowColor + lightColor)+hightlightColor;
            }
            ENDHLSL
        }
    }
}