金属で 2 つの異なる頂点バッファーを描画しています。1 つはテクスチャを使用 (頂点カラー データを無視) し、もう 1 つはテクスチャを使用せず (純粋に頂点カラー データを描画):
let commandBuffer = self.commandQueue.makeCommandBuffer()
let commandEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: rpd)
//render first buffer with texture
commandEncoder.setRenderPipelineState(self.rps)
commandEncoder.setVertexBuffer(self.vertexBuffer1, offset: 0, at: 0)
commandEncoder.setVertexBuffer(self.uniformBuffer, offset: 0, at: 1)
commandEncoder.setFragmentTexture(self.texture, at: 0)
commandEncoder.setFragmentSamplerState(self.samplerState, at: 0)
commandEncoder.drawPrimitives(type: .triangle, vertexStart: 0, vertexCount: count1, instanceCount: 1)
//render second buffer without texture
commandEncoder.setRenderPipelineState(self.rps)
commandEncoder.setVertexBuffer(self.vertexBuffer2, offset: 0, at: 0)
commandEncoder.setVertexBuffer(self.uniformBuffer, offset: 0, at: 1)
commandEncoder.setFragmentTexture(nil, at: 0)
commandEncoder.drawPrimitives(type: .triangle, vertexStart: 0, vertexCount: count2, instanceCount: 1)
commandEncoder.endEncoding()
commandBuffer.present(drawable)
commandBuffer.commit()
シェーダーは次のようになります。
#include <metal_stdlib>
using namespace metal;
struct Vertex {
float4 position [[position]];
float4 color;
float4 texCoord;
};
struct Uniforms {
float4x4 modelMatrix;
};
vertex Vertex vertex_func(constant Vertex *vertices [[buffer(0)]],
constant Uniforms &uniforms [[buffer(1)]],
uint vid [[vertex_id]])
{
float4x4 matrix = uniforms.modelMatrix;
Vertex in = vertices[vid];
Vertex out;
out.position = matrix * float4(in.position);
out.color = in.color;
out.texCoord = in.texCoord;
return out;
}
fragment float4 fragment_func(Vertex vert [[stage_in]],
texture2d<float> tex2D [[ texture(0) ]],
sampler sampler2D [[ sampler(0) ]]) {
if (vert.color[0] == 0 && vert.color[1] == 0 && vert.color[2] == 0) {
//texture color
return tex2D.sample(sampler2D, float2(vert.texCoord[0],vert.texCoord[1]));
}
else {
//color color
return vert.color;
}
}
これを行うより良い方法はありますか?テクスチャを使用したい頂点を黒に設定すると、シェーダーは色が黒かどうかを確認し、黒の場合はテクスチャを使用し、そうでない場合は色を使用します。
また、色付きのポリゴンとテクスチャ付きのポリゴンが画面上で重なっている場合、乗算機能を使用してそれらをブレンドする方法はありますか? MTLBlendOperation には加算/減算/最小/最大のオプションしかなく、乗算はないようですか?