1
1

More than 1 year has passed since last update.

ebitenで走査線シェーダーを作ってみた

Last updated at Posted at 2021-10-18

 ebitenのシェーダーで「走査線シェーダー(昔のブラウン管テレビの走査線を模倣する)」を作ったので、メモ代わりで公開します

 走査線処理的には、Windows版餓狼伝説MOWのドットの境界線を走査線で強調するパターンです

package main

func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
    if int(position.y) % 3 != 0 {
        return imageSrc0At(texCoord)
    }

    var clr vec3
    clr.r = imageSrc0At(texCoord).r * 0.5
    clr.g = imageSrc0At(texCoord).g * 0.5
    clr.b = imageSrc0At(texCoord).b * 0.5

    return vec4(clr, 1.0)
}

 ファミコンの頃の像解度をNintendo Switchで表示すると3×3倍になるので、「% 3」のmod処理で余りを調べて、Y軸で3ドットずつ走査線処理を行ってます

おまけ:進化版シェーダー

 ブラウン管はレーザー光線で表示していたため、画面が明るく、ぼやけてます。それを追加した現在のシェーダーは

package main

func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
    col := imageSrc0At(texCoord)

    // ボカシ
    var x,y float

    x = texCoord.x / position.x // 1dot当たりのテクセル数
    y = texCoord.y / position.y

    colA := imageSrc0At(vec2(x * 0.5 + texCoord.x - x, y * 0.5 + texCoord.y))
    colB := imageSrc0At(vec2(x * 0.5 + texCoord.x    , y * 0.5 + texCoord.y - y))
    colC := imageSrc0At(vec2(x * 0.5 + texCoord.x + x, y * 0.5 + texCoord.y))
    colD := imageSrc0At(vec2(x * 0.5 + texCoord.x    , y * 0.5 + texCoord.y + y))
    // x * 0.5、y * 0.5はドットの中心へずらしている

    col.r = (((colA.r + colB.r + colC.r + colD.r) * 0.25 * 0.25) + col.r * 0.75)
    col.g = (((colA.g + colB.g + colC.g + colD.g) * 0.25 * 0.25) + col.g * 0.75)
    col.b = (((colA.b + colB.b + colC.b + colD.b) * 0.25 * 0.25) + col.r * 0.75)

    // 走査線とブラウン管
    var clr vec3
    if int(position.y) % 3 != 0 {
        // ブラウン管なので明るい
        clr.r = col.r * 1.5
        if clr.r > 1.0 {    // 数値は1.0まで
            clr.r = 1.0
        }
        clr.g = col.g * 1.5
        if clr.g > 1.0 {
            clr.g = 1.0
        }
        clr.b = col.b * 1.5
        if clr.b > 1.0 {
            clr.b = 1.0
        }

        return vec4(clr, 1.0)
    } else {
        // 走査線
        clr.r = col.r * 0.5
        clr.g = col.g * 0.5
        clr.b = col.b * 0.5

        return vec4(clr, 1.0)
    }
}

となります。1dot当たりのテクセル数の求め方は、とりあえずの物で今後、変更するかも知れません

 物理学的には光線の波長のエネルギーは単純な四則演算で足す事や引く事が出来るので、掛け算で光線を強めるアンプの処理が可能になります

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1