OpenBVE
OpenBVE copied to clipboard
[Suggestion] TextureFunction for manipulating/swaping texture at runtime
Hello
As we know texture is very important for this game, especially the trains. But current method(that i know) for trains that have alot variety/livery is either 1. make separate trainset for each livery for player to choose before playing, 2. Using statesfunction formula that using pluginstates function from atsplugin such as bvec ats
For first method is good for performance but if we want to change the train appreance we need to exit and choose other variant and jump to last position. For second method pretty bad for performance because it load multiple object and texture at once for every states, the b3d mesh still the same but for every states its target different texture file. This how i write it in .animated file:
States = car1A.b3d, car1B.b3d Statesfunction = formula from #792
Car1 = the mesh object Car1A = the mesh using texture A Car1B = the mesh using texture B
Its not efficient because same mesh loaded two times to memory and the different only the texture they using, its ok if only 1 car use this but when entire trainset that have 10car use this it means you load 20 mesh data and 20 texture instead 10 mesh data and 20 texture.
So i propose an idea to use a stateschange like method but for texture.
The logic atleast the same as object states, but with new command as: Texturestates = texture1.png, texture2.png etc... TextureFunction = formula...
Also if using texture states you have a rules to follows as:
- ONLY valid for one object in [Object] section states
- In the mesh file b3d/csv the Load texture command must have atleast 2 texture targeted(this used when bvetshack disabled)
- StatesFunction is not supported if using this
The example
In b3d/csv file (lets call car1.b3d) [MeshBuilder] Vertex -1,0,0 Vertex -1,1,0 Vertex 1,1,0 Vertex 1,0,0 Face 0,1,1,2 Load texture1.png, texture2.png Coordinates 0,0,0 Coordinates 1,1,0 Coordinates 2,1,1 Coordinates 3,0,1
In .animated file [Object] States = car1.b3d StatesTexture = texture1.png, texture2.png (specify the texture you want to use) TextureFunction = formula...
Thats it, any thoughs are welcome π
NOTE: i personally use the second option but its eat more ram and make the fps drop significantly π . maybe combine the formula using pluginstates, cycle through object method and refreshrate command can make a perfect swapping method ? As when pluginstates is true cycle through that list of texture, how fast it scroll using refreshrate command, when the pluginstate is false stop the scroll and set the current texture for the trains. Pluginstates also can bind it to keyboard key isnt it ? So using the key on keyboard to control it.
The train mesh file CSV/B3D already has two texture locations and the second texture is used when the train enters a dark environment. I can think of using texture shifting to switch textures and only need one texture file. This would require you to do a lot of texture UV adjustment for the model. Other than that, I have no other reliably compatible ideas...
This leads me to a routing object that can texture switch, the Signal object.
You right, but isnt it the daytime and nightime texture method is an old way ? The new way is in https://github.com/leezer3/OpenBVE/wiki/Errata#lighting-behaviour-with-a-defined-daytime-and-nighttime-texture
Yes, but texture shifting need very big texture if you want pack many texture into one, i dont want to mess with UV its a bit confusing for me π .
Using signal object it means the route or something in the route that controling texture switch... for AI trains maybe it good ? But for player is big no for me, imagine need dive into route file just to texture switch for player train its inefficient i think.
My proposed idea can bind the formula to a key in keyboard so player can control train appearance whenever they want.
Another solution is like other trains simulator game is bind any formula to a clickable button in blank html window that already made by the addon creator it self.
No expert in this, but day and night texture are still in use.
The linked errata simply means that applying the same texture file on both day and night texture will no longer have a full-bright effect, but night texture is still in use and won't go away anytime soon.
Have you done a benchmark to see how much performance the current approach actually drops? As far as I know OpenBVE only renders what is visible on the screen. I'd imagine it won't hurt the performance too much.
The best approach is probably to just continue what you're doing, I've done this with a toggleable interior light train and it doesn't seems to have a major impact (Though I haven't done a proper benchmark either)
The daytime texture and nighttime texture method is, I think, If used as a paint look, it is a hacking method. I can imagine trains using this method changing appearance as they drive through tunnels and dark places on other routes, or even being in a mix of the two... Regarding the signal object, I was thinking of the way it switches textures, which is written in the development documentation.
Then there are my thoughts. I think the textures set within the model are the initial textures, while in the non-zero state of the animation the textures set by the Animated object are used, and the state without textures uses the initial texture. Consider non-train objects. If the texture switching state is a floating point number
@Kenny-Hui @JunmoreHeavyBox here my formula you can test in .animated file
[Object]
Position = 0, 0, 0
states = obj1.b3d, obj2.b3d, obj3.b3d
statefunction = if[pluginstate[10] == 0, currentState, if[pluginstate[10] == 1, mod[currentState + 1, TOTALOBJECTYOUHAVE], currentState]]
RefreshRate = 1 (1 seconds)
in word what we do is: if pluginstates number 10 is 0 use currentstate otherwise if pluginstate number 10 is 1 scroll through object states with each have 1 second to appear, if you set pluginstates number 10 to 0 when scrolling stop the scroll and use the last object appear as your current object.
i also using bvec ats plugin to took advantage of key assigment feature so i can bind it to the keyboard press
https://user-images.githubusercontent.com/76892624/201579199-aed89b99-1e0d-441b-a167-7c9f44d0fa8a.mp4
here what i could make, this is why i want texturestate and texturefunction command because under the hood its swapping both the mesh and texture not only the texture.
A more cleaner approach would be something like:
StateFunction = Mod[value + pluginstate[10], <Number of States>]
Anyways I don't see alot of issues with swapping the mesh, in most case it shouldn't bring down the performance when it's not rendered, and using animated probably won't result in any better performance. (Making changes to the exterior might be a bit troublesome though as you have to sync each exterior model)
If you're still down on swapping textures via .animated, then you have to think a better way of specifying the textures as nighttime texture is already in use.
Maybe something like LoadTexture, 1day.png, 1night.png, 2day.png, 2night.png in csv/b3d, by default it will use the first pair of textures, then you can setup a TextureStateFunction and return a custom index.
@Kenny-Hui thanks for simplify my formula it works as is should but much shorter π
Honestly this texture swapping problem is solved for now, and i think we dont need texturefunction. But what we need is easier route creation becuse the learning curve ia too steep for me π .
I will still open this issue for anyone who interested.
My floating point state idea is a little bad in that it is only good for fading between integer states near the current integer state, not fading textures across different state indices.
This floating point texture state could be used to animate a wheel being burned red by friction, and start timing the texture change when the wheel slips or locks up. Can I use two overlapping faces and a texture placeholder with no content to achieve its glowing variation? (^ο½^) Think of more uses for it.
@leezer3 Excuse me. I would like to know the principle of mixing night textures and day textures changes and the possibility of changing multiple textures in this way. This is a function of the change caused by wheel slip (without wheel lock).
States = WheelTread.b3d
TextureFunction = Value+If[WheelSlip,If[Value<2,0.0001,0],If[Value>0,-0.001,0]]
; TextureIndex 0=WheelTread.png,1=WheelTreadRed.png,2=WheelTreadLight.png
Too many issues :)
Essentially, this is not a good idea due to the day / night texture situation. Unfortunately, these are a hack to work around the lack of point light sources, and the fact that the lighting only supports a single ambient / dynamic light source.
Essentially, your route brightness is a value between 0 (night) and 255 (day), and blends proportionally between the two texture states. Extending something like this to multiple texture sets would only compound the original mess.
I'd agree that if you want to do this, please use an additional state. This should cost little to no extra assuming it's the same number of vertices.
As a secondary thought, wheelslip isn't going to generate a consistant band of color change around your entire wheel, or for that matter to produce any significant color change unless you sit there spinning on the spot for a good few minutes. If a color change like you're thinking of occurs, somethings is seriously broken..... Most you're likely to actually see in real life would be a few sparks.
There's a reason I wrote "without wheel lock". The relatively more common red-hot wheels are often the result of abnormal brake release. Poor drivers or forgotten maintenance.
~~And then consider the WheelLock variable? Feedback on panels and plugin.~~ ~~WheelSlip and WheelLock come together as a pair. https://github.com/leezer3/OpenBVE/issues/821#issuecomment-1333271804~~
A formula...
TranslateFunction = Floor[(NumberOfFRAME/1280)*(If[WheelSlip|BrakeCylinder<50,Min[1280,ValueοΌ((HEATING*(BrakeCylinder/1000)*Speedometer)-(AIRCOOLING*Speed))],Max[0,Value-(COOLING+(AIRCOOLING*Speed))]])]
I think my question is over.