0

だから私はOpenGL ESシェーダーの仕様を調べますが、そのようなものは見当たりません...

たとえば、単純な「ピンチでズーム」、「回転して向きを変える」、「移動して中央に移動」の HYDRA ピクセル ベンダー フィルターを作成しました。フラッシュで実行できます。これは、デフォルトのピクセル ベンダーの回転の例との例に基づいています。

<languageVersion: 1.0;> 

kernel zoomandrotate
<   namespace : "Pixel Bender Samples";
    vendor : "Kabumbus";
    version : 3;
    description : "rotate and zoom an image around"; >
{
    // define PI for the degrees to radians calculation
    const float PI = 3.14159265;

    // An input parameter to specify the center of the twirl effect.
    // As above, we're using metadata to indicate the minimum,
    // maximum, and default values, so that the tools can set the values 
    // in the correctly in the UI for the filter.
    parameter float2 center
    <
        minValue:float2(0.0, 0.0);
        maxValue:float2(2048.0, 2048.0);
        defaultValue:float2(256.0, 256.0);
    >;

    // An input parameter to specify the angle that we would like to twirl.
    // For this parameter, we're using metadata to indicate the minimum,
    // maximum, and default values, so that the tools can set the values 
    // in the correctly in the UI for the filter.
    parameter float twirlAngle
    <
        minValue:float(0.0);
        maxValue:float(360.0);
        defaultValue:float(90.0);
    >;

     parameter float zoomAmount
    <
        minValue:float(0.01);
        maxValue:float(10.0);
        defaultValue:float(1);
    >;

    // An input parameter that indicates how we want to vary the twirling
    // within the radius.  We've added support to modulate by one of two 
    // functions, a gaussian or a sinc function.  Since Flash does not support
    // bool parameters, we instead are using this as an int with two possible
    // values. Setting this parameter to be 1 will
    // cause the gaussian function to be used, unchecking it will cause 
    // the sinc function to be used.
    parameter int gaussOrSinc
    <
        minValue:int(0);
        maxValue:int(1);
        defaultValue:int(0);
    >;

    input image4 oImage;
    output float4 outputColor;

    // evaluatePixel(): The function of the filter that actually does the 
    //                  processing of the image.  This function is called once 
    //                  for each pixel of the output image.
    void
    evaluatePixel()
    {
        // convert the angle to radians
        float twirlAngleRadians = radians(twirlAngle);

        // calculate where we are relative to the center of the twirl
        float2 relativePos = outCoord() - center;

        // calculate the absolute distance from the center normalized 
        // by the twirl radius.
        float distFromCenter = length( relativePos );
        distFromCenter = 1.0;
        // modulate the angle based on either a gaussian or a sync.
        float adjustedRadians;

        // precalculate either the gaussian or the sinc weight
        float sincWeight = sin( distFromCenter ) * twirlAngleRadians / ( distFromCenter );
        float gaussWeight = exp( -1.0 * distFromCenter * distFromCenter ) * twirlAngleRadians;

        // protect the algorithm from a 1 / 0 error
        adjustedRadians = (distFromCenter == 0.0) ? twirlAngleRadians : sincWeight;

        // switch between a gaussian falloff or a sinc fallof
        adjustedRadians = (gaussOrSinc == 1) ? adjustedRadians : gaussWeight;

        // rotate the pixel sample location.
        float cosAngle = cos( adjustedRadians );
        float sinAngle = sin( adjustedRadians );

        float2x2 rotationMat = float2x2(
            cosAngle,   sinAngle,
            -sinAngle,  cosAngle
        );

        relativePos = rotationMat * relativePos; 
        float scale =  zoomAmount;
        // sample and set as the output color.  since relativePos
        // is related to the center location, we need to add it back in.
        // We use linear sampling to smooth out some of the pixelation.
        outputColor = sampleLinear( oImage, relativePos/scale + center );
    }
}

そこで、OpenGL ES シェーダーに移植したいと思います。math と parameters は OpenGL ES シェーダー言語に変換できますが、sampleLinear はどうすればよいですか? openGL ESシェーダー言語でアナログとは何ですか?

アップデート:

そこで、HYDRA フィルターに似たものを作成しました... webGL および OpenGL ES シェーダーと互換性があります...

#ifdef GL_ES
precision highp float;
#endif

uniform vec2 resolution;
uniform float time;
uniform sampler2D tex0;


void main(void)
{
    vec2 p = -1.0 + 2.0 * gl_FragCoord.xy / resolution.xy;
    // a rotozoom
    vec2 cst = vec2( cos(.5*time), sin(.5*time) );
    mat2 rot = 0.5*cst.x*mat2(cst.x,-cst.y,cst.y,cst.x);
    vec3 col = texture2D(tex0,0.5*rot*p+sin(0.1*time)).xyz;

    gl_FragColor = vec4(col,1.0);
}

それがどのように機能するかを確認するには、最新のブラウザーを取得し、shadertoyに移動して 1 つのテクスチャ (http://www.iquilezles.org/apps/shadertoy/presets/tex4.jpgたとえば) を提供し、コードを編集可能なテキスト aeria に貼り付けてヒットしここに画像の説明を入力ます...お楽しみください。だから..今、私は別の問題を抱えています...同じ画像のコピーではなく、1つの画像とその周りに黒を置きたいです...誰もそれを行う方法を知っていますか?

4

1 に答える 1

1

Per Adobe's Pixel Blender Reference, sampleLinear "Handles coordinates not at pixel centers by performing bilinear interpolation on the adjacent pixel values."

The correct way to achieve that in OpenGL is to use texture2D, as you already are, but to set the texture environment for linear filtering via glTexParameter.

You can use the step function and multiply by its result to get black for out-of-bounds pixels, or give your texture a single pixel black border and switch to clamping rather than repeat, also via glTexParameter.

If you want to do it in code, try:

#ifdef GL_ES
precision highp float;
#endif

uniform vec2 resolution;
uniform float time;
uniform sampler2D tex0;


void main(void)
{
    vec2 p = -1.0 + 2.0 * gl_FragCoord.xy / resolution.xy;
    // a rotozoom
    vec2 cst = vec2( cos(.5*time), sin(.5*time) );
    mat2 rot = 0.5*cst.x*mat2(cst.x,-cst.y,cst.y,cst.x);
    vec2 samplePos = 0.5*rot*p+sin(0.1*time);
    float mask = step(samplePos.x, 0.0) * step(samplePos.y, 0.0) * (1.0 - step(samplePos.x, 1.0)) * (1.0 - step(samplePos.y, 1.0));
    vec3 col = texture2D(tex0,samplePos).xyz;

    gl_FragColor = vec4(col*mask,1.0);
}

That'd restrict colours to coming from the box from (0, 0) to (1, 1), but it looks like the shader heads off to some significantly askew places, so I'm not sure exactly what you want.

于 2011-06-05T15:23:38.953 に答える