1

複雑な if-else 決定木を使用して GLSL フラグメント シェーダーを実装しようとしています。残念ながら、シェーダー コンパイラはかなり早い段階で「構文エラー - メモリ不足」エラーで失敗します。GLSL のコード サイズまたは決定木の深さに関する制約はありますか? この問題を克服する方法について何か提案はありますか?

bool block1(float p[16], float cb, float c_b) { 
  if(p[6] > cb)
   if(p[7] > cb)
    if(p[8] > cb)
     return true;
    else
     if(p[15] > cb)
      return true;
     else
      return false;
   else if(p[7] < c_b)
    if(p[14] > cb)
     if(p[15] > cb)
      return true;
     else
      return false;
    else if(p[14] < c_b)
     if(p[8] < c_b)
      if(p[9] < c_b)
       if(p[10] < c_b)
        if(p[11] < c_b)
         if(p[12] < c_b)
          if(p[13] < c_b)
           if(p[15] < c_b)
            return true;
           else
            return false;   // ';' : syntax error memory exhausted
          else
           return false;
         else
          return false;
        else
         return false;
       else
        return false;
      else
       return false;
     else
      return false;
    else
     return false;
   else
    if(p[14] > cb)
     if(p[15] > cb)
      return true;
     else
      return false;
    else
     return false;
  else if(p[6] < c_b)
   if(p[15] > cb)
    if(p[13] > cb)
     if(p[14] > cb)
      return true;
     else
      return false;
    else if(p[13] < c_b)
     if(p[7] < c_b)
      if(p[8] < c_b)
       if(p[9] < c_b)
        if(p[10] < c_b)
         if(p[11] < c_b)
          if(p[12] < c_b)
           if(p[14] < c_b)
            return true;
           else
            return false;
          else
           return false;
         else
          return false;
        else
         return false;
       else
        return false;
      else
       return false;
     else
      return false;
    else
     return false;
   else
    if(p[7] < c_b)
     if(p[8] < c_b)
      if(p[9] < c_b)
       if(p[10] < c_b)
        if(p[11] < c_b)
         if(p[12] < c_b)
          if(p[13] < c_b)
           if(p[14] < c_b)
            return true;
           else
            return false;
          else
           return false;
         else
          return false;
        else
         return false;
       else
        return false;
      else
       return false;
     else
      return false;
    else
     return false;
  else
   if(p[13] > cb)
    if(p[14] > cb)
     if(p[15] > cb)
      return true;
     else
      return false;
    else
     return false;
   else if(p[13] < c_b)
    if(p[7] < c_b)
     if(p[8] < c_b)
      if(p[9] < c_b)
       if(p[10] < c_b)
        if(p[11] < c_b)
         if(p[12] < c_b)
          if(p[14] < c_b)
           if(p[15] < c_b)
            return true;
           else
            return false;
          else
           return false;
         else
          return false;
        else
         return false;
       else
        return false;
      else
       return false;
     else
      return false;
    else
     return false;
   else
    return false;
}
4

1 に答える 1

4

私はシェーダー言語について何も知らないので、ここで手足を出すつもりです。

1. 論理の組み合わせ (and、or) を使用する

しかし、私は一般的なロジックと多くのプログラミング言語を知っています。次のようなコンストラクトの可能性は非常に高いです。

if(p[8] < c_b)
 if(p[9] < c_b)
  if(p[10] < c_b)
   if(p[11] < c_b)
    if(p[12] < c_b)
     if(p[13] < c_b)
      if(p[15] < c_b)
       return true;
      else
       return false;   // ';' : syntax error memory exhausted
     else
      return false;
    else
     return false;
   else
    return false;
  else
   return false;
 else
  return false;
else
 return false;

次の(単一の)ブール式と同等に簡単に述べることができます。

return (p[8] < c_b)
    && (p[9] < c_b)
    && (p[10] < c_b)
    && (p[11] < c_b)
    && (p[12] < c_b)
    && (p[13] < c_b)
    && (p[15] < c_b);

特定の言語の正確な文法に依存するand代わりに、使用する必要がある場合があります。&&

2.冗長性を排除する

少なくとも 2 つの「サブツリー」が完全に同一であることに気付きました。より具体的には、例えば 57 行目 (ここでは便宜上、フォーマットを簡略化しています):

    if(p[13] < c_b) if(p[7] < c_b) if(p[8] < c_b) if(p[9] < c_b) if(p[10] < c_b) if(p[11] < c_b) if(p[12] < c_b) if(p[14] < c_b)
        return true;
    else return false; else return false; else return false; else return false; else return false; else return false; else return false; else return false;

行#83と完全に同一です

   if(p[7] < c_b) if(p[8] < c_b) if(p[9] < c_b) if(p[10] < c_b) if(p[11] < c_b) if(p[12] < c_b) if(p[13] < c_b) if(p[14] < c_b)
       return true;
   else return false; else return false; else return false; else return false; else return false; else return false; else return false; else

(p[13] < c_b)条件が終わりに近づいただけです。これが発生するブランチを組み合わせる可能性は非常に高いです。

この (骨の折れる) プロセスを手動で行う代わりに、真理値表を作成し (考えられるすべての入力をマップするだけです)、単一のブール式を推測して、そこから結果値を生成することをお勧めします。

于 2013-04-05T08:24:20.597 に答える