MRが楽しい

MRやVRについて学習したことを書き残す

公式チュートリアル「HOLOGRAMS 230 2章」を試してみる

本日はチュートリアルお試し枠です。
いつも通り、以下ブログの記事を参考に実施します。
azure-recipe.kc-cloud.jp


今回はUnity上で様々なシェーダの動作を確認するプロジェクトです。
一つ目「BlueLinesOnWalls」LineScale:0.1 LinesPerMeter:4
f:id:bluebirdofoz:20170712000804j:plain

二つ目「BlueLinesOnWalls」LineScale:0.5 LinesPerMeter:4
f:id:bluebirdofoz:20170712000812j:plain

三つ目「BlueLinesOnWalls」LineScale:0.5 LinesPerMeter:1
f:id:bluebirdofoz:20170712000820j:plain

シェーダのコードを確認してみます。
因みにシェーダの書き方については以前に記事を書いています。合わせて確認します。
bluebirdofoz.hatenablog.com


・BlueLinesOnWalls.shader

Shader "Custom/BlueLinesOnWalls"
{
  Properties
  {
    _LineScale("LineScale", Float) = 0.1
    _LinesPerMeter("LinesPerMeter", Float) = 4
  }

  SubShader
  {
    Tags{ "RenderType" = "Opaque"}

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

      // These values map from the properties block at the beginning of the shader file.
      // They can be set at run time using renderer.material.SetFloat()
      // これらの値は、シェーダファイルの先頭にあるプロパティブロックからマップされます。
      // これらの値は、renderer.material.SetFloat()を使用して実行時に設定できます。
      float _LineScale;
      float _LinesPerMeter;
      
      // This is the data structure that the vertex program provides to the fragment program.
      // 頂点シェーダがフラグメントシェーダに提供するデータ構造
      struct VertToFrag
      {
        float4 viewPos : SV_POSITION;
        float3 normal : NORMAL;
        float4 worldPos: TEXCOORD0;
      };


      // This is the vertex program.
      // 頂点シェーダ
      VertToFrag vert (appdata_base v)
      {
        VertToFrag o;

        // Calculate where the vertex is in view space.
        // 頂点がビュー空間内のどこにあるかを計算します。
        o.viewPos = UnityObjectToClipPos(v.vertex);

        // Calculate the normal in WorldSpace.
        // WorldSpaceの法線を計算します。
        o.normal = UnityObjectToWorldNormal(v.normal);

        // Calculate where the object is in world space.
        // オブジェクトがワールド空間内のどこにあるかを計算します。
        o.worldPos = mul(unity_ObjectToWorld, v.vertex);

        return o;
      }

      // フラグメントシェーダ
      fixed4 frag (VertToFrag input) : SV_Target
      {
        // Check where this pixel is in world space.
        // wpmod is documented on the internet, it's basically a 
        // floating point mod function.
        // このピクセルがワールド空間内のどこにあるかを調べます。
        float4 wpmodip;
        float4 wpmod = modf(input.worldPos * _LinesPerMeter, wpmodip);

        // Initialize to draw black with full alpha. This way we will occlude holograms even when
        // we are drawing black.
        // 完全透過の黒を描画するために初期化します
        fixed4 ret = float4(0,0,0,1);

        // Normals need to be renormalized in the fragment shader to overcome 
        // interpolation.
        // 補間を克服するには、法線をフラグメントシェーダで再正規化する必要があります。
        float3 normal = normalize(input.normal);

        // If the normal isn't pointing very much up or down and the position in world space
        // is within where a line should be drawn, draw the line.
        // Since we are checking wpmod.y, we will be making horizontal blue lines.
        // If wpmod.y was replaced with wpmod.x or wpmod.z, we would be making vertical lines.
        // 法線が極端に上または下を指していない場合、かつ、
        // ワールド空間内の位置が線を描画する範囲内にある場合は、線を描画します。
        // wpmod.yをチェックして、水平の青い線を描きます。
        // wpmod.yをwpmod.xまたはwpmod.zに置き換えた場合、垂直の線を作成することになります。
        if (abs(normal.y) < 0.2f && abs(wpmod.y) < _LineScale* _LinesPerMeter)
        {
          ret.b = 1 - (abs(wpmod.y) / (_LineScale* _LinesPerMeter));
          ret.r = 0;
          ret.g = 0;
        }

        return ret;
      }
      ENDCG
    }
  }
}