2017-10-16 98 views
1

我有一個着色器函數,其功能類似於Blender3D中的「色彩漸變」節點。它輸入零和一之間的浮動,並輸出顏色,是按照指定的順序任意數量的顏色的共混物:色彩漸變着色器(cg/shaderlab)

blender3D色帶
blender3D color ramp

這是我的代碼:

fixed4 ColorRamp(float factor){ 
      float positions[5] = {_Pos0, _Pos1, _Pos2, _Pos3, _Pos4}; 
      fixed4 colors[5] = {_Color0, _Color1, _Color2, _Color3, _Color4}; 

      fixed4 outColor = _Color0; 

      for(int i = 0; i <4; i++){ 

       if(factor >= positions[i] && factor <positions[i+1]){ 
        fixed localFactor = (factor - positions[i])/(positions[i+1] - positions[i]); 
        outColor = lerp(colors[i], colors[i+1], localFactor); 
       }else if (factor > positions [_NumColors-1]){ 
        outColor = colors[_NumColors -1]; 
       } 
      } 
      return outColor; 
     } 

它的工作原理。但它很糟糕,原因如下:

  1. 斜坡中的顏色數是硬編碼的。在Unity編輯器中添加它們的列表會更好。
  2. if/else語句。我知道這些表現很糟糕,應該避免。
  3. 顏色數組在函數中聲明,這意味着必須爲每個片段創建一個新數組(我認爲)。

我的主要問題是第一個問題:如何在不需要編輯硬編碼值的情況下更改斜坡中的顏色數量?

回答

0
  1. 這是不可能的。着色器會自動編譯。並且編譯器不支持循環。你的循環只是語法糖,編譯時它會擴展到確定的迭代次數。
  2. If/else對於表現並不可怕。這只是爲了測試,因爲它會增加圈複雜度。
  3. 您可以在「屬性」塊中聲明數組。

對不起,但你不能在屬性塊中使用數組。你會在方法之外聲明它。

float positions[5]; 
fixed4 colors[5]; 

fixed4 ColorRamp(float factor){ 
    positions[0] = _Pos0; 
    positions[0] = _Pos2; 
    positions[0] = _Pos3; 
    positions[0] = _Pos4; 
    positions[0] = _Pos5; 

    colors[0] = _Color0; 
    colors[1] = _Color1; 
    colors[2] = _Color2; 
    colors[3] = _Color3; 
    colors[4] = _Color4; 

    fixed4 outColor = _Color0; 

    for(int i = 0; i <4; i++) 
    { 
     if(factor >= positions[i] && factor <positions[i+1]) 
     { 
      fixed localFactor = (factor - positions[i])/(positions[i+1] - positions[i]); 
      outColor = lerp(colors[i], colors[i+1], localFactor); 
     } 
     else if (factor > positions [_NumColors-1]) 
     { 
      outColor = colors[_NumColors -1]; 
     } 
    } 
    return outColor; 
} 

但是你必須初始化統一scritpt的外部數組。

float[] array = new float[] {1, 2, 3, 4, 5} 
material.SetFloatArray("positions", array); 
Vector4[] colors = new Vector4[] { new Vector4(), new Vector4(), new Vector4(), new Vector4(), new Vector4() }; 
material.SetVectorArray("colors", colors); 
+0

謝謝!你能否提供一個在屬性塊中聲明數組的例子?我遇到了麻煩,無論是從Unity編輯器傳遞數組還是從可以從Unity編輯器傳遞的屬性創建數組。 – dixiepig

0

最簡單的答案是:烤你漸變成紋理