2012-07-01 3 views
2

У меня есть несколько glsl, и это работает как шарм. Только компиляция занимает 3 минуты или что-то в этом роде. Я знаю, что это связано с углом, Angle - это часть программного обеспечения, которая преобразует код opengl es 2.0 в DirectX 9 для webgl на системах Windows. если я отключить угол, он скомпилируется за секунду. Кто-нибудь знает, почему вложенные петли медленны по склону. А если вокруг есть работа? Я имею в виду, я не могу просто позволить всем ждать больше минуты за шейдер.Webgl Угловые петли очень медленные

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

Просьба предоставить полный тестовый образец и файл с ошибкой (Enhancement) на странице проекта ANGLE: http://code.google.com/p/angleproject/issues/list –

ответ

3

GLSL ES не определяет, когда циклы и «динамически» ограниченные циклы должны быть обязательными. ANGLE использует это и делает разворот развертки: Если у вас есть for (int b = 0; b < numberOfSplitpoints; b++), то значение numberOfSplitpoints должно быть постоянным, иначе шейдер не будет компилироваться.

разворачивания цикл должен позволить родной шейдер оптимизатор делать больше оптимизации и минимизации расхождения, но (в коде), если у вас есть numberOfSplitpoints и fullkernelSize очень большой, развернутый код может получить очень длинный (код в внутри- большая часть будет повторяться numberOfSplitpoints*fullkernelSize*fullkernelSize раз), что может привести к тому, что оптимизатор и компилятор будут входить во всевозможные проблемы.

+0

Благодарим вас за четкое объяснение !! Я думаю, что я просто развожу большинство петель. Недостатком является то, что он настолько уродлив: P. возможно, было бы неплохо сделать разворачивание только на этапе предварительной подготовки. –

Смежные вопросы