# Iron-Warrior

Member

11

1. ## Toon Shader Using Unity

This tutorial is published with the permission of Erik Roystan Ross of https://roystan.net. Roystan writes articles about game development using Unity. GameDev.net strongly encourages you to support authors of high quality content, so if you enjoy Toon Shader Using Unity, then please consider becoming a patron. You can view the original article at https://roystan.net/articles/toon-shader.html. Source code at https://github.com/IronWarrior/UnityToonShader. Become a Patron! Interested in posting your articles on GameDev.net? Contact us or submit directly.
2. ## Understanding Gerstner Wave sharpness and normal calculation

Hi, I am currently working on implementing Gerstner Waves into a Unity shader based on this article. Note: All of my code is in C#, running on the CPU. I did this since it allows for much easier debugging/code inspection. After the algorithm is complete, I intend to rewrite it on the GPU in HLSL. I got this far implementing the positional part and started working on the normal part: https://imgur.com/SxSfOHE The calculated normals did not turn out so good. The following is a gif where the first half is the normals being calculated using Equation 12 in the article. The second half is using Unity's Mesh.RecalculateNormals(); method, which manually calculates the normals of each vertex by summing the weights of adjacent triangles (which I have been using to test the correctness of the algorithm, not that they would be exactly the same). https://imgur.com/aC6J8lb I realized my normals were having issues due to the wave sharpness (Q parameter in the article) being too high. Initially, I had a wave sharpness parameter for each individual wave, whereas reading the article again I realized it was a global parameter calculated for each wave as Qi = Q/(wi Ai x numWaves). I changed my sharpness to be a global value from 0-1 and have this code currently. void GerstnerWave(Vector3 i, out Vector3 p, out Vector3 n) { p = new Vector3(i.x, i.y, 0); foreach (Wave wave in waves) { float innerFunction = Vector2.Dot(wave.wavelength * wave.direction, new Vector2(i.x, i.y)) + wave.phase * Time.time; float cos = Mathf.Cos(innerFunction); float Qi = globalSteepness / (wave.wavelength * wave.amplitude * waves.Length); p.x += (Qi * wave.amplitude) * wave.direction.x * cos; p.y += (Qi * wave.amplitude) * wave.direction.y * cos; p.z += wave.amplitude * Mathf.Sin(innerFunction); } n = Vector3.zero; foreach (Wave wave in waves) { float wa = wave.wavelength * wave.amplitude; float s = Mathf.Sin(wave.wavelength * Vector2.Dot(wave.direction, p) + wave.phase * Time.time); float c = Mathf.Cos(wave.wavelength * Vector2.Dot(wave.direction, p) + wave.phase * Time.time); float Qi = globalSteepness / (wave.wavelength * wave.amplitude * waves.Length); n.x += wave.direction.x * wa * c; n.y += wave.direction.y * wa * c; n.z += Qi * wa * s; } n.x *= -1; n.y *= -1; n.z = 1 - n.z; } Where i is the input vertex position, p the output position and n the output normal. Wave is a class that holds all the wave specific values. Here is what I have using this: https://imgur.com/NaR5zXB All of the gifs so far are 5 waves with the same setting, except for the previous which has a global steepness value of 0.95. This looks a bit rough right now. I can't tell if the normals are wrong or just so many waves layered are naturally creating noise (Unity's RecalculateNormals is still much smoother). Not only that, but without individual steepness values the waves are pretty round and dull looking. To investigate, I created a simple wave system on a 10x10 plane. 4 waves moving vertically, horizontally and both diagonals. These normals turned out fine (look almost the same as the Recalculated ones with any steepness 0-1). https://imgur.com/OBb1mi2 So couple questions: Is the method of calculating normals above robust for 5+ variable sized waves. Am I doing something wrong? Having a global steepness value that is clamped from 0-1 makes the normals look correct in simple systems, but makes it difficult to get the waves to a higher sharpness value I need for the scene. Is it possible to have individual wave sharpnesses and get correct normals? I mostly just want my first gif, but with proper normals. Sorry for the massive post but have been working on this all weekend and want to figure it out! Thanks for any help, Erik Edit: Not sure why code formatting is odd, updating doesn't seem to fix it
3. ## Convex/Concave collision test algorithms (narrow phase)

You're right of course! I always forget to remember that, which is especially important in this case.   I would choose BVH. BSP is very slow to build, increases triangle count and may introduce additional numerical issues and contacts due to splits - just no. Octree is fine but i don't see advantages over less restricted BVH.   Oriented bounding boxes could be a big win if your world is not totally axis aligned.   I'm assuming then a for a triangle mesh BVH the volumes would overlap? Take the image below: (Pretend those are AABB!) It wouldn't be possible to partition this with AABBs without the BBs overlapping, unless you add triangles to both boxes (like in a BSP). If this is correct, I'm guessing if your object intersects both bounding volumes you'd then have to test both sides of the tree (please correct me if I'm wrong).   Thanks to both of you for your replies!
4. ## Convex/Concave collision test algorithms (narrow phase)

Hi, I've been researching convex/concave collision algorithms and am looking for some direction. When it comes to convex/convex, things are pretty easy to research (practically any Google search will return you GJK!), but I'm not entirely sure the optimal path for collisions between convex and arbitrary concave objects. Note for my purposes, I would be using a triangle mesh to describe the concave objects. From what I've seen online there are two options:   a) Run Convex/Triangle intersection test against your convex object and every triangle in the mesh (making sure to respect the normal direction of the triangle). This can be optimized by precomputing the triangle mesh into a Bounding Volume Hierarchy, like a BSP Tree or Octree. b) Decompose the triangle mesh into a set of convex objects. These kind of feel the same to me at a high level, since if you partition the space in A you're basically just decomposing your mesh into smaller objects anyways? The difference I see is that the object at the lowest level of the tree in B is much more efficient to test against, since it's just a single convex hull as opposed to a bunch of triangles in A. However, I'm guessing that building correct convex hulls that properly wrap the mesh could be more difficult to implement than A.   My use case is primarily for (ellipsoid or capsule) character collision (and other convex game objects) with world meshes. I'm leaning towards A for it's simplicity, but I wanted to get some input on possible options beforehand. As well, if A is a good option, is a BSP Tree the best way to go based on my use case?   Any input is appreciated, thanks very much. Erik
5. ## Space for Unity refugees?

Seeing an awful lot of familiar avatars here...   I don't post here much, but I really like to browse since many of the topics contain some fairly in-depth theory on various game development problems. I really like the Unity community but it doesn't have any real spaces for discussing in-depth problems (like Collision, AI, Networking) and is mostly dedicated to using the engine's built in tools (as it should be, it's the Unity forum!)
6. ## In depth articles about fast paced multiplayer network architecture

Yeah, the Overwatch video is great, was good to see that some of the things I was doing (predicted projectiles) were on the right course.   As we finally arrived at the weekend, I managed to sit down and write out a rough draft of how the networking should work. I outlined the server and client loops, as well as the base NetworkObject class that all networked objects would inherit from.   Server tick (fixed): - Load in any received inputs - Run Step(tick) on every object in the game world - Broadcast new state info to all clients   Client update (variable): - Read any incoming data and apply it to objects - Reconcile predicted objects, smooth non-predicted - Run Step(deltaTime) for all objects, caching inputs - If time > lastSendTime + sendInterval, send all cached inputs to the server.   Object types:   NetworkObject (everything) - Has series of variables that totally define it's state in the game world, from Transform (position, rotatation) to object specific states (flying, falling, exploding, whatever). - Should probably have an additional variable keeping track of how long it has been in a specific state (since some states last n seconds, like reloading a gun) - All state information must be smoothable - Object must be TOTALLY defined by state information; no other data about object is ever sent - Broadcasts all this information to clients each tick (when necessary)   -> Server only objects - Objects that are not owned by any client players. Barrels, land mines, dropped weapons...smoothed on clients   -> Client objects - Owned by a specific player. These objects are predicted locally and reconciled with server data - On non-owner clients, these are treated like any other server object and smoothed (not predicted).   Smoothing types:   -> Interpolation: Cache previous n ticks of data, then interpolate between them -> Extrapolation (dead reckoning): Run the object's Step(deltaTime) method. When server data comes in, rewind the object and replay previous frames (this is basically prediction?)   Main things I see needing to be addressed:   - Making a NetworkObject class that can have any amount of member variables serialized over the network (though obviously a limit number of types. Float, int, Vector3 and rotation data mainly). - Managing all of the state data and not destroying it when interpolating, extrapolating, predicting...and making sure not to replay certain things when reconciling (sounds, effects) so things don't happen twice. - Making sure this all works fine when the server and client are on the same machine (host). - Will need to keep track of the server's tick number on the client to be able to accurately reconcile objects      I'm sure I'll discover that some of this won't work quite so simply once I start implementing it, but I think it's a good star to steer my ship towards.
7. ## In depth articles about fast paced multiplayer network architecture

Hi there, I've been working on a multiplayer game for awhile now that is essentially (as far as coding goes) a first person shooter, using Unity. This is the first multiplayer project I've worked on and have been learning as I go. So far I have a prototype up and running, but it's written using Unity's High-Level API (using custom code, as opposed to their built in components) and overall is very limited. Here's a video of it.   After digging into Unity's HLAPI over and over I've come to the conclusion that it's simply not worth the hassle, and am planning to rewrite my netcode using their low-level api (which basically just handles connections and raw data transfer). So essentially I'll be writing it almost from scratch, from an architecture point of view.   Much like any FPS, it will be client-server architecture, with an authoritative server and prediction on the clients. Because my gameplay revolves around being able to precisely target enemies with a projectile (the sword boomerang), I've been predicting the boomerang's logic in addition to the players' (since I know in lots of games, projectiles are not predicted as there isn't much precision required to throw a grenade or fire a rocket). Finally, all non-player (non-predicted) entities on the client will be interpolated between authoritative positions sent from the server.   Obviously this is lots of complicated stuff! (To me, at least). My primary sources to get this far have been Valve's great multiplayer networking articles, and Gabriel Gambetta's superb high-level overview of fast-paced multiplayer games. What I feel that I'm missing out on right now is a resource that explains how to practically write code that performs all the above tasks. Once you start adding in interpolation, reconciliation, different kinds of prediction (dead reckoning and so on)...it starts to get pretty wild. Does anyone have any comprehensive articles or books that discuss implenting multiplayer games? I suppose if not, this thread can be the start of a discussion!
8. ## In depth articles about fast paced multiplayer network architecture

Great links! For anyone reading this in the future, start at the beginning of the ithare stuff and go through it. It seems dense and low leveled but already is really useful. Only skimmed the gaffer stuff, and while it's less structured looks well written.     Lots of good variety here, especially in topics that aren't common to see discussed.   Given that it doesn't seem likely there will pop up a tutorial titled "How to create a sword boomerang game in 5 easy steps," I'm going to start working on create a robust system for my above specs, and I'll post some high level designs here when I've got them. In theory, it should mostly come down to sending data to be synced and handling certain state changes as events (if a player enters the jump state, play appropriate animations). Then for all the smoothing and prediction and whatnot should all be done as a layer on top of this.
9. ## In depth articles about fast paced multiplayer network architecture

Yeah, networking for sure is something that you can't really build to be as general as graphics or collision (which most engines make their staple). For graphics if you want to make a completely different look it usually comes down to shaders (in the code portion at least) whereas networking there's lockstep vs predicted vs rollback and others...so I guess I shouldn't be too disappointed!   For your second paragraph, Good advice! When I look at other engines like Source they seem to always have command line tools to disable entity interpolation, prediction and so on, so in theory it seems all those components are just layers over the core logic of the world. I've rebuilt my game 4 times now (although bear in mind I had zero networking experience at the start), and I've written some stuff down describing how I want to do it this time, which I think I'll post here to see if anyone else is interested in the topic.
10. ## Collision response in Sphere vs concave Mesh

Hello,   I'm working on a character controller and having some trouble with resolving collisions after they are detected when colliding against concave meshes. The method I currently use to resolve collision is to find the nearest point on the surface of the object the sphere controller collided with with respect to the center of the sphere, and then translate the sphere to that point (offset by it's radius).     The above shows my method in 2d for simplicity, where the orange circle is the origin, the yellow is the movement translation and the green circle is where it ends up after resolution, with the vector to the nearest point shown in cyan. This works very nicely since it's fairly simple to implement and has the beneficial properties of allowing the character to "slide" across surfaces smoothly. The issue arises when you collide with "corners" on a concave mesh, as I show below.   Shown here the same steps occur but translating our yellow circle to the nearest point on the surface of the mesh results in our green circle still intersecting our mesh.   The easiest solution would be to run the collision detection recursively, stopping when the sphere no longer is colliding with any object. However, if there's a better solution available this would seem wasteful for performance, but I'm having trouble coming up with any ideas. It would be possible to take multiple nearest points (maybe the nearest point on every triangle on the mesh that is within the radius of the sphere?) and then test after resolution against each point to ensure that they are now further than the radius from the center of the sphere, but as we can see from the diagram above the triangles colliding with the green circle were not initially within range of the yellow circle.   Thanks for any input.
11. ## Collision response in Sphere vs concave Mesh

Thanks very much for this! Not only is it exactly what I was looking for, but it was also exactly the kind of thing I likely would have not found searching by myself.