Different sampler types for same sample texture unit in fragment shader.

本文记录了一个关于AMD显卡上特定shader出现验证失败的问题及其解决方案。问题表现为使用了特定shader的对象无法正常显示,并提示错误信息。作者通过排查发现,问题与sampler2DShadow类型的采样器有关,在未绑定纹理的情况下会导致此错误。最终通过为所有sampler2DShadow对象显式绑定纹理解决了问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个问题是几个月前碰到的,现象是这样的,N卡和Intel核显上都正常的shader,跑到A卡上就出错了,使用了这个shader的物体不显示,并且提示Validation failed! - Different sampler types for same sample texture unit in fragment shader.在网络上搜索了一下,很多人说是纹理绑定出错了,一张纹理被绑定了多次,经过仔细的排查,我这里可以确定没有出现绑定错误。所以被这个问题卡了很久,好在影响不是很大。

今天又碰到了这个问题,多次测试发现是使用了sampler2DShadow对象之后才出现这个问题的,如果代码里同时使用了sampler2DShadow和sampler2D对象,且都没有绑定纹理的话,就会报这个错误,就算这些纹理的采样语句被跳过不执行,也是一样的报错。

猜测可能sampler2D跟sampler2DShadow对象的默认值是一样的,比如都是0,然后shader编译阶段并没有进行检查,运行时发现不同的采样器要对同一个纹理采样,于是导致了运行错误。

在CPU里面对所有sampler2DShadow对象显式的绑定一个值,有纹理的绑定对应的纹理层,没有纹理的就绑定一个不存在的纹理层,我用的是15. 问题解决,错误不再出现。

我这个shader是一个很大的shader,里面有不同的功能模块,根据需求决定是否启用,所以有些shader代码运行时会被IF跳过,被跳过的模块用到的纹理也就不会进行绑定,我觉得这种做法是很合理的,确定不会使用的纹理为什么还要去绑定一次啊?N卡和Intel核显上能正常运行,就A卡不行,所以这个问题要算是A卡驱动的Bug了。

### Unity Shader 中 `SAMPLE_TEXTURE2D` 的用法示例 在 Unity Shader 中,`SAMPLE_TEXTURE2D` 是一个用于采样二维纹理的内置函数。它通常与资源绑定点相关联,并通过指定的采样器对象进行操作。以下是关于 `SAMPLE_TEXTURE2D` 的详细用法和示例。 #### 1. 基本概念 `SAMPLE_TEXTURE2D` 是 HLSL 中的一个内置函数,用于从绑定到特定槽位的纹理资源中获取像素值。其语法如下: ```hlsl float4 SAMPLE_TEXTURE2D(Texture2D texture, SamplerState sampler, float2 uv); ``` - `Texture2D texture`: 表示要采样的纹理资源。 - `SamplerState sampler`: 定义了如何对纹理进行采样(如过滤模式、寻址模式等)。 - `float2 uv`: 纹理坐标,用于指定采样的位置。 此函数返回一个包含四个分量(RGBA)的浮点数向量[^1]。 #### 2. 示例代码 以下是一个简单的 Unity Shader 片段着色器示例,展示如何使用 `SAMPLE_TEXTURE2D` 进行纹理采样: ```hlsl // 定义输入结构体 struct PS_Input { float4 position : SV_POSITION; float2 texCoord : TEXCOORD0; }; // 定义输出结构体 struct PS_Output { float4 color : SV_TARGET; }; // 绑定纹理和采样器 Texture2D _MainTex : register(t0); SamplerState sampler_MainTex : register(s0); // 片段着色器 PS_Output PS(PS_Input input) { PS_Output output; // 使用 SAMPLE_TEXTURE2D 对纹理进行采样 output.color = _MainTex.Sample(sampler_MainTex, input.texCoord); return output; } ``` 在上述代码中,`_MainTex.Sample(sampler_MainTex, input.texCoord)` 调用了 `SAMPLE_TEXTURE2D` 函数,从绑定到 `t0` 的纹理资源中采样,并使用 `s0` 中定义的采样器状态[^2]。 #### 3. 初始化和设置 为了在 Unity 中使用 `SAMPLE_TEXTURE2D`,需要确保纹理和采样器正确绑定到着色器资源视图(SRV)和采样器状态对象。Unity 提供了一个简化的工作流来实现这一点。例如,可以通过 `Properties` 块定义纹理资源: ```hlsl Properties { _MainTex ("Texture", 2D) = "white" {} } ``` 在此定义中,`_MainTex` 是一个可以被材质引用的纹理资源。Unity 自动处理纹理的加载和绑定过程[^3]。 #### 4. 注意事项 - 确保纹理资源已正确加载并绑定到着色器资源视图(SRV)。 - 采样器状态应根据需求配置,例如线性过滤或最近邻过滤[^4]。 - 在低性能设备上,建议减少纹理分辨率并采取其他优化措施以避免内存问题[^5]。 #### 5. 相关扩展 如果需要更复杂的纹理采样操作,可以考虑使用 `Load` 或 `Gather` 函数替代 `Sample`。这些函数提供了更高的灵活性,但可能需要手动实现某些采样逻辑[^6]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值