nesdev.com
http://forums.nesdev.com/

How to approach this texture scaling issue?
http://forums.nesdev.com/viewtopic.php?f=2&t=15700
Page 1 of 3

Author:  tokumaru [ Thu Mar 23, 2017 1:22 pm ]
Post subject:  How to approach this texture scaling issue?

I'm considering tweaking my raycasting engine to make a few improvements and one of the ideas I had was to increase the horizontal texture resolution while maintaining the number of rays that are cast. I plan to do this by rendering 2 texture columns for each ray that's cast, testing the position where the ray hits the wall with a precision of 8 units per block, and using that information to draw 2 consecutive slices of a 16-column texture.

This is simple for distant walls, but there's this awkward point when textures are scaled between 100% and 200% their actual width, where some screen columns should represent 1 texture column and others should represent 2, and I'm having a hard time figuring out How to make that decision.

The simplest thing I can think of is to render 2 texture columns when a 1/8 strip of the block is hit only once, but use the actual 1/16 strip if the same 1/8 strip is hit twice or more times. The main problem is that this doesn't work well when block faces are obstructed, either by the sides of the screen or by other blocks, because a partially visible wide strip can be mistaken for a narrow strip. The other problem is that detecting whether columns are repeats or not requires some looking ahead, which conflicts a bit with the rendering pipeline I have currently set up.

I don't know if I explained the problem clearly, or if anyone here has any interest in thinking of possible solutions, but if you do, please share your thoughts. Thanks.

Author:  dougeff [ Thu Mar 23, 2017 3:35 pm ]
Post subject:  Re: How to approach this texture scaling issue?

Stupid question. Can you use flat planes with well defined edges? Scaling would be less of an issue, in that scenario. (Like Star Fox).

Author:  tokumaru [ Thu Mar 23, 2017 4:32 pm ]
Post subject:  Re: How to approach this texture scaling issue?

That wouldn't help much I think. Even if I used another technique to find the exact edges of the walls, I doubt the NES would be able to do perspective-correct texture mapping on them as fast as my engine does now. The raycasting method is much simpler IMO, but we can only see what the rays hit. Unless we start shooting extra rays through walls or past the end of the FOV, but that could seriously affect the performance.

What I'm looking for is a cheap trick, like almost everything else in this engine is. Walls scaled to 100% or less use 2 conseccutive 1/16 strips from the texture, walls scaled to 200% or more use the exact 1/16 strip that was hit, and I need to find a good enough rule for what's in between.

Author:  tokumaru [ Fri Mar 24, 2017 1:19 am ]
Post subject:  Re: How to approach this texture scaling issue?

I think I figured this out: since I want to draw 2 texture columns per ray, I should consider that the exact spot the ray hits is between the points I have to sample, which are a little to the left and a little to the right. "A little" is just a small percentage of the distance... probably tan(1/2) * distance, which I can build a look-up table for.

This formula is only correct for perfectly perpendicular rays, but I don't think there'll be any noticeable distortion if it's used for rays hitting at steeper angles.

Anyway, this could (and probably should, for consistency) even be used in all cases, not just for walls scaled between 100% and 200%. Being able to use the same logic all the time is almost always better than handling special cases, IMO.

EDIT: I think the formula is wrong, I shouldn't be looking half a degree away from the center, it should be less. I'll figure out the exact value... :mrgreen:

Author:  tokumaru [ Wed Mar 29, 2017 9:19 pm ]
Post subject:  Re: How to approach this texture scaling issue?

Just to let you know, my idea worked fine. The added horizontal resolution greatly improved texture fidelity, without needing extra rays:
Attachment:
01-before.png
01-before.png [ 4.11 KiB | Viewed 1821 times ]
Attachment:
02-after.png
02-after.png [ 4.49 KiB | Viewed 1821 times ]

My 3-year-old daughter said it looks just like Minecraft... guess I'll take that as a compliment! :lol:

Anyway, I've also been playing with jumping/ducking and looking up/down:
Attachment:
03-ducking-and-looking-up.png
03-ducking-and-looking-up.png [ 4.6 KiB | Viewed 1821 times ]

The textures are getting a little too jagged for my taste, and since I can't think of many uses for this I might just give up on these features.

BTW, these shots are not from an NES program, but from a JavaScript prototype that uses an optimized version of the logic from my first raycaster. If all goes well with the prototype, I plan on making an updated NES version.

Author:  Myask [ Thu Mar 30, 2017 9:34 pm ]
Post subject:  Re: How to approach this texture scaling issue?

Can fudge either or both with some y-scroll, if you don't mind compromise.

Looks nice. What's the texture on the far right panel, though? It seems compromised near the corner.

Author:  tokumaru [ Thu Mar 30, 2017 10:06 pm ]
Post subject:  Re: How to approach this texture scaling issue?

Myask wrote:
Can fudge either or both with some y-scroll, if you don't mind compromise.

Scrolling could indeed help with looking up and down, but then there's the status bar in the way, and the edges to clip, so it's just easier to render the view with the center displaced up or down. What causes distortion is jumping/crouching, because the individual columns are shifted according to their distances (closer columns shift more than distant ones), causing some alignment issues with the texture mapping. I have no idea how to shift the columns and keep the textures aligned.

Quote:
Looks nice.

No it doesn't, it looks atrocious when scaled up! :lol: But it's the best I can come up under the current constraints (no raster effects and no pattern updates). The lack of raster effects is because I originally didn't want to use a mapper with IRQs, and the motivation to use a fixed tileset is speed, since changing the pattern tables is a very slow process that would greatly impact the gameplay. I really don't want to sacrifice the performance or shrink the 3D view too much. I'm now considering using MMC3 IRQs to increase the color count and the vertical resolution though, in order to have multi-colored textures (all built from a base set of 4 colors through dithering, of course) and better depth representation.

Quote:
What's the texture on the far right panel, though? It seems compromised near the corner.

Yeah, the rays hit at a pretty steep angle there, and my hack for increasing the horizontal texture resolution doesn't work so well at steep angles (it's table-based and calibrated for walls being observed straight on). It's supposed to be the same crate texture from the other face.

Author:  tokumaru [ Tue May 09, 2017 12:59 pm ]
Post subject:  Re: How to approach this texture scaling issue?

Just in case anyone is interested, here's a GIF showing some of the new stuff my raycasting engine supports:
Attachment:
raycaster-optimized.gif
raycaster-optimized.gif [ 950.12 KiB | Viewed 1493 times ]

We now have tiled floors, and most importantly, objects! Well, for now it's just a blue rectangle, but it's there to demonstrate that objects are placed, scaled and clipped correctly.

This capture is still from my JavaScript prototype, but this stuff is already being ported to the NES. Now that objects are working, I'm confident I can make a cool NES game out of this. Let me know if anyone is interested!

Author:  dougeff [ Tue May 09, 2017 1:16 pm ]
Post subject:  Re: How to approach this texture scaling issue?

Looks good. How many frames per second are you expecting?

Author:  tokumaru [ Tue May 09, 2017 1:21 pm ]
Post subject:  Re: How to approach this texture scaling issue?

I'm shooting for 15 frames per second. 3 hardware frames spent on the background, 1 frame for game logic and drawing objects. It'll probably drop to 12 at times, but that should still be playable.

EDIT: My old demo does 15fps most of the time, but doesn't have many of the features of the new engine (tiled floors, objects, looking up/down, stacked blocks). I did optimize a lot of things compared to the old demo, such as:

- Turning the binary search that calculated wall heights into a simple table look-up;
- Replacing the real-time bresenham texture scaling with something much simpler (can't describe it in 1 line, though);
- Using a different technique for detecting which texture column was hit, saving me 1 multiplication per wall slice;

These should significantly improve the performance compared to the old demo, but the new additions will probably cancel out the performance boost, which is why I expect it to run at a similar speed.

Author:  ccovell [ Tue May 09, 2017 5:20 pm ]
Post subject:  Re: How to approach this texture scaling issue?

Wow, and head tilt even. Looking very good.

Author:  tokumaru [ Tue May 09, 2017 8:23 pm ]
Post subject:  Re: How to approach this texture scaling issue?

Thanks. The head tilting is very simple really, it's done by simply moving the entire picture up/down. But I still think it makes the place look more 3D than if you could only look straight ahead. Not sure how I'll implement this action with the limited button count of an NES controller, though... I'm sure I'll have to rely on button combinations for extended actions such as looking up/down, changing weapons, strafing, and so on. I also can't think of many uses for this during actual gameplay, but I'll try to come up with something.

My main concern right now is rendering objects. They can't be drawn with background tiles because of the severe color limitations necessary to make everything fit in 256 tiles, so I always planned to draw objects with sprites. The problem is that the sprite capabilities of the NES aren't the best, and getting too close to objects will create problems. I'll have to prevent/discourage this kind of proximity (large bounding boxes?), but also design a sprite cycling method that deals gracefully with large objects for when they do happen.

Author:  DRW [ Tue May 09, 2017 8:44 pm ]
Post subject:  Re: How to approach this texture scaling issue?

tokumaru wrote:
Now that objects are working, I'm confident I can make a cool NES game out of this. Let me know if anyone is interested!

Sure. An actual raycasting game is still something that's completely missing on the NES.

What kind of game are you planning?

Author:  tokumaru [ Tue May 09, 2017 10:24 pm ]
Post subject:  Re: How to approach this texture scaling issue?

DRW wrote:
An actual raycasting game is still something that's completely missing on the NES.

Agreed.

Quote:
What kind of game are you planning?

The gameplay itself will be the typical "shoot the bad guys", "figure out how to progress", "get to the exit" type of thing for the most part, but instead of making the entire game have a single theme, I plan on paying homage to different first person shooters of the 90's by having various worlds based on different themes. Another thing I consider important is that game doesn't take itself too seriously, so even the blockiness of the graphics (and possibly other constraints) will be acknowledged in-game and justified by the story.

Author:  Pokun [ Tue May 09, 2017 11:02 pm ]
Post subject:  Re: How to approach this texture scaling issue?

Looks very good indeed!
Besides an FPS, I imagine it could make a cool dungeon crawler. In games like Megami Tensei it's very easy to get lost due to choppy 3D-mazes and limited access to a map, but with a fully animated 3D-maze like this it would be easier to navigate. Head tilting could be used automatically in scenes like when you discover stairs or so rather than during gameplay.

Page 1 of 3 All times are UTC - 7 hours
Powered by phpBB® Forum Software © phpBB Group
http://www.phpbb.com/