2011-06-05 64 views
0

所以我期待到OpenGL ES shader specs卻看不到這樣的......什麼是HYDRA(像素彎曲)sampleLinear的OpenGL ES 2 Shader語言模擬?

例如 - 我創建簡單的「掐ZOON」和「旋轉掉頭」和「移動到移動中心」 HYDRA的Pixel Bender過濾器。它可以在閃存中執行。所以,現在我想將它移植到OpenGL ES的渲染

<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); 
    } 
} 

:它是基於默認Pixel Bender的捻例子,this。數學和參數可轉換爲OpenGL ES着色器語言,但如何處理sampleLinear? OpenGL ES着色語言中的模擬是什麼?

更新:

所以我創造了類似我HYDRA過濾器支持WebGL和OpenGL ES着色器的東西... ... compatable

#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); 
} 

要看看它是如何工作的get現代瀏覽器,導航到shadertoy提供一個紋理(例如http://www.iquilezles.org/apps/shadertoy/presets/tex4.jpg),將我的代碼粘貼到可編輯文本aeria中,並打到enter image description here ...玩得開心。所以..現在我有另一個問題...我想有一個圖像和黑色周圍不是同一圖像的副本...任何人都知道如何做到這一點?

回答

1

根據Adobe的Pixel Blender Reference,sampleLinear「通過對相鄰像素值執行雙線性插值來處理不在像素中心的座標」。

在OpenGL中實現該功能的正確方法是使用texture2D,但您可以通過glTexParameter設置用於線性過濾的紋理環境。

您可以使用step函數並將其乘以其結果以獲得超出邊界像素的黑色,或者爲您的紋理指定一個像素黑色邊框並切換到夾緊而不是重複,也可以通過glTexParameter

如果你想這樣做的代碼,請嘗試:

#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); 
} 

那會限制顏色從盒子來從(0,0)到(1,1),但它看起來像着色器前往一些明顯的歪斜的地方,所以我不確定你想要什麼。