DirectX 11 DrawInstanced实例渲染顺序与Alpha混合问题咨询
DirectX 11实例化渲染2D精灵的Alpha混合问题
我尝试用DirectX 11的实例化技术渲染带Alpha通道的2D精灵(每个精灵包含4个顶点),发现使用DrawInstanced时,图元顺序会影响Alpha混合的渲染结果。
相关代码实现
输入布局定义
D3D11_INPUT_ELEMENT_DESC ied[] = { // vertex buffer {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, // instance buffer { "INSTANCEPOS", 0, DXGI_FORMAT_R32G32B32_FLOAT, 1, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_INSTANCE_DATA, 1}, { "TEXTUREID", 0, DXGI_FORMAT_R32_FLOAT, 1, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_INSTANCE_DATA, 1} };
顶点着色器代码
cbuffer CB_Matrix : register(b0) { matrix g_matrix; }; cbuffer CB_Position : register(b1){ float2 cb_position; }; struct VOut { float4 position : SV_POSITION; float2 uv : TEXCOORD0; float textureID : TEXTUREID; }; VOut VShader(float4 position : POSITION, float2 uv : TEXCOORD0, float3 instancePos : INSTANCEPOS, float textureID : TEXTUREID) { VOut output; float4x4 translate = { 1, 0, 0, cb_position.x, 0, 1, 0, cb_position.y, 0, 0, 1, 0, 0, 0, 0, 1 }; position += float4(instancePos, 0.0f); output.position = mul(translate, position); output.position = mul(g_matrix, output.position); output.uv = uv; output.textureID = textureID; return output; }
测试过程与现象
初始测试(Z轴统一为0)
初始化代码将所有实例的Z轴设为0:
for (uint32_t i = 0; i < NUM_INSTANCES; i++) { instances[i].Position.x = spriteData[i].Position.x; instances[i].Position.y = spriteData[i].Position.y; instances[i].Position.z = 0.0f; instances[i].TextureID = spriteData[i].TextureID; }
此时使用DrawInstanced渲染,重叠的精灵Alpha值显示异常。
调整后测试(从后到前设置Z轴)
修改初始化代码,将实例按从后到前排序,Z轴从1.0开始逐次递减0.0001:
float z = 1.0f; for (uint32_t i = 0; i < NUM_INSTANCES; i++) { z -= 0.0001f; instances[i].Position.x = spriteData[i].Position.x; instances[i].Position.y = spriteData[i].Position.y; instances[i].Position.z = z; instances[i].TextureID = spriteData[i].TextureID; }
修改后,重叠精灵的Alpha值显示正常。
疑问
- 这种从后到前排序的方案,能否保证在所有硬件上都解决Alpha混合问题?我未在DirectX文档中找到关于实例顺序的相关说明。
- 如果实例顺序确实重要,是否意味着
DrawInstanced是按顺序逐个渲染实例,类似GPU为每个实例触发一次Draw调用?
内容的提问来源于stack exchange,提问作者Marc Klein
相关产品推荐
相关产品推荐

