Difference between revisions of "love.graphics.newShader (日本語)"

m
m (注釈)
Line 122: Line 122:
 
<code>varying</code>  キーワードは頂点シェーダーおよび頂点間においての補間、さらにピクセル・シェーダーへ渡す値を設定するために使用できます。
 
<code>varying</code>  キーワードは頂点シェーダーおよび頂点間においての補間、さらにピクセル・シェーダーへ渡す値を設定するために使用できます。
  
明確な頂点のコードは <code>#ifdef VERTEX .. #endif</code> および明確なピクセルのコードは <code>#ifdef PIXEL .. #endif</code> にて包装することで頂点およびピクセル・シェーダーのコードは1ファイルまたは文字列にて組み合わせることができます。
+
明確な頂点のコードは <code>#ifdef VERTEX .. #endif</code> および明確なピクセルのコードは <code>#ifdef PIXEL .. #endif</code> のブロックで囲むことにより、頂点およびピクセル・シェーダーのコードは1ファイルまたは文字列にて組み合わせることができます。
  
 
== 組み込み変数 ==
 
== 組み込み変数 ==

Revision as of 14:06, 15 May 2017

LÖVE 0.9.0 から使用可能
love.graphics.newPixelEffect から名称変更。


O.png この関数は love.update または love.draw などから繰り返し呼び出すと動作が重くなることがあります。もし、特定の資源を何度も使う必要がある場合は、一括で作成と格納を行うことで効率的に再利用できます!  



ハードウェアにより加速化された頂点またはピクセル・エフェクトに対して Shader オブジェクトを新規作成します。Shader には頂点シェーダーのコード、ピクセル・シェーダーのコード、のいずれか、または両方が含まれています。

Shader は描画時にビデオカードにて実行される小型のプログラムです。頂点シェーダーは各頂点に対して一括で実行されます (例えば、 Image では頂点が4つあります。 - 角ごとに一つずつ。 Mesh では、さらに存在する場合があります)。ピクセル・シェーダーは描画されたオブジェクトが関係する画面上の各ピクセルに対して一括で実行します。全てのオブジェクトの頂点が頂点シェーダーにより処理された後にピクセル・シェーダーのコードは実行されます。

関数

概要

shader = love.graphics.newShader( code )

引数

string code
ピクセル・シェーダーまたは頂点シェーダーのコード、またはコードのあるファイルを指すファイルの名称。

返値

Shader shader
描画操作で使用する Shader オブジェクト。

関数

概要

shader = love.graphics.newShader( pixelcode, vertexcode )

引数

string pixelcode
ピクセル・シェーダーのコード、またはコードのあるファイルを指すファイルの名称。
string vertexcode
頂点シェーダーのコード、またはコードのあるファイルを指すファイルの名称。

返値

Shader shader
描画操作で使用する Shader オブジェクト。

注釈

引数 pixelcode および vertexcode は任意の順序にすることができます。

シェーダー言語

シェーダーは Lua ではプログラミングできませんが、代わりに特別なエフェクト言語を使用します。基本的にエフェクト言語は GLSL 1.20 (仕様書) であり既存の型へ若干の別名を追加したものです:

GLSL LÖVE シェーダー言語
float number
sampler2D Image
uniform extern
texture2D(tex, uv) Texel(tex, uv)

頂点シェーダーのコードには最低でも一本の関数が含まれており、その名前は position であり、関数は画面空間へ描画されたオブジェクトから変形された頂点の位置を生成します。

ピクセルシェーダーのコードには最低でも一本の関数が含まれており、その名前は effect であり、関数は描画されたオブジェクトが接触する各ピクセルに対して画面上へ混合される色を生成します。

さらに、 LÖVE は色値を与えるために VideoTexel(uv) 関数により描画を行って現在の位置に Video を描画します。Video は多数のテクスチャにより、 YUV データとして描画を行い、そしてシェーダーへ変換されるため、 Texel (テクセル) 関数は使用できません。

ピクセル・シェーダー関数

オブジェクト描画時に、ピクセルシェーダの effect 関数は何百回または何千回も呼び出されます: 画面において各ピクセルがオブジェクトが接触する場合に。そのような場合は、ピクセルシェーダは頂点シェーダーの後に実行されます。

概要

vec4 effect( vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords )

引数

vec4 color
love.graphics.setColor にて設定する描画色または頂点ごとの Mesh の色。
Image texture
テクスチャとして描画される画像または Canvas です。
vec2 texture_coords
ピクセルデータ取得先のテクスチャ内の位置です。テクスチャ座標は左上角 (0, 0) を起点とする場合に、通常は (0, 0) から(1, 1) までの範囲で標準化されます。
vec2 screen_coords
画面上のピクセルの座標。ピクセルの座標は標準化されません (テクスチャの座標とは異なります)。 (0.5, 0.5) は画面左上 (LÖVE version 0.10.0 以前では画面左下)を表します。

返値

vec4 output_color
ピクセルの色。

注釈

ピクセルシェーダーが使用されていない場合、 LÖVE は標準のものを使用します。これは、そのコードです:

vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords)
{
    vec4 texturecolor = Texel(texture, texture_coords);
    return texturecolor * color;
}

または Video では

vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords)
{
    vec4 texturecolor = VideoTexel(texture_coords);
    return texturecolor * color;
}

複数の Canvas が同時に表示される場合は (複数の Canvas を love.graphics.setCanvas への引数として渡したとき)、 Canvas ごとに個別の色を出力するために effect の代わりに effects 関数を使用できます。それは次のプロトタイプ(原型)があります:

void effects(vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords)
{
    // love_Canvases は vec4 色の書き込み可能な配列です。各索引は Canvas に一致しています。
    // 重要: 使用中の全ての Canvas へ値を代入しなければ、不具合が発生します。
    love_Canvases[0] = color;
    love_Canvases[1] = color + vec4(0.5);
    // など。
}

頂点シェーダー関数

概要

vec4 position( mat4 transform_projection, vec4 vertex_position )

引数

mat4 transform_projection
変換行列は love.graphics.translate および関連関数により影響を受けて正投影の行列と組み合わされます。
vec4 vertex_position
現在の頂点における生の未変形位置。

返値

vec4 output_pos
現在の頂点における最終変形位置。

注釈

頂点シェーダーが使用されていない場合、 LÖVE は標準のものを使用します。これは、そのコードです:

vec4 position(mat4 transform_projection, vec4 vertex_position)
{
    // 行列乗算を行うときに演算順序は重要です。
    return transform_projection * vertex_position;
}

注釈

頂点シェーダーのコードは画面へ描画される頂点毎に対して実行され(例えば love.graphics.rectangle は頂点を4つ生成します)、ピクセル・シェーダーへ頂点毎の配色およびテクスチャ座標の値を送信するのと同様に、原点座標から頂点位置へ画面空間を変形するために使用されます。

ピクセル・シェーダーのコードは描画されたオブジェクトに接触している画面上の各ピクセルに対して実行され、大抵は画像から読み込んで、画面上の対象ピクセルと混合する色を生成するのに使用されます。時にはピクセル・シェーダーは断片的シェーダーとも呼ばれています。

varying キーワードは頂点シェーダーおよび頂点間においての補間、さらにピクセル・シェーダーへ渡す値を設定するために使用できます。

明確な頂点のコードは #ifdef VERTEX .. #endif および明確なピクセルのコードは #ifdef PIXEL .. #endif のブロックで囲むことにより、頂点およびピクセル・シェーダーのコードは1ファイルまたは文字列にて組み合わせることができます。

組み込み変数

LÖVE はピクセルおよび頂点シェーダーの両方に対して若干の組込変数を提供します。こちらに全ての一覧があります: シェーダー変数

用例

シェーダーが設定されていない場合は動作する頂点およびピクセル・シェーダーのコードを使用してシェーダーを作成します。

function love.load()
    local pixelcode = [[
        vec4 effect( vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords )
        {
            vec4 texcolor = Texel(texture, texture_coords);
            return texcolor * color;
        }
    ]]

    local vertexcode = [[
        vec4 position( mat4 transform_projection, vec4 vertex_position )
        {
            return transform_projection * vertex_position;
        }
    ]]

    shader = love.graphics.newShader(pixelcode, vertexcode)
end

function love.draw()
    love.graphics.setShader(shader)
    -- なにか描画するもの
    love.graphics.setShader()
    -- さらになにか描画するもの
end

varying キーワードによりピクセルシェーダーにある事前変形された頂点位置をアクセスします。

頂点シェーダーのコード

varying vec4 vpos;

vec4 position( mat4 transform_projection, vec4 vertex_position )
{
    vpos = vertex_position;
    return transform_projection * vertex_position;
}

ピクセルシェーダーのコード

varying vec4 vpos;

vec4 effect( vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords )
{
    texture_coords += vec2(cos(vpos.x), sin(vpos.y));
    vec4 texcolor = Texel(texture, texture_coords);
    return texcolor * color;
}

上述の例では #ifdef を使用して1つの文字列またはファイルへ組み合わせます。

varying vec4 vpos;

#ifdef VERTEX
vec4 position( mat4 transform_projection, vec4 vertex_position )
{
    vpos = vertex_position;
    return transform_projection * vertex_position;
}
#endif

#ifdef PIXEL
vec4 effect( vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords )
{
    texture_coords += vec2(cos(vpos.x), sin(vpos.y));
    vec4 texcolor = Texel(texture, texture_coords);
    return texcolor * color;
}
#endif

関連



そのほかの言語