Introducing the Cockpit Paint Mod (CPM)

My only frustration is when there's an error in the extracted HLSL that I can't find, and I'm forced to write the mod in shader ASM - takes me bloody hours :) The ambient cabin lighting shader is a classic example, I can't figure out why the HLSL doesn't work. And the ASM version took me about a day and about a dozen game crashes before it was stable. Anyway, that's really a minor issue, plus it forces me to learn more about ASM.
The HLSL decompiler is a much lower priority than the assembler - we'll still accept bug reports about it and may fix some issues, but there are some fundamental problems with decompilation that mean it can really never be perfect, so using assembly is recommended wherever it fails - though as you noted assembly does remove the safety wheels and you can cause DirectX/driver/hardware crashes/stalls far more easily than HLSL.

A bit of history on that - back when DirectX 10/11 was still new and the 3D Vision modding community were just starting to look at creating a DX11 tool they ran into a bit of a problem - in DX9 Microsoft had provided functions to both disassemble and assemble shaders, and the DX9 tool (Helix Mod) just used those. However for DX11 Microsoft had only provided a HLSL compiler, and a disassembler for debugging - they didn't provide an assembler, so there was no official way to convert a shader binary to a human editable format and back again.

The most obvious solution was for someone in the community to write an assembler so we could use the same workflow as DX9, but they quickly encountered a problem - the DXBC binary shader format used in DX11 includes a hash in the header, and if this hash is incorrect DirectX will refuse to load the shader - and at the time no one could figure out what the hash was or how to replicate it. And thus Chiri, the original 3DMigoto author, made the decision to instead write the HLSL decompiler that you find in 3DMigoto today so that we could then feed the result of that back into Microsoft's HLSL compiler to get our modified shaders back into the game.

That worked fine for the game he was targeting at the time (Bioshock Infinite) since he added all the coverage he needed for that particular game (as well as a bunch of autofix magic that ended up being more specific to that game that had been hoped and has never been used since). After some... unfortunate competition showing up in the middle of his crowdfunding campaign Chiri had to abandon development of 3DMigoto, and Bo3b was able to convince him to release the project as open source and took over maintainership, and I joined the project not long after that. In this time Bo3b did a lot of work to improve the decompiler to work in many more games - fixing bugs, adding support for decompiling missing opcodes, trying to handle booleans and other data types better, etc, etc, and it was and still is quite remarkable how well the decompiler worked for games of that era.

However we were quite aware that there are some fundamental problems with decompilation compared to disassembling+reassembling that would mean it could never 100% accurately decompile every shader it might encounter. The biggest difference IMO is that DXBC deals with registers, while HLSL deals with variables. Registers don't have types - they just contain raw data that is interpreted as some type based on the instructions that are used on them - if the 'mul' instruction is used, than the data is treated as a float, while 'imul' treats it as an integer. HLSL on the other hand associates a type with a variable, and if it's used with the wrong type of operation an implicit or explicit cast is required. But it could get even more complex, because occasionally the compiler would pack multiple variables of different types into a single SIMD register (e.g. r1.x is a float, r1.y is an int), which has no equivalent in HLSL where all components of a SIMD variable have to be the same type. But these kind of quirks were relatively rare at the time - the vast majority of shaders we needed to alter only used float and maybe bool data types so the decompiler treated everything as a float by default and we just accepted that some shaders would require manual fixes to the HLSL to get them rendering accurately - Bo3b would improve the decompiler where we could, and we manually corrected the output where we couldn't.

Then came the Witcher III. This wasn't the first game to use compute shaders, but it was the first game to use them as part of the rendering pipeline in such a way where we needed to adjust those shaders to make the game render in stereo 3D (and ditto domain and geometry shaders). 3DMigoto had no support for these shader types at all at the time, and compute shaders... tend to use integer arithmetic far more than graphics shaders because among other things suddenly a lot of the maths to divide up work between hardware threads that used to be performed automatically by the driver/hardware in the graphics pipeline was now being coded by the game developers inside the compute shaders. Plus the compute shaders used a whole lot more opcodes than were used by graphics shaders, so getting the HLSL decompiler working well with them was looking to be a monumentous task.

However, in the time since 3DMigoto had existed Flugan had written his own tool which included a DXBC assembler and he had managed to reverse engineer the hash function Microsoft had used (when he showed me the code I immediately recognised (Googled) the constants as the same ones used in MD5 - I did my own analysis on that later and determined that Microsoft had started with MD5 but intentionally changed the layout of the final block so that normal MD5 hashing algorithms would not work). Flugan's assembler needed a lot of work to handle the shaders in the Witcher 3 (plus had a lot of problems beyond that), but I judged that to be less than the work that would have been required to make the HLSL compiler work with that game, so this was the point where we shifted focus away from improving the HLSL decompiler to improving Flugan's assembler - initially just to get enough opcode coverage for shaders used in the Witcher 3, and I later continued improving it, completing it's shader model 5 opcode coverage and hardening it to cope with shaders written by humans instead of machines (e.g. not crash if the user has different whitespace preferences to the disassembler, warn about incorrect operand counts instead of crashing, etc), and eventually adding the ShaderRegex engine to facilitate automatically patching shaders.

Of course then we encountered a new problem - some shaders weren't rendering correctly after being disassembled + reassembled, even with no changes made, which we determined was caused by Microsoft's disassembler outputting floats with %f, which only prints 6 digits after the decimal point - most of the time that is good enough, but it does lose some of the lower order bits, and in some cases those bits turned out to be very important. Initially as a proof of concept I solved this with an offline solution that would compare the shader assembly and DXBC bytecode, replacing the 6 digit floats with enough precision that was guaranteed to reconstruct the full 32bit value exactly, and this worked for the affected shaders - so Flugan took this idea and wrote a disassembler fixup pass so we could do this automatically inside 3DMigoto.

And since then, modern games have only used compute shaders more and more. Things like tile lighting are now extremely popular that cannot be done in the traditional graphics pipeline, and there is very little hope that the HLSL decompiler will ever be able to decompile those accurately. If someone wanted to join the development team and work on improving the decompiler we'd of course welcome it, but it is not our priority any more.
 
Last edited:
Worked like a charm for me in ED (Steam) in 2D (thanks for the extensive help docs @GeorjCostanza as I've never used EDHM UI before). Did a quick test in Steam VR and it looks great with supplied colour schemes. As expected, it will not load in my usual (open composite) VR setup (without a loader app) – but that's not the fault of this great MOD!
 
My screenshots are just titled random letters from Steam, and low quality... I've seen a few people have similar format naming as your screenshots. I play in VR so I'm wondering if you're using a 3rd party tool or something that can be binded to a controller for those high res shots? My older AMD GPU had it's own High res screen grab that was perfect, but my newer RTX seems to only have the on-screen pop-up suite (tried using macros to time keystrokes but worked inconsistently).

Pressing ALT+F10 is an in-game screenshot function for the Hi-Res pictures. F10 by itself will take a low res one.

i had no issues saving a thumbnail. maybe check the size or the formating of the pic u r using for the thumbnail

It's not just a thumbnail problem, it wont save my theme at all for some reason. The format (jpeg) and the size (200x61) is the exact same size and format that you get as a template when you click "save" during the theme save process.

I've just found that it is quite easy to "break" the mod while using EDHM to set it up. You can accidentally load the themes as "mods" in themselves and all sorts of other things. EDHM wont stop you from loading themes incorrectly.
 
Trust me it works as i have a beautiful Black and Gold Anaconda CPM Theme.
Eye of the beholder and all that jazz ;)

Wait till you see my cockpit!
Hmmm, bah humbug!
Damn Anaconda, I love the idea of the cockpit mod but no way im buying an Anaconda to use it ;)


Good job, looks good but I can wait :)



Edit - Ok I followed the link, I take it back, maybe i`ll be having a go later ;)
So was my initial sceptism justified or did I miss something, pretty sure when I followed the links I saw something saying that it could be used for other ships but when loading and trying to change ship I get no options to edit.

Maybe I had a blonde moment and it is still just for the Anaconda.
 
Eye of the beholder and all that jazz ;)

Wait till you see my cockpit!

So was my initial sceptism justified or did I miss something, pretty sure when I followed the links I saw something saying that it could be used for other ships but when loading and trying to change ship I get no options to edit.

Maybe I had a blonde moment and it is still just for the Anaconda.
Yeah it is just for the Anaconda for now but we will have it for the rest of the ships at some point it is just a waiting game for now so we all have to be patient
 
Absolutely amazing. Made a quick little video touring my new red and black PVE Anaconda. Can't wait for my AX Krait to get a makeover next!

The Atlanta Falcons approve that paint Scheme.

1663932096071.png
 
The HLSL decompiler is a much lower priority than the assembler - we'll still accept bug reports about it and may fix some issues, but there are some fundamental problems with decompilation that mean it can really never be perfect, so using assembly is recommended wherever it fails - though as you noted assembly does remove the safety wheels and you can cause DirectX/driver/hardware crashes/stalls far more easily than HLSL.

A bit of history on that - back when DirectX 10/11 was still new and the 3D Vision modding community were just starting to look at creating a DX11 tool they ran into a bit of a problem - in DX9 Microsoft had provided functions to both disassemble and assemble shaders, and the DX9 tool (Helix Mod) just used those. However for DX11 Microsoft had only provided a HLSL compiler, and a disassembler for debugging - they didn't provide an assembler, so there was no official way to convert a shader binary to a human editable format and back again.

The most obvious solution was for someone in the community to write an assembler so we could use the same workflow as DX9, but they quickly encountered a problem - the DXBC binary shader format used in DX11 includes a hash in the header, and if this hash is incorrect DirectX will refuse to load the shader - and at the time no one could figure out what the hash was or how to replicate it. And thus Chiri, the original 3DMigoto author, made the decision to instead write the HLSL decompiler that you find in 3DMigoto today so that we could then feed the result of that back into Microsoft's HLSL compiler to get our modified shaders back into the game.

That worked fine for the game he was targeting at the time (Bioshock Infinite) since he added all the coverage he needed for that particular game (as well as a bunch of autofix magic that ended up being more specific to that game that had been hoped and has never been used since). After some... unfortunate competition showing up in the middle of his crowdfunding campaign Chiri had to abandon development of 3DMigoto, and Bo3b was able to convince him to release the project as open source and took over maintainership, and I joined the project not long after that. In this time Bo3b did a lot of work to improve the decompiler to work in many more games - fixing bugs, adding support for decompiling missing opcodes, trying to handle booleans and other data types better, etc, etc, and it was and still is quite remarkable how well the decompiler worked for games of that era.

However we were quite aware that there are some fundamental problems with decompilation compared to disassembling+reassembling that would mean it could never 100% accurately decompile every shader it might encounter. The biggest difference IMO is that DXBC deals with registers, while HLSL deals with variables. Registers don't have types - they just contain raw data that is interpreted as some type based on the instructions that are used on them - if the 'mul' instruction is used, than the data is treated as a float, while 'imul' treats it as an integer. HLSL on the other hand associates a type with a variable, and if it's used with the wrong type of operation an implicit or explicit cast is required. But it could get even more complex, because occasionally the compiler would pack multiple variables of different types into a single SIMD register (e.g. r1.x is a float, r1.y is an int), which has no equivalent in HLSL where all components of a SIMD variable have to be the same type. But these kind of quirks were relatively rare at the time - the vast majority of shaders we needed to alter only used float and maybe bool data types so the decompiler treated everything as a float by default and we just accepted that some shaders would require manual fixes to the HLSL to get them rendering accurately - Bo3b would improve the decompiler where we could, and we manually corrected the output where we couldn't.

Then came the Witcher III. This wasn't the first game to use compute shaders, but it was the first game to use them as part of the rendering pipeline in such a way where we needed to adjust those shaders to make the game render in stereo 3D (and ditto domain and geometry shaders). 3DMigoto had no support for these shader types at all at the time, and compute shaders... tend to use integer arithmetic far more than graphics shaders because among other things suddenly a lot of the maths to divide up work between hardware threads that used to be performed automatically by the driver/hardware in the graphics pipeline was now being coded by the game developers inside the compute shaders. Plus the compute shaders used a whole lot more opcodes than were used by graphics shaders, so getting the HLSL decompiler working well with them was looking to be a monumentous task.

However, in the time since 3DMigoto had existed Flugan had written his own tool which included a DXBC assembler and he had managed to reverse engineer the hash function Microsoft had used (when he showed me the code I immediately recognised (Googled) the constants as the same ones used in MD5 - I did my own analysis on that later and determined that Microsoft had started with MD5 but intentionally changed the layout of the final block so that normal MD5 hashing algorithms would not work). Flugan's assembler needed a lot of work to handle the shaders in the Witcher 3 (plus had a lot of problems beyond that), but I judged that to be less than the work that would have been required to make the HLSL compiler work with that game, so this was the point where we shifted focus away from improving the HLSL decompiler to improving Flugan's assembler - initially just to get enough opcode coverage for shaders used in the Witcher 3, and I later continued improving it, completing it's shader model 5 opcode coverage and hardening it to cope with shaders written by humans instead of machines (e.g. not crash if the user has different whitespace preferences to the disassembler, warn about incorrect operand counts instead of crashing, etc), and eventually adding the ShaderRegex engine to facilitate automatically patching shaders.

Of course then we encountered a new problem - some shaders weren't rendering correctly after being disassembled + reassembled, even with no changes made, which we determined was caused by Microsoft's disassembler outputting floats with %f, which only prints 6 digits after the decimal point - most of the time that is good enough, but it does lose some of the lower order bits, and in some cases those bits turned out to be very important. Initially as a proof of concept I solved this with an offline solution that would compare the shader assembly and DXBC bytecode, replacing the 6 digit floats with enough precision that was guaranteed to reconstruct the full 32bit value exactly, and this worked for the affected shaders - so Flugan took this idea and wrote a disassembler fixup pass so we could do this automatically inside 3DMigoto.

And since then, modern games have only used compute shaders more and more. Things like tile lighting are now extremely popular that cannot be done in the traditional graphics pipeline, and there is very little hope that the HLSL decompiler will ever be able to decompile those accurately. If someone wanted to join the development team and work on improving the decompiler we'd of course welcome it, but it is not our priority any more.

Hey DSS,

Thanks for sharing the development history of 3Dmigoto, I really appreciate it! I've been looking at 3Dmigoto for a long time now and it's very interesting to hear how it's evolved. It sounds like there's a core group of 4 or 5 of you that have deep expertise in shader programming. I'd love to be able to contribute one day .. I'm taking courses in python that are teaching general programming concepts, but I'm really interested in the graphics / rendering pipeline. If you were starting over, what sort of learning path would you recommend?

And is there anything interesting we can do with compute shaders in Elite?
 
Pressing ALT+F10 is an in-game screenshot function for the Hi-Res pictures. F10 by itself will take a low res one.



It's not just a thumbnail problem, it wont save my theme at all for some reason. The format (jpeg) and the size (200x61) is the exact same size and format that you get as a template when you click "save" during the theme save process.

I've just found that it is quite easy to "break" the mod while using EDHM to set it up. You can accidentally load the themes as "mods" in themselves and all sorts of other things. EDHM wont stop you from loading themes incorrectly.

Hiya, I encountered the same bug as well, and passed a detailed bug report to Blue Mystic. He's since release a fix though I haven't had a chance to try it yet. Do you know if it's fixed the export issue?

Also, he's going to implement a file import validation so CPM mods don't accidentally end up in the HUD mod section

Please let me know if you spot any other issues so we can get it all running smoothly for the main release
 
Hi CMDRs,

Sorry I've been away for a few days, and thanks for trying out the CPM. Your feedback is really important so we can make this mod as cool as possible

I've added one small feature for the next release .. I wasn't happy with the lights on the HOTAS panel - sometimes the info panels can become blindingly bright depending on the custom colour, plus I wanted you to have the option of default Elite lights or colour modded. I found a buffer last night that let's me target the HOTAS lights independently from the panel, so I'll add an option for default or coloured, plus a dimmer

It won't mess with your current profiles, but you'll probably need to set the HOTAS panel options and then export again

Here's some examples,

Default Elite panel

1663943086892.png


Default with dimmer

1663943111372.png


Colour modded

1663943141201.png


Colour modded with keyboard

Anaconda-HOTASmod.jpg


You might notice I lerp'd the left side of the HOTAS panel (lighting fade) to reduce the bloom that made it quite distracting, and I hope you'll be happy with the result
 
Hiya, I encountered the same bug as well, and passed a detailed bug report to Blue Mystic. He's since release a fix though I haven't had a chance to try it yet. Do you know if it's fixed the export issue?

Also, he's going to implement a file import validation so CPM mods don't accidentally end up in the HUD mod section

Please let me know if you spot any other issues so we can get it all running smoothly for the main release
Just updated EDHM and it has indeed fixed the export problem, please pass on my thanks to Blue Mystic for that and his future fixes/updates.
 
Revenge of the Sith

Courier-Sith.jpg


Just a quick update

Blue Mystic and I have taken the feedback from the Anaconda prototype and redesigned a few systems. It should work more smoothly now, and less prone to errors

The Vette and Mamba are currently in beta testing on the EDHM discord, and I'll hopefully have the Gutamaya ships ready for beta testing by the weekend

Anaconda themes made during the prototype testing won't work with the new version, but I can update your theme for you (psychicEgg#9971 on discord) when you install the new version of the CPM

o7
 
Revenge of the Sith

View attachment 324840

Just a quick update

Blue Mystic and I have taken the feedback from the Anaconda prototype and redesigned a few systems. It should work more smoothly now, and less prone to errors

The Vette and Mamba are currently in beta testing on the EDHM discord, and I'll hopefully have the Gutamaya ships ready for beta testing by the weekend

Anaconda themes made during the prototype testing won't work with the new version, but I can update your theme for you (psychicEgg#9971 on discord) when you install the new version of the CPM

o7
All good, was expecting things like this.

I have written down all my settings and RGB values so I can carry my theme across multiple ships more easily, so replicating my theme again shouldn't be a problem. Thanks for offering to do it for people though, much respect.
 
I'm a Krait Phantom user, this is the perfect time for me to help with the beta testing.... but after entered on the Discord I'm a little confused about how to try the CPM - there is no instructions about how to setup, and the github that marvin mentioned have on the commit history the deletion of a zip file, and we only have the PDFs and the Readme.md file in there
 
Back
Top Bottom