簡體   English   中英

iOS Metal API在體積內繪制3d紋理

[英]iOS Metal API draw 3d texture inside the volume

因此,我正在嘗試渲染具有3d紋理的多維數據集。 紋理包含3片3種不同的顏色,紅色,綠色和藍色。 每個切片由具有相同顏色的4個像素組成。 工作正常。 https://imgur.com/a/a5oXi

private func makeTexture() {
    let width = 2
    let height = 2
    let depth = 3
    let byteSize = 4
    let bytesPerRow = byteSize * width
    let bytesPerImage = bytesPerRow * height
    let blue: UInt32 = 0x000000FF
    let green: UInt32 = 0xFF00FF00
    let red: UInt32 = 0x00FF0000

    let textureDescriptor = MTLTextureDescriptor()
    textureDescriptor.pixelFormat = .bgra8Unorm
    textureDescriptor.width = width
    textureDescriptor.height = height
    textureDescriptor.depth = depth
    textureDescriptor.textureType = .type3D

    let image = UnsafeMutableRawPointer.allocate(bytes: width*height*depth*byteSize, alignedTo: 1)
    image.storeBytes(of: red, toByteOffset: 0, as: UInt32.self) 
    image.storeBytes(of: red, toByteOffset: 4, as: UInt32.self)
    image.storeBytes(of: red, toByteOffset: 8, as: UInt32.self)
    image.storeBytes(of: red, toByteOffset: 12, as: UInt32.self)

    image.storeBytes(of: green, toByteOffset: 16, as: UInt32.self)
    image.storeBytes(of: green, toByteOffset: 20, as: UInt32.self)
    image.storeBytes(of: green, toByteOffset: 24, as: UInt32.self)
    image.storeBytes(of: green, toByteOffset: 28, as: UInt32.self)

    image.storeBytes(of: blue, toByteOffset: 32, as: UInt32.self)
    image.storeBytes(of: blue, toByteOffset: 36, as: UInt32.self)
    image.storeBytes(of: blue, toByteOffset: 40, as: UInt32.self)
    image.storeBytes(of: blue, toByteOffset: 44, as: UInt32.self)

    texture = device?.makeTexture(descriptor: textureDescriptor)

    let region = MTLRegionMake3D(0, 0, 0, width, height, depth)
    texture?.replace(region: region,
                     mipmapLevel: 0,
                     slice: 0,
                     withBytes: image,
                     bytesPerRow: bytesPerRow,
                     bytesPerImage: bytesPerImage)
}

片段着色器代碼:

struct VertexOut{
float4 position [[position]];
float3 textureCoordinate;
};

fragment half4 basic_fragment(VertexOut in [[stage_in]],
                          texture3d<half> colorTexture [[ texture(0) ]]) {

    constexpr sampler textureSampler (mag_filter::nearest,
                                  min_filter::nearest);

    // Sample the texture to obtain a color
    const half4 colorSample = colorTexture.sample(textureSampler, in.textureCoordinate);

    // We return the color of the texture
     return colorSample;
}

然后我想使紅色和藍色切片透明,所以我將alpha設置為0

 let blue: UInt32 = 0x000000FF
 let green: UInt32 = 0xFF00FF00
 let red: UInt32 = 0x00FF0000

片段着色器現在包含

const half4 colorSample = colorTexture.sample(textureSampler, in.textureCoordinate);
if (colorSample.a <= 0)
   discard_fragment();

並期望看到帶有綠色的切口,但我只看到綠色的邊緣https://imgur.com/a/yGQdQ

多維數據集內部沒有任何內容,而且我甚至看不到后邊緣,因為cullMode設置為.front。

我可以繪制並看到對象內的紋理,以便可以看到其內部嗎? 到目前為止,我還沒有找到辦法。 當我將紋理類型設置為3d時,不是應該為3D對象的每個像素計算顏色嗎? 不只是邊緣? 也許可以,但是不顯示?

不,3D紋理無法幫助您。

沒有3D對象,只有三角形(您提供)。 盡管它們位於3D空間中,但它們是2D對象。 Metal不會通過告訴您要繪制的三角形來推斷您要繪制的實體。 沒有通用的3D繪圖API可以做到這一點。 通常這是不可能的。 除其他事項外,請記住,您甚至不必將所有三角形都賦予Metal。 他們可以分為平局。

據Metal所知,任何物體都沒有“內部”,只有點,線和三角形。 如果要渲染對象的內部,則必須對其建模。 對於一個立方體的切片,您必須計算“暴露於內部”的新表面,並將三角形傳遞給Metal進行繪制。

3D紋理只是可以使用3D坐標采樣的紋理。 請注意,在繪制片段着色器之前已經做出了有關繪制哪些片段的決定,Metal甚至不知道在做出這些決定時會使用3D紋理。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM