コンテンツにスキップ

HCSLの基本構造

HCSLの座標系・ベクトル・行列はすべて「右手系・列優先(column-major)」で設計されています。 HCSLは以下のような構造をしており、hcsl・pass・renderparam・attribute・input・output・uniform・shaderの8種類のブロックから構成されます。

versionは基本的に1で構いませんが、互換性が切れるようなことがあった時に更新されます。 passブロックはhcslブロックの中に複数個書くことが可能で、重ね塗りのようなことができます。

各ブロックの詳細は後ろの項目で説明します。

#version 1
hcsl "シェーダー名"
{
    pass 描画パス名
    {
        renderparam
        {
            // 描画パラメーター
        }

        variant
        {
            // シェーダーバリアント
        }

        attribute
        {
            // 頂点アトリビュート
        }

        output vertex
        {
            // 頂点シェーダーアウトプット
        }

        uniform vertex
        {
            // 頂点シェーダー Uniform Value
        }

        shader vertex
        {
            // 頂点シェーダー
        }

        input fragment
        {
            // フラグメントシェーダーインプット
        }

        output fragment
        {
            // フラグメントシェーダーアウトプット
        }

        uniform fragment
        {
            // フラグメントシェーダーUniformValue
        }

        shader fragment
        {
            // フラグメントシェーダー
        }
    }

    pass 描画パス名
    {
        // 描画パスは複数個書いて重ね塗りを行うこともできる
    }
}

実装例

#version 1

hcsl "WavePlane"
{
    pass Geometry_Opaque
    {
      renderparam
      {
        bool hel_z_write = true;
        int  hel_cull_mode = HEL_CULL_NONE;
      }

      // 頂点アトリビュート
      attribute
      {
        vec3 _Position : VS_POSITION;
        vec3 _Normal : VS_NORMAL;
        vec2 _TexCoord0 : VS_UV;
      }

      // 頂点シェーダーアウトプット
      output vertex
      {
        vec4 outPos : VS_OUT_POSITION;
        vec3 WorldNormal;
        vec3 WorldPos;
        vec2 uv;
      }

      // 頂点シェーダーUniformValue
      uniform vertex
      {
        float _Seed = 1.0;
        float _Size = 0.1;
      }

      // 頂点シェーダー
      shader vertex
      {
        float g_Offset;

        float wave(vec2 st)
        {
            return sin(st.x * 50.0 + HEL_TIME) * 1.5;
        }

        void main()
        {
          g_Offset = 10.0;

          vec4 pos = vec4(_Position, 1.0);
          pos.y += wave(_TexCoord0 * _Size + vec2(_Seed + g_Offset));

          outPos = HEL_MATRIX_P * HEL_MATRIX_V * HEL_MATRIX_W * pos;
          WorldNormal = (HEL_MATRIX_W * vec4(_Normal, 0.0)).xyz;
          uv = _TexCoord0;
        }
      }

      // フラグメントシェーダーインプット
      input fragment
      {
        vec3 WorldNormal;
        vec2 uv;
      }

      // フラグメントシェーダーアウトプット
      output fragment
      {
        vec4 outColor : FS_COLOR;
      }

      // フラグメントシェーダーUniformValue
      uniform fragment
      {
        vec4 _MainColor = vec4(1.0);
        sampler2D _MainTex;
        vec4 _MainTex_ST;
      }

      // フラグメントシェーダー
      shader fragment
      {
        vec3 hsv2rgb( vec3 c )
        {
          vec3 rgb = clamp( abs(mod(c.x*6.0+vec3(0.0,4.0,2.0),6.0)-3.0)-1.0, 0.0, 1.0 );
          return c.z * mix( vec3(1.0), rgb, c.y);
        }

        void main()
        {
          vec4 col = vec4(1.0);

          vec2 st = uv;
          st *= _MainTex_ST.xy;
          st += _MainTex_ST.zw;

          col.rgb *= helTexture(_MainTex, st).rgb;
          col.rgb *= _MainColor.rgb;
          col.rgb *= hsv2rgb(vec3(mod(HEL_TIME, 1.0), 1.0, 1.0));

          outColor = col;
        }
      }
    }

    pass Geometry_AlphaBlending
    {
      renderparam
      {
        bool hel_z_write = true;
        int  hel_cull_mode = HEL_CULL_NONE;
      }

      // 頂点アトリビュート
      attribute
      {
        vec3 _Position : VS_POSITION;
        vec3 _Normal : VS_NORMAL;
        vec2 _TexCoord0 : VS_UV;
      }

      // 頂点シェーダーアウトプット
      output vertex
      {
        vec4 outPos : VS_OUT_POSITION;
        vec3 WorldNormal;
        vec3 WorldPos;
        vec2 uv;
      }

      // 頂点シェーダーUniformValue
      uniform vertex
      {
        float _Seed = 1.0;
      }

      // 頂点シェーダー
      shader vertex
      {
        float g_Offset;

        float wave(vec2 st)
        {
            return cos(st.x * 50.0 + HEL_TIME) * 1.5;
        }

        void main()
        {
          g_Offset = 10.0;

          vec4 pos = vec4(_Position, 1.0);
          pos.y += wave(_TexCoord0 + vec2(_Seed + g_Offset));

          outPos = HEL_MATRIX_P * HEL_MATRIX_V * HEL_MATRIX_W * pos;
          WorldNormal = (HEL_MATRIX_W * vec4(_Normal, 0.0)).xyz;
          uv = _TexCoord0;
        }
      }

      // フラグメントシェーダーインプット
      input fragment
      {
        vec3 WorldNormal;
        vec2 uv;
      }

      // フラグメントシェーダーアウトプット
      output fragment
      {
        vec4 outColor : FS_COLOR;
      }

      // フラグメントシェーダーUniformValue
      uniform fragment
      {
        vec4 _OutlineColor = vec4(1.0);
      }

      // フラグメントシェーダー
      shader fragment
      {
        void main()
        {
          vec4 col = _OutlineColor;

          outColor = col;
        }
      }
    }
}

Feedback