简体   繁体   中英

Blend multiple MTLTextures

I'm trying to figure out the best way to handle multiple textures layered on top of each other in Metal. The objective is to have the following features:

  • Many textures layered. (10 to 20)
  • Position/Scale control of each texture.
  • Blend mode support for each texture - (screen, multiply, etc.), so opacity would be required.

Think of it like your layer tree in photoshop.

I've started this project and have one layer working well - but it's not clear what the most performant way would be to handle the multiple layers in metal shaders. My first thought was to pass an array of textures in the fragment function as well as an array of the associated position/scale mappings, but not sure if that's the right path? How would blending work in that scenario?

Thanks in advance!

EDIT 5/5/21

I don't have it 100% working yet, but I do have two textures layered with each other. It's definitely rough and not ideal - but sorta shows what I'm after. I feel like this all might not want to live on a single fragment function? If each layer has a different blend mode set this could get messy. It's also fixed to only two textures currently.

typedef struct {
    float4 pos [[position]];
    float2 texCoords;
} RasterizerData;

typedef struct {
    simd_float2 pos;
    simd_float2 scale;
} FragmentPosition;

fragment float4
defaultFragmentShader(RasterizerData in [[stage_in]],
                      constant array<FragmentPosition, 2> &texCoordsScales [[buffer(0)]],
                      array<texture2d<float, access::sample>, 2> texture [[texture(0)]]) {
    
    constexpr sampler samplr(filter::linear,
                             mag_filter::linear,
                             min_filter::linear,
                             coord::pixel,
                             address::clamp_to_zero);
    
    float4 color1 = texture[0].sample(samplr, in.texCoords * (1 / texCoordsScales[0].scale) - texCoordsScales[0].pos);
    float4 color2 = texture[1].sample(samplr, in.texCoords * (1 / texCoordsScales[1].scale) - texCoordsScales[1].pos);
    return mix(color1, color2, 0.5);
   
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM