简体   繁体   English

在像素着色器中检测单通道纹理

[英]Detect single channel texture in pixel shader

Is it possible to detect when a format has a single channel in HLSL or GLSL?是否可以检测格式何时在 HLSL 或 GLSL 中具有单个通道? Or just as good, is it possible to extract a greyscale color from such a texture without knowing if it has a single channel or 4?或者同样好,是否可以从这样的纹理中提取灰度颜色而不知道它是单通道还是 4 通道?

When sampling from texture formats such as DXGI_FORMAT_R8_*/GL_R8 or DXGI_FORMAT_BC4_UNORM, I am getting pure red RGBA values (g,0,0,1).从 DXGI_FORMAT_R8_*/GL_R8 或 DXGI_FORMAT_BC4_UNORM 等纹理格式采样时,我得到纯红色 RGBA 值 (g,0,0,1)。 This would not be a problem if I knew (within the shader) that the texture only had the single channel, as I could then flood the other channels with that red value.如果我知道(在着色器中)纹理只有一个通道,这就不是问题,因为我可以用那个红色值填充其他通道。 But doing anything of this nature would break the logic for color textures, requiring a separate compiled version for the grey sampling (for every texture slot).但是做任何这种性质的事情都会破坏颜色纹理的逻辑,需要一个单独的编译版本来进行灰色采样(对于每个纹理槽)。

Is it not possible to make efficient use of grey textures in modern shaders without specializing the shader for them?如果不为现代着色器专门化着色器,就不可能在现代着色器中有效地使用灰色纹理吗?

The only solution I can come up with at the moment would be to detect the grey texture on the CPU side and generate a macro on the GPU side that selects a different compiled version of the shader for every texture slot.目前我能想到的唯一解决方案是在 CPU 端检测灰色纹理并在 GPU 端生成一个宏,为每个纹理槽选择不同的着色器编译版本。 Doing this with 8 texture slots would add up to 8x8=64 compiled versions every shader that wants to support grey inputs.使用 8 个纹理槽执行此操作将为每个想要支持灰色输入的着色器添加多达 8x8=64 个编译版本。 That's not counting the other macro-like switches that actually make sense being there.这还不包括其他真正有意义的类似宏的开关。

Just to be clear, I do know that I can load these textures into GPU memory as 4-channel greyscale textures, and go from there.明确一点,我知道我可以将这些纹理作为 4 通道灰度纹理加载到 GPU memory,然后从那里加载到 go。 But doing that uses 4X the memory, and I would rather load in 3 more textures.但是这样做会使用 4X memory,我宁愿再加载 3 个纹理。

In OpenGL there's two ways to achieve what you're looking for:OpenGL中,有两种方法可以实现您要查找的内容:

  1. Legacy: The INTENSITY and LUMINANCE texture formats will when sampled result in vec4(I,I,I,I) or vec4(L,L,L,1) .旧版: INTENSITYLUMINANCE纹理格式将在采样时产生vec4(I,I,I,I)vec4(L,L,L,1)
  2. Modern: Use a swizzle mask to apply user defined channel swizzling per texture: glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, {GL_RED,GL_RED,GL_RED,GL_ONE});现代:使用调配蒙版对每个纹理应用用户定义的通道调配: glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, {GL_RED,GL_RED,GL_RED,GL_ONE});

In DirectX 12 you can use component mapping during the creation of a ShaderResourceView .DirectX 12中,您可以在创建ShaderResourceView期间使用组件映射

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM