Skip to main content
GameDev.net gamedev.net
🔒 Locked

Using a Variable Inertia Law (NKTg) to Interpolate the Masses of 8 Planets for Advanced Motion Simulation in Games

Started by NKTgLaw Sep 13, 2025 at 1:12 AM 24 replies 5.4k views
Original Post
NKTgLaw
NKTgLaw

Hi everyone,

I’ve been working on a concept I call the NKTg Law of Variable Inertia, which was recently tested against NASA’s real-time planetary data (30–31 Dec 2024). The idea comes from astrophysics, but I think it has great potential for game physics simulations — particularly if you want motion that feels more alive and less rigid than standard Newtonian models.

📐 The NKTg Law

The NKTg Law describes how inertia can vary depending on three quantities:

NKTg = f(x, v, m)

  • x = position (relative to a reference point)
  • v = velocity
  • m = mass

Two fundamental interaction terms are defined:

NKTg₁ = x × p NKTg₂ = (dm/dt) × p

where p = m × v is linear momentum.

👉 The signs of these terms define whether motion stabilizes, resists, or amplifies. This can be applied in orbital mechanics or game objects with changing mass (e.g., spaceships consuming fuel).

🔭 Experimental Verification with NASA Data

Using NASA JPL Horizons data for all 8 planets at the end of 2024, I interpolated their masses using:

m = NKTg₁ / (x × v)

When compared with NASA’s official planetary masses, the results matched with error < 0.0001%.

This shows that NKTg₁ is a conserved quantity across the Solar System.

💻 Code Example (C# style demo)

Here’s a simplified implementation for all 8 planets:

using System; using System.Collections.Generic; class NKTgSimulation { struct Planet { public string Name; public double X; // position (km) public double V; // velocity (km/s) public double NKTg1; public double NASA_Mass; } static double InterpolateMass(double x, double v, double NKTg1) { return NKTg1 / (x * v); } static void Main() { var planets = new List<Planet> { new Planet { Name="Mercury", X=6.981793e7, V=38.86, NKTg1=8.951e32, NASA_Mass=3.301e23 }, new Planet { Name="Venus", X=1.08939e8, V=35.02, NKTg1=1.858e34, NASA_Mass=4.867e24 }, new Planet { Name="Earth", X=1.471e8, V=29.29, NKTg1=2.571e34, NASA_Mass=5.972e24 }, new Planet { Name="Mars", X=2.4923e8, V=24.07, NKTg1=3.850e33, NASA_Mass=6.417e23 }, new Planet { Name="Jupiter", X=8.1662e8, V=13.06, NKTg1=2.024e37, NASA_Mass=1.898e27 }, new Planet { Name="Saturn", X=1.50653e9, V=9.69, NKTg1=8.303e36, NASA_Mass=5.683e26 }, new Planet { Name="Uranus", X=3.00139e9, V=6.8, NKTg1=1.772e36, NASA_Mass=8.681e25 }, new Planet { Name="Neptune", X=4.5589e9, V=5.43, NKTg1=2.534e36, NASA_Mass=1.024e26 } }; foreach (var p in planets) { double mInterp = InterpolateMass(p.X, p.V, p.NKTg1); double delta = p.NASA_Mass - mInterp; Console.WriteLine($"{p.Name}: NASA={p.N

frob
frob

Moving to Math and Physics.

While it's interesting and perhaps useful to planetary physicists, I don't see the connection to game development.

Game simulations jump from one location to another because waiting months or years isn't fun. We don't do the complex math of interplanetary motion, fuel calculation, and the months of quiet time with tiny course corrections due to the forces applied for urine dumps.

Instead it's about the spaceport with stories, hit the “board the ship” UI button, and after a loading screen, see the crowd at the other spaceport. The fun is the social part of the gameplay, or the trade, not mechanics of interplanetary motion.

Or the game might jump to dogfights in space, using physics and weapons closer to aereal dogfights in a volume just a few kilometers large, if that. The fun is being the ace pilot in combat, not the mechanics of calculating intercepts, computing fuel consumption, or running the high precision numbers far beyond what typical floating point or built-in transcendental math functions provide.

If you want to do the math, or try to make it fun, that's your hobby. Just don't expect mass-market appeal from it, nor a gameplay bullet point “now with even more accurate conservation of energy equations”, while competitors have a patch: "now with three more playable species" or “even more missions in the exciting DLC storyline.”

RmbRT
RmbRT

Interpolating mass of planets? Are you telling me the mass of planets is in constant fluctuation to a significant degree? Is that really what this is about or did I just read it wrong? Also, if you get within 0.0001% of the “observed” mass, does that mean that planetary masses fluctuate by more than 0.0001% over a 2 day period? Do planets constantly eject or receive matter? And why did you only validate this for a period of 2 days? 2 days is nothing in the grand scheme of things. Planets don't move that much within a day or two.

This honestly sounds like another schizo post to me.

Walk with God.
JoeJ
JoeJ

RmbRT said:

Are you telling me the mass of planets is in constant fluctuation to a significant degree?

Sounds what he means is that inertia is changing, not mass. If an elastic body is squeezing, e.g. due to rotation around itself, inertia would change to different values although mass stays the same.

But i don't understand it either. Maybe more explanation is needed.

Personally i would think about inertia values used in rigid body physics simulation, where we use 3 values describing inertia on 3 given local axis for 3D to model 'rotation resistance'. But the post seems to refer a 1D example, so maybe it's about something totally different. ‘Inertia’ has multiple meanings.

However, in our simulations we accept a crude approximation already, as the 3 values can only describe an ellipsoid. (3x3 tensor can still only do a sheered ellipsoid i guess)
So we can not even model inertia of a simple box accurately, and nobody complains or sees a reason to improve this (which would come at a massive cost i've heard).
Considering this, it's not clear to me what the motivation actually is. I remember people working on a space sim, and they handled things like a fuel tank with dynamic changes on mass properties during simulation. That's not a big problem or limitation.

taby
taby

RmbRT said:

This honestly sounds like another schizo post to me.

Fuck you, man.

fastcall22
fastcall22

taby said:

Fuck you, man.


that's fair. of all the posts i've seen in the wild of that type, this one doesn't fit that definition.
let's keep on-topic and civil.

frob had covered most of the critique. there's much work to be done if you want to prove your algorithm is more alive and less rigid than newtonian physics; a dump of floating point numbers to stdout won't be enough.

RmbRT
RmbRT

JoeJ said:
Considering this, it's not clear to me what the motivation actually is. I remember people working on a space sim, and they handled things like a fuel tank with dynamic changes on mass properties during simulation. That's not a big problem or limitation.

That's what I also thought. Anything that is accurate enough to be plausible is definitely good for games, especially the simpler it is to compute. I don't think you get immersion from increased accuracy of mass or inertia of planets in a game. Especially since a game would just put them on fixed, somewhat plausible orbits to begin with, so that they don't accidentally escape due to numerical errors or something.

For rigid bodies, simple approximations are appropriate, as long as you properly track the center of mass and do collision detection properly. As soon as you get into semi-flexible territory, momentum and mass are the least of your worries anyway, when have arbitrary points of deformation and all that, and material stress etc. But that's not really a necessary gameplay feature anyway except for games that rely on accurate physics as a feature.

Walk with God.
JoeJ
JoeJ

RmbRT said:
That's what I also thought. Anything that is accurate enough to be plausible is definitely good for games, especially the simpler it is to compute. I don't think you get immersion from increased accuracy of mass or inertia of planets in a game. Especially since a game would just put them on fixed, somewhat plausible orbits to begin with, so that they don't accidentally escape due to numerical errors or something.

Yeah, if we talk about a typical modern game at the scale of characters.

But maybe no if we consider a mobile game. No dressed up third person characters, but an entire universe at the screen. Maybe i need to suck up galaxies into my super massive black holes, and things like relativistic physics could be noticeable and part of the mechanics.

It's just that i'm not convinced from given examples of planet orbits or bodies with dynamic mass, which we can do probably well enough.
But maybe there are other cases where the proposal would make a difference?

RmbRT said:
For rigid bodies, simple approximations are appropriate, as long as you properly track the center of mass and do collision detection properly.

The problem is not to compute where things are, but where they go ; )

RmbRT said:
As soon as you get into semi-flexible territory, momentum and mass are the least of your worries anyway

There is no ‘momentum and mass’, since momentum is mass times velocity.
And you still worry about it just as much, because conservation of momentum always is the primary objective of any physics simulation.

RmbRT said:
But that's not really a necessary gameplay feature anyway except for games that rely on accurate physics as a feature.

The few soft body simulations i've seen were not about accuracy, but about fun or to give some convincing impression about a sack of potatoes for example.

Nice video proposing a very simple approach, also showing how relevant this is for games:

RmbRT
RmbRT

JoeJ said:
Nice video proposing a very simple approach, also showing how relevant this is for games:

LOL at 2:30 where he normalises the distance between the vectors and then multiplies it by half the distance… He could simply take half of the distance… Seems alright, though.

By semi-flexible, I was referring to stuff like a steel beam that might bend under weight, etc. Something that's usually treated as rigid, but still has some flexibility, which may get temporarily or permanently deformed in arbitrary places depending on where it collides with what objects etc. Then you suddenly have a very complicated setup. And some materials simply snap instead of bending, or snap after bending to some degree. And then different materials break in different ways. A tree limb breaks differently from a glass pane. If a game focuses on accurate simulations of such things, then you need to pull out the big guns. But for something like stars, planets, and whatnot, for almost all intents and purposes, you can even just use a mostly static skybox and nobody would really notice. And then again you also want to make sure that the planet doesn't leave orbit through accumulated numerical errors, that would be catastrophic. And players should not be able to accidentally or intentionally do that, either. Unless that's what the game is explicitly about. I remember a few years back there was some kind of interplanetary RTS where you could launch nuclear missiles and all that across planets.

Anyway, not something that I can see apply to games well, unless you literally build the entire game around this one mechanic and make it the core point of the game.

P.S.: regarding me being sceptical of the OP: he literally names his user name after this “law” and it's a post full of emojis, the code formatting is wrong and the code also is cut off in the middle. I've interacted with deranged people online a lot over the years and it just ticks all the boxes on my checklist. They always can't shut up about this one thing they are obsessed with, and they can't communicate clearly, and it's often nonsensical or hard to follow what they say. If I really cared about sharing my precious algorithm so much that I even named my account after it, then I would at least make sure the code is properly pasted and complete and formatted appropriately. The emojis are just my personal taste but I would never use them like that. Doesn't give off a credible impression to me. And if OP is really serious about this, then I think it is my duty to inform him of the impression he is giving off, so that he is at least aware of it. He is free to continue to write like that, though. And as I pointed out, why only test this for 2 days? Planets don't do crazy stuff within that timeframe, so it doesn't even prove anything. I'd want to see a test that runs for at least a quarter of an orbit or something.

P.P.S.: rather than pandering to, or defending people who are clumsy like this, I feel we are doing them much more of a favour by giving them a reality check. Unless you want this kind of conduct to become the acceptable norm in this forum. Which again, you are free to. I have higher standards and I feel compelled to inform people of crass departure from my standards. Could I have said it more pleasantly? Sure. Would it make a difference? Not really, at least from my repeated experience. Is this forum a place where everyone must be guaranteed to feel good? Or is this a place where we try to have quality discussions about game development? And you may try to defend OP's feelings here, but what about me, the person who has to read his writings? What about defending my enjoyable experience as a user of this site?

Walk with God.
fastcall22
fastcall22

well said, rmbrt. i've reflected on your criticisms, and i agree on every point. if OP wants to remain a member here, he will participate in these discussions. so far, it has just been thinly veiled spam.


anyway, check out this new formula that chatgpt has convinced me that is the greatest formula since sliced bread.

B(t) = P[0]*(1−t)^2 + P[1] * 2*(1−t)*t + 2P[2]*t

i call it... continuously-smooth-lines-copyright-2025-fastcall22. i invented it. it's better than regular lines because they're curved.

and here's the kicker / here's the catch: / the punchline? / but wait (ironic em-dash here) there's more. / now here's the thing: / and here's where it gets interesting:

\:ironic\_emoji\_bullet\_point\_here\: it draws curves instead of straight lines. everyone uses `y = mx + b or p(t) = P[0]*(1-t) P[1]*(t)`. but with this new formula, you can get a different line, one that's curved instead of straight.

here's how you can use it:

# conceptually set up a set of points
# do something conceptually with a list of points
P = [ ... # actually set the points ]

# do something conceptually with it
a = # actually compute y = mx + b

b = # actually compute quadratic bezier curve

# actually compute the error
error = b - a

# conceptually output the error
print(...)  # actually output the error

(i'm mostly posting to vent about having to sift through so much AI slop in the wild; both on the internet and in the real world...)

JoeJ
JoeJ

RmbRT said:
LOL at 2:30 where he normalises the distance between the vectors and then multiplies it by half the distance… He could simply take half of the distance… Seems alright, though.

Hmm, he just explains geometrically, but does not show any ‘unoptimized’ code?

But anyway, this reminds me on an optimization avoiding the square root, quoting Thomas Jakobsen:

The pseudo-code for satisfying the constraint (C2) is
// Pseudo-code to satisfy (C2)
delta = x2-x1;
deltalength = sqrt(delta*delta);
diff = (deltalength-restlength)/deltalength;
x1 -= delta*0.5*diff;
x2 += delta*0.5*diff;

We now discuss how to get rid of the square root operation. If the constraints
are all satisfied (which they should be at least almost), we already know what
the result of the square root operation in a particular constraint expression
ought to be, namely the rest length r of the corresponding stick. We can use
this fact to approximate the square root function. Mathematically, what we do
is approximate the square root function by its 1st order Taylor-expansion at a
neighborhood of the rest length r (this is equivalent to one Newton-Raphson
iteration with initial guess r). After some rewriting, we obtain the following
pseudo-code:
// Pseudo-code for satisfying (C2) using sqrt approximation
delta = x2-x1;
delta*=restlength*restlength/(delta*delta+restlength*restlength)-0.5;
x1 -= delta;
x2 += delta;

RmbRT
RmbRT

fastcall22 said:
(ironic em-dash here)

I think em-dashes are getting unjust hate — it's a perfectly valid means of punctuation. At least on my German keyboard on linux, I can type it with Alt Gr + Shift + dash. I think people who complain about how only AI uses the em-dash need to up their typing game, LOL.

Interesting observation regarding Bresenham's line algorithm: The original uses lots of ifs and has one huge critical path, I think you're faster on modern PCs if you just do the slope division and then do multiple iterations interleaved from there on (for example using fixed-point math). Lots of algorithms that we have nowadays are really only performant on those old in-order CPUs.

Man, I wish CPU vendors would just ditch floats and just give me a fully pipelined integer division instead. I once tried to make a SIMD-ised 16.16 fixed-point software rasteriser in WASM, but the division was really problematic because I needed to calculate slopes for the triangle edges, which would let me step through two edges at a fixed y-step per iteration and then just fill one scanline, instead of the variable-speed Bresenham which might take multiple iterations per y-step. I also found out during that time that nobody even does scanlines and edges anymore. Everyone just loops through a rectangle, and per pixel, checks point inclusion via the barycentric coordinates (which require float division or something).

Another pain point was that you would need to interpolate over 1/z, and then invert that once more, to get the z per pixel. And you can only divide once every 6–14 cycles, even on modern CPUs. I hate it that for floats, you even get a SIMD floating point division instruction at a higher throughput. But at least you can use a lookup table to precompute that stuff for small triangles…

JoeJ said:
Hmm, he just explains geometrically, but does not show any ‘unoptimized’ code?

He geometrically/visually explained norm(b-a) * (len(b-a)/2) or something (not going to bother rewatching), when really what he should have done was just (b-a)*0.5, or, if using integer/fixed-point vectors: (b-a)>>1.

Walk with God.
JoeJ
JoeJ

RmbRT said:
I also found out during that time that nobody even does scanlines and edges anymore. Everyone just loops through a rectangle, and per pixel, checks point inclusion via the barycentric coordinates (which require float division or something).

Surprise, Nanite uses traditional scanlines.
I looked up the very first code, and it had surprising low complexity to do this.
Very good work. Eventually worth a look even if you don't believe in ‘unlimited detail’ (which is just an application).

RmbRT said:
Interesting observation regarding Bresenham's line algorithm: The original uses lots of ifs and has one huge critical path, I think you're faster on modern PCs if you just do the slope division and then do multiple iterations interleaved from there on (for example using fixed-point math). Lots of algorithms that we have nowadays are really only performant on those old in-order CPUs.

Yes, but you miss one important argument: Bresenham does not give you subpixel accuracy, so edges jump. DDA gives this for free, so edges crawl smoothly. That's the real death sentence to Bresenham, i would say.

RmbRT said:
Another pain point was that you would need to interpolate over 1/z, and then invert that once more, to get the z per pixel. And you can only divide once every 6–14 cycles, even on modern CPUs.

The usual solution is (well, was) to do the divide only each N pixels, interpolating in between. If N is 4, the texture error is noticeable only with a reference image. Carmack used this in Quake to get the division ‘for free’ on the newest Pentium chips.

You want to make some FGPA rasterizer, i guess? If so, what rendering resolution do you expect?

RmbRT
RmbRT

JoeJ said:
Yes, but you miss one important argument: Bresenham does not give you subpixel accuracy, so edges jump.

I used 16.16 fixedpoint (with a 0.5 offset), that gave me perfect accuracy for anything up to 32k pixels or something.

JoeJ said:
You want to make some FGPA rasterizer, i guess? If so, what rendering resolution do you expect?

From full HD upwards.

JoeJ said:
The usual solution is (well, was) to do the divide only each N pixels, interpolating in between. If N is 4, the texture error is noticeable only with a reference image. Carmack used this in Quake to get the division ‘for free’ on the newest Pentium chips.

I also thought about doing something just like that. Especially for large triangles, it seems very useful and practical. I actually started to build a system where it looks up triangles that are 4×4 pixels or smaller in a LUT. I look up the shape based on the placement of the corners, and then get a mask of which pixels are inside and which aren't. I also laid out the image buffer to place 4×4 pixels in one cacheline. The cacheline is 16 bytes r, 16 bytes g, 16 bytes b, 16 bytes a. This allows me to use the XMM registers to directly render all pixels in one operation (one operation per colour channel). Since most triangles on screen except for the really large triangles are within that size, roughly, I can just fetch multiple triangles ahead of time from the LUT, to hide latencies. From the LUT, I get a byte mask that I can then apply to the SIMD registers to just use one blend operation.

I also wanted to extend that approach to precompute the S,T coordinates in the LUT (in 0.4 fixed-point or something, or 1.3), so that it would apply to texture mapping, etc. It wouldn't be perfect for extremely depth-stretched triangles, but that's probably acceptable. Then I could completely skip the depth interpolation & shape computation altogether for smaller triangles. And anything that is considerably larger than that can then use the faster version that you mentioned. The only annoying part about this is when a triangle crosses chunk boundaries. But even then, this approach at least touches way fewer cachelines per triangle on average, and since it's always a fetch-modify-writeback operation, that saves a lot of memory bandwidth. I never got around to implement that approach fully, though. Also, WASM really sucks for when what you really want to do is handroll native assembly, since the XMM registers don't get shadowed / renamed like the scalar 64-bit registers (as far as I can tell), so you manually have to take care of register usage so that multiple executions can run in parallel. It also sucks that WASM doesn't have prefetch instructions.

Basically I had a SIMD preprocessing stage for the triangles, which also ran a classifier on it, and then had a switch, which looked at a pair of triangles (whether they were one pixel, ≤4x4pixel, or larger), and then inlined the whole code to draw that sequence in each case, so that I only had one branch miss on every second triangle. If I could handroll that in assembly, I could make do with less code duplication and smaller code size and all that, probably, but since I was doing that in the browser with WASM, I couldn't use any of the more involved techniques.

I think the popular approach of using buckets and multiple threads actually sucks. Where you pre-sort the triangles into multiple spatial buckets, and then have different threads handle different buckets. I don't think the cost of the bucket sorter is doing any good, but I haven't implemented both versions for a fair comparison. Also depends on how big your caches are and all that.

JoeJ said:
Surprise, Nanite uses traditional scanlines. I looked up the very first code, and it had surprising low complexity to do this.
Very good work. Eventually worth a look even if you don't believe in ‘unlimited detail’ (which is just an application).

That's just the straightforward and natural way you would do that anyway. It makes everything much simpler.

I just remembered this video, and I think it was very impressive:

Walk with God.
JoeJ
JoeJ

RmbRT said:
From full HD upwards.

That's high res. Then you also need high res geometry, better lighting, and more expensive stuff.
With a lower image resolution, human eyes are much more forgiving to approximations.
Though, low res really benefits from anti aliasing, which is expensive too.

One alternative i would consider is a point splatting renderer like in Dreams. Avoids a lot of triangle problems e.g. large vs. small, clipping, etc. But also introduces new problems (holes, requirement for dense content).

RmbRT said:
XMM registers

Why a SW rasterizer for x86 CPUs? Every x86 computer also has some GPU?

RmbRT
RmbRT

JoeJ said:
Why a SW rasterizer for x86 CPUs? Every x86 computer also has some GPU?

I just wanted to make a proof of concept for a new approach to software rendering on a CPU. I started out in WASM since it's so easy to render to a canvas in the browser, but if I'm already trying to model an algorithm that needs to have high performance, then I also need to optimise it for the test machine it runs on. If I had an ARM computer, I'd be wanting to do use ARM assembly. Anyway, if I find a solution that is really fast on an x86, then I can identify pain points and let those flow into my FPGA ISA design. But the general intent was just to fully leverage the capabilities of a CPU for rendering, and to see what kind of algorithm design that would favour.

And in addition to finding out what kind of algorithm you would use to get the maximum possible rendering performance out of a CPU, you also find out what kind of input you want for that algorithm, how it wants to be used, etc. For example GPUs nowadays suck at triangles <2×2 pixels, because they render 2x2 pixels at a time, always. On a software renderer, a 1-pixel triangle can simply be translated into a single write operation (depending on pixel buffer layout), and is cheaper than a multi-pixel triangle. Triangles just larger than 4×4 pixels would actually be quite a bit slower than a ≤4×4 pixel triangle in my implementation, since it would have to compute slopes and all that via division (again, in the current design only), and that is just expensive. A huge triangle however would be quite fast, too. So in its current design, you would want to ensure that you either do large triangles, or very small ones that typically don't get larger than 4×4 pixels. And maybe preparing the input in a certain way could also help, so that has to regather less context during preprocessing. So if you could somehow already ensure that certain geometry is guaranteed to be ≤4x4 pixels per triangle, or guarantee that it is large, then it doesn't have to do the classifier step. Or if you could guarantee that there is no order dependence during a certain sequence of geometry, that would also help a lot. Another thing is that you can easily define perfect shapes such as spheres on a CPU, which is harder to do on a GPU. And you can directly insert knowledge of the topology into the rendering algorithm, and you can finally reintroduce proper quads, which can also ease the load on the renderer a lot, too.

For example my vision for quads is that you provide 3 points, and the fourth point is computed as being the mirrored first point, so it simply mirrors the first triangle. And then if you make a quad strip, you only add one more point to define another quad:

A --- B --- D --- E
|   /#|   /#|   /#|
| /###| /###| /###|
C --- 1 --- 2 --- 3

Points A, B, C, D, E are given in the vertex buffer, and points 1, 2, 3 are calculated from the other points on the fly (the #-shaded triangles are simply mirrored from their neighbour). This completely removes the edge case of nonplanar quads, because they will by definition be planar. And the renderer can make use of that knowledge, and doesn't have to attempt to draw two triangles, but can instead have an optimised routine for drawing a quad. Of course, the geometry would still end up being transformed spatially, so it wouldn't just be a literal rectangle.

Walk with God.
JoeJ
JoeJ

RmbRT said:
That's just the straightforward and natural way you would do that anyway. It makes everything much simpler.

But scanline renderer is much more complex than bounding box with test per pixel. You need to sort edges, set them all up, iterate edges. For the bounding box you only need the 3 edge equations to do the brute force test. Much simpler, and SIMD can evaluate all 3 equations at once.

Nanite picked the scanlines because a single thread draws one triangle, and reducing processed pixels to the minimum also reduces execution divergence.
But GPUs picked the brute force box because it's easy to parallelize for a thread per pixel approach.

If your geometry resolution is not crazy high, the simple box approach would be better, probably?

But actually, the most efficient would be both - a coarse scanline method to find overlapping tiles, then brute force per tile.
Due to the coarse culling, not many threads are wasted on empty pixels.
That's how GPUs currently do it, afaik. But i expect they will add an additional fast path for small triangles with next gen consoles.

It works, but it's very complicated. There must be a better way, using a simpler primitive. So points instead triangles.
Voxels have been explored to death already, but points not so much. The surprising success of Spherical Gaussians seems quite a wink.

JoeJ
JoeJ

For example my vision for quads is that you provide 3 points, and the fourth point is computed as being the mirrored first point, so it simply mirrors the first triangle.

Btw, i think the Sega Dreamcast could only render quads, no triangles.

But i don't think you idea gives a big benefit, if at all.
1. Likely you use many quads to model a kind of grid, which then forms boxes, cylinders, etc. But if so, the vertex you want to spare must exist anyway, for one of the adjacent quads. Sp you do not spare it's memory. You could spare some vertices by rotating winding order of the adjacent quad, but it's not much for the complexity.

2. Quads can not do curved surfaces, except cylinders or spheres for example. But for organic curved models, a quad won't be flat, and thus you must split it into triangles.

But i see potential wins from similar ideas:
Building pairs of triangles to form quads, which can be done on arbitrary meshes so we end up with only a small percentage of pure triangles. The quads are still rendered as 2 triangles, but often the quad memory layout allows for optimizations. Intel uses this for Arc ray tracing for example.

Allowing entire grids of quads as a rendering primitive, so the same idea and advantage, just extended to larger patches of x * y quads.
It could take an array of vertices in intrinsic order, not requiring any index buffers for a primitive.

Grids of quads are quite common and useful, but imo only if they support arbitrary curvature, and thus triangulation in the end.

RmbRT
RmbRT

Quads still make a difference even if they don't necessarily save total memory, because they still save the bandwidth at which the GPU has to fetch vertices from the buffer. A quad strip via triangle strip requires two vertices per quad, while a true quad strip would only require one. And you can still save memory by having only every second row in a grid defined, like this:

A --- B --- D --- E  // starts with ABC, continues with D, E
|   /#|   /#|   /#|
| /###| /###| /###|
C --- 1 --- 2 --- 3
| \###| \###| \###|
|   \#|   \#|   \#|
F --- G --- H --- I // Starts with FCG, continues with H, I

The row below that, though, can only be done via indexing, or by creating a more complex primitive. Which is of course not an issue if you can just inject a routine for that into the renderer. And of course you can also generate geometry procedurally on a software renderer, or draw things that aren't really defined by a geometric primitive, since you have direct access to the frame buffer. I guess modern GPUs can somewhat do similar things, too, at least the procedural generation of geometry by emitting triangles from within a shader. Never played around with that, though.

Another obvious primitive would be a real rectangle for sprite blitting or something. Maybe rotated, or maybe not. Would help with GUIs and 2D games in general.

JoeJ said:
Grids of quads are quite common and useful, but imo only if they support arbitrary curvature, and thus triangulation in the end.

Yes and no. You would probably want smoothed out surfaces, but they don't necessarily need to be made up of triangles. You could literally have something that “raytraces” a curved mesh, without actually involving triangles. But you could also have something that does triangulate it to various LODs. That's the beauty of software rendering. The problem is just that CPUs aren't that well-suited for the massive parallelism, and GPUs aren't that well-suited to arbitrary rendering methods.

JoeJ said:
Allowing entire grids of quads as a rendering primitive, so the same idea and advantage, just extended to larger patches of x * y quads. It could take an array of vertices in intrinsic order, not requiring any index buffers for a primitive.

Yeah, that would be great, too. And you could specify a LOD method which could automatically perform even increased triangulation on a quad if it is close/big, and less if it is small. And if it gets too small, it can also merge quads into larger quads. I guess that's somewhat like nanite's LOD reduction. And it can do this LOD morphing gradually as a smooth transition.

If I had one of those “3D” series CPUs with their insane cache sizes, I could probably write a crazy-fast software renderer like Brilliant Games did in that tech demo. But the reality is that on most consumer devices, even a full HD image at 3 bytes per pixel does not fit into last-level cache, so you might get lots of cache misses during rendering. My laptop has only 4MiB of LLC, and a full HD picture takes 6MiB, or 8MiB if you have an alpha channel / 4-byte aligned pixels.

The sad truth, though, is that even if I do build an FPGA CPU that supports this shader-like execution model, it won't have enough cache, either, and will run at slower clock speeds and higher power draw, and at lower circuitry complexity, so it will not compare. But at least it would be a solid foundation that could one day be converted into silicon. If a CPU was designed from the start to be also well-suited for software rendering, then that would also make it extremely powerful for all kinds of things besides rendering, too. And you would finally no longer need a dedicated GPU, probably. Meaning also no more drivers, and we would finally return to the age of simply drawing pixels to the screen.

But quads aren't really the main selling point, anyway. It was just some small thing I noticed that you could do on a software renderer that you can't really do well on a triangle-based GPU. There are probably much more awesome things that you can do in software that aren't feasible in hardware that I'm just not aware of.

Walk with God.
JoeJ
JoeJ

And you can still save memory by having only every second row in a grid defined, like this:

Yeah, but you need to know vertices 1, then 2, before you can calculate 3. This dependency enforces serialization, and caching vertices becomes more complicated and necessary.

And worse: This only works for perfect grids. So not only you prevent curvature, but also arbitrary vertex placement on the plane.
(The only reason to tessellate a surface which can be represented by a single flat polygon is to generate arbitrary texture coordinates at desired spots, which you have just disabled as well)
You can still tessellate a box or a cylinder, but no cone for example. Try to model anything in blender where all those constraints are met and good luck on that.
(Btw, there exists special software for modern architecture design which tries to flatten the faces of a quad model, so it could be build from glass. For architects such constraints can be interesting, but for 3D artists trying to make general game models it just becomes pain.)

So you end up with a potential optimzation which can be used only in rare special cases, and likely isn't worth the added complexity.
Notice that are no more triangle strips in modern APIs afaik. Even this optimization which seems general turned out to fall in this category.

RmbRT said:
I guess modern GPUs can somewhat do similar things, too, at least the procedural generation of geometry by emitting triangles from within a shader.

Yeah, it's very flexible now with mesh shaders.
But it's more interesting for you to analyze history how they got there:
NVs first gfx chips could not do triangles but only curved parametric patches, targeting CAD.
It was not successful.
But they tried again, later with HW accelerated OpenGL bezier patches for GeForce3.
But the feature was removed from the next chip generation.
I have emailed them asking why, since i used it and it was super fast. The legendary Cass Everitt himself replied, telling me nobody else used it, so it had to go.
But they tried again, much later, with tessellation shaders. This was somewhat flexible. It was used and became supported by all APIs and other IHVs. It gave us displacement mapping in games. But because displacement mapping requires a seamless UV parametrization, in practice it can be used only on topologically flat surface patches. So we saw it used only on terrain heightfields in practice.

So, are tess. shaders worth the silicon? No. It's still not flexible enough, and pretty useless.
All it was good war is to make modern GPUs so complicated, competing companies can not enter the GPU market.
Instead, we converge towards a monopol, where only one company dominates all the market and becomes super rich.
Which is what happened, as expected from american economy.

Now, after all that special case shit, we eventually arrived at a pro-per solution: Mesh shaders, which are finally fully flexible and pretty cool.
But at the same day their practical application was diminished, because raytracing can not support any form of tessellation or procedural meshes.

Modern GPUs are a disaster of restricted fixed function circuits implementing legacy crap, hindering long term progress much more than it helped it in the short term.
Lesson learned: Flexibility > efficiency.

Imo, modern GPUs should be just compute and texture filter units. No rasterization at all, and no triangle raytracing, and please no black boxed acceleration structures. We would not loose as much as we think, and more companies / countries could make their own GPUs, leading to healthy competition and progress, and better prices.

RmbRT said:
Yeah, that would be great, too. And you could specify a LOD method which could automatically perform even increased triangulation on a quad if it is close/big, and less if it is small.

But why would you want to tessellate a flat grid at all in the first palce? It remains flat, so the tessellation adds no visible detail.
It can be useful for curved patches, yes. E.g. cloth, Nurbs, etc. But that's all again just special cases.
I was missing such grids back then, when we had triangle fans and strips. It would have made sense at this time.
But those times are gone. Modern consoles and gaming PCs neither need nor want such optimaztions, imo.

Though, mobile / handheld is another story due to power limits. Fixed function is still critical here.
And you may fall into this category of expected performance, so maybe you can't join my ‘SW flexibility > HW fixed function’ mindset on this.

RmbRT said:
But the reality is that on most consumer devices, even a full HD image at 3 bytes per pixel does not fit into last-level cache, so you might get lots of cache misses during rendering.

But you don't need the framebuffer to be cached at all, since you rarely read from it (except depth).
You rather need cache for the geometry and textures you actually read.
Frame buffer can be tiled. Requires to process some primitives multiple times, but easy to tune for the best compromise.

RmbRT said:
The sad truth, though, is that even if I do build an FPGA CPU that supports this shader-like execution model, it won't have enough cache, either, and will run at slower clock speeds and higher power draw, and at lower circuitry complexity, so it will not compare.

Yeah, thus your HD resolution target feels too optimistic to me. Idk ofc., but i want to say that to me a high display resolution is no selling point at all. I also don't care about a high texture resolution. Neither makes games looking better imo. It's often just a waste.

Maybe that's just me. I see so many complaints about low texture resolution in technical game reviews. Though, maybe that's because low res is easy to spot to the untrained eye, while e.g. flaws in lighting are hard to identify and describe. So maybe low resolution is often just the scapegoat chosen out of incompetence.

RmbRT said:
If a CPU was designed from the start to be also well-suited for software rendering, then that would also make it extremely powerful for all kinds of things besides rendering, too.

It has been tried with Intels Larrabee. But it failed since it was neither a good CPU nor a good GPU.
I don't see how one architecture could fit both needs. Massive parallel processing vs. single threaded general purpose is really two completely different things.
No, i believe the perfect HW for games already exists, but only in the console space. CPU and GPU on one chip, but with high bandwidth memory. That's what we need to save the PC platform. But what do we get? Strix Halo AI workstations for 2000 bucks. >:(

It's depressing, so i often think about you and your crazy plan to make your own HW. You are somewhat right.

RmbRT said:
There are probably much more awesome things that you can do in software that aren't feasible in hardware that I'm just not aware of.

Yeah, maybe. But i see the biggest chances on innovation by omitting triangles as the primitive. Triangles require adjacency, which is both their strength and weakness.
I already use point splatting to generate environment maps for my GI probes. But i calculate visibility before this rasterization step using ray tracing.
Next on my todo list is a new attempt to merge those tasks with only rasterization methods. I've tried this before, but it was way too noisy to work.
Now i have some now idea to increase accuracy using moments. Not sure if it's practical, but if it works maybe i can use it also to render the primary image…

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.