|
Thanks, I'm glad to hear it I've eliminated the shadow issue. I think the takeaway here is "CinemachineSmoothPath does not like being scaled". I had a global .25x scaling factor on the entire cinematic, as a way to bring the giant snowflake model down to a size where it wasn't being swallowed by fog. But that meant that I had positions that were, like, 20k units away from the origin. I pushed the scaling factor down to just the snowflake, and then fixed the path nodes, and now there's no shadow jitter. Very weird. I think the planes are also moving a bit more smoothly, though there's still jitter there. We'll see if it's still bugging me tomorrow, when I have fresh eyes.
|
# ? Oct 19, 2021 21:48 |
|
|
# ? May 23, 2024 16:43 |
|
Floating-point precision issues caused by large distances, maybe?
|
# ? Oct 20, 2021 00:25 |
|
yeah if you're 20,000 units away from origin you're gonna start seeing fpp jitter
|
# ? Oct 20, 2021 01:34 |
|
Yeah, but it was more than just that, because if I turned off the Cinemachine stuff, then the jitter went away. So I think there were some extra calculations being done by Cinemachine's positioning/aiming code, that were causing noticeable loss of precision. The fix is the same in any case
|
# ? Oct 20, 2021 04:22 |
|
Is Cinemachine a unity plugin for making cinematic shots like that?
|
# ? Oct 20, 2021 14:31 |
|
Raenir Salazar posted:Is Cinemachine a unity plugin for making cinematic shots like that? Cinemachine is a general-purpose camera control system. You have your standard Unity camera, you stick a "Cinemachine brain" on it, then you create "virtual cameras" (empties with CinemachineVirtualCamera components). The highest-priority virtual camera's settings (transform, field of view, near and far clip planes, etc.) are copied to the real camera. You can change priority to switch viewpoints and settings, with a variety of different transitions --- no crossfades, though, which is a shame but understandable given the cost and complexity of rendering two cameras simultaneously. Then the virtual cameras have various settings to determine how they move, how they decide what to look at, etc. That said, I would not use the camera movement/look-at parts of Cinemachine for gameplay personally, because, while it gives you a fair amount of control, it does not give you absolute control over your camera. Sometimes you need to be able to say "the camera does this, right now", and Cinemachine doesn't let you do that. I still use the virtual cameras in gameplay, but only so I can swap between them with the priority system. For example, I have one virtual camera that is basically stuck on a circular track around the player, and another one that sits inside the player's ship to represent the binoculars view. When I want to switch from orbit to binoculars, I just bump the binoculars' priority. For cinematics, where you have total control over the scene, though? Go nuts. This is a pretty simple cinematic -- just a single shot, the camera's following a path, while looking at an object that is following a different path. The planes are similarly on paths. Incidentally, CinemachineSmoothPath is a very useful component for basically any time you want to define a 3D curve that passes through a set of points. I use it all the time for all kinds of things that don't necessarily have anything to do with cameras.
|
# ? Oct 20, 2021 15:39 |
|
Neat! I'll have to look into it when I finally work on my RPG project. In other news I succeeded in implemented theConnected-Component Labeling algorithm; It feels to me that it isn't inherently different from Sebastian Lague's flood fill algorithm See here but it works. At first I thought it didn't succeed when the eastern continent was all black but it turns out it was just randomly that colour, I made it so Random was set according to DateTime.Now and I was able to verify it was working fine. I can probably optimize it further which would hopefully skip over a lot of already scanned items buuuut I went and timed it for the 8k by 4k version and I was waiting a solid three minutes for it to load. I think this might be part of why I am looking for a Scanline based implementation as I suspect pushing and poping the queue is probably more operations than looping through a row? I think there might be a CCL algorithm variant that does it in a scanline so I'll check that out; but if its still over a minute of twiddling my thumbs I either need to multithread this or put it to the GPU. Or make it async so it just gradually loads in and I just add like a loading symbol while its coming in.
|
# ? Oct 21, 2021 04:23 |
|
Nicely done. Edit: Oh I see now this isn't your code. I don't know how closely you copied it, but I'll leave these notes here Looking at that code you could probably speed it up by merging GetRegionTiles into GetRegions, or at least share mapFlags between them. I see two issues with splitting it up like this: 1) GetRegionTiles allocates it's own mapFlags every run. It would be more efficient to just share a single mapFlags and use a different flag for each region (1,2,3...) 2) Right now in GetRegions takes the output of GetRegionTiles and then marks mapFlags[x,y] = 1; for each tile. If mapFlags was shared this loop could be removed entirely. If that's not fast enough there are almost certainly faster algorithms out there (the wikipedia "two pass" algorithm looks like it's faster and doesn't use queues). HappyHippo fucked around with this message at 16:27 on Oct 21, 2021 |
# ? Oct 21, 2021 16:21 |
|
I'm scared to show my code but here goes, I only kinda borrowed the naming convention, I'm just remarking that logically speaking the algorithms don't seem too different, I hadn't used Sebastian Lague's code for this in a long while except as a very rough guideline for interesting processes. I followed the outline here Here for "One component at a time" CCL.quote:1. Start from the first pixel in the image. Set current label to 1. Go to (2). Code: code:
1. The algorithm iterates over a lot of empty space; which will be worse if I were to invert it for water areas since its basically waisting a lot of iterations. Hence my earlier idea to just do one pass for all tiles and queue'ing up all tiles that don't match to ignore duplicates without incurring additional costs. 2. I'm not sure if a Queue is more expensive than just iterating over a row or column; but changing this to a scanline implementation could be faster than using the Queue? 3. I feel like the checks on the cardinal directions might also be costly that might be averted in a scanline implementation but I'm not sure how expensive it actually is. 4. I think I'm creating and ultimately not using a LOT of lists which might be why its pretty slow as thats 32 MILLION unused lists being made in the 8k by 4k usage. 5. Could move the Random initialization out of GetRegion. My intuition is that optimizing it might help a lot but probably not enough to make it a tolerable wait to compute it.
|
# ? Oct 21, 2021 18:10 |
|
Interest thing I didn't know until yesterday: Supergiant Games Hades was rewritten in C++ during the middle of early access from their C#/XNA code base they've been using since Bastion. I thought that was a bold decision considering the game was out in early access for some time.
|
# ? Oct 21, 2021 18:20 |
|
Raenir Salazar posted:I'm scared to show my code but here goes, I only kinda borrowed the naming convention, I'm just remarking that logically speaking the algorithms don't seem too different, I hadn't used Sebastian Lague's code for this in a long while except as a very rough guideline for interesting processes. I followed the outline here Here for "One component at a time" CCL. I think one quick thing might be to move this check: code:
|
# ? Oct 21, 2021 18:51 |
|
Good thinking! I'll give it a shot after work.
|
# ? Oct 21, 2021 18:54 |
|
Two more thoughts: 1) This algorithm works with either a queue or a stack. Profile with both to see if one is faster. 2) In C#, Queue and Stack are built on top of arrays. When you add an item, if there's capacity in the internal array, it's O(1). But if the internal array is out of capacity, a new larger array is allocated, everything is copied, and then the item is added, which is O(n). The capacity is only decreased if you explicitly call TrimExcess. Since your Queue/Stack begins/ends empty, I'd just share one across the calls to GetRegion, to avoid having to redo the expensive reallocations each call.
|
# ? Oct 21, 2021 20:11 |
|
edit: fixed the img link baby puzzle fucked around with this message at 02:36 on Oct 22, 2021 |
# ? Oct 22, 2021 01:33 |
|
The first half had me confused for a moment but it clicked for me with the second half.
|
# ? Oct 22, 2021 01:43 |
|
Raenir Salazar posted:The first half of that paragraph made me think things. The second half made me go d'aww. I was really fighting with whether to make the obvious joke lol
|
# ? Oct 22, 2021 01:45 |
|
Tip posted:I was really fighting with whether to make the obvious joke lol Bah! e: This is what I get for failing to commit and my posting cowardice. Raenir Salazar fucked around with this message at 01:50 on Oct 22, 2021 |
# ? Oct 22, 2021 01:45 |
|
guess I wasn't the only one
|
# ? Oct 22, 2021 01:47 |
|
😤 but also 🤣 Also sorry for Imgur link but I’m too old to know how to post images on mobile baby puzzle fucked around with this message at 01:51 on Oct 22, 2021 |
# ? Oct 22, 2021 01:48 |
|
But seriously though who is Daniel Lemon, what game did they make? I'm googling and there is a Disney game developer by that name on Linkedin but nothing else that comes up.baby puzzle posted:😤 but also 🤣 IIRC it should've auto-embedded.
|
# ? Oct 22, 2021 01:51 |
|
xgalaxy posted:Interest thing I didn't know until yesterday: Do you have a source for this? That sounds absolutely nuts and I’d love to hear more about it. I wonder if “rewriting in c++” means they built an entirely new engine or if they just used native bindings to an existing one
|
# ? Oct 22, 2021 01:52 |
|
Raenir Salazar posted:But seriously though who is Daniel Lemon, what game did they make? I'm googling and there is a Disney game developer by that name on Linkedin but nothing else that comes up. Daniel Lemon is baby puzzle, the person who posted the link, and the creator of SEQUENCE STORM
|
# ? Oct 22, 2021 01:56 |
|
TooMuchAbstraction posted:Daniel Lemon is baby puzzle, the person who posted the link, and the creator of SEQUENCE STORM AAaaaaaaaaah!!!!! I thought baby puzzle was the other person!
|
# ? Oct 22, 2021 02:08 |
|
omg i always thought I'd feel comfortable tying this account to me irl, but seeing it in person is another thing.
|
# ? Oct 22, 2021 02:24 |
|
What we're learning here though is you need to do more marketing, as your name does not bring up your game when I googled it.
|
# ? Oct 22, 2021 02:26 |
|
I'm in that Gen X category that learned the hard way, early, not to tie real life to anything online. I think that has held me back as far as marketing.
|
# ? Oct 22, 2021 02:27 |
|
Mood.
|
# ? Oct 22, 2021 02:36 |
|
giogadi posted:Do you have a source for this? That sounds absolutely nuts and I’d love to hear more about it. I wonder if “rewriting in c++” means they built an entirely new engine or if they just used native bindings to an existing one It was in the noclip documentary series about the release of Hades. They built a new engine on top of The Forge (which is more of a renderer and not a complete engine). See: https://github.com/ConfettiFX/The-Forge#supergiant-games-hades Interestingly enough Bethesda's Starfield is also built on top of The Forge. xgalaxy fucked around with this message at 03:26 on Oct 22, 2021 |
# ? Oct 22, 2021 03:23 |
|
HappyHippo posted:I think one quick thing might be to move this check: HappyHippo posted:Two more thoughts: Alrighty so I implemented these changes; predictably the first suggestion I think had the largest performance increase. Going from a 1 minute 30ish seconds to just 9 seconds for all land tiles. However inverting it and doing water tiles is still around 30 seconds. So I can expect it on the high side to take around 40 to 42 seconds for the whole map. Passing in the Queue to use and switching to a Stack in total resulted in saving about 1 second off the total time; fairly significant all things considered but not the biggest dent in terms of the total amount of time. I don't think my random colour thing takes a lot of time; and didn't really see much of a difference removing it. I also tried to use structs created by value instead of instantiated using "new" but didn't seem to have a performance difference, total time varied between 28 and 32 seconds regardless. Here's the water map for funsies: I think the next change is to try iterating over the entire map using the Stack to track when the processing hits a tile that's not in the same label/colour so instead of iterating over already iterated tiles and skipping them with an if; it should just jump to unprocessed tiles which might be a bit faster but there's still millions of tiles to process and presumably starting at 0,0 and processing the water I imagine was the largest chunk, while skipping over the land tiles probably didn't take long at all since processing land tiles originally was only like 9 seconds so skipping over like 20 million tiles was probably fast; so skipping over 10 million is like twice as fast since it should only take half the time? My guess is it probably still takes around 35 seconds to do the whole 8k by 4k texture, possibly up to 45s with my proposed change to just do it all at once. The next step after that if that's the case is to try the two pass algorithm; which in the "faster" variation of it is basically a scanline based algorithm. After that I probably either need to rely on multithreading or the GPU; but multithreading might be sufficient because if I can get it down to like 10s then having like 8 threads will have it done in like 2 seconds.
|
# ? Oct 22, 2021 04:46 |
|
xgalaxy posted:Interest thing I didn't know until yesterday: I had to do this in reverse once, take a game written in an in-house C++ engine with a lot of middleware and lua scripted gameplay that was written for Xbox360 and port it to C#/XNA to run on Windows Phone 7. Project budget was two programmers and eventually one tech artist, it took us 18 months. I learned a lot.
|
# ? Oct 22, 2021 07:11 |
|
Raenir Salazar posted:
i.e. For 'up' you could replace this with current.y-1>=0, for 'down' replace it with current.y+1<InHeight, etc. But scanlines would save you a lot more by making it so you're doing approximately one check per pixel, where right now you're doing four checks every pixel (i.e. you go up, then you immediately do all the checks for "should I go down again", where with scanlines you know you just came from there and don't need to do that.)
|
# ? Oct 22, 2021 13:34 |
|
Raenir Salazar posted:Going from a 1 minute 30ish seconds to just 9 seconds for all land tiles. Nice! quote:I also tried to use structs created by value instead of instantiated using "new" but didn't seem to have a performance difference, total time varied between 28 and 32 seconds regardless. Also roomforthetuna's suggestion is a good catch, 75% of your bounds checks are unnecessary. HappyHippo fucked around with this message at 14:58 on Oct 22, 2021 |
# ? Oct 22, 2021 14:41 |
more falafel please posted:I had to do this in reverse once, take a game written in an in-house C++ engine with a lot of middleware and lua scripted gameplay that was written for Xbox360 and port it to C#/XNA to run on Windows Phone 7. Project budget was two programmers and eventually one tech artist, it took us 18 months. I learned a lot. What did you end up doing as an alternative to the lua? I'm currently struggling to find a decent scripting interface for C#.
|
|
# ? Oct 22, 2021 14:48 |
|
Depending on your target platforms, or if you even need to modify them at runtime on all platforms, you could probably just use C# instead of using a whole separate language and runtime compile on the platforms that support editing. e: Also depends on how much you trust the people doing the scripting. Might not want to give random players the ability to run arbitrary code. chglcu fucked around with this message at 15:08 on Oct 22, 2021 |
# ? Oct 22, 2021 15:00 |
|
Polio Vax Scene posted:What did you end up doing as an alternative to the lua? I'm currently struggling to find a decent scripting interface for C#. I've been wanting to use F# for scripting in another project. You can compile FSX files into code during runtime and extend you programs this way. Don't know if it works the way I imagine it will, but it should be doable. Like this: https://stackoverflow.com/questions/6859534/how-to-run-a-f-script-in-the-context-of-c-sharp-application
|
# ? Oct 22, 2021 17:10 |
|
Do we have a discord for this thread? Feels like we should. SQL is such a pain in the rear end when you mix it with Python but at least I'm getting the hang of things.
|
# ? Oct 22, 2021 17:59 |
|
D34THROW posted:Do we have a discord for this thread? Feels like we should. You'd think it wouldn't be that bad since ODBC + Python is like the Official Data Scientist Starter Pack.
|
# ? Oct 22, 2021 18:00 |
|
SQL is a pain everywhere because it's string building and making strings safely is a very not fun part of programming.
|
# ? Oct 22, 2021 18:03 |
|
xzzy posted:SQL is a pain everywhere because it's string building and making strings safely is a very not fun part of programming. That is true. I work for a database company and we "solved" the issue by creating a translation layer. The upside is that it works really well but the downside is it's yet another thing to learn. code:
code:
|
# ? Oct 22, 2021 18:09 |
|
|
# ? May 23, 2024 16:43 |
|
Polio Vax Scene posted:What did you end up doing as an alternative to the lua? I'm currently struggling to find a decent scripting interface for C#. WP7 doesn't allow *any* native code, so we couldn't use libraries that weren't pure C#. We found a physics middleware that fit the bill (original engine used Bullet, and this was similar enough), but we didn't find a way to do the Lua runtime (there actually was a straight port of the Lua interpreter to C#, but it was ungodly slow and leaked references like a sieve, which means 100ms hitches more than 1x/second). The good news was they had a strictly enforced Hungarian-style naming scheme for Lua scripts which meant I could use an awful lot of regex to get 90% of the Lua code translated to C# in a couple days, and then spent about a month fixing up everything else. I had also worked on the prequel to this game, so I was very familiar with the way their gameplay script system worked.
|
# ? Oct 22, 2021 18:38 |