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

DX11中如何设置着色器实现部分物体纯色部分纹理渲染?

实现同一场景中纯色与纹理物体共存的渲染方案(Windows 10 SDK)

我之前用Windows 10 SDK做3D渲染的时候也碰到过这个问题——网上教程大多只讲单一渲染模式,很少提混合场景的实现。其实不用纠结只能二选一,有两种靠谱的方案可以实现,我给你拆解清楚:

方案一:通用着色器(推荐,减少状态切换开销)

这种方案是把颜色和纹理坐标都整合到着色器结构体里,通过一个控制标记来动态选择渲染模式,不用频繁切换着色器。

1. 着色器结构体定义

把两种顶点属性都包含进去,这样不管是纯色还是纹理物体,都能共用一套输入输出:

// 顶点输入结构体:包含位置、顶点颜色、纹理坐标
struct VertexIn {
    float4 Pos : POSITION;
    float4 Color : COLOR;
    float2 Tex : TEXCOORD0;
};

// 顶点输出结构体:传递裁剪空间位置、顶点颜色、纹理坐标到像素着色器
struct VertexOut {
    float4 Pos : SV_POSITION;
    float4 Color : COLOR;
    float2 Tex : TEXCOORD0;
};

2. 顶点着色器实现

顶点着色器的工作就是完成坐标变换,同时把颜色和纹理坐标原封不动传递给像素着色器:

// 常量缓冲区:存放世界/视图/投影矩阵
cbuffer MatrixBuffer : register(b0) {
    float4x4 World;
    float4x4 View;
    float4x4 Projection;
};

VertexOut VS(VertexIn input) {
    VertexOut output;

    // 坐标空间转换:本地空间 → 世界空间 → 视图空间 → 裁剪空间
    float4 posWorld = mul(input.Pos, World);
    float4 posView = mul(posWorld, View);
    output.Pos = mul(posView, Projection);

    // 直接传递顶点颜色和纹理坐标
    output.Color = input.Color;
    output.Tex = input.Tex;

    return output;
}

3. 像素着色器实现

通过一个常量缓冲区的标记来决定是用纯色还是采样纹理,同时支持纹理和顶点颜色的混合(比如给纹理加 tint 效果):

// 渲染控制常量缓冲区:标记当前物体的渲染模式
cbuffer RenderControlBuffer : register(b1) {
    int UseTexture; // 0 = 纯色渲染,1 = 纹理渲染
};

// 纹理和采样器资源
Texture2D ObjTexture : register(t0);
SamplerState ObjSampler : register(s0);

float4 PS(VertexOut input) : SV_TARGET {
    if (UseTexture == 1) {
        // 采样纹理,可选和顶点颜色相乘实现颜色叠加
        float4 texColor = ObjTexture.Sample(ObjSampler, input.Tex);
        return texColor * input.Color;
    } else {
        // 直接返回顶点颜色,实现纯色渲染
        return input.Color;
    }
}

4. 渲染流程注意点

  • 渲染纯色物体时:
    • 顶点数据里的纹理坐标可以随便填(比如float2(0,0)),不会影响结果
    • 更新RenderControlBuffer里的UseTexture为0
    • 不需要绑定纹理/采样器(绑定了也没关系,因为逻辑会跳过采样)
  • 渲染纹理物体时:
    • 正确填充顶点的纹理坐标
    • 更新RenderControlBuffer里的UseTexture为1
    • 绑定对应的纹理和采样器资源

方案二:两套独立着色器(适合简单场景)

如果场景里物体类型区分很明确,也可以直接用你给出的两套结构体,分别写对应的着色器,渲染时切换着色器即可:

纯色渲染着色器

struct VertexIn { float4 Pos : POSITION; float4 Color : COLOR; };
struct VertexOut { float4 Pos : SV_POSITION; float4 Color : COLOR; };

cbuffer MatrixBuffer : register(b0) {
    float4x4 World;
    float4x4 View;
    float4x4 Projection;
};

VertexOut VS(VertexIn input) {
    VertexOut output;
    float4 posWorld = mul(input.Pos, World);
    float4 posView = mul(posWorld, View);
    output.Pos = mul(posView, Projection);
    output.Color = input.Color;
    return output;
}

float4 PS(VertexOut input) : SV_TARGET {
    return input.Color;
}

纹理渲染着色器

struct VS_INPUT { float4 Pos : POSITION; float2 Tex : TEXCOORD0; };
struct PS_INPUT { float4 Pos : SV_POSITION; float2 Tex : TEXCOORD0; };

cbuffer MatrixBuffer : register(b0) {
    float4x4 World;
    float4x4 View;
    float4x4 Projection;
};

Texture2D ObjTexture : register(t0);
SamplerState ObjSampler : register(s0);

PS_INPUT VS(VS_INPUT input) {
    PS_INPUT output;
    float4 posWorld = mul(input.Pos, World);
    float4 posView = mul(posWorld, View);
    output.Pos = mul(posView, Projection);
    output.Tex = input.Tex;
    return output;
}

float4 PS(PS_INPUT input) : SV_TARGET {
    return ObjTexture.Sample(ObjSampler, input.Tex);
}

渲染流程注意点

  • 渲染纯色物体时,设置并使用纯色渲染的着色器
  • 渲染纹理物体时,切换到纹理渲染的着色器,同时绑定对应的纹理和采样器

两种方案里,通用着色器的方式更高效,因为减少了着色器切换的状态开销,适合复杂场景;两套着色器更直观,适合简单场景,你可以根据自己的项目需求选择。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:33:39