以下の内容はhttps://redhologerbera.hatenablog.com/entry/2025/01/09/201938より取得しました。


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

本日はShader枠です。

今回はShaderの

〇環境

・Unity6000.0.2f1

・Windows11PC

〇セルルックなライティング

Unityのシェーダーの場合ライティングによる影の計算はNdotLが基本的な考え方です。

NdotLとはメッシュの法線=Normal、とライト=Lightのドット積によってライトが当たる面を計算するという意味です。

 ライトのベクトルと比較してメッシュの向きが一致する場合は影、逆に逆行している場合はライトが当たる部分というようになります。

https://redhologerbera.hatenablog.com/entry/2022/11/11/231804

今回は、基本形のライティングシェーダーから流用してセルルックなライティングを行います。  

Shader "Unlit/TutorialShader"
{
    Properties
    {
     //   _MainTex ("Texture", 2D) = "white" {}
        _MainColor("Color" ,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;
            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);
                float4 lightColor = float4(lt.color, 1);
                return col* lightColor*strength;
            }
            ENDHLSL
        }
    }
}

このままでは以下のように写実的にグラデーションとして影が付きます。

セルルックな見た目にするためには影の付き方をグラデーションではなくメリハリがあるつけ方をする必要があります。

そこでNdotLの計算結果をStep関数を用いて0,1に分割することでこれが可能です。

                //ライトの向きを計算
                float strength = dot(lt.direction, i.normalWS);
                float4 lightColor = float4(lt.color, 1);
                return col* lightColor* step(0.3,strength);

Step関数は引数との差をもとに0,1で値を分けてくれます。

これによってセルルックなライティングの基本形が完成しました。

本日は以上です。




以上の内容はhttps://redhologerbera.hatenablog.com/entry/2025/01/09/201938より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14