HSP
GLSL

HSP3.5 HGIMG4 で高品質circle代用

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

実行すると以下のようになります。

実行結果
z03disc1.png
左が circle 命令, 右が今回の楕円描画

上記サンプルではオレンジ色一色に塗りましたがなにか画像を貼り付けて楕円にくりぬいたりすることもできると思います。