3

現在、OpenGLES 2.0 を使用して Android および IOS デバイス用に記述されたエンジンを webgl に移植していますが、シェーダーを使用して問題に遭遇しました。モバイル アプリ用に作成されたシェーダーのほとんどは、webGL では機能しません。例 :

( $ は、コンパイルされる前にプリプロセッサによって値に置き換えられます)

頂点シェーダー:

uniform mat4 u_mvpMatrix;

attribute vec4 a_position;
attribute vec2 TexCoordIn;

varying vec2 TexCoordOut; 
varying highp vec2 MCPosition;
varying float radius1;
varying float radius2;

uniform int time;
const int delay = ($2*60)/1000;
const int animDuration = ($3*60)/1000;

void main()
{
    gl_Position = u_mvpMatrix * a_position;

    MCPosition = a_position.xy;

    TexCoordOut = TexCoordIn;

    int timer = time - delay;
    radius1  = float(240 * (timer-26) / animDuration);
    radius2  = float(240 * (timer-1)  / animDuration);

}

フラグメント シェーダー :

precision mediump float;

uniform vec2 spriteSize;
uniform vec2 spritePosition;
uniform lowp float alpha;
uniform lowp float brightness;
uniform sampler2D Texture;
uniform int time;


varying vec2 MCPosition;
varying vec2 TexCoordOut; 
varying float radius1;
varying float radius2;

const float hexRadius = 7.0;
const float hexWidth = hexRadius*sqrt(3.0);
const float cos30 = hexRadius/hexWidth;
const float midHexRadius = hexRadius/2.0;
const float midHexWidth = hexWidth/2.0;
const vec2 centerEffect = vec2($1,$0);

const float SIDE =  hexRadius * 3. / 2.;
const float HEIGHT = hexWidth;
const float SEMI_HEIGHT = HEIGHT / 2.;
const float RADIUS = hexRadius;


vec2 cellIndex(float i, float j) 
{
    float mX = i * SIDE;
    float mY = SEMI_HEIGHT * (2. * j + mod(i, 2.));
    return vec2(mX, mY);
}

void main()
{  
    vec2 center;
    bool isOnEdge = false;

    float x = MCPosition.y;
    float y = MCPosition.x;

    float ci = floor(x/SIDE);
    float cx = mod(x, SIDE);

    float isCiImpair = mod(ci, 2.);

    float ty = y - isCiImpair * SEMI_HEIGHT;
    float cj = floor( ty / HEIGHT);
    float cy = ty - HEIGHT * cj;

    float border = abs(RADIUS / 2. - RADIUS * cy / HEIGHT);

    if (cx > border) 
    {
        center = cellIndex(ci , cj);

        if( cy < 1. || cy > (HEIGHT-1.) || (cx- border) < 1.0)
        {
            isOnEdge = true;
        }
    }
    else 
    {
        center = cellIndex(ci - 1., cj + isCiImpair - ((cy < SEMI_HEIGHT) ? 1. : 0.));  

        if( (border - cx ) < 1.0)
        {
            isOnEdge = true;
        }
    }



    float distFromCenter = distance(centerEffect, center);

    if(distFromCenter > radius2)
    {
        gl_FragColor =  vec4(0.);
    }
    else
    {
        vec4 texColor =  texture2D(Texture, TexCoordOut);

        //filling is over
        if(distFromCenter < radius1)
        {
            gl_FragColor =  texColor;
        }
        else
        {
            float ratio = (radius2 - distFromCenter)/(radius2 - radius1);

            gl_FragColor = vec4(texColor.a * ratio);

            if(!isOnEdge)
            {
                gl_FragColor.rgb *= texColor.rgb;
            }
        }
        gl_FragColor.rgb *= brightness;
    }

}

OpenGLES では魅力的に機能しますが、webGL では const float が非定数値で初期化されているという報告があります。私が行う操作は、const を宣言するときに常に同じ結果を返します。

An error occurred compiling the shaders: ERROR: 0:17: '=' :  assigning non-constant to 'const mediump float'
ERROR: 0:18: '=' :  assigning non-constant to 'const mediump float'
ERROR: 0:20: '=' :  assigning non-constant to 'const mediump float'
ERROR: 0:24: '=' :  assigning non-constant to 'const mediump float'
ERROR: 0:25: '=' :  assigning non-constant to 'const mediump float'

それについて何かできることはありますか、それとも WebGL GLSL の仕様に合わせてすべてのシェーダーを書き直す必要がありますか?

4

2 に答える 2

4

私が webGL シェーダーに取り組んでいたとき、許可された唯一の定数は純粋な数値であり、私はまだ方法を見つけていません。書き直すしかないようです。:P

于 2013-05-17T18:00:50.693 に答える