2

ここにいくつかのglslがあり、それは魅力のように機能します。コンパイルだけで3分程度かかります。これは角度によるものだと私は知っています。Angleは、Windowsシステムでopengles2.0コードをwebgl用のdirectX9に変換するソフトウェアです。angleを無効にすると、1秒でコンパイルされます。ネストされたループの角度が非常に遅い理由を誰かが知っていますか?そして、回避策がある場合はどうなりますか?つまり、シェーダーごとに1分以上待たせることはできません。

for ( int b = 0; b < numberOfSplitpoints; b++ ) {
    if ( cameraDepth > splitPoints[b] && cameraDepth < splitPoints[b+1] ) {
        const float numberOfSplitpoints = float( NUMBER_OF_SPLIT_POINTS - 1 );
        vec4 projCoords = v_projTextureCoords[b];

        projCoords /= projCoords.w;
        projCoords = 0.5 * projCoords + 0.5;

        float shadowDepth = projCoords.z;

        projCoords.x /= numberOfSplitpoints;
        projCoords.x += float(b) / numberOfSplitpoints;


        for( int x = 0; x < fullkernelSize; x++ ) {
            for( int y = 0; y < fullkernelSize; y++ ) {
                vec2 pointer = vec2( float(x-kernelsize) / 3072.0, float(y-kernelsize) / 1024.0 );
                float convolution = kernel[x] * kernel[y];
                vec4 color = texture2D(shadowMapSampler, projCoords.xy+pointer);

                if(encodeDepth( color ) + shadowBias > shadowDepth) {
                    light += convolution;
                } else {
                    light += convolution * 0.6;
                }
            }
        } 
    }
}

vec2 random = normalize(texture2D(randomSampler, screenSize * uv / 64.0).xy * 2.0 - 1.0);
float ambiantAmount = 0.0;

const int kernel = 4;

float offset = ssoasampleRad / depth;


for(int x = 0; x<kernel; x++) {

    vec2 a  = reflect(directions[x], random) * offset;

    vec2 b  = vec2( a.x *0.707 - a.y*0.707, 
                    a.x*0.707 + a.y*0.707 );

    ambiantAmount += abientOcclusion(uv, a*0.25, position, normal);
    ambiantAmount += abientOcclusion(uv, b*0.50, position, normal);
    ambiantAmount += abientOcclusion(uv, a*0.75, position, normal);
    ambiantAmount += abientOcclusion(uv, b, position, normal);
}
4

1 に答える 1

4

GLSL ESは、whileループを定義せず、「動的に」制限されたforループを必須にします。ANGLEはこれを利用して、広範なループ展開を行います。があればfor ( int b = 0; b < numberOfSplitpoints; b++ )numberOfSplitpointsは定数式である必要があります。そうでない場合、シェーダーはコンパイルされません。

ループ展開により、ネイティブシェーダーオプティマイザーがより多くの最適化を実行し、発散を最小限に抑えることができるはずですが、(コード内で)numberOfSplitpoints非常fullkernelSizeに大きい場合、展開されたコードは非常に長くなる可能性があります(最も内側のコードは繰り返し取得されnumberOfSplitpoints*fullkernelSize*fullkernelSizeます) )、オプティマイザとコンパイラがあらゆる種類の問題を引き起こす可能性があります。

于 2012-07-14T10:07:59.287 に答える