Swift+Metal 광선 효과

11685 단어 SwiftMetaliOS

Swift+Metal 광선 효과


스위프트+메탈로 발광효과(Unity가 말하는 블룸)를 쉽게 표현하는 수법.
완성형↓

광선 효과를 사용하려면


1. 일반적인 렌더링을 수행합니다.

2. 빛나고 싶은 부분과 색깔의 마스크를 만든다.

3. 마스크에 고스 박사를 덮은 후.

4. 흐릿한 이미지를 일반 표현에 추가합니다.

광선 효과를 표시하는 프로그램


모든 절차가 여기 있다↓
https://github.com/fuziki/metalBloom
・단계 1&2
렌더링 텍스쳐 두 장 준비.
(일반 렌더링 및 마스크에 사용)
MetalEz.swift
func makeRenderTexture() -> MTLTexture {
        let texDesc = MTLTextureDescriptor()
        texDesc.width =  (mtkView.currentDrawable?.texture.width)!
        texDesc.height =  (mtkView.currentDrawable?.texture.height)!
        texDesc.depth = 1
        texDesc.textureType = MTLTextureType.type2D

        texDesc.usage = [MTLTextureUsage.renderTarget, MTLTextureUsage.shaderRead]
        texDesc.storageMode = .private
        texDesc.pixelFormat = .bgra8Unorm

        texDesc.usage = .unknown

        return device.makeTexture(descriptor: texDesc)!
}
MetalEz.swift
        viewRenderTexture = makeRenderTexture()        
        bloomRenderTexture = makeRenderTexture()
부스러기 마스크로 각각 두 텍스쳐에 렌더링과 마스크를 씁니다.
Shaders.metal
struct FragmentOut {
    half4 color0 [[ color(0) ]];
    half4 color1 [[ color(1) ]];
};
fragment FragmentOut fragmentShader(VertexOut in [[stage_in]],
                                    texture2d<half>  diffuseTexture [[ texture(0) ]],
                                    texture2d<half>  bloomTexture [[ texture(1) ]])
{
    constexpr sampler defaultSampler;
    FragmentOut out;
    float lt = saturate(dot(in.normal, lightDirection));
    if (lt < 0.5) lt = 0.5;
    half4 color =  half4(diffuseTexture.sample(defaultSampler, float2(in.texcoord))*lt);
    out.color0 = color;
    if (is_null_texture(bloomTexture)) {
        out.color1 = half4(0,0,0,0);
    } else {
        out.color1 = bloomTexture.sample(defaultSampler, float2(in.texcoord));
    }
    return out;
}
• 단계 3
마스크를 쓰고 고스 패티를 쓰다.MetalPerformanceShader를 사용하여 공격합니다.
소스에 기록된 텍스쳐와 대상에 기록된 텍스쳐가 동일합니다.
MetalEz.swift
            var myTexture: MTLTexture? = bloomRenderTexture
            let kernel = MPSImageGaussianBlur(device: device, sigma: 20.0)
            kernel.encode(commandBuffer: commandBuffer!,
                          inPlaceTexture: &myTexture!, fallbackCopyAllocator: nil)
• 단계 4
일반적인 렌더링 및 효과를 결합합니다.
3단계와 마찬가지로 Metal PerformanceShader를 사용합니다.
계산 결과는'view'이다.currentDrawable?.texture)!'쓰기
(MTLexture는 연산자를 사용하여 전달할 수 없음)
MetalEz.swift
            let addKernel = MPSImageAdd(device: device)
            addKernel.encode(commandBuffer: commandBuffer!,
                             primaryTexture: viewRenderTexture,
                             secondaryTexture: bloomRenderTexture,
                             destinationTexture: (view.currentDrawable?.texture)!)

끝말


MTLTExture 주변에 Tips가 있어서 필요하면 머지않아 총결산(대략)

좋은 웹페이지 즐겨찾기