N64 additive transparency

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
N64 additive transparency
by on (#203319)
Apparently the blender did have an additive mode, but it didn't clamp the output. Assuming this is true, it explains a lot. The lack of additive transparency had a profound effect on the visual character of the system; if I could change one thing about the N64, this might be it.

Is this behaviour easy to change in microcode, or would you have to go the long way (load the framebuffer as a texture, do the addition and clamping in the render units) and kill your fillrate? Or is it outright impossible?
Re: N64 additive transparency
by on (#203321)
As I understand it, RSP microcode is just a vertex shader and isn't intended to do things to individual pixels.
Re: N64 additive transparency
by on (#203325)
From what I've heard, Tepples is correct. If I'm not mistaken, the RSP gives the RDP different parameters for drawing something, (does the geometry) and the RDP renders it. Getting the RSP to actually draw anything (if it's possible at all) would probably be prohibitively slow. (It would have to be done in software.)

I'm surprised the lack of additive blending is what you would first change about the N64. Most people complain about the low resolution textures (small texture cache, although I think cartridge space had just as much to do with it) or the "Vaseline covered" video. (I have no idea what this is caused by, but it seems more prevalent is some games than others.)
Re: N64 additive transparency
by on (#203337)
The texture cache was twice the size of the one in the PSX, and as Rare showed it was certainly possible to work around it. Nintendo/SGI were just stingy with their tools. The RDRAM was high-latency, sure, but it was very fast and there weren't a lot of better options available at the time. I'm sure the CPU/RAM interface could have been improved, but I'm not a hardware engineer so I don't know what you'd have to sacrifice to do that. It'd be a major change for sure. The cartridge format had advantages and disadvantages vs. CDs, and the lack of FMV never bothered me; IIRC the N64 basically pioneered the "in-engine cutscene" for this very reason. And I'm pretty sure you could turn off both antialiasing and texture filtering if you really wanted to.

But the blender not clamping its output is just a straight-up dumb move. Take a look at this:

Attachment:
bodyharvest1.jpg
bodyharvest1.jpg [ 7.2 KiB | Viewed 8878 times ]

Or this:

Attachment:
naboo1.jpg
naboo1.jpg [ 17.78 KiB | Viewed 8878 times ]


Notice how despite the fact that they look like they're from different generations, they both have the same problem. Faking it with alpha just doesn't cut it. The only thing that looks decent is pure white.

From the looks of things, the color combiner clamps its output (or at least it clamps the chroma key operation, and the description of the blender - which is immediately downstream of the color combiner - asserts that all the inputs are clamped), and the formula does look flexible enough to do additive transparency. Unfortunately it doesn't operate on framebuffer pixels, meaning you would indeed have to do this the long way. Maybe the really long way, if you can't convince the RDP to combine transformed and untransformed texture data...
Re: N64 additive transparency
by on (#203338)
The gpu *can* be programmed to do fullscreen effects, it's that flexible. The RE2 port used it to do colorspace conversion in the FMVs, the article even includes the code.
Re: N64 additive transparency
by on (#203341)
What I mean is that you can't use the current framebuffer pixel directly as a source for the color combiner. That's the blender's job. It seems like if you want to do additive transparency with the color combiner, you have to get the framebuffer in the front end of the pipeline somehow, and the easiest way to do that is probably through the texture cache.

Now the question is: can you combine a transformed, perspective-corrected trilinear-interpolated texture map with a linear bitmap this way? If not, you might have to draw each additive object to a blank buffer and load it in together with the relevant section of the framebuffer to do the combination properly. (Maybe I should look into how environment mapping works.)

You could also just convert the scene to 24-bit (without expanding the RGB values) to give yourself some headroom for the blender, and then just clamp it back to 15-bit after drawing all the additive objects. But that only gives you enough room for about 7 whites stacked on top of a light background before it overflows...

The point is, all of this extra maneuvering costs fillrate, which is the bottleneck on the N64. It'd probably be okay for a modest number of objects, but a busy battle scene full of lasers and explosions could be a problem. As a non-expert, I'm not sure how much of a problem exactly, but if Nintendo/SGI had just clamped the output of the blender this wouldn't be an issue.
Re: N64 additive transparency
by on (#203746)
I'm sorry if this seemed like a bit of a rhetorical question. It wasn't. The responses actually resulted in me getting [what I think is] a better understanding of how the RCP works, once I cross-checked what people were saying with what I thought I remembered from the manual.

So I guess I got what I asked for, if not exactly what I wanted.

...

The N64 is a bit frustrating for me, since I'm reasonably sure I will never be able to produce a game that maxes out the hardware. It's too much work. The SNES is on the border, but this... I maintain that BotW is probably possible on N64. The idea that I might be able to prove it some day - even with a team behind me - is laughable. That's just an example, but it's illustrative.

It's fun to read about the N64's internals, but I think I'll end up sticking to SNES. Just finishing my current project is a big enough challenge...
Re: N64 additive transparency
by on (#203758)
93143 wrote:
I'm reasonably sure I will never be able to produce a game that maxes out the hardware. It's too much work


Only way I know of to do this is to go back in time and work with Rare on Perfect Dark.
Re: N64 additive transparency
by on (#203761)
As good as Perfect Dark looks, It shouldn't make the N64 run at 12fps.
Re: N64 additive transparency
by on (#203779)
It's not like it's hard to go beyond the commercial era, just by writing your own microcode, which most of them never did :P
Re: N64 additive transparency
by on (#216380)
Merging in my reply to the post in this thread http://forums.nesdev.com/viewtopic.php?f=5&t=17169&start=30#p216192

93143 wrote:
I'm just saying that there was a surprising amount of overlap given the power difference, which may be attributable to the N64 being hard to program, compounded by the inefficient official microcode holding the system back

I would say for the vast majority of developers any inefficiencies in the official microcode would not have been problem, because they would have been memory bandwidth bound well before they were at the stage to push RSP hard. Rather, the issue was that the official microcode was built around the use of a z-buffer, which guzzled away at precious memory bandwidth (as noted in my previous post, the N64 did not have significantly higher "peak" memory bandwidth than its console competition anyway).

The more technically advanced N64 games, with memory bandwidth under a certain level of control, could certainly have put pressure on RSP. For example, Conker with its multiple light sources, or the Factor 5 games with their relatively complex terrain generation from heightmaps. I believe the consensus among developers was that SGI did not get the balance right in the official microcode between vertex/lighting quality and performance (probably owing to their workstation background), which is why the top-level developers had to tweak provided microcodes or write their own. SGI did actually provide updated versions of the official microcode throughout the N64's life which would have made life a fair bit easier. As for the official audio microcode, it seems to have been unnecessarily resource hungry, maybe because SGI did not have the experience of an audio hardware company. For developers like Factor 5 who needed to squeeze more performance out of RSP, they wrote their own audio 'driver'.

93143 wrote:
Comparing bad N64 games with good PlayStation games can make it look like the PlayStation was more powerful, which is not something you tend to get with (say) the NES vs. the SNES

I don't think I quite understand your point here. It has always been true that the best programmed games on weaker hardware in a console generation look better than the worst programmed games on stronger hardware in the same generation. For example, the Xbox was unequivocally stronger than the PS2 (blending aside, thanks to eDRAM) but Xbox game Bruce Lee: Quest of the Dragon looked worse than the older PS2 game The Bouncer.

The comparison between NES and SNES is not legitimate because the technical difference between the two consoles was several times that of PS1 and N64, or PS2 and Xbox. A sufficiently large generational difference in technology and tools will usually rescue even poorly programmed games from looking less graphically advanced than older titles.

93143 wrote:
Speaking of RAM, what was the latency like on the RCP side? I've heard figures as high as 600 ns for a CPU cache miss, but I can't imagine that's representative of RCP random access

600ns for a CPU cache miss sounds right. Of course that timing also accounts for the memory controller being built into RCP and being physically external to the CPU. That means the latency for RCP's random access will definitely be lower but I'm not sure exactly by how much.

93143 wrote:
Also, I believe the N64's RAM was divided into four banks; did this have any relevance to latency?

It is divided in two banks, with color intended to go into one and z into the other (though not mandatory), but the banks are not simultaneously accessible. Yes, it's supposed to greatly decrease latency through address pipelining. Because RDRAM does row and column addressing separately, you should theoretically be able to change banks without incurring significant latency even though the access is going outside the current page (which should be useful when switching between color and z buffers). Unfortunately, like most things related to RDRAM, in practice it didn't work nearly that well so you still got much of the latency. Though I'm unsure if the fault was with the RDRAM design itself or the memory controller in RCP.

EDIT: Oops. Checked into it. The RDRAM really is divided into four banks.

Texture cache is divided into four simultaneously accessible banks, though. That's how RDP achieves one-cycle bilinear filtering.

93143 wrote:
And yet, it seems that certain late games, such as World Driver Championship, managed to match or exceed the PlayStation's advertised capabilities (180,000 textured tris per second) while maintaining the additional features that made N64 polygons so power-intensive...

World Driver Championship didn't use a z-buffer, so that meant it was far less memory bound than most other N64 games. As RSP is both wider and clock-faster than GTE, and RDP has almost double the pixel-fill rate of PS1's GPU (even with most features turned on) it's unsurprising that N64 can put out considerably more and better polygons than Playstation when memory bandwidth is out of the way. Not having a z-buffer won't be good in every situation though, so that's why SGI would have considered z-buffering the sensible "default option". EDIT: More choice for developers would have been even better...

93143 wrote:
I'm sorry; I can't accept that without more detail. What's wrong with the methods I proposed? I could guess, but that's not a path to edification

My apologies, I was simply describing what would have been SGI's intended use case for RCP's additive blending. I have the following points to make about the theoretical workaround described in your earlier post.

1) Yes, the color combiner does clamp its output.

2) Copy mode won't increase the speed of copying the framebuffer into TMEM (that would continue to be memory bus bound anyway). All copy mode does is make pixels go through RDP's pipeline faster by skipping almost all processing. So rather than making framebuffer -> TMEM go more quickly, it would make TMEM -> framebuffer go faster. The purpose is to make 2D tiling really fast.

3) I don't think you can have reliable pixel-level control over primitives already dispatched to RDP (not without insane cycle counting across the whole console, anyway). So you can't change RDP attributes or modes on individual primitive pixels and get expected results every time. Reliable per-primitive changes are possible through the synchronization function though.

But I think what you are describing is definitely possible with the color combiner in two cycle mode. The color combiner maths is newcolor = (A - B) x C + D. So you could write your own color combiner function like this newcolor = (1 - 0) x TEXEL0 + TEXEL1, with TEXEL0 being the texture for blending, and TEXEL1 being the framebuffer chunk both loaded into TMEM. You could still use the result of this in a second color combiner operation. The N64's little 'pixel shader' may yet save the day.

I haven't given sufficient thought as to what this would mean for the blender (including anti-aliasing or fog) so I may get back to you on that. But as you can imagine, this would be hell on TMEM. I still think it may all be madness in practice, but maybe it is not.

There's no way to safely pre-clamp the pixels if you want to use the blender, except as I stated before, be really conservative and cautious with the hardware additive blending feature as SGI intended. I suppose you could do the additive blending with the CPU if you wanted for some software rendering. Since the N64 has a unified memory architecture, the CPU can just read/write straight to the framebuffer. Hardly an efficient use of resources, but it's there.
Re: N64 additive transparency
by on (#216392)
realityengine wrote:
93143 wrote:
Comparing bad N64 games with good PlayStation games can make it look like the PlayStation was more powerful, which is not something you tend to get with (say) the NES vs. the SNES

I don't think I quite understand your point here. It has always been true that best programmed games on weaker hardware in a console generation looks better than the worst programmed games on stronger hardware in the same generation. [...]

The comparison between NES and SNES is not legitimate because the technical difference between the two consoles was several times that of PS1 and N64, or PS2 and Xbox. A sufficiently large generational difference in technology and tools will usually rescue even poorly programmed games from looking less graphically advanced than older titles.

Could comparison of graphical production values between inter-generation consoles and both the best of the previous gen and the worst of the next gen be valid? Examples could include good NES games vs. bad TG16 games, or good TG16 games vs. bad Super NES games. Or ColecoVision/MSX between Atari 2600/Intellivision and NES, or Jaguar and 3DO between Genesis/Super NES and Saturn/PlayStation.

realityengine wrote:
600ns for a CPU cache miss sounds right. Of course that also accounts for the latency of the memory controller being built into RCP and existing externally to the CPU.

GPU-on-the-northbridge is also seen in Xbox 360 and Intel GMA. How do those overcome it? Is the embedded VRAM in the Xbox 360's Xenos northbridge/GPU the key?

realityengine wrote:
World Driver Championship didn't use a z-buffer, so that meant it was far less memory bound than most other N64 games. As RSP is both wider and clock-faster than GTE, and RDP has almost double the pixel-fill rate of PS1's GPU (even with most features turned on) it's unsurprising that N64 can put out considerably more and better polygons than Playstation when memory bandwidth is out of the way. Not having a z-buffer won't be good in every situation though, so that's why SGI would have considered z-buffering the sensible "default option".

What's the standard workaround for lack of depth buffering? I've heard a few, such as running bin sort on triangles or precomputing each object's ordering from each of the 8 corners of the bounding cube. Is there a way to write Z but not read Z, in order to have geometry intersect a transparent water plane?
Re: N64 additive transparency
by on (#216399)
tepples wrote:
Could comparison of graphical production values between inter-generation consoles and both the best of the previous gen and the worst of the next gen be valid? Examples could include good NES games vs. bad TG16 games, or good TG16 games vs. bad Super NES games. Or ColecoVision/MSX between Atari 2600/Intellivision and NES, or Jaguar and 3DO between Genesis/Super NES and Saturn/PlayStation.

I'm not setting a strict rule. Of course it is possible to make even a PS4 game have less advanced 3D visuals than a Sega Saturn game! It just gets less and less likely as tech and tools get better. A comparison IMO is really only valid when the specs are sufficiently close. 'Sufficiently' is subjective.

tepples wrote:
GPU-on-the-northbridge is also seen in Xbox 360 and Intel GMA. How do those overcome it? Is the embedded VRAM in the Xbox 360's Xenos northbridge/GPU the key?

The GPU being on the same die as the memory controller is actually an advantage to the GPU, since it can access RAM with less latency than the CPU. So I'm not sure what exactly you mean by those GPUs needing to overcome something. Either way, it's not an absolutely massive difference. Intel CPUs only stopped having external memory controllers with Core i7 in 2008. IIRC AMD moved to internal memory controllers with Athlon 64 in 2003. Yet, AMD's Phenom demonstrated no substantial memory advantages to Intel Core 2 Duo. The Athlon 64 demonstrated memory advantages over the Pentium 4, but maybe that was just because the Pentium 4's architecture wasn't particularly good.

tepples wrote:
What's the standard workaround for lack of depth buffering? I've heard a few, such as running bin sort on triangles or precomputing each object's ordering from each of the 8 corners of the bounding cube.

The Z-Sort microcode, which was an official (yet feature incomplete) N64 microcode that formed the basis for Boss Studios titles (e.g. World Driver Champion) allowed developers to provide any suitable triangle sorting algorithm which would then be used to generate back-to-front display lists.

BSP trees were also very popular. There was also the Crash Bandicoot approach of just pre-computing the depth buffer on workstations (meant no user camera control though).

tepples wrote:
Is there a way to write Z but not read Z, in order to have geometry intersect a transparent water plane?

Do you mean on N64 or more generally?
Re: N64 additive transparency
by on (#216407)
realityengine wrote:
93143 wrote:
Comparing bad N64 games with good PlayStation games can make it look like the PlayStation was more powerful, which is not something you tend to get with (say) the NES vs. the SNES

I don't think I quite understand your point here. It has always been true that the best programmed games on weaker hardware in a console generation look better than the worst programmed games on stronger hardware in the same generation.

Part of the problem is that it's difficult to be precise when I'm trying to express my interpretation of my impression of other people's opinions. What I mean is that the N64 (for debatable reasons) failed to convince a certain subset of gamers that it was even more powerful than the PSX at all. There's a popular perception that PSX games tended to be higher-poly than N64 games, and have higher-res textures; even if this is partly or largely false, there's a reason people think this stuff. And there are definitely people who prefer the PlayStation's image quality. Maybe there's fanboyism mixed in there, as there tends to be with Mega Drive audio vs. SNES audio, but as in that case there's something to be said for it. PSX polygons plus high-level artistry could look very impressive, particularly in screenshots, or to someone who'd decided he didn't care about affine swim or vertex jitter, or preferred jaggies to blur. And yes, I believe additive blending helped. Prerendered backgrounds and FMV absolutely helped...

It was possible for the N64 to trounce the PSX pretty much on all counts in terms of real-time graphics, as demonstrated by a handful of high-level games. But it seems to have been unusually difficult to get anywhere near that level, leading to the comparison being much more of a matter of taste than it should have been given the power gap on paper.

The fact that some people think the PS2 was massively more powerful than the GameCube is much more bewildering. Maybe they're just going on published performance numbers (which were extremely apples-to-oranges that gen)...

Quote:
The comparison between NES and SNES is not legitimate because the technical difference between the two consoles was several times that of PS1 and N64, or PS2 and Xbox.

The SNES wasn't all that much more powerful than the NES. Twice the CPU clock speed, twice the word length (but an 8-bit bus that nerfed it a bit, not to mention slow ROM and RAM), similar resolution and video architecture but with higher-quality pixels (kinda like the N64 vs. the PSX) and, uh... six times the video memory bandwidth, with the PPU beefed up to handle it. Yeah, that could be important...

Okay, it's not a great analogy...

Quote:
It is divided in two banks, with color intended to go into one and z into the other (though not mandatory), but the banks are not simultaneously accessible.

Are you sure? I've seen a reference to it having four banks of 1 MB each, and a reference to it having two banks of 1 MB each.

Quote:
Copy mode won't increase the speed of copying the framebuffer into TMEM (that would continue to be memory bus bound anyway).

I was kinda thinking out loud there. I had absentmindedly assumed that copying the framebuffer into TMEM would take the same amount of time as drawing a pixel, which was never true, but that's what I was comparing copy mode to. (I believe copy mode can be used for loading TMEM, so you wouldn't have to do the transfer entirely manually, but I suppose whether using copy mode is a good idea would depend on the implementation.)

Quote:
I don't think you can have reliable pixel-level control over primitives already dispatched to RDP (not without insane cycle counting across the whole console, anyway)

That's what I was afraid of. I don't know how mipmapping works, but I assume it just uses the same coordinate transform on a different texture tile. Changing the transform would appear to be out of scope.

Quote:
But I think what you are describing is definitely possible with the color combiner in two cycle mode. The color combiner maths is newcolor = (A - B) x C + D. So you could write your own color combiner function like this newcolor = (1 - 0) x TEXEL0 + TEXEL1, with TEXEL0 being the texture for blending, and TEXEL1 being the framebuffer chunk both loaded into TMEM.

But where would you get TEXEL1? It has to change per-pixel, but not based on the transform you used to get TEXEL0. Can you get the RDP to load one of the constant colour registers from TMEM every other cycle?

It would work fine going the long way, by pre-rendering the additive graphic and reloading it as a texture so you can just step through the pixels one by one (and maybe you could speed that up by pre-rendering and reloading in 8bpp indexed, if the colour profile is sufficiently one-dimensional or if you don't mind nearest neighbour), but I don't see how you get this in one step unless the additive graphic is to be rendered untransformed (like in a 2D sidescroller or something).

...

Wait a minute. The rasterizer generates an RGBA pixel value in addition to the texture coordinates and LOD level. Where does that come from? Is it just the vertex shader value?

Quote:
There's no way to safely pre-clamp the pixels if you want to use the blender

The method I described should work mathematically. It's not an attempt to avoid TMEM thrash; it's just a modification of the color combiner method to maybe improve framebuffer metadata handling. Use the first color combiner cycle to do the clamped add, then use the second cycle to subtract the framebuffer texel from the added and clamped sum (the result of this subtraction cannot overflow, so it won't be re-clamped). The output of this process should be blender-safe by simple arithmetic, since it's exactly the result you want minus the thing you're about to add it to.

Code:
CC0: COMBN = max(0,min(255,(1-0)*TEXEL0+TEXEL1))
CC1: PIX = max(0,min(255,(0-1)*TEXEL1+COMBN))
BL0: BLEND = PIX + MEM
BL1: MEM = BLEND

Or, in other words:

FBUF = clamp(SHINY+FBUF) - FBUF + FBUF

It may seem like a waste of math, and it means you can't actually shade the pixels because it uses both color combiner cycles just to pre-clamp them, but if it helps with antialiasing and/or Z-buffering it might be worth it.
Re: N64 additive transparency
by on (#216430)
Realityengine, do you know what was the optimal way to deal with large textures? Was Rare's way documented anywhere?

I can certainly imagine preprocessing to split models and textures to smaller ones, but I don't think that's the best way.
Re: N64 additive transparency
by on (#216466)
93143 wrote:
What I mean is that the N64 (for debatable reasons) failed to convince a certain subset of gamers that it was even more powerful than the PSX at all.

As stated in my previous post, I think it is mostly down to the fact there was more crossover between the most popular games on PS1 and those with the best visuals than there was on N64. Most of N64's best looking games were released in a later period where sales for the console had drastically slowed down.

93143 wrote:
Maybe there's fanboyism mixed in there, as there tends to be with Mega Drive audio vs. SNES audio, but as in that case there's something to be said for it.

Well, there are potentially three times more PS1 fans than N64 fans. Previously I alluded to poor N64 emulation being another factor. I think emulation had a parallel influence on recent online Mega Drive vs SNES audio debates. Putting aside whether one is actually 'objectively' better than the other at sound, for a long time (and continuing to some extent) the FM emulation of Mega Drive's audio was generally poor and (unduly) gave the console a bad name. Conversely, SNES audio emulation tended to be high quality and even sounded better than the real console, which you could argue gave its audio too good of a reputation. I think there is some similarity with PS1 and N64, where emulators would commonly boost PS1 visually and degrade N64's graphics.

93143 wrote:
The fact that some people think the PS2 was massively more powerful than the GameCube is much more bewildering. Maybe they're just going on published performance numbers (which were extremely apples-to-oranges that gen)...

I actually would have to go into the camp that says the two consoles were very similar in overall power. Texturing was of course far better on Gamecube, and unlike on PS2 you didn't have to produce ridiculously strange sized (and often blurry) framebuffers. But at the same time, the Gamecube's vertex hardware was extremely inflexible. So if you wanted to do any interesting vertex shading with dynamic elements, you would be completely stuffed. The CPU could not save you there either because it didn't implement full-SIMD but paired singles so its vertex performance was relatively low. Also the main memory should have been larger and faster to at least match PS2's main RAM, but it didn't. At the same time, Gamecube's auxiliary memory had such low bandwidth (81 MB/s) it's better to describe it as like a rewritable N64 cartridge on steroids as opposed to actual RAM. Additionally, even with the Gamecube's relatively good pipeline efficiency, there was no way for it (or the Xbox for that matter) to challenge the PS2's monstrously high destination blending speed.

With Gamecube, ArtX didn't set out to create a PS2 performance beater, but produce a 'cheaper PS2' with a much gentler development curve through smart design. I would say they succeeded very soundly. And while the Gamecube's vertex shader was inflexible, it actually had similar "peak" vertex power to Emotion Engine when the right situation presented itself. ArtX tailored Flipper to Factor 5's requirements (after Nintendo they were the main contributors to ArtX's 'how can we improve on RCP' developer forum), so the vertex shader's capabilities was a great fit for the Rogue Squadron sequels. PS2 was extremely difficult to get good performance out of it (there was a notorious Sony statistic presented around 2003 where the average PS2 game was only utilizing around 5% of one of the two vector units), but the top games do more 'interesting' things on the vertex end of things than the top Gamecube games, though framebuffer image quality always remained fairly bad on PS2 (it wasn't always perfect for Gamecube either - if you wanted destination alpha, you were forced into 6bpc framebuffers instead of 8bpc). TEV on Gamecube was often underutilized and underrated. Despite being a "fixed" pixel shader like the N64's color combiner, it actually had more flexible texture combine stages than the Xbox's GeForce 3. It's also a misnomer for some people to say the PS2 had no 'pixel shading'. While the PS2 didn't have a pixel shading unit, the multipass based design made creating pixel shading like effects with its blender a practical possibility.

The comparison between the two consoles is very multi-faceted and I would have only scratched the surface at most.

93143 wrote:
The SNES wasn't all that much more powerful than the NES. Twice the CPU clock speed, twice the word length (but an 8-bit bus that nerfed it a bit, not to mention slow ROM and RAM), similar resolution and video architecture but with higher-quality pixels (kinda like the N64 vs. the PSX) and, uh... six times the video memory bandwidth, with the PPU beefed up to handle it. Yeah, that could be important...

The SNES PPU is a massive leap over the NES PPU. It's the console's biggest asset, and arguably represents a fairly significant improvement over the Mega Drive VDP (though it still has some NES-like oddities in the sprite engine which hold it back somewhat).

93143 wrote:
But where would you get TEXEL1? It has to change per-pixel, but not based on the transform you used to get TEXEL0. Can you get the RDP to load one of the constant colour registers from TMEM every other cycle?
It would work fine going the long way, by pre-rendering the additive graphic and reloading it as a texture so you can just step through the pixels one by one (and maybe you could speed that up by pre-rendering and reloading in 8bpp indexed, if the colour profile is sufficiently one-dimensional or if you don't mind nearest neighbour), but I don't see how you get this in one step unless the additive graphic is to be rendered untransformed (like in a 2D sidescroller or something).

I'm not sure what you mean by 'pre-rendering' the additive graphic or constant color registers in TMEM (TMEM has registers?), but yes, one of the biggest issues would be ensuring that the 2D framebuffer coordinates used to create TEXEL1 match the rasterized 2D coordinates of the primitive which RDP is processing. The CPU would first have to generate the appropriate coordinate range, and then use this information to load TMEM. RSP can write out the result of its matrices to its data cache or main memory, so at least the CPU wouldn't have to do any transforms itself.

Mipmapping has nothing to do with it. RDP supports multitexturing without LOD.

93143 wrote:
Wait a minute. The rasterizer generates an RGBA pixel value in addition to the texture coordinates and LOD level. Where does that come from? Is it just the vertex shader value?

RGBA will come from RSP.

93143 wrote:
Code:
CC0: COMBN = max(0,min(255,(1-0)*TEXEL0+TEXEL1))
CC1: PIX = max(0,min(255,(0-1)*TEXEL1+COMBN))
BL0: BLEND = PIX + MEM
BL1: MEM = BLEND


Well I stand corrected. Your CC1 is quite a clever way of pre-clamping the pixels. In my mind I had incorrectly imagined that any value underflow would immediately be clamped (either intentionally or the internal register not permitting signed values), but of course the more likely behavior is that it will work properly with no clamping occurring until the end.

However, despite your ideas I think devoting one stage of the color combiner and one stage of the blender just to additive blending is unnecessary. If you look at how the hardware additive mode in the blender works, it has these particular blender flags turned on:
1) enable color/cvg read/modify/write memory access
2) don’t overwrite memory cvg (i.e. does not disturb the anti-aliasing of silhouette edges)
3) force blend enable
4) ZMODE opaque surface (i.e. updates z-buffer).

We know these flags are safe to use with additive blending, because SGI chose them for it. If you were to create a blending mode that used these flags but without the official additive mode being enable (just normal blend mode, which won't do very much here), it should be perfectly compatible with anti-aliasing and z-buffer in a single blender stage. However, note that SGI treat additive blended surfaces like they are opaque.
Re: N64 additive transparency
by on (#216469)
calima wrote:
Realityengine, do you know what was the optimal way to deal with large textures? Was Rare's way documented anywhere?

I can certainly imagine preprocessing to split models and textures to smaller ones, but I don't think that's the best way.

Good memory bandwidth management. I believe that was exactly Rare's method. Their games would constantly "defragment" the position of textures loaded in RAM. As main RAM suffered from a large random access penalty, this meant maintaining the position of textures in RAM that would facilitate, as much as possible, linear access or (less preferably but acceptably) banked access.

EDIT: Other good techniques were using low color depth textures (since they consumed less texture memory) and then adding color through vertex shading, and repeatedly tiling a texture (so as not to stretch it out too much) followed by using multitexturing to blend another texture a few times arbitrarily over the tiled texture to make the pattern look less repetitive and more detailed.

You needed to split models and textures into smaller pieces, since each primitive could only have 4 KB of texture data mapped to it at most. I imagine this kind of thing could have caused bigger headaches for artists than programmers. Switching in new texture data in the middle of a single primitive being rendered was not officially supported.
Re: N64 additive transparency
by on (#216477)
realityengine wrote:
93143 wrote:
What I mean is that the N64 (for debatable reasons) failed to convince a certain subset of gamers that it was even more powerful than the PSX at all.
As stated in my previous post, I think it is mostly down to the fact there was more crossover between the most popular games on PS1 and those with the best visuals than there was on N64. Most of N64's best looking games were released in a later period where sales for the console had drastically slowed down.

I think we're on the same page here.

Quote:
Putting aside whether one is actually 'objectively' better than the other at sound, for a long time (and continuing to some extent) the FM emulation of Mega Drive's audio was generally poor and (unduly) gave the console a bad name. Conversely, SNES audio emulation tended to be high quality and even sounded better than the real console, which you could argue gave its audio too good of a reputation.

Inaccurate emulation could make the SNES sound worse too. F-Zero sounded horrible in ZSNES because the engine noise was poorly emulated. Also, non-damping interpolation schemes sometimes brought out noise that the real system muffled, or threw off the intended mix balance, though I agree that in general they tended to be an improvement (you could compensate for the muffling with proper sample prefiltering, but I don't think most developers did).

One complicating factor is that the best-known games didn't always have the best audio, and there was unexplored potential in both systems. Comparing Sonic the Hedgehog with Super Mario World doesn't tell you much. Comparing Time Trax with Green Lantern gives you a better sense of the possible, but those still don't stretch either system to its limits. I'm not sure about the Mega Drive, but I'd say the S-SMP has still not been fully exploited even in the chiptune scene.

Quote:
I think there is some similarity with PS1 and N64, where emulators would commonly boost PS1 visually and degrade N64's graphics.

I'd consider that likely. A lot of people either only know emulation or have gotten used to it, and don't even realize or remember that PSX games had such bad polygons. I myself was away from my N64 for an extended period, and was surprised when I got back and realized that there were lighting effects in F-Zero X not properly represented in PJ64 - I knew how it looked originally, I knew the emulation was glitchy, and the emulator still trained me to think the game looked worse than it did.

Quote:
The comparison between the two consoles is very multi-faceted and I would have only scratched the surface at most.

Looks like it was even more apples-to-oranges than I thought...

Quote:
though it still has some NES-like oddities in the sprite engine which hold it back somewhat.

Tell me about it. I'm trying to port an advanced shmup to the SNES, and I can't even let myself daydream about being able to specify sprite sizes per-axis per-sprite like on the Mega Drive. I did get around the 16 KB limit, but the technique I used isn't easy to generalize...

Quote:
I'm not sure what you mean by 'pre-rendering' the additive graphic

Draw the additive graphic in a blank secondary framebuffer with the appropriate transforms and interpolation, and maybe vertex shading/mipmapping/fogging if desired, so it appears as it would onscreen. Then reload the result as a texture. This way you can just step through the pixels in both the additive graphic and the framebuffer texture, without worrying about the transforms being different between them. (It may be reasonable to pre-render whole objects rather than triangles, so that you're dealing with longer horizontal runs when reloading TMEM.)

(Can you use transforms and interpolation and such when drawing in 8bpp?)

Or is it actually possible to combine a transformed additive texture with an untransformed framebuffer texture in a single pass? I still don't have a clear idea of how flexible the rasterizer is. With a simple zoom you could just set the texture size appropriately, but anything more complex seems like it wouldn't work...

Quote:
or constant color registers in TMEM (TMEM has registers?)

No, the color combiner has registers, that can be used as sources for its operations. I assume you have to load them with the RSP, but I don't know for a fact that the RDP can't load them from TMEM automatically, so I asked.

Quote:
2) don’t overwrite memory cvg (i.e. does not disturb the anti-aliasing of silhouette edges)

Oh. Well, that solves that problem.

Quote:
4) ZMODE opaque surface (i.e. updates z-buffer).

This doesn't seem like such a big deal if you handle transparencies properly (draw them last, and/or use Z ordering). It shouldn't be necessary to use this setting; you'd get glitchy results either way if you did something dumb enough to need it. Not sure why I was worried...

realityengine wrote:
Switching in new texture data in the middle of a single primitive being rendered was not officially supported.

I believe that's what people claim Rare did. Not for all of their games, but supposedly some later ones. I can't find a reference and I may be wrong.
Re: N64 additive transparency
by on (#216485)
realityengine wrote:
Switching in new texture data in the middle of a single primitive being rendered was not officially supported.
This is exactly what I was curious about. Did anybody manage to do it, and if so, how.
Re: N64 additive transparency
by on (#216541)
93143 wrote:
I believe that's what people claim Rare did. Not for all of their games, but supposedly some later ones. I can't find a reference and I may be wrong.

How would this even work? Seems like you'd have to make a lot of assumptions for how the polygon is being drawn onscreen.

realityengine wrote:
As stated in my previous post, I think it is mostly down to the fact there was more crossover between the most popular games on PS1 and those with the best visuals than there was on N64. Most of N64's best looking games were released in a later period where sales for the console had drastically slowed down.

Yeah, I'm not sure how you can say the PS1's visuals hold up to the N64's after seeing things like Star Wars Episode I: Racer, Conker's Bad Fur Day, Indiana Jones and the Infernal Machine, and World Driver Championship...

realityengine wrote:
and unlike on PS2 you didn't have to produce ridiculously strange sized (and often blurry) framebuffers

What now? I was always under the impression many PS2 games were blurrier because the PS2 didn't have enough graphics processing power to fill a 640x480 framebuffer, not because of some other limitation.

realityengine wrote:
Also the main memory should have been larger and faster to at least match PS2's main RAM, but it didn't. At the same time, Gamecube's auxiliary memory had such low bandwidth (81 MB/s) it's better to describe it as like a rewritable N64 cartridge on steroids as opposed to actual RAM.

Isn't this pretty much designed for audio, where the very low bandwidth wouldn't be an issue? I can't imagine the GameCube was really at a ram disadvantage from the PS2 with most games. Nintendo did seem to have a ram problem (even proportional to the rest of the hardware) for whatever reason though; you've got the NES with it's puny 2KB of ram, the SNES with it's slow ass main ram and its not-so-stellar 64KB of audio ram as well as sprites only having access to 16KB of ram (which isn't really a problem with the ram itself, but whatever) and the N64 with its apparently slow and although larger than the competition, still small amount of ram. Even go all the way to the Wii U, which had 2GB of ram but the OS and auxiliary processes took almost half of it if I'm not mistaken.

realityengine wrote:
With Gamecube, ArtX didn't set out to create a PS2 performance beater

Well, that's what they did. Resident Evil 4 is a famous example of the GameCube looking very noticeably better than the PS2; it was my impression this game actually stopped most of the debate. Regardless of the insane polygon per second numbers given by Sony, games on the GameCube often looked better than those on the PS2, and if not, they looked identical, which can probably be attributed to a lack of effort on the developer anyway seeing the huge difference in sales between the PS2 and the GameCube/Xbox.
Re: N64 additive transparency
by on (#216549)
93143 wrote:
Looks like it was even more apples-to-oranges than I thought...

The only consoles of that generation with reasonably comparable graphics hardware are the Gamecube and Xbox (and Xbox soundly wins, aside from the occasionally pixel shading situation where TEV is better, and the sometimes faster blending on the eSRAM). PS2's Graphic Synthesizer is still unique to this day because of its focus on massively high overdraw (particularly useful for alpha blending because you can't avoid overdraw there) and the Dreamcast's PowerVR2 has a mostly unique (on a home device, at least) focus on massively low overdraw. I think this particular contrast would have added to PS2 hype back in the day where the console was touted as an absolute monster that would make even the Dreamcast look last-gen. When the Dreamcast's VRAM bandwidth is 0.8 GB/s and the PS2's VRAM is 48 GB/s, to the layman it made the Dreamcast look extremely weak. Of course because of the overdraw design difference, PS2 has to read/write VRAM all of the time while Dreamcast only has to do it infrequently, so this VRAM difference is stripped of almost all meaning in context.

93143 wrote:
Draw the additive graphic in a blank secondary framebuffer with the appropriate transforms and interpolation

It's a 'neater' way of doing things, but to me it sounds like a mostly unnecessary waste of the console's processing and memory time.

93143 wrote:
(Can you use transforms and interpolation and such when drawing in 8bpp?)

Are you trying to ask here if RDP supports 8bpp output? I'm fairly sure the answer is no.

93143 wrote:
Or is it actually possible to combine a transformed additive texture with an untransformed framebuffer texture in a single pass?

I still think the only way to do one-pass additive blending with textures is just using the hardware additive blender.

93143 wrote:
the color combiner has registers, that can be used as sources for its operations

I can't see them being specifically useful here (though they could be useful for the additional color combiner pass). If you wanted to do additive blendng without a texture against the framebuffer, it would be better just to use the vertex shade rather than the registers.

calima wrote:
This is exactly what I was curious about. Did anybody manage to do it, and if so, how.

It's not really a practical possibility because you can only sync the RDP pipeline per-primitive. There's an enormous virtually unavoidable risk that swapping the TMEM data in the middle of a primitive will either result in garbage texels being loaded into the pipeline (from an incomplete texture transfer) or simply the timing on the swap over point being wrong (meaning that the point on the primitive surface where the old texture should have stopped and the new texture should have started won't be as expected).

Espozo wrote:
What now? I was always under the impression many PS2 games were blurrier because the PS2 didn't have enough graphics processing power to fill a 640x480 framebuffer, not because of some other limitation.

No, the problem was that due to PS2 Graphic Synthesizer's reliance on extremely high drawing speed, to maximize performance you needed to create as many back buffers in VRAM as possible (also main RAM was invisible to Graphic Synthesizer). Unfortunately due to the size of the VRAM only being 4 MB, that didn't leave a lot of room (plus the texture cache had to share that space). That left developers with a range of choices, none of them too good. For the framebuffers to all fit, they either had to decrease the framebuffer size (makes jaggies and/or blur), decrease color depth (makes banding), or decrease the texture cache (usually resulted in lower texture resolution and/or memory thrashing). Remember also the PS2 has no hardware texture compression except for CLUT (if you could call that compression) putting more pressure on that limited space, though 'software' (i.e. vector unit driven) techniques were developed later on in the console's life.

Also because Graphic Synthesizer's anti-aliasing unit didn't work (broken design in silicon), developers would to come up with buffer tricks to smooth out jaggies. One way to do that was to have different sized front and back buffers and try to 'supersample' the output. Of course, while this would have some success in removing jaggies, it would also create a lot of blur since it wasn't proper supersampling.

There are more complicated factors at play, but I can tell you that while PS2 had a lot of problems, pixel fill speed was the least of them. At just filling any given resolution with pixels it was much faster than the other console of its generation (well it did have 4 times more pixel pipelines than Xbox and Gamecube).

EDIT: Gamecube only stored one back buffer in VRAM (eSRAM). The front buffers (or any other buffers) all had to be copied to main RAM. While this meant the Gamecube didn't regularly have any size limitations, it did put a significant damper on memory bandwidth. However, this also meant that with MSAA mode on, the back buffer had to be smaller, which is probably why it was rarely used. A neat bit of trivia: Flipper is capable of z-buffer compression but only when MSAA is enabled (though Xbox's NV2A does it all the time).

Espozo wrote:
Isn't this pretty much designed for audio, where the very low bandwidth wouldn't be an issue? I can't imagine the GameCube was really at a ram disadvantage from the PS2 with most games.

Sure, for audio the speed is not a big problem (PS2 also has audio RAM but it is much smaller though actually faster), but the fact is that Gamecube's main RAM is only 24 MB and the PS2's is 32 MB. It caused annoyance for Gamecube developers to have to constantly switch in things from slow auxiliary RAM into the much faster main RAM. I guess you could argue that the bandwidth difference between the main RAM on the two consoles was not that significant anyway, because in practice the PS2's RDRAM with its high latency would have a lower effective bandwidth, while the Gamecube's 1T-SRAM would actually achieve close to its peak.

Curiously, the Gamecube received a significant downclocking prior to its release. Flipper originally ran at 200mhz (later 162mhz) and main RAM had 3.2 GB/s bandwidth (same as PS2, later downgraded to 2.6 GB/s). I think the Gecko CPU was made faster though (probably needed changing anyway due to the different system bus multiplier).

Espozo wrote:
Resident Evil 4 is a famous example of the GameCube looking very noticeably better than the PS2; it was my impression this game actually stopped most of the debate.

I wouldn't put too much stock in this comparison. Resident Evil 4 was a Gamecube exclusive for almost all of its development lifespan. Given the major differences in graphics hardware architecture between the two consoles, I would say that any game that was not developed as multiplatform from the start could not be properly ported across the two in a way that would maximize their power (at least, not without a lot of extra development time).

Espozo wrote:
which can probably be attributed to a lack of effort on the developer anyway seeing the huge difference in sales between the PS2 and the GameCube/Xbox.

Sure, but the PS2 was also way harder to develop for than the Gamecube, so it kind of balanced out. IMO the real reason the graphics between the two (excluding the worst efforts on each) looked fairly equal overall is because their hardware power was pretty evenly matched despite different strengths.

In my experience checking out multiplatform versions between the two consoles, I generally noticed that the Gamecube versions almost always had higher framebuffer resolution and better texture quality, but the PS2 versions broadly had better vertex-related things, like higher quality reflections and nicer quality lighting. Just an observation of mine, which I think lines up with a reasonably informed view on their hardware capabilities.
Re: N64 additive transparency
by on (#216563)
realityengine wrote:
I wouldn't put too much stock in this comparison. Resident Evil 4 was a Gamecube exclusive for almost all of its development lifespan. Given the major differences in graphics hardware architecture between the two consoles, I would say that any game that was not developed as multiplatform from the start could not be properly ported across the two in a way that would maximize their power (at least, not without a lot of extra development time).

Well, here's a game that was developed for the PS2 and released on the GameCube and Xbox later. Granted, the only real difference is the framebuffer size, but I'd figure that if a game were being made with the PS2 in mind, they'd scale up the load to where the system would be running at about full capacity even with the smaller framebuffer, unless it doesn't quite work like that...

Attachment:
Burnout 1.png
Burnout 1.png [ 610.74 KiB | Viewed 8258 times ]

realityengine wrote:
Curiously, the Gamecube received a significant downclocking prior to its release. Flipper originally ran at 200mhz (later 162mhz) and main RAM had 3.2 GB/s bandwidth (same as PS2, later downgraded to 2.6 GB/s). I think the Gecko CPU was made faster though (probably needed changing anyway due to the different system bus multiplier).

Yeah, I've heard they sped up the CPU too from something like low 400's Mhz to 486Mhz. Weird that they'd slow everything else down; I guess it was running into heat related issues?

realityengine wrote:
but the PS2 versions broadly had better vertex-related things, like higher quality reflections and nicer quality lighting

Have any examples? I've never actually noticed this. Multiplatform games on the GameCube have pretty much always been greater or equal to the PS2 from what I've seen. I do cite a lack of effort though because many Xbox ports I've seen look no better than the GameCube versions. I've heard that the CPU's between both are pretty much evenly matched, but that the Xbox has an advantage with the GPU.
Re: N64 additive transparency
by on (#216570)
Espozo wrote:
Well, here's a game that was developed for the PS2 and released on the GameCube and Xbox later. Granted, the only real difference is the framebuffer size, but I'd figure that if a game were being made with the PS2 in mind, they'd scale up the load to where the system would be running at about full capacity even with the smaller framebuffer, unless it doesn't quite work like that...

I don't think that's quite the best example. Burnout was clearly developed as a multiplatform game (I don't really see how they could turn around both Gamecube and Xbox ports in about 5 months otherwise). Granted, it'll be easier to port from PS2 to Gamecube/Xbox than the other way around, if for no other reason than the PS2's esoteric hardware. The size of the framebuffer would have little impact on performance, given as I've said, the PS2 was not really fill-rate bound at all (if supersampling, the actual rendering buffer might not actually be smaller). Those early PS2 games would likely be more bound by how much performance they could ring out of the twin vector units (most developers in 2002 only were able to use 5% of VU0) and dealing with the PS2's relatively low general performance MIPS central core. And extra bad image quality (including textures), due to not yet working out the best approaches on dealing with limited VRAM space.

Espozo wrote:
Yeah, I've heard they sped up the CPU too from something like low 400's Mhz to 486Mhz. Weird that they'd slow everything else down; I guess it was running into heat related issues?

May have also been yields. Flipper was a pretty big chip, so parts of it may not have correctly handled the higher speed on an excessive number of production samples.

EDIT: N64's RCP was also downclocked before launch (66mhz to 62.5mhz). So was the CPU (100mhz to 94mhz).

Espozo wrote:
Have any examples? I've never actually noticed this. Multiplatform games on the GameCube have pretty much always been greater or equal to the PS2 from what I've seen. I do cite a lack of effort though because many Xbox ports I've seen look no better than the GameCube versions. I've heard that the CPU's between both are pretty much evenly matched, but that the Xbox has an advantage with the GPU.

I don't really want to start a PS2 vs Gamecube holy war. Plus it's really easy to cherrypick particular games to push a particular view. I prefer a more detached perspective. But I can give you one example: https://www.youtube.com/watch?v=ORbVdTBeUOU. Notice how the PS2's framebuffer, as usual, is low resolution, but it has a much more sophisticated lighting and reflection model than the Gamecube? Well it might be a bit hard to tell unless you look closely.

Regarding Gecko (PPC750) vs the Pentium III in the Xbox, I think the Pentium III has a fair edge in general performance. In old PC vs Mac benchmarks, a 500mhz PPC750 would generally lose by a small margin to a Pentium III at 733mhz (might be because PPC750 had fairly slow cache). Though if dealing with really bad code, I can see Gecko's larger L2 cache (256 KB vs 128 KB) being a bit more resilient to it. As for SIMD, I think there's little question that Gecko is significantly slower. Whatever per-cycle advantage the PPC750 has over the PIII would be wiped out by the former only having paired singles and the later having SSE (even though PIII's SSE sucks). So the Xbox's PIII would win the SIMD contest even on clock speed alone (and probably by that margin in terms of percentage).
Re: N64 additive transparency
by on (#216573)
realityengine wrote:
(I don't really see how they could turn around both Gamecube and Xbox ports in about 5 months otherwise)

I didn't think 5 months was particularly short to port over a game, especially one as barebones as it? I doubt they programmed the game in MIPS assembly (if that's even humanly possible...)

realityengine wrote:
Well it might be a bit hard to tell unless you look closely.

It's not; the GameCube version looks considerably worse, almost as if on purpose (for starters, why is it so much brighter?). Although, you could argue that about Resident Evil 4 as well. The difference in hair quality sticks out like a sore thumb.
Re: N64 additive transparency
by on (#216578)
Espozo wrote:
I didn't think 5 months was particularly short to port over a game, especially one as barebones as it? I doubt they programmed the game in MIPS assembly (if that's even humanly possible...)

It's less time than that because it still has to go through QA (including by the licensor) and then manufacturing (fairly long wait on the Gamecube mini disks). But it actually seems that this wasn't the first Renderware engine game for Gamecube, but THPS3 was already on it. IIRC THPS3 on Gamecube had pretty bad performance, so they might have spent the time porting Burnout to optimize the engine better for the console. In any case, I think the fact it was on Renderware proved the technology wasn't only meant for one platform.

Espozo wrote:
It's not; the GameCube version looks considerably worse, almost as if on purpose (for starters, why is it so much brighter?). Although, you could argue that about Resident Evil 4 as well. The difference in hair quality sticks out like a sore thumb.

Might have been a (bad) attempt to hide the downgraded lighting. As for Resident Evil 4, if the hair is that bad it sounds like they botched the alpha (which should otherwise be a strength of the PS2). Any port that uses prerecorded footage from the original version for cutscenes is, in my mind, a red flag for a port that didn't have enough time and/or money behind it. South Park for PS1 had the same thing going on.
Re: N64 additive transparency
by on (#216581)
How about using the vertex unit as a geometry processor then, outputting triangles that do not exist in the source model? Would such an approach have any advantage over just having a preprocessed model?
Re: N64 additive transparency
by on (#216590)
calima wrote:
How about using the vertex unit as a geometry processor then, outputting triangles that do not exist in the source model? Would such an approach have any advantage over just having a preprocessed model?

In terms of getting around that texturing issue you previously mentioned, probably not. But to create interesting surfaces for extra detail? Tessellation has value.

https://ultra64.ca/files/other/Game-Developer-Magazine/GDM_November_1999_Putting_Curved_Surfaces_to_Work_on_the_Nintendo_64.pdf
Re: N64 additive transparency
by on (#216594)
realityengine wrote:
As for Resident Evil 4, if the hair is that bad it sounds like they botched the alpha (which should otherwise be a strength of the PS2).

I'm not familiar enough with 3D hardware to tell you if that's the problem. The scene isn't exactly the same so it isn't a completely fair comparison, but look:

Image
Re: N64 additive transparency
by on (#216613)
realityengine wrote:
93143 wrote:
Draw the additive graphic in a blank secondary framebuffer with the appropriate transforms and interpolation
It's a 'neater' way of doing things, but to me it sounds like a mostly unnecessary waste of the console's processing and memory time.

Okay, but 'neater' than what? If my assumptions are right, I'm not sure there is any other way to do clamped additive blending on the N64 in the general case (other than attempting a reverse transform on the framebuffer, which I admit this method is neater than...).

Whether using clamped additive blending is a good idea in a specific instance can only be determined once a broadly optimal method has been established and profiled (and I doubt we'll even get that far). If there's a faster way than what I've described, I want to hear about it.

I think the problem can be subdivided into (at least) five plausible scenarios, only one of which requires the full treatment:

1. Full-Screen One-Step Blending
The SNES does this. All you have to do is fill two framebuffers, a main screen and a subscreen, taking care to set alpha for main screen pixels to indicate whether or not to blend with the subscreen. Then just run both screen buffers through the RDP and do the alpha-keyed blend in the color combiner. Should be reasonably efficient and predictable, since you're dealing with a constant amount of contiguous data. Still takes something like a quarter of a frame for 320x240 16-bit at 60 fps, but you only have to do it once.

Maybe it's also possible to combine the buffers using Z instead of alpha, but I haven't thought about that. Maybe it's not.

2. 2D Sprite Blending
Some faux-retro games do this. Each sprite can be additively blended, and they can stack. To pull this off, you'd just take the sprite texture and the chunk of framebuffer you want to paste it over, load them into TMEM, and do the blend in the color combiner. Since both textures are 1:1, no transform mismatch issues can arise.

3. Scaled Rectangular Primitive Blending
Should be similar to sprite blending, except that now you have to figure out how big your primitive will be on screen and load that amount of framebuffer (presumably you'd do this in stages, if you couldn't fit everything in TMEM all at once). Since both transforms are rectilinear, with no rotation, skew, or perspective, it should be possible (I think) to reliably blend an arbitrarily-scaled additive texture with a 1:1 framebuffer texture simply by specifying appropriate sizes for the texture tiles. Anything you could accomplish with fog in a secondary buffer could be done with a constant colour (or at most vertex shading) in CC0, with the additive blend done in CC1. (Using fog with additive blending in the primary buffer is a bad idea because it will not have the desired effect.)

Open questions:
- can you use entirely arbitrary texture sizes, so that the texture coordinates can be matched at any scale? (I guess yes - I think I read somewhere that you can)
- can you select trilinear for one texture and nearest neighbour for the other, so that the primitive size need not be an integer? (I guess no)

4. Untextured 3D or Non-Rectilinear Blending
Use vertex shading, or constant colours if desired, and blend that with the framebuffer texture. Can execute in one-cycle mode. Might not play well with the Z-buffer, but then transparency in general doesn't play well with the Z-buffer; just use the standard workarounds.

5. Textured 3D or Non-Rectilinear Blending
The general case. This is what I was attempting to find a solution to with my pre-rendering scheme. If it is not possible to have the rasterizer provide two different sets of texture coordinates based on different transforms on alternate cycles, I think the most efficient way to handle this case is to pre-render the additive object (or primitive, if doing a whole object at once doesn't gain enough efficiency to make up for processing a bunch of blank pixels around the edges) and load the result as a texture; once this is done, the remaining procedure is equivalent to case 2 above. This is somewhat similar to how environment mapping was done on the N64 (render a scene, use it as a texture).

If it is possible to alternate transforms in two-cycle mode, you don't need to pre-render, and this case becomes basically equivalent to case 3 above.

Open question:
- can the rasterizer handle two different transforms on alternate cycles in two-cycle mode? (I guess no)

...

Alternately, as I mentioned before, you could render in 32-bit mode using 16-bit colours (or really any less-precise colour space), which gives you a bit of headroom for just using the blender. Still not perfectly safe, but better than nothing. You'd have to be able to brighten the colours substantially with the color combiner to properly convert the framebuffer back to 16-bit; I think that's probably possible...

Quote:
93143 wrote:
(Can you use transforms and interpolation and such when drawing in 8bpp?)
Are you trying to ask here if RDP supports 8bpp output? I'm fairly sure the answer is no.

No. I know the VI can't display 8bpp (at least, I don't see a flag for it), but the description of the blender in the manual describes three "color image formats", these being 32-bit RGBA, 16-bit RGBA, and 8-bit. So it seems that the blender can write to an 8-bit framebuffer, even if it's not allowed to be the final display buffer.

What I don't know is under what circumstances 8bpp is a valid blender target - it would be neat if you could do a full render, but I have a feeling it's only valid for copy mode or something like that.

Quote:
93143 wrote:
Or is it actually possible to combine a transformed additive texture with an untransformed framebuffer texture in a single pass?
I still think the only way to do one-pass additive blending with textures is just using the hardware additive blender.

So that's a no? There's only one transform that can be set in the rasterizer regardless of mode, and you have to change it manually with the RSP?

Quote:
93143 wrote:
the color combiner has registers, that can be used as sources for its operations
I can't see them being specifically useful here (though they could be useful for the additional color combiner pass).

I was thinking maybe you could get it to automatically load a colour from TMEM into one of those registers every other cycle, just incrementing the address each time. This would avoid the problem with the transforms being different between the framebuffer and the additive texture. But there was never really a reason to suspect this was possible, and I suppose it was too much to hope that you could do texturing, however primitive, with anything other than the texture unit...
Re: N64 additive transparency
by on (#216639)
realityengine wrote:
calima wrote:
How about using the vertex unit as a geometry processor then, outputting triangles that do not exist in the source model? Would such an approach have any advantage over just having a preprocessed model?

In terms of getting around that texturing issue you previously mentioned, probably not. But to create interesting surfaces for extra detail? Tessellation has value.

https://ultra64.ca/files/other/Game-Developer-Magazine/GDM_November_1999_Putting_Curved_Surfaces_to_Work_on_the_Nintendo_64.pdf

Yeah I've read that, my question was more about whether triangles between RSP and RDP go to RAM or cache - is it faster to stream existing triangles from RAM or to generate new ones on-chip?