티스토리 뷰

Texture 매핑
var depthTexture: MTLTexture! = nil
let depthTextureDescriptor =
MTLTextureDescriptor.texture2DDescriptor(
pixelFormat: .depth32Float,
width: Int(layerSize.width),
height: Int(layerSize.height),
mipmapped: false)
depthTexture = device.makeTexture(descriptor: depthTextureDescriptor)
※ Texel : Texture의 조각
Mipmapping
MTLBitCommandEncoder
func generateMipmaps(for texture: MTLTexture)
Sampling
Sampler : 좌표계, addressing mode, filtering 등 reading texture와 관련된 렌더 상태를 캡슐화한 객체
Address Modes
음의 좌표를 갖고 있거나 texture의 측정값이 1을 넘을 때 등의 상황에 사용
MTLSamplerAddressMode
- clampToEdge
- mirrorClampToEdge
- repeat
- mirrorRepeat
- clampToZero
- clampToBorderColor

Filters Modes
linear
nearest
Anisotropy
Sampler States
MTLSamplerState
var diffuseTexture: MTLTexture! = nil
var samplerState: MTLSamplerState! = nil
let samplerDescriptor = MTLSamplerDescriptor()
samplerDescriptor.minFilter = .nearest
samplerDescriptor.magFilter = .linear
samplerState = device.makeSamplerState(descriptor: samplerDescriptor)
commandEncoder.setFragmentTexture(diffuseTexture, at: 0)
commandEncoder.setFragmentSamplerState(samplerState, at: 0)
※ GPU를 사용하지 않고 Shader function안에서 sampler를 만들 수도 있다.
Texture와 Sampler를 Graphic Function에 전달
Texture 생성
func textureForImage(_ image:UIImage, device:MTLDevice) -> MTLTexture? {
let imageRef = image.cgImage!
let width = imageRef.width
let height = imageRef.height
let colorSpace = CGColorSpaceCreateDeviceRGB()
let rawData = calloc(height * width * 4,
MemoryLayout<UInt8>.size)
let bytesPerPixel = 4
let bytesPerRow = bytesPerPixel * width
let bitsPerComponent = 8
// Core Graphics
let options = CGImageAlphaInfo.premultipliedLast.rawValue |
CGBitmapInfo.byteOrder32Big.rawValue
let context = CGContext(data: rawData,
width: width,
height: height,
bitsPerComponent: bitsPerComponent,
bytesPerRow: bytesPerRow,
space: colorSpace,
bitmapInfo: options)
context?.draw(imageRef, in: CGRect(x: 0,
y: 0,
width: CGFloat(width),
height: CGFloat(height)))
// MTLTextureDescriptor
let textureDescriptor =
MTLTextureDescriptor.texture2DDescriptor(
pixelFormat: .rgba8Unorm,
width: Int(width),
height: Int(height),
mipmapped: true)
let texture = device.makeTexture(descriptor: textureDescriptor)
let region = MTLRegionMake2D(0, 0, Int(width), Int(height))
texture.replace(region: region,
mipmapLevel: 0,
slice: 0,
withBytes: rawData!,
bytesPerRow: bytesPerRow,
bytesPerImage: bytesPerRow * height)
free(rawData)
return texture
}
diffuseTexture = self.textureForImage(UIImage(named: "bluemarble")!, device: device)
Metal Texture Functions
struct TexturedInVertex
{
packed_float4 position [[attribute(0)]];
packed_float4 normal [[attribute(1)]];
packed_float2 texCoords [[attribute(2)]];
};
struct TexturedColoredOutVertex
{
float4 position [[position]];
float3 normal;
float2 texCoords;
};
struct Uniforms
{
float4x4 projectionMatrix;
float4x4 modelViewMatrix;
};
vertex TexturedColoredOutVertex vertex_sampler(
device TexturedInVertex *vert [[buffer(0)]],
constant Uniforms &uniforms [[buffer(1)]],
uint vid [[vertex_id]])
{
float4x4 MV = uniforms.modelViewMatrix;
float3x3 normalMatrix(MV[0].xyz, MV[1].xyz, MV[2].xyz);
float4 modelNormal = vert[vid].normal;
TexturedColoredOutVertex outVertex;
outVertex.position = uniforms.projectionMatrix *
uniforms.modelViewMatrix * float4(vert[vid].position);
outVertex.normal = normalMatrix * modelNormal.xyz;
outVertex.texCoords = vert[vid].texCoords;
return outVertex;
}
fragment half4 fragment_sampler(
TexturedColoredOutVertex vert [[stage_in]],
texture2d<float, access::sample> diffuseTexture [[texture(0)]],
sampler samplr [[sampler(0)]])
{
float4 diffuseColor = diffuseTexture.sample(samplr, vert.texCoords);
return half4(diffuseColor.r, diffuseColor.g, diffuseColor.b, 1);
}
'iOS > Metal' 카테고리의 다른 글
Metal 좌표계 (0) | 2022.01.26 |
---|---|
Metal: Metal Resources (0) | 2022.01.07 |
Metal: MetalKit (0) | 2022.01.07 |
Metal: Shader (0) | 2022.01.07 |
Metal: MTLTexture to CIImage 변경 시 rgb값 그대로 가져오기 (0) | 2022.01.06 |