Summary including updates:
Unity 5 scene using deferred lighting, containing approximately 200 lights spread along 800 units of space.
Most of the lights are point lights, some are spots - the spots work fine.
The point lights cut instantly to dark at around 150-200 units away from the camera.
If large numbers of point lights are moved inside this range they work without issue.
Switching the Render Priority between Auto and Important makes no difference.
If I play a different scene in the editor which allows me to load this scene, it displays correctly! It still does not display correctly when played directly or when running the build.
I've got a basic scene together, which consists of 5 cloned sections of corridor, each with 12 lights, so 60 total.
However, only the first couple of sections show properly, the others are almost completely dark:
(please be kind, I only started this one today :P)
And from the editor, with the end section highlighted to show the distance better:
As you can faintly see, the lights are actually there, just very, very dim:
When you walk down the corridor, they snap to full brightness as you approach.
This is on a build with deferred lighting set, and the pixel light count turned right up, just in case.
I' guessed this might relate to LOD or camera range in some way, but I can't seem to get anything to effect the issue currently.
(This scene is actually based around the lights cutting out and switching to emergency lighting so I really do need to be able to control them!)
UPDATE
The lights you can see are spot lights. The lights that are disappearing are all point lights.
You can just see the spot lights uplighting onto the ceiling in the distance, but the main ceiling lights just go completely dark.
UPDATE 2
I've added a frankly silly number of lights into the scene and extended the corridor, to run some tests.
There are now 24 lights per section, and a total of 8 sections, making 192 lights in all:
I wanted to check if more lights would cut out, and they don't. It seems to be entirely based around range - around 150-200 units in my scene.
To confirm this, I also walked to the center of the tunnel to see if the number of lights visible would effectively double, including ones behind - they do.
I also moved all of the sections close to the camera to confirmed that all the lights can be displayed at once without problems, and this works as well.
UPDATE 3
I have found a situation where the scene displays correctly!
If I press play in the editor on my main menu scene, then press the UI button that loads this scene, it displays correctly!
It still does not display correctly either when playing the scene directly, or when running the final build.
My solution for this problem is (I'm new, but I found this helped):
Go to quality settings
Search for Pixel Light Count
Raise this number to actual number of your lights in your scene.
This parameter establishes number of sources of light which can be displayed at they same time - I think.
Related
Is it possible to do an effect like in the provided picture, where the screen would glitch at certain time intervals? Also, would it be possible if you have many thing going on in the screen(many separate moving parts such as shown below )
local ball
local background
local goal
local scoreTxt
You could take a screen capture of the group, slice it up horizontally and then adjust the x positions slightly between each slice, but this would be a little CPU intensive.
To capture/save the screen:
https://docs.coronalabs.com/api/library/display/capture.html
To import the saved screenshot and slice it up:
https://docs.coronalabs.com/guide/media/imageSheets/index.html
As for the greenish/purple linear effects, you might have to manually pre-create them for each object, and show them before you take a screen capture, then hide them right away.
I want to make a 2 player mode, split screen style, like Tiny Wings HD did where each side of an iPad gets a flipped orientation screen of the current Level.
I wanted to also implement it on tvOS (without the flipped orientation) as I feel TV begs for this sort of gameplay as it's pretty classic to have this style of gameplay on TV (e.g. Mario Kart 64 or Goldeneye).
Over on the Apple Developer forum, someone suggested that it could be done as follows, but, there we're no other responses.
"You can have two views attached to the main window (add a subview in your viewcontroller). To both views you can present a copy of the scene. Then you can exchange game data between scenes via singletons."
I was looking for a more in-depth explanation as I don't exactly understand what the answer is saying.
I'd just like to be able to have two cameras both rendering the same scene but one focusing on player 1 and the other player 2.
Obviously this isn't a simple answer, so I don't expect a full in-depth tutorial.
Unfortunately I could find no info on this.
Has anyone tried this?
A sample project would be ideal or some documentation/links that might help.
I'm sure a demonstration of this would be valuable to quite a lot of people.
No Cameras involved or necessary
The players just look like they're moving along the x axis because the backgrounds are scrolling by. You can allow the players to move up & down on the y axis whether jumping, ducking, rolling or following a path like in Tiny Wings, but the player never leaves their x position. You can even have each half of the screen background scrolling at different speeds to represent that one player is moving faster than the other.
In your update method in you scene file you can scroll your backgrounds, and in your touches methods you can jump, duck etc the players
Instead of using an SKView to present an SKScene, you can use SKRenderer and MTKView. SKRenderer renders a scene into a Metal pipeline, which in turn can be presented by an MTView.
Crucially, you can decide if SKRenderer updates the scene, allowing you to render the same scene frame multiple times (possibly using different cameras).
So a pipeline might look like this:
Apple actually talk about this option in Choosing a SpriteKit Scene Renderer. There's also a section about using SKRenderer in Going Beyond 2D with SpriteKit from WWDC17 which is quite helpful. This answer also shows how to use SKRenderer (albeit in Objective-C).
I've got a scene where a certain number of nodes spawn at the top of the screen and another batch of nodes at the bottom. Now if they collide, I want the game to end which it does, the only problem is that the collision causes a major frame drop or stutter/lag whatever you can think. It basically stops the game for a second and it continues.
The nodes don't have textures. There are no sounds playing when the nodes collide. I've stripped everything down and left just the nodes to collide and the problem persists. I can't point a finger at where it's really coming from since i've left nothing unturned and the scene is not complex 8/9 nodes most at a time.
This doesn't always happen sometimes the nodes collide and everything runs smooth. The only other information i can provide is that the nodes are moving rather fast so they fly in and out of the scene within 0.05 seconds which i tried setting it to a longer duration the problem still persists just more rarely. When the game is over the user has the option to present the scene again which adds the scene from the beginning.
This question leans more toward people who might have had a similar issue , since I don't know what more information I can provide. (Square nodes collide right away the game stops for a second and continues). Thanks.
I'm writing a app using Scenekit where the client wishes to push the limits of animation in IOS. This particular app has requirements where I"m pushing out to the screen over 1,500 redraws. Even with this many redraws, I've locked down the FPS to 60, which is great, but when I add all elements the client wants, the redraws are pushed to 7,500 redraws (and yes, this isn't a mistake or a joke, this is the redraw number even though it's almost 50-80 times more than most redraw times I've seen with scenekit). At this level of redrawing, the screen contains 1.7 million vertices, and around 800k polygons. This is a a lot of stuff, and it's really too much stuff for this app to be useful to anyone because now my FPS drops to 15-30FPS which is expected from drawing over 3K geometry elements on screen. What I've done so far:
I clone all nodes, cloning allows me to push the limits of Scenekit. I was able to fit on screen over 1.5k constant CAAnimations with over 1.8K unique geometries placed in different locations across the screen.
I've forced all windows, views, and screens in app to be opaque by looping through all windows and setting their opaque property to yes.
Question is this, I can deal with the performance issues, but I'm having a problem with the node cloning. Well, the node cloning works, but the problem is that each geometry that is pushed to the screen must have a different size and it seems like there is no way to change the geometry of each separate clone. I know that I can change the geometry of a "copied" node (SCNNode *node = [masterNode copy];), and I know I can change the materials property of a cloned node, but is there a way to change the geometry of the cloned node? Apple doesn't give any insight about the geometry being changed, but they do talk about changing the materials. Am I to assume that I can't change the size of the geometry of the clone? I can change the transform, pivot, rotation, animation, position, etc, of the clone, but the size of the geometry won't change. For my purposes, I just need the "height" variable of a cylinder to be changeable, I have everything else in good order, AND, there's no other way to push over 2k redraws to a screen without node cloning, I've tried it without cloning and FPS drops to less than 10 with just 300 redraws when declaring each geometry and node with geometry as it's own unique variable.
Lastly, given this same scenario, how much of a performance increase should I expect by moving from Scenekit to Metal. I'm not worried about the math, the level of detail, the time consuming operations of setting up the rendering pipeline or whatever else might come my way, I'm merely trying to find the BEST solution for my problem here, and I've not used Metal yet because I'm not sure I'd get different results given how many polygons, vertices, and redraws are required. Thanks.
is there a way to change the geometry of the cloned node
I believe you can change the baked geometry itself, but not the parametric one (not the SCNCylinder). So you can (to change the height):
Scale the node
Change the Transformation Matrix (so scaling too, just a different way to)
Add a Geometry Shader modifier that moves the points up/down on the axis you want
Changing the actual geometry kind of defeats the whole purpose of cloning, so I don't think there is a way around that.
Lastly, given this same scenario, how much of a performance increase should I expect by moving from Scenekit to Metal.
A lot. Around 30% from what I've seen, but again it will depend on your setup. Metal comes with iOS 9, and you won't have to do anything to get it for your scene, so just update one of your devices and try it there, to see if it helps!
Out of curiosity: why do you need so much cylinders? Could you not cheat the way they are rendered?
I am creating a game using cocos2dx 2.1.4. Its FPS drops continuously , and never recover.
Please find the details as follows
Background about the way I am doing things:-
Its game about scrolling down some shapes, each shape is made up of some square blocks.I have 7 kind of blocks. All loaded in a Sprite Sheet and using these blocks from this sprite sheet I create a shape.
A level file is consist of these shapes. I load two levels at the same time one onscreen and another off screen to make it seamless scrolling. For loading two levels at the same time I used two different CCSprite game batch nodes as :-
CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("56blackglow.plist");
_gameBatchNode1 = CCSpriteBatchNode::create("56blackglow.png", 200);
_gameBatchNode1->retain();
this->addChild(_gameBatchNode1,kForeground);
_gameBatchNode2= CCSpriteBatchNode::create("56blackglow.png", 200);
_gameBatchNode2->retain();
this->addChild(_gameBatchNode2,kForeground);
The problem I am facing is that as I keep on playing the game frame rate drops continuously , from 60 fps till 10 fps and never recovers or might recover in near future , as I observed for 20 minutes but its too much time to wait.
My observations:-
1> I used Time profiler it shows maximum time is in draw() calls. Also if I play game very fast the peak of time increases in track, that should be fine as I am giving more work to do, but once a peak is attained it remains approximately at that height only, even if I leave the game Idle. Is it normal ? According to me it should have returned to its normal peak once the current work is done.
2> Some where I thought its happening because I used two batch nodes and removing its children on a user touch immediately might causing it slow but then after removing the children it should run normal. to give an idea is it ok to remove 10 children from batch node immediately ? some guys say its very slow process. Just to check if this causing problem , I did :-
Instead of removing them I just set visibility of the children to false.But still FPS drops and never recovers.
Please share your thoughts on this.
Though SpriteBatchNodes are generally quite good for drawing a lot of elements efficiently, I think there are best used for static/not-so-dynamic elements. In your case, if you have a lot of elements which go out of the screen but are still alive the draw() function will have to make some checks, thus hogging your performance (even if you set isVisible(false); explicitly, it still nedds to be checked).
In your case I think it would be better if you simply added new shapes outside of screen via some time-based function, and if they scroll outside of view simply remove them from scene, without using batchNodes.
Just found that with every touch, I am adding 8 new sprites to the layer, and its adding every time I touch . So with time I am giving more and more work to do. This is the problem
Actually I wanted to replace the sprite at 8 places with a touch, the way I was doing every time :-
_colorBottom1=CCSprite::createWithSpriteFrameName(png[0]);
this->addChild(_colorBottom1,kForeground);
_colorBottom1->setPosition(ccp((_colorPanelLeftPad)*_blockWidth,_blockWidth));
It was causing this sprite to be added with every touch.
but it should have been (Replace the texture instead of creating the Sprite again):-
CCSpriteFrame *frame1=CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(png0);
_colorBottom1->setDisplayFrame(frame1);