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当たりのテクセル数の求め方は、とりあえずの物で今後、変更するかも知れません
物理学的には光線の波長のエネルギーは単純な四則演算で足す事や引く事が出来るので、掛け算で光線を強めるアンプの処理が可能になります