Совершенно уверен, что у меня это работает.
Свифт-код для установки MTLTexture
и установки его в SCNTechnique
.
let tech:SCNTechnique = getTechnique()
let textureLoader = MTKTextureLoader(device: MTLCreateSystemDefaultDevice()!)
let filePath = Bundle.main.url(forResource: "gradient", withExtension: "png")!
do {
let gradTexture: MTLTexture = try textureLoader.newTexture(URL: filePath, options: nil)
let matPropTexture = SCNMaterialProperty(contents: gradTexture)
tech.setObject(matPropTexture, forKeyedSubscript: "myTexture" as NSCopying)
} catch {
print("Unexpected error: \(error).")
}
scnView.technique = tech
gradient.png
- 256 x 1pxцветовой градиент (синий -> зеленый -> красный) изображение, которое я использую для отображения одного значения в псевдоцвет.(например; )
Вот полное определение прохода техники из проходов, заданных в моем списке.
<key>mix_outline</key>
<dict>
<key>draw</key>
<string>DRAW_QUAD</string>
<key>metalVertexShader</key>
<string>pass_through_vertex</string>
<key>metalFragmentShader</key>
<string>mix_outline_fragment</string>
<key>inputs</key>
<dict>
<key>colorSampler</key>
<string>color_scene</string>
<key>depthSampler</key>
<string>depth_outline</string>
<key>myTextureSampler</key>
<string>myTexture</string>
</dict>
<key>outputs</key>
<dict>
<key>color</key>
<string>COLOR</string>
</dict>
</dict>
myTexture
необходимо определить враздел символов в технике plist также.
<key>symbols</key>
<dict>
<key>myTexture</key>
<dict>
<key>type</key>
<string>sampler2D</string>
</dict>
</dict>
Я также видел сообщение об ошибке «У прохода нет памяти для ввода myTextureSampler», когда этот блок символов не был включен. Это может быть вашей проблемой?
И, наконец, определение фрагментного шейдера.
fragment half4 mix_outline_fragment(out_vertex_t vert [[stage_in]],
texture2d<float, access::sample> colorSampler [[texture(0)]],
texture2d<float, access::sample> depthSampler [[texture(1)]],
texture2d<float, access::sample> myTextureSampler [[texture(2)]])
{
float4 myTextureColor = myTextureSampler.read(uint2(55, 0));
float4 outline = depthSampler.sample( s, vert.uv);
float4 scene_color = colorSampler.sample( s, vert.uv);
// float4 fragment_color = mix(scene_color, float4(0.0, 0.0, 0.0, 0.0), outline.r);
float4 fragment_color = mix(scene_color, myTextureColor, outline.r);
return half4(fragment_color);
}
Есть несколько других проходов, связанных с этой техникой, которые я не включил;просто чтобы дать некоторый контекст, он визуализирует сцену за один проход и использует буфер глубины вывода на другом проходе с оператором Собеля для генерации краев в текстуру depthSampler
.Вышеуказанный шейдер pass + фрагмент рисует эти края поверх оригинального рендеринга сцены.Я использовал сплошной черный цвет для краев, но, посмотрев на это, кажется, что смог прочитать цвет из MTLTexture
, который я предоставляю SCNTechnique
, и использовать его для краев.