पर UINT8 घटक प्रकार के साथ बनावट बनावट मेरे पास एक छवि है जिसे मैं प्रोग्रामेटिक रूप से उत्पन्न करता हूं और मैं इस छवि को एक गणना शेडर को बनावट के रूप में भेजना चाहता हूं। जिस तरह से मैं इस छवि को उत्पन्न करता हूं वह यह है कि मैं प्रत्येक आरजीबीए घटकों की गणना UInt8
मानों के रूप में करता हूं, और उन्हें UInt32
में जोड़ता हूं और इसे छवि के बफर में संग्रहीत करता हूं। मैं कोड का निम्न भाग के साथ ऐसा कर:धातु कंप्यूट शेडर
guard let cgContext = CGContext(data: nil,
width: width,
height: height,
bitsPerComponent: 8,
bytesPerRow: 0,
space: CGColorSpaceCreateDeviceRGB(),
bitmapInfo: RGBA32.bitmapInfo) else {
print("Unable to create CGContext")
return
}
guard let buffer = cgContext.data else {
print("Unable to create textures")
return
}
let pixelBuffer = buffer.bindMemory(to: RGBA32.self, capacity: width * height)
let heightFloat = Float(height)
let widthFloat = Float(width)
for i in 0 ..< height {
let latitude = Float(i + 1)/heightFloat
for j in 0 ..< width {
let longitude = Float(j + 1)/widthFloat
let x = UInt8(((sin(longitude * Float.pi * 2) * cos(latitude * Float.pi) + 1)/2) * 255)
let y = UInt8(((sin(longitude * Float.pi * 2) * sin(latitude * Float.pi) + 1)/2) * 255)
let z = UInt8(((cos(latitude * Float.pi) + 1)/2) * 255)
let offset = width * i + j
pixelBuffer[offset] = RGBA32(red: x, green: y, blue: z, alpha: 255)
}
}
let coordinateConversionImage = cgContext.makeImage()
जहां RGBA32
एक छोटे से struct कि स्थानांतरण और UInt32
मूल्य बनाने करता है। यह छवि ठीक हो गई है क्योंकि मैं इसे UIImage
में परिवर्तित कर सकता हूं और इसे अपनी फोटो लाइब्रेरी में सहेज सकता हूं।
समस्या उत्पन्न होती है जब मैं इस छवि को एक गणना शेडर को बनावट के रूप में भेजने की कोशिश करता हूं। नीचे मेरी शेडर कोड है:
kernel void updateEnvironmentMap(texture2d<uint, access::read> currentFrameTexture [[texture(0)]],
texture2d<uint, access::read> coordinateConversionTexture [[texture(1)]],
texture2d<uint, access::write> environmentMap [[texture(2)]]
uint2 gid [[thread_position_in_grid]])
{
const uint4 pixel = {255, 127, 63, 255};
environmentMap.write(pixel, gid);
}
इस कोड के साथ समस्या यह है कि मेरी बनावट के प्रकार uint
है, जो कि 32-बिट, और मैं 32-बिट पिक्सल उसी तरह मैं पर क्या उत्पन्न करना चाहते है सीपीयू, 4 8-बिट मानों को जोड़कर। हालांकि, मैं धातु पर ऐसा नहीं कर सकता क्योंकि byte
प्रकार है कि मैं सिर्फ एक साथ जोड़ सकता हूं और uint32
बना सकता हूं। तो, मेरा सवाल यह है कि 2 डी बनावट को संभालने और मेटल कंप्यूट शेडर पर 32-बिट पिक्सेल सेट करने का सही तरीका क्या है?
बोनस प्रश्न: इसके अलावा, मैंने इनपुट बनावट प्रकार के रूप में texture2d<float, access::read>
के साथ उदाहरण शेडर कोड देखे हैं। मुझे लगता है कि यह 0.0 और 1.0 के बीच एक मान का प्रतिनिधित्व करता है लेकिन 0 और 255 के बीच मूल्यों के साथ एक असाइन किए गए int पर इसका क्या लाभ है?
संपादित करें: स्पष्टीकरण के लिए, शेडर के आउटपुट बनावट, environmentMap
, इनपुट बनावट के समान सटीक गुण (चौड़ाई, ऊंचाई, पिक्सेलफॉर्मैट, आदि) है। मुझे लगता है कि यह काउंटर अंतर्ज्ञानी है कि हम uint4
को एक पिक्सेल के रूप में सेट कर रहे हैं, जिसका अर्थ है कि यह 4 32-बिट मानों से बना है, जबकि प्रत्येक पिक्सेल 32-बिट होना चाहिए। इस वर्तमान कोड के साथ, {255, 127, 63, 255}
का सटीक परिणाम {2550, 127, 63, 255}
है, जिसका अर्थ यह है कि आउटपुट बनावट में लिखे जाने से पहले मानों को 0-255 के बीच क्लैंप किया जाता है। लेकिन यह बेहद प्रतिद्वंद्वी है।
धन्यवाद वॉरेन, इसने कई चीजों को मंजूरी दे दी। इसके अलावा, अगर कोई इस पर और जानकारी चाहता है, तो धातु छायांकन भाषा विशिष्टता के अध्याय 7.7 बनावट का पता लगाने और रूपांतरण नियम देखने के लिए जगह है। – halileohalilei