HGIMG4 で 高品質 circle 代用
HGIMG4 では circle 命令を使って2D楕円を簡単描画できますが16分割でありアンチエイリアスもかかっていません。そこで描画負荷が高い代わりにもうちょっとだけ高画質な楕円描画を用意してみました。
フラグメントシェーダーでユーザー指定の gcopy(実際に使用する命令は celput) を実装します。
シェーダーファイルの作成
まず以下のファイルを作成します。
res/shaders/sprdisc.frag
#if defined(OPENGL_ES) || defined(GL_ES)
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
#endif
#define PI 3.1415926535
uniform vec4 u_px;
uniform sampler2D u_texture;
varying vec2 v_texCoord;
void main() {
vec2 pxo = (v_texCoord - 0.5) * u_px.z;
vec2 ned = vec2(abs(pxo.x / u_px.x), abs(pxo.y / u_px.y));
float yrate = atan(ned.y, ned.x) / PI * 0.5;
float rate = mix(u_px.x, u_px.y, yrate);
float lv = rate / u_px.w * (1.0 - length(ned));
gl_FragColor = texture2D(u_texture, v_texCoord);
gl_FragColor.a = lv;
}
使い方
シェーダーの uniform u_px でパラメータを調整し celput(gcopy) で実際の描画を行います。
#include "hgimg4.as"
gpreset
setcls CLSMODE_SOLID, 0x000033
vs = "res/shaders/sprite.vert"
fs = "res/shaders/sprdisc.frag"
gpusershader vs,fs, ""
side = 512
buffer 2, side,side, screen_offscreen + screen_usergcopy
celdiv 2, side,side, side/2, side/2
gpgetmat id_mtl, 2, GPGETMAT_OPT_SCRMAT
// 横半径、縦半径、buffer の一辺の大きさ、アンチエイリアス幅
gpmatprm4 id_mtl, "u_px", 250.0, 150.0, side, 2.0
redraw 0
color 255,128,0
boxf
redraw 1
gsel 0
gmode 2
repeat
getreq fps, SYSREQ_FPS
redraw 0
color 224,224,224
circle 50,50, 400,400, 0
pos 600,300
celput 2
pos 8,8
mes strf("%2d [fps]", fps)
redraw 1
await 1000/60
loop
実行すると以下のようになります。
実行結果 |
---|
左が circle 命令, 右が今回の楕円描画 |
上記サンプルではオレンジ色一色に塗りましたがなにか画像を貼り付けて楕円にくりぬいたりすることもできると思います。