Math formulas for floor and ceiling texture mapping.

Math formulas for floor and ceiling texture mapping.

Postby Graf Zahl » Wed Sep 09, 2020 4:50 am

Is there any technical documentation that explains in detail how the Build engine performs its texture mapping - especially the math being used to map a texture onto a floor or ceiling surface? The formulas being used by the engine are nearly incomprehensible - the one for the 2D map messes around with aspect ratio projection to find these and Polymost has some weird function call in there that messes around with the bit organization of floating point numbers.

Isn't there anything better? So far all I found were rather superficial explanations of the various sector bits but nothing that does a detailed explanation of how all these values work together to produce a texture coordinate.
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
 
Joined: 19 Jul 2003
Location: Germany

Re: Math formulas for floor and ceiling texture mapping.

Postby Redneckerz » Thu Sep 10, 2020 12:14 pm

Graf Zahl wrote:Is there any technical documentation that explains in detail how the Build engine performs its texture mapping - especially the math being used to map a texture onto a floor or ceiling surface? The formulas being used by the engine are nearly incomprehensible - the one for the 2D map messes around with aspect ratio projection to find these and Polymost has some weird function call in there that messes around with the bit organization of floating point numbers.

Isn't there anything better? So far all I found were rather superficial explanations of the various sector bits but nothing that does a detailed explanation of how all these values work together to produce a texture coordinate.

Does Fabian Sanglard's piece help you out?
User avatar
Redneckerz
To it's ports i may have seen
Spotlight Team
 
Joined: 25 Nov 2019
Discord: Redneckerz#8399
Operating System: Windows Vista/7/2008 64-bit
Graphics Processor: nVidia (Legacy GZDoom)

Re: Math formulas for floor and ceiling texture mapping.

Postby Graf Zahl » Thu Sep 10, 2020 12:24 pm

No, it never says much about these things and even if it did, it would not be of much use because it only concerns the software renderer.

My problem is that I've been trying to rewrite the automap drawer but the texture math in there is utterly obtuse. It doesn't calculate the texture coordinates in world space but in screen space, first factoring in the aspect ratio and then factoring it out again and any chance of getting a nice and clean formula is lost in that.

And Polymost isn't really much better. It uses a weird function called krecip that performs some bit fuckery with floats and insn't documented anywhere. The name already tells me a bit but the thing it actually performs is just ???
I was just hoping that someone had written down the math for this somewhere, it'd save me quite a bit of time determining it myself.
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
 
Joined: 19 Jul 2003
Location: Germany

Re: Math formulas for floor and ceiling texture mapping.

Postby mikolah » Sat Sep 12, 2020 2:00 am

Here's a somewhat verbose explanation I made for a project I'm currently working on, seems like it can be of use:

There are 5 flags that control floor/ceiling texturing:
* SWAP_XY = 4: swaps X and Y of sampled texture coordinate, then flips the texture horizontally;
* TEXTURE_EXPANSION = 8: halves the texture size by doubling the sampled texture coordinates (Ken's Build docs call it "Double Smooshiness" because of course);
* FLIP_X = 16: flips texture horizontally;
* FLIP_Y = 32: flips texture vertically;
* RELATIVE_ALIGN = 64: moves texture space origin to first wall's coords, orients texture space X axis along the wall, also flips texture space Y axis because build.
In Build, tile images store pixels from top to bottom. However, for floor/ceiling textures, Y axis starts at the bottom and increases towards the top. This makes floor/ceiling textures vertically flipped by default. However, Build being Build, If RELATIVE_ALIGN flag is set, Y axis behaves as expected. Because of course.
1 texel = 16 map units (a 128x128 texture fits into a 2048x2048 square), or 8 map units if TEXTURE_EXPANSION bit is set.
Offsets are specified in 1/256 increments relative to texture size and lie within [0, 255] range - for instance, an offset of (64, 128) will move the texture by 1/4 of its width horizontally and 1/2 of its height vertically, regardless of its dimensions.
Map coordinates can be transformed to texture coordinates as follows:
Code: Select allExpand view
SCALE_FACTOR = 16  # 1 texel = 16 map units
OFFSET_RATIO = 256  # 1 offset = 1/256 of texture size

# By default, texture coordinates start at (0, 0) and are oriented along the map grid
origin_x = 0
origin_y = 0
angle = 0

if RELATIVE_ALIGN:
   # Texture aligned to the first wall, change the coordinate system
   origin_x = wall_x
   origin_y = wall_y
   angle = wall_angle

# Convert map coordinates to texture coordinate system
tex_x = ((map_x - origin_x) * cos(angle) - (map_y - origin_y) * sin(angle)) / SCALE_FACTOR
tex_y = ((map_x - origin_x) * sin(angle) + (map_y - origin_y) * cos(angle)) / SCALE_FACTOR

if TEXTURE_EXPANSION:
   # Halve texture size (lol double smooshiness)
   tex_x *= 2
   tex_y *= 2

# Emulate software renderer's buggy non-power-of-2 texture handling
if software:
   # Round width and height down to nearest power of 2
   t = 0x80000000
   while t > texture_width:
      t >>= 1
   texture_width = t
   
   t = 0x80000000
   while t > texture_height:
      t >>= 1
   texture_height = t
      

# Add offsets to texture coordinates
tex_x += texture_width * offset_x / OFFSET_RATIO
tex_y += texture_height * offset_y / OFFSET_RATIO

if FLIP_X:
   # Flip texture horizontally
   tex_x = -tex_x

if FLIP_Y:
   # Flip texture vertically
   tex_y = -tex_y

if RELATIVE_ALIGN:
   # Wall-aligned textures are flipped vertically because build lol
   tex_y = -tex_y

if SWAP_XY:
   # Swap X and Y texture coordinates and flip texture horizontally
   tex_x, tex_y = tex_y, -tex_x

tex_x = int(tex_x % texture_width)
tex_y = int((-tex_y) % texture_height)

# Build tiles are in column-major order
texel = texture[tex_x * texture_height + tex_y]


Pretty sure this is correct, although I could have forgotten a minus sign somewhere or something. Hope this helps.
User avatar
mikolah
 
Joined: 06 Oct 2016
Discord: Mikolah#5576
Github ID: mykola-ambar
Graphics Processor: ATI/AMD with Vulkan Support

Re: Math formulas for floor and ceiling texture mapping.

Postby Graf Zahl » Sat Sep 12, 2020 10:59 am

There must be a bit more. There's code in there that compresses one of the axes when the texture is being used on a sloped floor.

Code from Polymost:

Code: Select allExpand view
      if (globalorientation & 2)
        {
            int i = krecipasm(nsqrtasm(uhypsq(xy.x,xy.y)));
            r = i * (1.f/1073741824.f);
        }
        else
        {
            int i = nsqrtasm(uhypsq(xy.x,xy.y)); if (i == 0) i = 1024; else i = 1048576 / i;
            r = i * (1.f/1048576.f);
        }


Code: Select allExpand view
   if ((globalorientation&(2+64)) == (2+64)) //Hack for panning for slopes w/ relative alignment
    {
        float r = global_cf_heinum * (1.0f / 4096.f);
        r = polymost_invsqrt_approximation(r * r + 1);

        if (!(globalorientation & 4))
            fxy.y *= r;
        else
            fxy.x *= r;
    }
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
 
Joined: 19 Jul 2003
Location: Germany

Re: Math formulas for floor and ceiling texture mapping.

Postby mikolah » Mon Sep 14, 2020 1:09 am

Not really sure what the first snippet does.
The second snippet seems to calculate the cosine of the slope angle (through the 1 / sqrt(tg(slope) ^2 + 1) trig identity) and "compress" the texture in screen space along the screen Y axis accordingly.

Both of them seem unrelated to the texture coordinates as seen from a top-down view. Playing around with different sector flag/slope combinations in Mapster doesn't affect the texture as seen on the automap.
User avatar
mikolah
 
Joined: 06 Oct 2016
Discord: Mikolah#5576
Github ID: mykola-ambar
Graphics Processor: ATI/AMD with Vulkan Support

Re: Math formulas for floor and ceiling texture mapping.

Postby Graf Zahl » Mon Sep 14, 2020 7:02 am

Well, Polymost surely went its completely unique route of doing hardware rendering. I'm not sure that even half the code in there makes any sense in a sane world...
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
 
Joined: 19 Jul 2003
Location: Germany

Re: Math formulas for floor and ceiling texture mapping.

Postby sinisterseed » Mon Sep 14, 2020 11:02 am

Ah but you see, sanity does not belong to the realm of Build, here things are done on a whole different level :p .
User avatar
sinisterseed
GZDoom RO Translator & Raze Tester
 
Joined: 05 Nov 2019
Twitch ID: sixhundredsixteen
Github ID: sinisterseed
Operating System: Windows 10/8.1/8/201x 64-bit
OS Test Version: No (Using Stable Public Version)
Graphics Processor: nVidia with Vulkan support

Re: Math formulas for floor and ceiling texture mapping.

Postby Basil Hoshforth » Mon Sep 14, 2020 2:49 pm

Upon further investigation, the first snippet of the code seems to be introduced in this commit (props to Dynamo for finding this):
https://voidpoint.io/terminx/eduke32/-/ ... w=parallel
to make Polymost more similar to the classic renderer.
Basil Hoshforth
 

Re: Math formulas for floor and ceiling texture mapping.

Postby Graf Zahl » Mon Sep 14, 2020 3:29 pm

Oh my - Build...

Will there ever be a time when it doesn't depend on weird quirks and shitty shortcuts and require workarounds to reproduce its math failures?
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
 
Joined: 19 Jul 2003
Location: Germany


Return to General

Who is online

Users browsing this forum: No registered users and 0 guests