Jump to content
The Dark Mod Forums

[Feature discussion] Ability to colorize character clothes via the _color spawnarg


MirceaKitsune
 Share

Recommended Posts

Should first mention this isn't a request as the change is something I should be fully capable of doing on my own: The engine fully supports it and I already used this setup when I imported a bunch of custom models, it just needs to be done for the vanilla ones... something similar was recently implemented to allow torches to have colored flames, this is kinda the same thing but for characters instead. I wanted a discussion thread first so I know if other mappers and players want this and will use it, also if the devs would accept it if I was to do the work.

TDM allows all model entities to contain a grayscale texture which can be set to any color via the "_color" spawnarg of the entity. The only requirement is having the appropriate textures then simply adding your paint image to the material with the "colored" keyword:

	// Shirt
	{
		blend diffusemap
		map models/md5/chars/guard/body_shirt
		colored
	}

I'd like some of the AI characters to support this for setting custom colors on clothes. Imagine you make a city where you want the city watch to be red instead of the default blue as it would fit your theme better, you'd just set "_color 0.5 0 0" on your guard and you have them representing your faction of choice! It would be just as useful on civilians to easily obtain more unique characters without needing extra assets for each... what if you want the nobleman with the green tunic to have a purple tunic, or the noblewoman with the blue dress to have a red dress?

Obviously this requires editing the character textures... I've done this sort of thing many times in Gimp fortunately, might even be able to generate them with a bash script using ImageMagick; The color just needs to be extracted from the base diffuse texture, desaturated, then put in a separate image as an intensity map. By saving it as grayscale with no alpha channel it should take up little extra space, granted the engine doesn't have issues with grayscale tga / dds compressed images (all specular maps should also be using that).

Obviously each affected character would have a default "_color" spawnarg matching the default color so existing FM's won't see any changes. There's only one issue here: Due to the colorization technique being different, there's likely no way it can be made to look the exact same way... the clothes may appear just a little more or less bright or saturated, not by a lot just that it likely won't be perfectly the same. Is that considered too breaking to be accepted, or are there other reasons why anyone believes I shouldn't spend time on this?

Link to comment
Share on other sites

Why even consider editing the existing materials to respond to the _color spawnarg?

This seems totally unnecessary - just make a new material and skin definition for your colorable material and then if you want to color an ai you can select that option from the skin browser without altering the look of any core assets at all.

  • Like 2
Link to comment
Share on other sites

1 hour ago, Wellingtoncrab said:

Why even consider editing the existing materials to respond to the _color spawnarg?

This seems totally unnecessary - just make a new material and skin definition for your colorable material and then if you want to color an ai you can select that option from the skin browser without altering the look of any core assets at all.

That's also an option but it has some drawbacks: The mapper needs to extract and edit the textures in an image editor... we can assume they have Photoshop and know how to change the hue, but many won't bother going that far if it's not a readily available option. Also keep in mind the texture contains multiple colors, for instance you need to edit only the green vest without changing the hue on brown leather, this can be trickier to do... with a texture map it will automatically change only the colored part. It also requires redistributing the textures and increasing the FM size, probably not by a lot but if you want to keep it light and minimize extra assets it can matter. With this approach you can have the same character in multiple colors without loading a new texture in memory for each, a commoner with a red tunic and one with a blue one would use the same textures in memory. Plus you can freely change and preview the color in DR, much easier than having to edit textures.

I'll probably try this just for the city watch as a test first then share some screenshots: Shouldn't be too much work for just one character to see what results I get. If that works and is considered okay, I'll do it just for builders nobles and some commoners... should only be done for those few characters that have a colored fabric vest.

Edited by MirceaKitsune
Link to comment
Share on other sites

@MirceaKitsuneSorry I admittedly cannot follow your statement. You do not need to modify an existing material to make a new material definition and all you need to apply it to an existing model is a skin definition. So there is no need to be concerned about altering the look of existing materials or trying to color match them (which would be as you mention very difficult using colorization given all the color variances in a typical texture) when you can just make a brand new material definition and skin definition for this without touching core definitions at all. That is material not texture  so once you set it up I don’t see why a mapper would need to interact with an image editor, they would pick your new skin which references the new material and greyscale maps you have created and then will tweak the _color spawnarg just you are describing.

Look at the light models in core which support the _color spawnarg - these usually have separate skins which denote they support custom _color or not. Same principle applies here.

 

Link to comment
Share on other sites

( This will also require a custom skin def ... )

This is what is proposed:

Custom material:

/some_custome_material_name
// Shirt
	{
		blend diffusemap
		map makeIntensity(models/md5/chars/guard/body_shirt)
		_color
	}

Please visit TDM's IndieDB site and help promote the mod:

 

http://www.indiedb.com/mods/the-dark-mod

 

(Yeah, shameless promotion... but traffic is traffic folks...)

Link to comment
Share on other sites

16 minutes ago, Wellingtoncrab said:

@MirceaKitsuneSorry I admittedly cannot follow your statement. You do not need to modify an existing material to make a new material definition and all you need to apply it to an existing model is a skin definition. So there is no need to be concerned about altering the look of existing materials or trying to color match them (which would be as you mention very difficult using colorization given all the color variances in a typical texture) when you can just make a brand new material definition and skin definition for this without touching core definitions at all. That is material not texture  so once you set it up I don’t see why a mapper would need to interact with an image editor, they would pick your new skin which references the new material and greyscale maps you have created and then will tweak the _color spawnarg just you are describing.

Look at the light models in core which support the _color spawnarg - these usually have separate skins which denote they support custom _color or not. Same principle applies here.

I see what you mean now, sorry my brain can be slow sometimes: Instead of modifying the existing skins and textures, I should indeed define a new skin intended for colorization. That's definitely better if I think about it, thanks for bringing this to my attention.

I only have one problem then: I don't want to create a second diffuse texture, only the color map meant to override the colored area. In my custom material, how can I first subtract the shirt color from the original texture to blacken it out? This is to avoid intermediary colors in areas where they blend, so if you colorize your guard to red you don't see purple at a pixel where the color map intensity is 0.5 and blends over the blue in default. I could avoid this is there was a material blend option to change the hue based on my map, instead of applying a new color on top it... I'm not aware of a way to do that though. Any thoughts please?

16 minutes ago, nbohr1more said:

( This will also require a custom skin def ... )

This is what is proposed:

Custom material:

/some_custome_material_name
// Shirt
	{
		blend diffusemap
		map makeIntensity(models/md5/chars/guard/body_shirt)
		_color
	}

Thanks. The original texture would be grayscale but I should use that keyword for safe measure. Saving the tga / dds as grayscale would have helped to reduce file size, unfortunately some engines have issues with that format so I'll have to check if TDM recognizes non-RGB. For now I can just save it normally and use the existing compression, specular maps don't seem to saved this way either.

Link to comment
Share on other sites

Got something better: "blend filter" seems to do what I want, changing the color of the texture without erasing brightness information. Only downsides are that it darkens the output more than it should, whereas black covers everything so it will likely need an alpha channel. There must be a better way... for now though gives me the exact feel I desire and for which I wanted this feature :)

139086890_testing(2022-11-0723-31-26)(-113.79280_3568.25).thumb.jpg.d01c2cc42183c0084737c9e969bc887f.jpg

  • Like 1
Link to comment
Share on other sites

5 hours ago, datiswous said:

So how is this done? With a material and skin dev?

Yes. You only need an extra texture consisting of a grayscale map, then in the material you overlay it on top of everything else... give your material overlay the argument "colored" and it will use the color of the entity's "_color" spawnarg. You can only have one color but that's good enough... if multiple args were supported we could technically colorize the hair and eyes and so on, but that would be going too far and is unnecessary.

Think I know what I need to get it working properly which I'll try later tonight. The shirt map must have an alpha channel and should be overlayed based on that, color must represent brightness entirely and shouldn't be used for blending. This way it should cover the default blue on the guard without losing brightness information on the color map either.

Do I use "maskalpha", "alphaTest 0.5", and / or "blend gl_dst_alpha, gl_one"? I forgot which it was to overlay a texture based entirely on its alpha channel. Once that's done it should be just a matter of doing the proper textures and untangling the skins / materials to add the extra ones.

Link to comment
Share on other sites

If it works properly and you find a way to describe it easily this could maybe be added somewhere in the wiki. I find that quiet good for adding new looks to the over and over used existing ones without having an additional software tool

  • Like 1

"Einen giftigen Trank aus Kräutern und Wurzeln für die närrischen Städter wollen wir brauen." - Text aus einem verlassenen Heidenlager

Link to comment
Share on other sites

I've been making progress but a proper solution remains complicated. I tried every blend mode possible and nothing does what I want. Help would be appreciated on what I should do with the material.

The issue is I don't want to needlessly duplicate the original diffuse texture only to create a copy with the mask extruded, so that the colored area where the shirt comes on top is blackened out. I also can't simply apply the mask on top of the original texture as then the two colors blend together... for instance red becomes purple because it's added on top of the guard's normally blue shirt. For this reason I first need to subtract the mask from the diffuse map before adding it back as its colored self. I can't however find a satisfactory way of doing this, and so far had to result to a hack that partly works:

	//use the color texture to set shirt color to the _color spawnarg
	//the intensity must first be subtracted from the original texture then added back colored
	{
		blend diffusemap
		map makeIntensity(models/md5/chars/guards/cityguard_armor_color)
		rgb -1
	}
	{
		blend diffusemap
		map makeIntensity(models/md5/chars/guards/cityguard_armor_color)
		colored
	}

By using "rgb -1" I can invert the mask texture and apply this inversion to darken the area. Apart from seeming like a dodgy solution however, this can result in a negative color if the _color spawnarg is set to something less than 1: When that happens the guard's shirt starts experiencing dark spots as if there's a black hole on him.

Other blend modes won't work because they destroy lighting information. "blend gl_dst_color, gl_one" for instance will map the texture accordingly, but does so at full brightness and results in a glowing vest. This is why giving the mask an alpha channel doesn't help either, you can only use "blend diffusemap" but that mixes based on brightness. What do you suggest?

For now, with colors set to full intensity, my hacky material produces a beautiful result that looks gorgeous!

976342759_testing(2022-11-0823-26-56)(106.65303_768.25).thumb.jpg.2fe09d1a874788afecb301da86f4ca29.jpg

Link to comment
Share on other sites

Finally got it! The blend modes drove me insane as it took an hour to find the right mix, what I wanted for darkening was "blend gl_zero, gl_one_minus_src_color". One mistake I made was clearing the alpha channel of the destination, I believe that's why diffuse could no longer be applied on top and it all remained black. Now I'm properly subtracting the color of the mask then applying it back as its colorized self, no alpha channel required though the image must be as contrasted and close to white as possible to work effectively.

	//use the color texture to set shirt color to the _color spawnarg
	//the intensity must first be subtracted from the original texture then added back colored
	{
		blend gl_zero, gl_one_minus_src_color
		map makeIntensity(models/md5/chars/guards/cityguard_armor_color)
	}
	{
		blend diffusemap
		map makeIntensity(models/md5/chars/guards/cityguard_armor_color)
		colored
	}

And here's an image of the final result with this, the color map will still need to be further improved. On the left you can see the half intensity colors while on the right it's at maximum brightness. Let me know what you think and if I should change anything before I keep going.

1743121285_testing(2022-11-0902-14-58)(223.14-0_0368.25).thumb.jpg.a3d7a740ee3648ea4c470b6f049d8620.jpg

Link to comment
Share on other sites

That's pretty impressive, so I could use that by importing the shader to my FM and then adjust the colour in the entity properties? I personally would go with the left side, but I would like to see some of the colours even more less saturated if possible, like the green, it is a bit too colourful but that's only my opinion

"Einen giftigen Trank aus Kräutern und Wurzeln für die närrischen Städter wollen wir brauen." - Text aus einem verlassenen Heidenlager

Link to comment
Share on other sites

10 hours ago, SeriousToni said:

That's pretty impressive, so I could use that by importing the shader to my FM and then adjust the colour in the entity properties? I personally would go with the left side, but I would like to see some of the colours even more less saturated if possible, like the green, it is a bit too colourful but that's only my opinion

Yes, you'll just give a guard with this skin the _color spawnarg as you would a light to colorize it. And you can adjust brightness hue and saturation in the spawnarg: They only appear like that since in my example I set them to full values like "_color 0 1 0", for less saturation you can use something like "_color 0.5 1 0.5" instead. I wish they were a little brighter, not sure why they remain so dark at full intensity, but overall I'm happy with how it works.

Link to comment
Share on other sites

2 hours ago, SeriousToni said:

I would like to try this out please. :)

It's in very early stage; Wanted to at least get the guards done before posting anything so there's one complete set: The skins and materials are a little tangled and it's not clear what is what, while extracting the color in Gimp takes attention as the selection can get mixed up. If you want the early test I can try sending it on Discord, only one extra texture for now so it should be within its file limits.

Link to comment
Share on other sites

3 hours ago, SeriousToni said:

Man I wish TDM multiplayer was here

I'd like that too. Wouldn't do the typical shooter modes in TDM though: Multiplayer would be great to allow more than one player on a FM at once... either working cooperatively to beat it together, or in face of multiple teams each team competing to complete its own objectives first. Now that would be neat.

But it would require enormous changes I doubt anyone will make. Everything in TDM is hardwired around there being one player, countless things would need to be changed just to understand the concept of more than one player entity.

Color characters aren't just for that though: The main goal is being able to more accurately represent your theme, like a builder or monarch city would feel more fitting with red city watch. It's also to make multiple characters appear more unique in the case of civilians, like if you want 5 noblemen in your FM and have them all look more unique you can give each one a differently colored shirt... existing skins already do that but you're limited to fewer options whereas this doesn't store or load extra textures in memory per character since it's all done in the material with one map.

Link to comment
Share on other sites

4 hours ago, datiswous said:

I guess you could also use this for different colored animals for example?

Yes it could but wouldn't using the skin system be better for that?

I know that using the colored system, permits to do variable colors very easily, good for carpets, flags, cloth, etc and also only have a single material, but if your idea is to make more varied looking characters, with a single model, I think the skin system is better, it means more materials need to be created but it also means more flexibility and power.

The skin system is very powerful, was designed exactly to make different material variations for a single model and it does way more than just swap colors, you can have characters that look somewhat different geometrically, by hiding or showing hidden peace's on a model, etc.

On a animal for example you can have a model with fur and another without it by just hiding the fur geometry, or one with a collar on his neck and another without it, without swapping models, just the skin.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

  • Recent Status Updates

    • nbohr1more

      The Dark Mod is hosting an Ask Me Anything thread on the PC Gaming reddit forum:  https://www.reddit.com/r/pcgaming/comments/10nfcwj/hello_we_are_the_international_development_team/
      Feel free to join the discussion there
      · 0 replies
    • stgatilov

      Bumped into an interesting piece of wisdom called Hyrum's Law:
      With a sufficient number of users of an API, it does not matter what you promise in the contract: all observable behaviors of your system will be depended on by somebody.
      · 5 replies
    • The Black Arrow

      I love playing The Dark Mod when it's cold in my place. Bonus points when it's a bit (or even very) dark and it's raining, too.
      · 1 reply
    • The Black Arrow

      I've been having stutters in Vulkan, apparently it's Nvidia Drivers' fault, so I reverted to 512 according to this: https://www.nvidia.com/en-us/geforce/forums/geforce-graphics-cards/5/505679/regular-microstutter-in-vulkan-applications-after-/?topicPage=40

      And no, that did NOT fix it. What's going on? My GPU is an RTX 2070, by the way.
      · 4 replies
    • datiswous

      I just figured out how to make subtitles work in TDM (srt) for ingame cutscenes and how to automatically generate the srt file in Kdenlive's speech recognition (I just had to edit it a bit).
      Kdenlive is a free and open source multiplatform pretty advanced video editor.
      Test case is the first builder gost scene in Requiem saying:
      1 00:00:00,180 --> 00:00:02,140 the builder be with you this night 2 00:00:02,600 --> 00:00:04,840 there will be secrets all around you 3 00:00:05,040 --> 00:00:06,439 so have a keen eye The following page gives you the basic info:
      https://wiki.thedarkmod.com/index.php?title=Subtitles
      These 2 tutorials give you the info for creating the srt files:
      If you run into the problem the Kdenlive cannot find your Python PATH, then here is a solution:
      https://www.mail-archive.com/kde-bugs-dist@kde.org/msg672183.html
      Edit: During the installation of Python, in the installer, if you select more options, you can specify to set the PATH. I tried this on another Windows computer and this fixed the issue. Much easier solution.
       
      This is all the code for the testcase:
       
      Maybe I will create a seperate (text,images based) tutorial on the wiki.
      · 8 replies
×
×
  • Create New...