今日まなび009:MaterialPropertyBlockを使っていて出てきた疑問とかまとめ

  • 今日の学び
    • 元のMaterialに設定した値は継承されない。型のデフォ値?になるっぽい
    • 別のMaterialPropertyBlockのインスタンス作ってからGetした場合でも設定した値はとれる
    • インスペクタの挙動:MaterialPropertyBlockで設定した値は実行時に変えられなくなる
    • 複数のMaterialPropertyBlockのインスタンスが同じプロパティを更新した場合は後勝ちになる
続きを読む

今日まなび(20240829):深度バッファを表示してみる

「今日まなび」は最低1日1h、ゲーム作るために学びたいことなんでもいいから学んでいくコーナー。
完全自分用でまとめることは考えなくてOK.1記事1h。(1hでどんだけ学べるかのスピード感もみていきたいので)
1hのうちに次回学ぶことも決定しておくこと

環境:unity2021.3.40f


今日の学び

深度バッファはカメラからの距離を0~1の範囲で表した値をピクセル単位に定義されている領域というか情報群。
これがあることによってピクセル単位に手前のオブジェクトを判断して手前にあれば描画する、奥なら描画しない(Zテスト)。
といった制御ができるやつだ。

今回はこの深度バッファの値を実際に画面に表示してみる。
深度値を使ってできる表現を学んでいきたいのでその予備ちしき。

light11.hatenadiary.com

  • cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test20240829 : MonoBehaviour
{
    public Material mat;
    void Start()
    {
        GetComponent<Camera>().depthTextureMode |= DepthTextureMode.Depth;

    }

    public void OnRenderImage(RenderTexture source, RenderTexture dest)
    {
        Graphics.Blit(source, dest, mat);
    }
}
  • shader
Shader "Test/20240829"
{
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            sampler2D _CameraDepthTexture;

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float2 uv : TEXCOORD0;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                return o;
            }
            
            fixed4 frag (v2f i) : SV_Target
            {
                fixed depth = UNITY_SAMPLE_DEPTH(tex2D(_CameraDepthTexture,i.uv));
                depth = Linear01Depth(depth);  //←これいれないとうまく表示できなかった
                return fixed4(depth,depth,depth,1);
            }
            ENDCG
        }
    }
}

なんかかっこいいのができた

今日は時間がもうないので明日深くこのコードを見ていく!

TODO (調べたいこと、やりたいこととか疑問)

・ポストプロセスで例えばモノクロを適応したときに、一部分(例えば特定のキャラの描画だけとか)には適応したくない場合がある。
これまでカメラをわけて対応してきたが1つのカメラでもそういった制御ができる方法はないか
・Unityで深度バッファの値をどうやって取得できる?


・法線マップを扱う
・Unityのシャドウマップってなんだろう
・影を制御したい、動かしたり形を変えたり、色をかえたり


・StandardShaderでできることを把握しておきたい
・名前わすれたけど、プロファイラーのPassごとの描画を調査できるやつの使い方まなびたい
・shaderで図形描いたりするのによく使う関数と使い方まとめ

終わったやつ

・自作shaderを適応したQuadでも影を落としたい

今日まなび(20240828):Quadに張った透過テクスチャの形にあわせて影を落とす②(達成!)

「今日まなび」は最低1日1h、ゲーム作るために学びたいことなんでもいいから学んでいくコーナー。
完全自分用でまとめることは考えなくてOK.1記事1h。(1hでどんだけ学べるかのスピード感もみていきたいので)
1hのうちに次回学ぶことも決定しておくこと

環境:unity2021.3.40f


直近の目標まとめ。 →透過テクスチャを張ったQuadにカスタムShaderを適応したら影がでなくなってしまったので影をつけたい

今日の学び

前回調べた影を落とすコードを自作Shaderに適応してみる。…できた!!
右がStandardShader、左が自作Shaderである。
(赤いのは環境光を赤くしてるからで、自作Shader側は環境光の影響をまだうけていない、けど落ち影はでてるとわかる図)

Shader "20240828_custom" {
    Properties{
        _MainTex("Albedo", 2D) = "white" {}

        //落ちる影の描画この2行↓も必要だった!!!!
        _Color("Color", Color) = (1,1,1,1)
                _Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5
    }

    SubShader {
        Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
        LOD 100

        //1パス目はカスタムしたいことを書く。
        Pass {
            Tags { "LightMode" = "ForwardBase" }
            Blend SrcAlpha OneMinusSrcAlpha

            CGPROGRAM
           #pragma vertex vert
           #pragma fragment frag
           #pragma target 2.0

            #include "UnityCG.cginc"

            struct appdata_t {
                float4 vertex : POSITION;
                float2 texcoord : TEXCOORD0;
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            struct v2f {
                float4 vertex : SV_POSITION;
                float2 texcoord : TEXCOORD0;
                float4 pos : TEXCOORD1;

                UNITY_FOG_COORDS(1)
                UNITY_VERTEX_OUTPUT_STEREO
            };

            v2f vert (appdata_t v)
            {
                v2f o;
                UNITY_SETUP_INSTANCE_ID(v);
                UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
                return o;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                return tex2D(_MainTex, i.texcoord);
            }
            ENDCG
        }


        //2パス目で、落ちる影の描画
        Pass {
            Name "ShadowCaster"
            Tags { "LightMode" = "ShadowCaster" }

            ZWrite On ZTest LEqual

            CGPROGRAM
            #pragma target 3.0

            // -------------------------------------


            #pragma shader_feature_local _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
            #pragma shader_feature_local _METALLICGLOSSMAP
            #pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
            #pragma shader_feature_local _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
        }
    }
}

まとめ

というわけで、透過テクスチャにあわせて影を落とすのに必要な作業は2つだった。

・実体の描画用のPassのあとに影を落とす用のPassを追加する

   SubShader {
        Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
        LOD 100

        //1パス目はカスタムしたいことを書く。
        Pass {
            Tags { "LightMode" = "ForwardBase" }
            Blend SrcAlpha OneMinusSrcAlpha

            CGPROGRAM
           #pragma vertex vert
           #pragma fragment frag
           #pragma target 2.0

            #include "UnityCG.cginc"

            struct appdata_t {
                float4 vertex : POSITION;
                float2 texcoord : TEXCOORD0;
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            struct v2f {
                float4 vertex : SV_POSITION;
                float2 texcoord : TEXCOORD0;
                float4 pos : TEXCOORD1;

                UNITY_FOG_COORDS(1)
                UNITY_VERTEX_OUTPUT_STEREO
            };

            v2f vert (appdata_t v)
            {
                v2f o;
                UNITY_SETUP_INSTANCE_ID(v);
                UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
                return o;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                return tex2D(_MainTex, i.texcoord);
            }
            ENDCG
        }


        //2パス目で、落ちる影の描画
        Pass {
            Name "ShadowCaster"
            Tags { "LightMode" = "ShadowCaster" }

            ZWrite On ZTest LEqual

            CGPROGRAM
            #pragma target 3.0

            // -------------------------------------


            #pragma shader_feature_local _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
            #pragma shader_feature_local _METALLICGLOSSMAP
            #pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
            #pragma shader_feature_local _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
        }

・上記だけだと不十分でPropertyで以下の定義を追加して指定できるようにすることも必要。

Properties{
        _MainTex("Albedo", 2D) = "white" {}

    //落ちる影の描画この2行↓も必要だった!!!!
    _Color("Color", Color) = (1,1,1,1)
        _Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5
}

TODO (調べたいこと、やりたいこととか疑問)

・名前わすれたけど、プロファイラーのPassごとの描画を調査できるやつの使い方まなびたい ←次回
・ことなるポストプロセスを適応したい場合にカメラを分けなくてもいい方法あるんじゃないか
・Unityで深度バッファの値をどうやって取得できる?
・法線マップを扱う
・shaderで図形描いたりするのによく使う関数と使い方まとめ

終わったやつ

・自作shaderを適応したQuadでも影を落としたい

今日まなび(20240827):Quadに張った透過テクスチャの形にあわせて影を落とす①

「今日まなび」は最低1日1h、ゲーム作るために学びたいことなんでもいいから学んでいくコーナー。
完全自分用でまとめることは考えなくてOK.1記事1h。(1hでどんだけ学べるかのスピード感もみていきたいので)
1hのうちに次回学ぶことも決定しておくこと

環境:unity2021.3.40f


直近の目標まとめ。 →透過テクスチャを張ったQuadにカスタムShaderを適応したら影がでなくなってしまったので影をつけたい

今日の学び:

前回調べたとりあえず影を落とす処理をQuadに反映してみたらこのようになった。 右はStandardシェーダーで、左がカスタムShaderである。

たしかに影は落ちたが、透過部分が反映されておらずメッシュの形(今回はQuadを使っているので4角形)で影が落ちてしまった。


というわけでStandardシェーダーの中身をみて、透過部分を考慮して影を落としている部分を調査したら以下の部分のようだった。

 //  Shadow rendering pass
 Pass {
     Name "ShadowCaster"
     Tags { "LightMode" = "ShadowCaster" }

     ZWrite On ZTest LEqual

     CGPROGRAM
     #pragma target 3.0

     // -------------------------------------


     #pragma shader_feature_local _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
     #pragma shader_feature_local _METALLICGLOSSMAP
     #pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
     #pragma shader_feature_local _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
 }

次回、これを自作Shaderに適応できるか試す

TODO (調べたいこと、やりたいこととか疑問)

・自作shaderを適応したQuadでも影を落としたい ←今進行中
・ことなるポストプロセスを適応したい場合にカメラを分けなくてもいい方法あるんじゃないか
・Unityで深度バッファの値をどうやって取得できる?
・法線マップを扱う
・shaderで図形描いたりするのによく使う関数と使い方まとめ