You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

HLSL DirectX问题:像素着色器颜色生成异常

HLSL线段颜色渐变问题:方案1失效原因解析

问题场景

通过SV_VertexID索引颜色表生成3条线段,预期每条线段两个顶点颜色不同,中段实现颜色渐变。实际测试结果:

  • 方案2可行:顶点着色器(VS)中从颜色表获取对应顶点的颜色,传递给像素着色器(PS)后直接输出,渐变效果正常。
  • 方案1失效:将SV_VertexID传递给PS,在PS中通过该索引从颜色表取色,此时每条线段颜色单一,无渐变效果。

测试代码

static float2 vertices[6] = {
   float2(-0.95f, -0.95f),
   float2(0.95f, 0.95f),
   float2(-0.95f, 0),
   float2(0.95f, 0),
   float2(-0.95f, 0.95f),
   float2(0.95f, -0.95f)
};

static float3 colors[6] = {
   float3(1,0,1), // 紫色
   float3(0,0,1), // 蓝色
   float3(0,1,1), // 青色
   float3(0,1,0), // 绿色
   float3(1,1,0), // 黄色
   float3(1,0,0) // 红色
};

struct Output { 
  float4 pos : SV_POSITION;
  float3 color1 : COLOR;
  uint vID : TEXCOORD0; 
};

//----------------------------------------- 顶点着色器
Output VSMain(uint vID : SV_VertexID) {
   Output v1;
   v1.pos = float4(vertices[vID], 0, 1);
   v1.color1 = colors[vID];
   v1.vID = vID;
   return v1;
}

//----------------------------------------- 像素着色器
float4 PSMain(Output v1) : SV_Target {

   float4 color2 = float4(colors[v1.vID],0); // 方案1:失效
   //float4 color2 = float4(v1.color1,0); // 方案2:可行

   return color2;
}

原因解析

核心逻辑:GPU光栅化的属性插值规则

GPU完成顶点着色器计算后,进入光栅化阶段时,会对不同类型的顶点输出属性执行不同处理:

  • 浮点类型属性(如color1):自动执行线性插值,线段上的每个像素会拿到起点和终点属性值的混合结果,这就是颜色渐变的来源。
  • 整数/无符号整数类型属性(如vID):不会执行插值操作,光栅化时会直接取距离当前像素最近的顶点的整数值,因此PS中拿到的vID只会是线段两个端点的其中一个ID,用它取色自然只能得到单一颜色,无法实现渐变。

方案对比

  • 方案2直接传递浮点类型的颜色值,利用GPU的自动插值特性,完美实现了线段的颜色渐变。
  • 方案1传递的是无符号整数类型的顶点ID,绕过了GPU的插值逻辑,导致无法产生渐变效果。

内容的提问来源于stack exchange,提问作者MarcioAB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 16:54:55