2016-07-12 21 views
0

Ich versuche einen Fragment-Shader zu erstellen, der verwendet werden kann, wenn eine Materialeigenschaft einen Farbtyp oder eine Textur hat. Aber ich stieß auf ein großes Problem. Lassen Sie uns sagen, dass ich ein Werkstoff Struktur wie dieses:Testattribute im Metallfragment Shader

typedef struct { 
    vector_float4 diffuseColor; 
    bool useDiffuseTexture; 
} Material; 

und Fragment-Funktion:

fragment float4 fragment_main(Vertex vert [[stage_in]], 
           constant Constants &uniforms [[buffer(0)]], 
           constant Material &material [[buffer(1)]], 
           texture2d<float> diffuseTexture [[texture(0)]], 
           sampler   diffuseTextureSampler [[sampler(0)]] 
          ) 
{...} 

In Fragment Körper werde ich entweder:

float4 diffuseColor = material.diffuseColor; 

oder wenn Material diffuse Textur:

float4 diffuseColor = diffuseTexture.sample(diffuseTextureSampler, float2(vert.textcoords)); 

Problem ist, dass ich nicht wirklich auf das Vorhandensein von Textur im Shader testen kann, also dachte ich, dass ich es als param in einer Struktur übergeben werde:

bool useDiffuseTexture;

aber dieser Code aus irgendeinem Grund:

float4 diffuseColor = material.diffuseColor; 
if (material.useDiffuseTexture == true) { 
     diffuseColor = diffuseTexture.sample(diffuseTextureSampler, float2(vert.textcoords)); 
} 

immer ruft diffuseTexture und wirft Fehler:

Textur bei Index 0 für diffuseTexture Bindung fehlt [0]

I‘ Ich bin mir nicht sicher, was ich falsch mache. Ich kann keine Bindung haben, weil es keine Textur gibt.

Vielen Dank im Voraus

Antwort

1

Auch wenn Sie in Ihrer Funktion verwenden Sie es nicht, jede Textur, Puffer oder Sampler-Parameter muss ein entsprechendes Objekt in der Argument Tabelle gebunden haben. In Ihrem Fall könnten Sie eine "Dummy" -, 1x1-Textur binden, um diese Anforderung zu erfüllen, oder Sie könnten zwei Shader-Varianten (und damit zwei Render-Pipelinestatus) haben, einen, der die diffuse Farbe verwendet und einen, der die diffuse Textur abtastet.

+0

Dank @warrenm, ich vermutete, dass ich mit so etwas enden werde. Unterschiedliche Pipelines sind wirklich keine Option, da diffuse nur eine Variante unter anderen Materialeigenschaften ist (dasselbe gilt für Glanz, Emission, Umgebung usw.), und zwischen diesen gibt es viele mögliche Kombinationen. Ich würde auch mehrere Rendering-Durchgänge mit unterschiedlichen Pipeline-Zuständen für jedes mögliche Material vermeiden. Also, ich denke, dass Dummy-Textur nur Option übrig ist. –

+0

Ich nahm an, dass weitere Permutationen lauern könnten :) Ich würde jedoch bemerken, dass Sie keinen einzigen Durchlauf pro Material benötigen würden, da Sie zwischen Render-Pipeline-Zuständen zwischen Zeichenaufrufen wechseln können. – warrenm