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

如何从大尺寸D3D12Resource提取指定区域生成640x640资源?

D3D12大尺寸资源截取640x640区域的正确实现方法

针对你需要从任意尺寸D3D12Resource中提取640x640区域(不缩放)的需求,以下两种方案可以解决问题,同时纠正你之前使用视口和裁剪矩形的错误思路:

方案一:通过渲染管线绘制指定区域到目标资源

你之前的错误在于混淆了视口、裁剪矩形的作用:视口负责将顶点NDC坐标映射到渲染目标的像素空间,裁剪矩形仅限制渲染目标上的绘制范围,二者都无法直接选择输入资源的采样区域。正确的做法是让视口匹配目标资源尺寸,通过着色器调整UV来精准采样输入资源的指定区域。

步骤与代码示例

  1. 准备目标资源:创建640x640的D3D12Resource,确保格式与输入资源一致(如DXGI_FORMAT_R8G8B8A8_UNORM),并将其设置为渲染目标。
  2. 设置视口与裁剪矩形:完全匹配目标资源尺寸,确保绘制内容填满整个目标资源:
// 目标资源为640x640,视口和裁剪矩形均对应此尺寸
CD3DX12_VIEWPORT viewport(0.0f, 0.0f, 640.0f, 640.0f);
CD3DX12_RECT scissorRect(0, 0, 640, 640);
pCommandList->RSSetViewports(1, &viewport);
pCommandList->RSSetScissorRects(1, &scissorRect);
  1. 在着色器中调整采样UV:以截取输入资源(640, 0)-(1024, 640)区域为例,计算UV的偏移与缩放系数,精准定位采样范围:
Texture2D inputTex : register(t0);
SamplerState inputSampler : register(s0);

float4 PSMain(float4 pos : SV_POSITION, float2 uv : TEXCOORD0) : SV_TARGET
{
    // 输入资源尺寸为1024x1024,计算目标区域的UV参数
    const float inputWidth = 1024.0f;
    const float inputHeight = 1024.0f;
    const float startX = 640.0f;
    const float startY = 0.0f;
    const float targetWidth = 640.0f;
    const float targetHeight = 640.0f;

    // 转换UV到目标区域范围
    float2 uvOffset = float2(startX / inputWidth, startY / inputHeight);
    float2 uvScale = float2(targetWidth / inputWidth, targetHeight / inputHeight);
    float2 adjustedUV = uv * uvScale + uvOffset;

    return inputTex.Sample(inputSampler, adjustedUV);
}

方案二:使用CopySubresourceRegion直接复制像素区域

如果不需要经过渲染管线处理,直接复制像素区域的性能更高,适合批量切片场景。

步骤与代码示例

  1. 创建目标资源:生成多个640x640的D3D12Resource,将资源状态设置为D3D12_RESOURCE_STATE_COPY_DEST。
  2. 计算源区域坐标:根据输入资源尺寸,确定每个640x640切片的起始坐标(如1024x1024资源可切出(0,0)、(0,640)两个完整切片,剩余区域可按需补黑或忽略)。
  3. 执行复制操作:调用CopySubresourceRegion完成区域复制:
// 输入资源:pInputResource(状态为D3D12_RESOURCE_STATE_COPY_SOURCE)
// 目标资源:pTargetResource(640x640,状态为D3D12_RESOURCE_STATE_COPY_DEST)
// 要截取的源区域起始坐标(startX, startY)
const UINT startX = 0;
const UINT startY = 640;

D3D12_COPY_SUBRESOURCE_REGION copyRegion = {};
copyRegion.srcSubresource = 0;
copyRegion.srcX = startX;
copyRegion.srcY = startY;
copyRegion.srcZ = 0;
copyRegion.dstSubresource = 0;
copyRegion.dstX = 0;
copyRegion.dstY = 0;
copyRegion.dstZ = 0;
copyRegion.Width = 640;
copyRegion.Height = 640;

// 执行区域复制
pCommandList->CopySubresourceRegion(
    pTargetResource, 0,
    0, 0, 0,
    pInputResource, 0,
    &copyRegion
);

// 复制完成后,将目标资源转换为后续需要的状态(如SHADER_RESOURCE)
CD3DX12_RESOURCE_BARRIER barrier = CD3DX12_RESOURCE_BARRIER::Transition(
    pTargetResource,
    D3D12_RESOURCE_STATE_COPY_DEST,
    D3D12_RESOURCE_STATE_SHADER_RESOURCE
);
pCommandList->ResourceBarrier(1, &barrier);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 14:06:01