simple machines forum

Please login or register.

Login with username, password and session length
 

News:

Remember to make your own backup of posts before submitting.

 
 

Author Topic: New "illumination" (bitmap) system info  (Read 194 times)

Holy Diver

  • Website System
  • Administrator
  • *****
  • Offline Offline
    • MaleView Profile
    • About/Support Me/Sword of Moonlight
look out honey, 'cause I'm using technology
Holy Diver says,
« on: September 26, 2020, 02:39:16 AM »

Right now I'm working on adding a new feature to support KF2's variable ambient light levels.

I think there is already space made for it in the English version of the SOM_MAP tool, but it's disabled. I'm calling this "illumination" that evokes both lights and "illuminated" manuscripts. I'm also calling it "bitmaps" for short. It shouldn't be confused with any other use of bitmaps.

The basic idea is to attach bitmaps (e.g. BMP files) to map layers. You can think of it as annotating your map, kind of like the second sense of "illumination" if they don't directly apply to lighting logic.

I'm planning on trying to use this system to implement AI for KF2's flying and swimming monsters and probably environmental acoustics too, and maybe even the sound of the sea on the beaches.

Yesterday I worked out the relevant parts of the Ex.ini file. I want the system to be maximally flexible, but I think I will try to add a basic system to SOM_MAP too, for beginners. But I'm not sure how to bridge the last step of having the RGB settings actually change the game experience for them without consulting their Ex.ini file. I might leave it to do nothing just to force them to reckon with the Ex.ini file. It could just multiply the lights (by default) but that would leave the impression that's all it's good for.

Here, below, is my initial Ex.ini section for KF2. It's based on a byte from its map cells where one layer is in green and one layer is in blue.

Code: [Select]
[Bitmap]

0_00 = West Melanat

bitmap_ambient = 1_
bitmap_ambient_mask = not(2_*15,3840) 
bitmap_ambient_saturation = b&w(not(1_*17,255))

[Editor]

tile_illumination_bitmap = 1_
tile_elevation_increment = 0.125

0.125 is unrelated, that's the unit in KF2's PlayStation data, instead of 0.1 that SOM uses. It's binary based instead of decimal.

tile_illumination_bitmap tells SOM_MAP to use the same BMP for the second map layer, since they share data. 1_ is the base layer's map number. This refers to what bitmap SOM_MAP will open when the map is loaded. I think the same button that is used for overlays will have an option added to change the RGB bitmap.

0_00 links the 0th bitmap index to 00.bmp. This notation is the same as the new [Volume] section for linking textures to volumetric transparency effects.

bitmap_ambient is selecting 1_ just like before for the ambient effect, which must be coordinated with the internal game logic. Most other uses are simply up to the author to factor into their Ex.ini calculator code.

bitmap_ambient_mask has to do with KF only uses 4 bits for this purpose. I've chosen to keep the raw values and pack more data into the same bitmap. There's also data in the other 4 bits I don't yet understand. It looks like it's related to monster territories. (I will probably reformat them at some point so that each parameter has its own color channel, and the bitmaps probably won't be shared at that point.)

bitmap_ambient_saturation sets the actual light level. In this case it scales 4-bit values up to 8-bit RGB (b/w) values. I don't actually know how to interpret the values. I will have to do some trial-and-error unless someone informs me. But there may be a need for at least two ways to manipulate the lighting, and I'm not sure this way is appropriate to the word "ambient" here since scaling all light isn't really "ambient" light how it's normally used in computer graphics terminology.

So you can say this last part is just a sketch at this stage.

It looks complicated but most of that comes from the fact that I've chosen to leave the data compressed. It could be separated into two gray-scale RGB bitmaps and none of the unpacking logic would be necessary then.

The masking will automatically shift the values to remove zeroes on the right. That just means that the green data channel will start at zero like the blue channel. The reason it's helpful is if a color index is used as an optimization then this eliminates the non-color information so that the index won't be bogged down by bogus redundant entries.

I think I'm going to expose this data via a built-in system number called "blt" that I think stands for bitmap-layer-table but blt is also a traditional shorthand for what programmers call "bit block transfer" that means putting bitmaps/sprites onto the screen usually. Initially it will just be used to sample the bitmaps in calculator code. Maybe I will eventually let it overwrite data, but I doubt it, since the calculator code ethos is "functional programming" which would be violated by doing that. That said, I don't think I will use MapComp for this feature, because it will be easier to do early trial-and-error tests if I don't have to compile the map, and it will leave the door open to doing dynamic changes like Echo Night's light switch system. Plus it would strip lighting information out of the MPX files by compressing the natural lighting or vice-versa, or distorting the new material settings.

But the "bitmap_ambient_saturation" won't be recomputed every "frame" either. If I do enable dynamic changes something will have to trigger reevaluation, possibly restricted to specific pixel values or regions. That might be a new "event" in SOM_MAP or something else, but I can't readily think of what else since historically the event system is the only way to drive something like this.
« Last Edit: September 26, 2020, 06:48:10 AM by Holy Diver »

Holy Diver has 2452 posts

Holy Diver

  • Website System
  • Administrator
  • *****
  • Offline Offline
    • MaleView Profile
    • About/Support Me/Sword of Moonlight
look out honey, 'cause I'm using technology
Holy Diver says,
« Reply #1 on: October 03, 2020, 06:50:53 PM »

Okay it took me a while to pull my chair up to this task but I'm doing it now. I think this morning while waking up I gamed out the potential strategies and realized that it couldn't be done in a shader with a texture. Not that I wanted to do it that way but it was the only way I could think to do it dynamically for the map elements. It would be complicated any other way because the tiles aren't drawn one by one. I wouldn't want to use a texture but it can't work because if triangles are on the edge of a cell (most are) then that coordinate would be at 0 on the texture and that would have to round to the same pixel.

I'm sure I've thought about it before. Doing soft transitions is also not very feasible. KF2 doesn't do soft transitions. But I think were I to try it it would need to depend on the tile connectivity data in the PRT files to work. Even then I'm not positive it'd be airtight.

This made me to think, the reason I'm writing this now, I think something in the future is to add lighting groups to SOM_MAP. Since it has limited real-estate that's pretty much full now, I think the "hack" way to add this feature will be to double-click on a title in the new RGB drawing mode I'm going to develop before long, and this will reuse the light setup window to define new lighting for this tile and any other tiles with the same RGB values. In that case your value would just be a code. And there can be a way to change the interpretation of that code. Also there are R G B buttons, so I guess if just one is clicked the code could be interpreted as a wildcard matching only one color channel. (In this case the lights button will also bring up the group lighting instead of the global lighting.)

This is actually a problem I've faced with my KF2 project because some of the lighting in KF2 isn't based on the map lighting, so I have no way to define a new array of lighting to match it. It takes a lot of parameters to define lighting so there's really no way to shoehorn it. So I thought, if there's a way it should reuse the light window in SOM_MAP. Or use a dummy map to add lamps. Basically use SOM_MAP as a lighting studio tool. So I could at least use this scheme as an excuse to develop a lightweight light definitions file format.

Oddly there's already a new file format called LYT that is for layer definitions. But I think I will resist trying to add lights to it even though phonetically it sounds light "light" (in that annoying Silicon Valley wannabe way.)

The other impetus for this is a more practical one. That's map transitions. A problem that arises from warping to new maps is you have to choose to do a hard lighting change or stick with the same lighting for everywhere in your game. King's Field actually does the latter as far as know.

Dark Souls fades in lighting transitions if you pay attention. It actually does it abruptly and the loud text it flashes on screen is meant to draw your attention away from the transition.

SOM can't do a transition this way because its lights are "baked into" its MPX format. I could try to develop an alternative lighting model, but TBH baked lighting has benefits and I'm not sure it's a big priority right now. I definitely do have plans to develop a new system and new map editor one day when the time is right that I will call Dark Slayer then to be a sister to SOM. But now is not that day.

So instead the best option seems to be lighting groups. Verdite recently mentioned to me he wanted to (somehow) do a project with (what I assume is) texture based shading. I don't know if that's wise. But it gave me an idea that I could develop a system to export the MPX geometry so that vertex based lighting could be generated in other modeling software, and then import that back into the MPX file. That would let you model lighting however you want.

But in this system the "objects" and NPCs would still need to be lit somehow. In that case I don't know how they could be lit to match the MPX other than to vaguely mimic the nearby map lighting. But I guess at a minimum if there were lighting groups the lighting could then be better localized and so better approximated. Or maybe the groups could be assigned (somehow) to some alternative environmental lighting, like cube maps or something. I think Half-Life 2 went all out with cube-maps. Cube maps can even be generated from the real map geometry.

EDITED: In case anyone wants to know "how I'm doing it" I'm applying the ambient extension to the vertex colors when the MPX is loaded in the player component. In the future I will let it change in response to an event or something. In that case the MPX file will have to be partially loaded again to get the original vertex colors because applying the ambient is destructive. The rest of the geometry will be done in shader, not with textures, but just as an additional light parameter.
« Last Edit: October 04, 2020, 01:55:15 PM by Holy Diver »

Holy Diver has 2452 posts

Holy Diver

  • Website System
  • Administrator
  • *****
  • Offline Offline
    • MaleView Profile
    • About/Support Me/Sword of Moonlight
look out honey, 'cause I'm using technology
Holy Diver says,
« Reply #2 on: October 06, 2020, 09:59:58 PM »

Here's a new image of this project in action. The formula here for KF2 is pretty funky. I don't know if it's best to adopt it for all SOM projects or how to go about making it programmable. Of course it is possible to use the Ex.ini calculation system to produce the result, but I don't know if it's ideal to do that for every vertex color pair in the MPX file. It would impact load time.

Code: (C++) [Select]
vc = vc*powf(bc,vc*4)
I've rewritten this to be easier to understand. vc is the MPX color, bc is the bitmap color that controls the darkening.

I ended up going through a color look up table to produce the number that is bc. So it's not strictly the color in the bitmap. In fact that is a 6-bit value that's split up into blue and green for each layer.

Code: (Ex.ini) [Select]
bitmap_ambient_saturation = id(nan(ambient_lut[1_],255),-1,-1)
The id function is producing an RGB triplet. The -1 values tell it to copy the first field, so it's grayscale in other words. The nan function replaces undefined values with 255.

I am going to stick with the saturation language since there can't really be more than one color after all, it's just a matter of what to do with it. In that case I may add an extension for different modes to choose from, and parameters for those modes as necessary.

I don't have great plans for SOM. I just want it to be able to have enough features to reproduce King's Field II, and later some other classic games. I don't want it to be restrictive. I just don't want people to come to it expecting it to bend to their will or provide a raft of contemporary graphics effects. I want to find the minimal effects to produce simple, uncomplicated experiences.

Note: SOM is on the left. The skeletons and other things aren't darkened yet. I notice in thumbnail form it's lighter. I might be able to darken it two or three shades but it could be the ceiling or fog is different and that would make the walls less accurate. I have to close out and start the game over to try different values. There's no dial to play with in the game. The formula seems to get very close but that doesn't mean it's accurate to what's really happening. But I think it's passable.
« Last Edit: October 07, 2020, 02:18:44 PM by Holy Diver »

Holy Diver has 2452 posts