[英]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.