I've been working with ARKit and Metal on the Vision Pro, but I've encountered a slight flickering issue with the mesh rendered using Metal. The flickering tends to occur around the edges of objects or on pixels with high color contrast, and it becomes more noticeable as the distance increases. Is there any way to resolve this issue?
Delve into the world of graphics and game development. Discuss creating stunning visuals, optimizing game mechanics, and share resources for game developers.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Issue Summary:
In our Flutter application, we utilize Tencent's TRTC API for voice and video communication. While the broadcast functionality operates correctly on Android, it fails to respond on iOS devices. Attempting to initiate a broadcast results in no action, and long-pressing the broadcast button does not reveal the broadcast extension.
Steps to Reproduce:
Add Broadcast Upload Extension:
In Xcode, navigate to File > New > Target.
Select Broadcast Upload Extension and add it to the project.
2. Build the Project:
Attempt to build the project.
Encounter the error: "Cycle inside Runner; building could produce unreliable results."
3. Resolve Build Cycle Error:
Go to the project’s Build Phases.
Locate the Embed App Extensions phase.
Move Embed App Extensions just below Copy Bundle Resources.
Ensure the Copy only when installing option is selected.
Rebuild the project; the cycle error is resolved.
4.Test Broadcast Functionality:
Install the app on an iOS device.
Tap the broadcast button; observe no response.
Long-press the broadcast button in the top right hand scroll down menu; the broadcast extension is not listed.
5. Isolate the Issue:
Create a new Flutter project.
Repeat the above steps to add the broadcast upload extension.
The issue persists: broadcast functionality remains unresponsive on iOS.
The code is pretty simple
kernel void naive(
constant RunParams *param [[ buffer(0) ]],
const device float *A [[ buffer(1) ]], // [N, K]
device float *output [[ buffer(2) ]],
uint2 gid [[ thread_position_in_grid ]]) {
uint a_ptr = gid.x * param->K;
for (uint i = 0; i < param->K; i++, a_ptr++) {
val += A[b_ptr];
}
output[ptr] = val;
}
when uint a_ptr = gid.x * param->K, the code got 150 GFLops
when uint a_ptr = gid.y * param->K, the code got 860 GFLops
param->K = 256;
thread per group: [16, 16]
I'd like to understand why the performance is so different, and how can I profile/diagnose this to help with further optimization.
Topic:
Graphics & Games
SubTopic:
Metal
I would like to implement zoom functionality in my SceneKit game: when the user performs the pinch gesture on a point on the screen, the scene zooms in to make that point larger.
Until now I simply changed SCNCamera.focalLength, but this simply zooms in to the center of what is currently visible on screen. Is it somehow possible to implement the zoom functionality described above by perhaps interactively rotating the camera at the same time towards the pinched point? Is there a formula for this? I would like to avoid suddenly rotating the camera to face the pinched point when the pinch gesture begins and then zoom in while the pinch is in progress.
Leaderboard has not worked for past two days. What’s up with that?
Topic:
Graphics & Games
SubTopic:
GameKit
Hi guys! Is there any way to get a frame at certain time? I'm writing plug-in and want to use 2 frames before and 2 frames after current frame in order to render final image.
Topic:
Graphics & Games
SubTopic:
General
I've noticed a major third-party app has the following flag set to 1/true in its Info.plist: CAMetalLayerWantsCompositingDependencies
Does anyone know if it’s recognized by Core Animation / Metal, and what it’s supposed to do? It might obviously have zero relationship to the OS, defined by that app and for that app... but since it looks very much like an unofficial/undocumented environment setting, it might be great to know what problem it solves. I happen to have issues related to compositing other CALayers over a CAMetalLayer in my app... so this definitely stood out as interesting.
Thank you!
Topic:
Graphics & Games
SubTopic:
Metal
This game is where you can play over 100 games and every game is very different and unique and you can save your favorite game over the 100 in store them and you can store over 100 if you like them all make your wildest dreams that you can search up as games and they could have them Youtubers, you can make good videos with this game, the Creator.
:D
Hope you enjoy it also I’m a kid so I don’t know how to make an update.
Topic:
Graphics & Games
SubTopic:
SpriteKit
Hi Friends!
I’m facing an issue with SceneKit.
I’m developing a 3D mobile game. I have a character 3D model and several skeletal animations CAAnimation. I import both the model and the animations from Maya in *.dae format. The character’s animations play continuously one after the other, with each new animation being triggered randomly. The transition between animations makes smoothly by setting the fadeInDuration and fadeOutDuration properties. Here’s an example of the code:
import UIKit import QuartzCore import SceneKit
class TestAnimationController: UIViewController {
var bodyNode: SCNNode?
override func viewDidLoad() {
super.viewDidLoad()
let scnView = SCNView(frame: self.view.bounds)
scnView.backgroundColor = .black // Set your desired background color
scnView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
let scene = SCNScene(named: "art.scnassets/scene/Base_room/ROOM5.scn")!
bodyNode = collada2SCNNode(filepath: "art.scnassets/female/girl_body_races.dae")!
bodyNode?.renderingOrder = 10
scene.rootNode.addChildNode(bodyNode!)
playIdleAnimation()
scnView.scene = scene // Assign the scene to the SCNView
self.view.addSubview(scnView) // Add the SCNView to your main view)
}
func collada2SCNNode(filepath:String) -> SCNNode? { if let scene = SCNScene(named: filepath) { let node = scene.rootNode.childNodes[0] return node } else { return nil } }
func playIdleAnimation() {
let array = [
"art.scnassets/female/animations/idle/girl_idle_4.dae",
"art.scnassets/female/animations/idle/girl_idle1.dae",
"art.scnassets/female/animations/idle/girl_idle2.dae",
"art.scnassets/female/animations/idle/Girl_idle3.dae",
]
let animation = CAAnimation.animationWithSceneNamed(array.randomElement() ?? "")!
self.setAnimationAdd(
fadeInDuration: 1.0,
fadeOutDuration: 1.0,
keyTime: 0.99,
animation,
isLooped: false
) { [weak self] in
guard let self = self else { return }
try? self.playBoringAnimations()
}
}
func playBoringAnimations() {
let array = [
"art.scnassets/female/animations/boring/girl_boring1.dae",
"art.scnassets/female/animations/boring/girl_boring2.dae",
"art.scnassets/female/animations/boring/girl_boring3.dae",
"art.scnassets/female/animations/boring/girl_boring4.dae",
"art.scnassets/female/animations/boring/girl_boring5.dae",
"art.scnassets/female/animations/boring/girl_boring6.dae",
"art.scnassets/female/animations/boring/girl_boring8.dae"
]
let animation = CAAnimation.animationWithSceneNamed(array.randomElement() ?? "")!
self.setAnimationAdd(
fadeInDuration: 1.0,
fadeOutDuration: 1.0,
keyTime: 0.99,
animation,
isLooped: false
) { [weak self] in
guard let self = self else { return }
try? self.playIdleAnimation()
}
}
func setAnimationAdd(fadeInDuration : CGFloat, fadeOutDuration : CGFloat, keyTime : CGFloat, _ animation: CAAnimation, isLooped: Bool, completion: (() -> Void)?) {
animation.fadeInDuration = fadeInDuration
animation.fadeOutDuration = fadeOutDuration
if !isLooped {
animation.repeatCount = 1
} else {
animation.repeatCount = Float.greatestFiniteMagnitude
}
animation.animationEvents = [
SCNAnimationEvent(keyTime: keyTime, block: { _, _, _ in completion?() })
]
bodyNode?.addAnimation(animation, forKey: "avatarAnimation")
}
}
Everything worked perfectly until I updated to iOS 18. On a physical device, the animations now transition abruptly without the smooth blending that was present in earlier iOS versions. The switch between them is very noticeable, as if the fadeInDuration and fadeOutDuration parameters are being ignored.
However, in the iOS 18 simulator, the animations still transition smoothly as before.
Here two example videos - IOS 17.5 and IOS 18 https://youtube.com/shorts/jzoMRF4skAQ - IOS 17,5 smooth https://youtube.com/shorts/VJXrZzO9wl0 - IOS 18 not smooth
I try this code in IOS 17.5, everything works fine
Does anyone have any ideas on how to fix this issue?
Topic:
Graphics & Games
SubTopic:
SceneKit
Tags:
Games
Core Animation
Graphical Debugger
Visual Design
Hello everyone and thank you for you're time!
I got an issue with uploading several icons to testflight. I'm using Game Maker Studio as my engine for the game.
This is the error that I'm getting, even when I try to use the old icons for the game, that worked in the past. I tried to transform the icons, using this site "https://makeappicon.com/", but I still got the same validation error. Can you help me fixing the issue - thank you so much!
I am trying to use the SVGF denoiser to denoise my ray traced shadows (and also other textures later). I do get a smoothed image, but with wonky denoising.
I need the depth-normal textures and motion textures for the SVGF and assume that these are badly filled in my case. However, neither in the above linked documentation nor in the WWDC19 video I find how they should be defined. I am looking to answers to:
Is depth in red or alpha channel for the depth-normal texture?
Are the normals in screen space?
Is depth linear?
Is it distance or z coordinate in view space? Or even logarithmically scaled or something else?
Are the motion vectors supposed to be in pixels per frame?
What is the orientation of the axis? Is y up or down?
Are there are other restrictions on the formats?
Also the linked code did not help me (I have not found any SVGF so far; also all the code is in Objective-C++, not Swift, but that's a different topic).
So how should I fill these textures.
Can someone point me to the documentation where these kinds of questions are answered?
Hello,
MacOS 26 Betas are limiting games (noticeably, games that use java) to the native display of the MacBook Pro (120hz). Even connecting an external display this is not changing. I have submitted a bug report, but I have not had any responses to it yet. I am looking to see if anyone may have an answer or fix to this issue.
Thanks!
Topic:
Graphics & Games
SubTopic:
General
Hi team, I'm looking for the RealityKit debugger in Xcode 26 beta 3. I'm running a RealityKit app on my iPad running iPadOS 26 b3, but the debugger option is not there in Xcode.
I have really enjoyed looking through the code and videos related to Metal 4. Currently, my interest is to update a ReSTIR Project and take advantage of more robust ways to refit acceleration Structures and more powerful ways to access resources.
I am working in Swift and have encountered a couple of puzzles:
What is the 'accepted' way to create a MTL4BufferRange to store indices and vertices?
How do I properly rewrite Swift code to build and compact an Acceleration Structure?
I do realize that this is all in Beta and will happily look through Code Samples this Fall. If other guidance is available earlier, that would be fabulous!
Thank you
I facing to many lags in pubgmobile when i m playing its not running properly
Hello, I'm tracking down a bug where useResource doesn't seem to apply proper synchronization when a resource is produced by the render pass then consumed by the compute pass, but when I use MTLFence between the to signal and wait between the render/compute encoders, the artifact goes away.
The resource is created with MTLHazardTrackingModeTracked and useResource is called on the compute encoder after the render pass. Metal API Validation doesn't report any warnings/errors.
Am I misunderstanding the difference between the two APIs? I dug through the Metal documentation and it looks like useResource should handle synchronization given the resource has MTLHazardTrackingModeTracked but on the other hand, MTLFence should be used to ensure proper synchronization between command encoders. Can someone can clarify the difference between the two APIs and when to use them.
The welcome banner is off the top left side of the screen instead of coming down the center. This behavior is encountered when running my iOS application on macOS.
Hello I trying to implement authentication via apple services in unity game with server made as another unity app On client side I succesfully got teamPlayerID signature salt timestamp publicKeyUrl According to this documentation https://developer.apple.com/documentation/gamekit/gklocalplayer/fetchitems(foridentityverificationsignature:)?language=objc
I have to
Verify with the appropriate signing authority that Apple signed the public key.
As I said my server is special build of unity project So now I have this kind of C# programm to check apple authority over public certificate i got from publicKeyUrl
TextAsset textAsset;
byte[] bytes;
textAsset = Resources.Load<TextAsset>("AppleRootCA-G3");
bytes = textAsset.bytes;
rootCert.ChainPolicy.ExtraStore.Add(new X509Certificate2(bytes));
textAsset = Resources.Load<TextAsset>("AppleRootCA-G2");
bytes = textAsset.bytes;
rootCert.ChainPolicy.ExtraStore.Add(new X509Certificate2(bytes));
textAsset = Resources.Load<TextAsset>("AppleIncRootCertificate");
bytes = textAsset.bytes;
rootCert.ChainPolicy.ExtraStore.Add(new X509Certificate2(bytes));
rootCert.Build(cert);
Where cert is X509Certificate2 object I ge from publicKeyUrl
AppleIncRootCertificate AppleRootCA-G2 AppleRootCA-G3 is certificates I got from https://www.apple.com/certificateauthority/
But it is not work Anytime rootCert.Build(cert); return false Why it is not work? May be I build keychain using wrong root CA cert? Or whole approach incorrect? Please help
I'm trying to add support to PS5 DualSense controller.
when I try to use the API from here:
https://developer.apple.com/documentation/gamecontroller/gcdualsenseadaptivetrigger?language=objc
None of the API works, am I missed anything?
The code is like this:
if ( [ controller.extendedGamepad isKindOfClass:[ GCDualSenseGamepad class ] ] )
{
GCDualSenseGamepad * dualSenseGamePad = ( GCDualSenseGamepad * )controller.extendedGamepad;
auto funcSetEffectTrigger = []( TriggerEffectParams& params, GCDualSenseAdaptiveTrigger *trigger ) {
if ( params.m_mode == TriggerEffectMode::Off )
{
[ trigger setModeOff ];
NSLog(@"setModeOff trigger.mode:%d", trigger.mode );
}
else if ( params.m_mode == TriggerEffectMode::Feedback )
{
[ trigger setModeFeedbackWithStartPosition: 0.2f resistiveStrength: 0.5f ];
}
else if ( params.m_mode == TriggerEffectMode::Weapon )
{
[ trigger setModeWeaponWithStartPosition: 0.2f endPosition: 0.4f resistiveStrength: 0.5f ];
}
else if ( params.m_mode == TriggerEffectMode::Vibration )
{
[ trigger setModeVibrationWithStartPosition: position amplitude: amplitude frequency: frequency ];
}
};
if ( L2 )
{
funcSetEffectTrigger( params, dualSenseGamePad.leftTrigger );
}
if ( R2 )
{
funcSetEffectTrigger( params, dualSenseGamePad.rightTrigger );
}
}
I've also tested to add "Game Controllers" capability to Target, still not working.
Can't find anything else from the document or forums.
I've no idea what need to do.
Hey, I've been struggling with this for some days now.
I am trying to write to a sparse texture in a compute shader. I'm performing the following steps:
Set up a sparse heap and create a texture from it
Map the whole area of the sparse texture using updateTextureMapping(..)
Overwrite every value with the value "4" in a compute shader
Blit the texture to a shared buffer
Assert that the values in the buffer are "4".
I have a minimal example (which is still pretty long unfortunately).
It works perfectly when removing the line heapDesc.type = .sparse.
What am I missing? I could not find any information that writes to sparse textures are unsupported. Any help would be greatly appreciated.
import Metal
func sparseTexture64x64Demo() throws {
// ── Metal objects
guard let device = MTLCreateSystemDefaultDevice()
else { throw NSError(domain: "SparseNotSupported", code: -1) }
let queue = device.makeCommandQueue()!
let lib = device.makeDefaultLibrary()!
let pipeline = try device.makeComputePipelineState(function: lib.makeFunction(name: "addOne")!)
// ── Texture descriptor
let width = 64, height = 64
let format: MTLPixelFormat = .r32Uint // 4 B per texel
let desc = MTLTextureDescriptor()
desc.textureType = .type2D
desc.pixelFormat = format
desc.width = width
desc.height = height
desc.storageMode = .private
desc.usage = [.shaderWrite, .shaderRead]
// ── Sparse heap
let bytesPerTile = device.sparseTileSizeInBytes
let meta = device.heapTextureSizeAndAlign(descriptor: desc)
let heapBytes = ((bytesPerTile + meta.size + bytesPerTile - 1) / bytesPerTile) * bytesPerTile
let heapDesc = MTLHeapDescriptor()
heapDesc.type = .sparse
heapDesc.storageMode = .private
heapDesc.size = heapBytes
let heap = device.makeHeap(descriptor: heapDesc)!
let tex = heap.makeTexture(descriptor: desc)!
// ── CPU buffers
let bytesPerPixel = MemoryLayout<UInt32>.stride
let rowStride = width * bytesPerPixel
let totalBytes = rowStride * height
let dstBuf = device.makeBuffer(length: totalBytes, options: .storageModeShared)!
let cb = queue.makeCommandBuffer()!
let fence = device.makeFence()!
// 2. Map the sparse tile, then signal the fence
let rse = cb.makeResourceStateCommandEncoder()!
rse.updateTextureMapping(
tex,
mode: .map,
region: MTLRegionMake2D(0, 0, width, height),
mipLevel: 0,
slice: 0)
rse.update(fence) // ← capture all work so far
rse.endEncoding()
let ce = cb.makeComputeCommandEncoder()!
ce.waitForFence(fence)
ce.setComputePipelineState(pipeline)
ce.setTexture(tex, index: 0)
let threadsPerTG = MTLSize(width: 8, height: 8, depth: 1)
let tgCount = MTLSize(width: (width + 7) / 8,
height: (height + 7) / 8,
depth: 1)
ce.dispatchThreadgroups(tgCount, threadsPerThreadgroup: threadsPerTG)
ce.updateFence(fence)
ce.endEncoding()
// Blit texture into shared buffer
let blit = cb.makeBlitCommandEncoder()!
blit.waitForFence(fence)
blit.copy(
from: tex,
sourceSlice: 0,
sourceLevel: 0,
sourceOrigin: MTLOrigin(x: 0, y: 0, z: 0),
sourceSize: MTLSize(width: width, height: height, depth: 1),
to: dstBuf,
destinationOffset: 0,
destinationBytesPerRow: rowStride,
destinationBytesPerImage: totalBytes)
blit.endEncoding()
cb.commit()
cb.waitUntilCompleted()
assert(cb.error == nil, "GPU error: \(String(describing: cb.error))")
// ── Verify a few texels
let out = dstBuf.contents().bindMemory(to: UInt32.self, capacity: width * height)
print("first three texels:", out[0], out[1], out[width]) // 0 1 64
assert(out[0] == 4 && out[1] == 4 && out[width] == 4)
}
Metal shader:
#include <metal_stdlib>
using namespace metal;
kernel void addOne(texture2d<uint, access::write> tex [[texture(0)]],
uint2 gid [[thread_position_in_grid]])
{
tex.write(4, gid);
}