2016-07-12 28 views
0

我试图制作一个片段着色器,可用于某些材质属性为颜色类型或纹理的情况。但是我遇到了很大的问题。 比方说,我有一个材料结构是这样的:金属碎片着色器中的测试属性

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

和片段的功能:

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)]] 
          ) 
{...} 

在片段的身体我要么有:

float4 diffuseColor = material.diffuseColor; 

,或者如果材料有弥漫质地:

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

问题是我无法真正测试着色器中是否存在纹理,所以我认为我会将它作为参数传递给struct:

bool useDiffuseTexture;

但由于某种原因这个代码:

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

总是调用diffuseTexture并引发错误:

缺少质感索引0约束力的diffuseTexture [0]

我我不知道我做错了什么。由于没有纹理,我无法进行装订。

在此先感谢

回答

1

即使你没有在你的函数中使用它,每一个纹理,缓冲,或采样参数必须在参数表中绑定相应的对象。在你的情况下,你可以绑定一个“虚拟”,1x1纹理来满足这个要求,或者你可以有两个着色器变体(以及两个渲染管线状态),一个使用漫反射颜色,另一个使用漫反射纹理。

+0

谢谢@warrenm,我怀疑我最终会得到这样的结果。不同的管线实际上不是一种选择,因为漫反射只是其他材质属性中的一种变体(镜面反射,发射,环境等同样),并且在它们之间有许多可能的组合。我也会避免为每种可能的材料使用不同管线状态的多次渲染过程。所以,我猜那个虚拟纹理只剩下选项。 –

+0

我认为可能会有潜在的额外排列:)但是,我会注意到,您不需要每个材质一次传递,因为您可以在绘制调用之间切换渲染管线状态。 – warrenm