#Color Mask shader with custom colours
1 messages · Page 1 of 1 (latest)
I'm trying to make Tekken 8 avatars for Bonelab but all of the base textures are white/grey so that they can be customised in game
i'm able to colour some of it but it isn't really accurate and the rest of it gets left uncoloured
colour shift 3 and 4 being blue and alpha but there isn't any for the colour mask texture i have
Normally if you have a greyscale texture you want to apply colour to later you just multiply/add/whatever against this texture.
Are you trying to use a mask texture to control how strongly 4 colours get applied to the greyscale tex?
each of the shades are different colours
all of these except the splitnumberperchannel colour
tbh i cant understand what you actually want to do from the shader graph.
How are you trying to use this mask then
A mask thats RGBA would imply 4 maskable colours
I want to be able to choose the colours that change
like i can select the dark green and set it to be black
yeah thats the problem
i need more maskable colours
This will quickly become too complex. It can be done by altering the colour if the input is close enough to some color. Shader graph has a node for this but no idea of amplify does
https://docs.unity3d.com/Packages/com.unity.shadergraph@17.4/manual/Replace-Color-Node.html
If you have 8 for example, you would need to do 8 in a row. If you wanted to stop early you need to introduce branching which is not ideal.
The best solution would be a compute shader to just make a new texture with the desired changes so we dont have to care about such things but that may not be possible in this case?
comple?
whoops. i meant "complex"
ok i checked and it does have it
how would i implement it?
you would do the replace colour as many times in a row as you want to support
but previous results will influence subsequent results too so its not great
Would 4 colours max be acceptable? Are vertex colours usable here?
I need probably 6 colours minimum
cause some of the colour mask textures have more
mask textures are easier because you just do:
float3 col = float3(0,0,0);
col += colour1 * mask.r;
col += colour2 * mask.g;
col += colour3 * mask.b;
col += colour4 * mask.a;
because we just use the mask channels to control strength of some colours
but this does rely on careful mask creation too but its prefered to reduce cost of the shader
I tried the replace colour node and it kinda works but also doesn't at the same time
it only makes it lighter or darker when i move the colour wheel thing
do you have an example?
I've tried a few ways and none of them work properly
well in theory it would be
- sample texture
- colour replacement 1
- colour replacement 2
and so on
if you do one after another (connect output of replacement 1 into replacement 2) they will potentially mess up the result
The better alternative is to do the colour distance check yourself on the original texture sample and then use that to reduce or keep a certain colour.
either way its gonna be a bit annoying to do and wont be fully reliable
i have it like this
multiplying the replace results all together is wrong. It returns the original color or the desired replacement
understand what the node does and then think what this is doing
no idea if the nodes in amplify are documented so you are on your own there
or whatever this shader creator is
its amplify
yeah i dont think this is gonna work
its close but you just lack some knowledge on how fragment shaders work
Id recommend something like this:
float4 col = SampleTexture(texture, uv);
float3 tint = float3(0,0,0); //Start with black
tint += distance(col, id1) < 0.01 ? colour1 : float3(0,0,0); //If sampled colour is close enough to id1, add color 1. Else add black.
//Repeat as many times as needed
tint += distance(col, id2) < 0.01 ? colour2 : float3(0,0,0);
//Apply tint
col += col * tint;
Here if the sampled color is similar enough to the id colour, we use the corresponding colour to tint later.
This implementation avoids branching which is why we add black when not close to the id colour (failed match).
How you apply the tint may need to change but hopefully the example is somewhat helpful
Looking at the texture and this "inputs" list, I think there is a simple indexing logic applied.
If I guess correctly, the "SplitNumberPerChannel" value defines the number of different values for each channel of the control texture, from the look of it it seems to be 4 in green and 3 in red (to have 7 total colors).
The colors seems to be exclusive, so the pseudocode would be something like :
rIsEmpty = (textureSample.r == 0)?1:0;
index = floor( textureSample.r * numberPerChannel.r );
index += numberPerChannel.r * rIsEmpty + floor(textureSample.g * numberPerChannel.g);
Then pass the colors as a VectorArray to the material and you can retrieve the value from the index :
color = colorArray[index];
I'd rather do color masking by hue rather than brightness, since otherwise when interpolating between different color indices they likely have to go through unrelated indices
Especially when the brightest color is next to black
Not sure if using hue is impractically expensive though
this is the math under the hood with some notes http://paste.amplify.pt/view/raw/d04e77e0