﻿//https://zenn.dev/dimebag29/articles/1aa7189dd8d954
Shader "Test/DebugShader"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _IntergerCount ("IntergerCount", Range(1, 6)) = 6
        _DecimalCount ("DecimalCount", Range(0, 6)) = 6
    }
    SubShader
    {
        Tags { "Queue" = "Transparent" }
        Cull Off
        ZWrite Off
        Blend SrcAlpha OneMinusSrcAlpha

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            struct appdata
            {
                fixed2 uv : TEXCOORD0;
                fixed4 vertex : POSITION;
                fixed4 color : COLOR;
            };

            struct v2f
            {
                fixed2 uv : TEXCOORD0;
                fixed4 vertex : POSITION;
                fixed4 color : COLOR;
            };

            sampler2D _MainTex;
            int _IntergerCount;
            int _DecimalCount;

            //アタッチした画像の数字記号の桁数、0123456789+-.で全部で13桁
            static fixed textureDigit = 13;
            //スクリーン上に表示されるImageのwidthを、数字一桁分のwidthに圧縮するために使う
            static fixed toSoloWidth = 12;

            //スクリーン上に表示する数字と記号の桁数。符号、整数、小数点記号、小数点数に分かれる
            fixed viewDigitCount()
            {
                return 1 + _IntergerCount + step(1, _DecimalCount) + _DecimalCount;
            }
   
            v2f vert (appdata v)
            {
                v2f o;
                
                //画像の横幅を数字一桁まで圧縮した上で、必要な数字の桁分まで広げる
                fixed soloWidth = v.vertex.x / toSoloWidth;
                v.vertex.x = soloWidth * viewDigitCount();
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                o.color = v.color;
                return o;
            }

            //num = Textrue上の表示したい数字もしくは記号の座標、0~12までの可能性がある
            //placeIdx = 表示したいスクリーン上の座標のidx, 一番左が0
            fixed4 getNumber(v2f i, int num, int placeIdx)
            {
                fixed oneCellWidth = 1 / textureDigit * toSoloWidth / viewDigitCount();

                //表示したい数字の座標にuvを修正
                fixed2 fixUv;
                fixUv.x = i.uv.x + num * oneCellWidth - placeIdx * oneCellWidth;
                fixUv.x = fixUv.x / toSoloWidth * viewDigitCount();
                fixUv.y = i.uv.y;

                //対象の桁と関係ない部分は切り捨てて画像を返す
                fixed cutRight = step(i.uv.x, oneCellWidth + placeIdx * oneCellWidth);
                fixed cutLeft = 1 - step(i.uv.x, placeIdx * oneCellWidth);
                fixed4 col = tex2D(_MainTex, fixUv) * cutRight * cutLeft;
                return col;
            }

            //渡された数値の指定の桁の値を取得
            int getDigit(float num, float digit)
            {
                return (int)(abs(num) * digit) % 10;
            }

            //指定の桁の整数の画像を取得
            //addIdx = 大きいほど整数の桁が小さくなる
            fixed4 getIntegerTextureNumber(v2f i, float num, int baseIdx, int addIdx)
            {
                float digit = pow(10, -1 * (_IntergerCount - addIdx - 1));
                int digitNum = getDigit(num, digit);
                return step(addIdx, _IntergerCount - 1) * getNumber(i, digitNum, baseIdx + addIdx);
            }

            //指定の桁の小数点数の画像を取得
            //addIdx = 大きいほど小数点数の桁が小さくなる
            fixed4 getDecimalTextureNumber(v2f i, float num, int baseIdx, int addIdx)
            {
                float digit = pow(10, addIdx + 1);
                int digitNum = getDigit(num, digit);
                return step(addIdx, _DecimalCount - 1) * getNumber(i, digitNum, baseIdx + addIdx);
            }

            //渡した数字を画像に変換
            fixed4 convertNumver(v2f i, float num)
            {
                fixed4 col = 0.0;

                //最初に+か-の符号を描画
                int placeIdx = 0;
                fixed isSignMinus = 1 - step(0, num);
                col += getNumber(i, 10 + isSignMinus, placeIdx);

                //整数部分を表示
                placeIdx += 1;
                for(int cnt = 0; cnt < _IntergerCount; cnt++)
                {
                    col += getIntegerTextureNumber(i, num, placeIdx, cnt);
                }

                //小数点記号を表示
                placeIdx += _IntergerCount;
                col += step(1, _DecimalCount) * getNumber(i, 12, placeIdx);

                //小数点数表示
                placeIdx += 1;
                //何故か小数点以下でfor文を使った計算を行うと大きく値がずれるので１つずつ実行
                col += getDecimalTextureNumber(i, num, placeIdx, 0);
                col += getDecimalTextureNumber(i, num, placeIdx, 1);
                col += getDecimalTextureNumber(i, num, placeIdx, 2);
                col += getDecimalTextureNumber(i, num, placeIdx, 3);
                col += getDecimalTextureNumber(i, num, placeIdx, 4);
                col += getDecimalTextureNumber(i, num, placeIdx, 5);
                /*
                for(int cnt = 0; cnt < _DecimalCount; cnt++)
                {
                    col += getDecimalTextureNumber(i, num, placeIdx, cnt);
                }     
                */
                
                return col;
            }
            
            fixed4 frag (v2f i) : SV_Target
            {
                //整数値が大きいと小数点以下の数値が大きくバグる
                float num = _ScreenParams.x;
                return convertNumver(i, num);
            }
            ENDCG
        }
    }
}