Nengalore Posted March 4, 2016 Share Posted March 4, 2016 (edited) Hi, I don't know if anyone here is taking plugin requests, but if they are, I have one. So... I need a 'Palette Mask' plugin, for textures. I tried learning how to make a plugin, but I couldn't, and I really only want to make this one plugin. The idea is simple, but the actual creation, I assume not so much. Basically, how it works is: There's a little UI, you pick two colors, a primary (palette1), and a secondary (palette2). You open a file browser, and choose a 'Palette Mask' image. You open another file browser, and choose a 'Palette Map' image If the palette mask is black, then the diffuse texture (base image) is displayed. If it's red, then the palette1 color mixed with the palette map texture is displayed. If it's green, then the palette2 color mixed with the palette map texture is displayed. If it's blue, then this pixel has a metallic specular color The alpha value of the palette mask is not used. Any other colors (cyan, purple etc.) are just combinations of these cases. If you are interested in how the palette1/palette2 colors are mixed with the palette map, I posted some HLSL shader code here: http://pastebin.com/EVja22sK I am willing to pay for this plugin, if it works correctly. If you're interested in my request, please reply, and I will give you a few sample textures to work with. Thank you, -Nen Edited March 4, 2016 by Nengalore Quote Link to comment Share on other sites More sharing options...
toe_head2001 Posted March 4, 2016 Share Posted March 4, 2016 (edited) If I understand you correctly, that shouldn't be too hard. Go ahead and post the samples, and I and/or one of the other plugin developers will look into it. That code snippet that you linked to is Java, but converting Java to C# is pretty straightforward as they are mostly the same. Edit: Read your post too fast. I see it's HLSL, not Java. Can you blame a guy, they look much alike. Edited March 4, 2016 by toe_head2001 Quote (September 25th, 2023) Sorry about any broken images in my posts. I am aware of the issue. My Gallery | My Plugin Pack Layman's Guide to CodeLab Link to comment Share on other sites More sharing options...
Nengalore Posted March 4, 2016 Author Share Posted March 4, 2016 (edited) If I understand you correctly, that shouldn't be too hard. Go ahead and post the samples, and I and/or one of the other plugin developers will look into it. That code snippet that you linked to is Java, but converting Java to C# is pretty straightforward as they are mostly the same. These are small textures, just as an example, if you want different textures, just ask. For this texture, if you want to show me that your plugin worked, take a snip of your screen after using your plugin with these colors: palette1: RGB: 65, 64, 73 palette2: RGB: 172, 27, 44 PluginSamples.zip Edited March 4, 2016 by Nengalore Quote Link to comment Share on other sites More sharing options...
Nengalore Posted March 4, 2016 Author Share Posted March 4, 2016 Please post here with any progress. Quote Link to comment Share on other sites More sharing options...
Nengalore Posted March 4, 2016 Author Share Posted March 4, 2016 Read your post too fast. I see it's HLSL, not Java. Can you blame a guy, they look much alike. Will you still try? Quote Link to comment Share on other sites More sharing options...
BoltBait Posted March 4, 2016 Share Posted March 4, 2016 If you keep bumping this thread, I'm going to close it. Quote Download: BoltBait's Plugin Pack | CodeLab | and a Computer Dominos Game Link to comment Share on other sites More sharing options...
Nengalore Posted March 4, 2016 Author Share Posted March 4, 2016 If you keep bumping this thread, I'm going to close it. Sorry, that was not my intention. Quote Link to comment Share on other sites More sharing options...
toe_head2001 Posted March 5, 2016 Share Posted March 5, 2016 I got about 20 lines into converting that code snippet to C#, and then I realized it is missing some code in a few places. For example: if (paletteMaskMapValue.x < paletteMaskMapValue.y) { palette = palette2; The 'palette2' variable is not declared anywhere in the file. Quote (September 25th, 2023) Sorry about any broken images in my posts. I am aware of the issue. My Gallery | My Plugin Pack Layman's Guide to CodeLab Link to comment Share on other sites More sharing options...
Nengalore Posted March 5, 2016 Author Share Posted March 5, 2016 (edited) I got about 20 lines into converting that code snippet to C#, and then I realized it is missing some code in a few places. For example: if (paletteMaskMapValue.x < paletteMaskMapValue.y) { palette = palette2; The 'palette2' variable is not declared anywhere in the file. Well I mentioned that 'palette1' (primary) and 'palette2' (secondary) refer to the two color selections on the UI. Edited March 5, 2016 by Nengalore Quote Link to comment Share on other sites More sharing options...
toe_head2001 Posted March 5, 2016 Share Posted March 5, 2016 This morning I spent some more time on this. I was able to recreate some of the needed HLSL functions (frac, saturate, ect.) in C# based on info from MSDN, but there are places in the code I have no idea what the outcome of the line of code should be. I simply don't know enough about HLSL to continue. I've heard HLSL can be used directly in .Net via WPF, but I'm not too familiar with that either. Here's my work-in-progress of that file(about half). I can't be sure if my changes are correct. Hidden Content: using System; namespace MapMask { internal struct Float3 { public float R; public float G; public float B; public Float3(float first, float second, float third) { R = first; G = second; B = third; } } public class Class1 { float frac(float n) { float number = n - (float)Math.Truncate(n); return number; } float saturate(float n) { float number; if (n < 0) number = 0; else if (n > 1) number = 1; else number = n; return number; } float lerp(float x, float y, float s) { float number = x + s * (y - x); return number; } // =================================================================================== // HUEING // =================================================================================== //Utility Functions Float3 ExpandHSL(Float3 HSL) { //float3 outputVal = inVal * (maxVal - minVal) + minVal; Float3 expanded = HSL; expanded.R = (HSL.R * (.706f - .3137f)) + .3137f; //reexpand hue expanded.R -= .41176f; //offset hue expanded.G = (HSL.G * .5882f); expanded.B = (HSL.B * .70588f); return expanded; } Float3 AdjustLightness(Float3 HSL, float brightness, float contrast) //Adjust the lightness of the HSL { HSL.B = (float)(Math.Pow(HSL.B, contrast) * contrast); HSL.B = brightness + ((1 - brightness) * HSL.; return HSL; } float OffsetHue(float hue, float hueOffset) { float H = frac(hue + hueOffset); return H; } float OffsetSaturation(float saturation, float satOffset) { float S = saturation; S = (float)Math.Pow(S, satOffset); S = S * (1 - satOffset); S = saturate(S); return S; } Float3 OffsetHSL(Float3 HSL, float hueOffset, float satOffset) { float H = OffsetHue(HSL.X, hueOffset); float S = OffsetSaturation(HSL.Y, satOffset); return new Float3(H, S, HSL.Z); } Float3 ConvertHSLToRGB(Float3 HSL) { const float fOneThird = 0.333333333f; const float fTwoThirds = 0.666666666f; Float3 color; float temp1, temp2; float H = HSL.R; float S = HSL.G; float L = HSL.B; //if (S == 0) // return float3(L, L, L); float LtimesS = L * S; if (L < 0.5f) temp2 = L + LtimesS; else temp2 = L + S - LtimesS; temp1 = 2.0f * L - temp2; Float3 temp3 = frac(new Float3(H + fOneThird, H, H - fOneThird)); Float3 temp3Times6 = 6.0f * temp3; Float3 temp3Times2 = 2.0f * temp3; Float3 temp3Times1point5 = 1.5f * temp3; Float3 firstEquation = temp1 + (temp2 - temp1) * 6.0f * temp3; Float3 secondEquation = temp1 + (temp2 - temp1) * (fTwoThirds - temp3) * 6.0f; if (temp3Times6.R < 1.0f) color.R = firstEquation.R; else if (temp3Times2.R < 1.0f) color.R = temp2; else if (temp3Times1point5.R < 1.0f) color.R = secondEquation.R; else color.R = temp1; if (temp3Times6.G < 1.0f) color.G = firstEquation.G; else if (temp3Times2.G < 1.0f) color.G = temp2; else if (temp3Times1point5.G < 1.0f) color.G = secondEquation.G; else color.G = temp1; if (temp3Times6.B < 1.0f) color.B = firstEquation.B; else if (temp3Times2.B < 1.0f) color.B = temp2; else if (temp3Times1point5.B < 1.0f) color.B = secondEquation.B; else color.B = temp1; return color; } Float3 ManipulateHSL(in Float3 HSL, float4 palette) { HSL = ExpandHSL(HSL); HSL = AdjustLightness(HSL, palette.z, palette.w); HSL = OffsetHSL(HSL.rgb, palette.x, palette.y); return HSL; } float ManipulateAO(in float ao, float brightness, float contrast) { brightness += 1; //brightness + ((1 - brightness) * HSL.; float ret = ao * (brightness + (1 - brightness) * ao); return saturate(ret); } void HuePixel( in float4 diffuseMapValue, in float4 specularMapValue, float4 paletteMaskMapValue, float4 paletteMapValue, out Float3 fragmentDiffuseColor, out float4 fragmentSpecularColor ) { fragmentDiffuseColor = diffuseMapValue.rgb; fragmentSpecularColor = specularMapValue; float paletteMaskSum = paletteMaskMapValue.x + paletteMaskMapValue.y; // Only use the palette that applies float4 palette; Float3 chosenSpecColor, chosenMetallicSpecColor; if (paletteMaskMapValue.x < paletteMaskMapValue.y) { palette = palette2; chosenSpecColor = palette2Specular.rgb; chosenMetallicSpecColor = palette2MetallicSpecular.rgb; } else { palette = palette1; chosenSpecColor = palette1Specular.rgb; chosenMetallicSpecColor = palette1MetallicSpecular.rgb; } // Get the palette map, apply the deltas, and convert it to RGB Float3 HSL = ManipulateHSL(new Float3(paletteMapValue.g, paletteMapValue.b, paletteMapValue.a), palette); float ambientOcclusion = ManipulateAO(paletteMapValue.r, palette.z, palette.w); HSL.z *= ambientOcclusion; Float3 RGB = ConvertHSLToRGB(HSL); //Blend the result into the original diffuse fragmentDiffuseColor = lerp(diffuseMapValue.rgb, RGB.rgb, paletteMaskSum); // Determine the hue specular color Float3 hueSpecColor; const Float3 white = new Float3(1, 1, 1); float metallicMask = paletteMaskMapValue.b; //1.0 uses chosenMetallicSpecColor, .5 uses white, 0.0 uses chosenSpecColor if (metallicMask > .5) { hueSpecColor = lerp(white, chosenMetallicSpecColor, (metallicMask - 0.5) * 2); } else { hueSpecColor = lerp(chosenSpecColor, white, metallicMask * 2); } hueSpecColor *= specularMapValue.r; fragmentSpecularColor.rgb = lerp(fragmentSpecularColor.rgb, hueSpecColor, paletteMaskSum); } } } Quote (September 25th, 2023) Sorry about any broken images in my posts. I am aware of the issue. My Gallery | My Plugin Pack Layman's Guide to CodeLab Link to comment Share on other sites More sharing options...
Nengalore Posted March 5, 2016 Author Share Posted March 5, 2016 (edited) This morning I spent some more time on this. I was able to recreate some of the needed HLSL functions (frac, saturate, ect.) in C# based on info from MSDN, but there are places in the code I have no idea what the outcome of the line of code should be. I simply don't know enough about HLSL to continue. I've heard HLSL can be used directly in .Net via WPF, but I'm not too familiar with that either. Here's my work-in-progress of that file(about half). I can't be sure if my changes are correct. Hidden Content: using System; namespace MapMask { internal struct Float3 { public float R; public float G; public float B; public Float3(float first, float second, float third) { R = first; G = second; B = third; } } public class Class1 { float frac(float n) { float number = n - (float)Math.Truncate(n); return number; } float saturate(float n) { float number; if (n < 0) number = 0; else if (n > 1) number = 1; else number = n; return number; } float lerp(float x, float y, float s) { float number = x + s * (y - x); return number; } // =================================================================================== // HUEING // =================================================================================== //Utility Functions Float3 ExpandHSL(Float3 HSL) { //float3 outputVal = inVal * (maxVal - minVal) + minVal; Float3 expanded = HSL; expanded.R = (HSL.R * (.706f - .3137f)) + .3137f; //reexpand hue expanded.R -= .41176f; //offset hue expanded.G = (HSL.G * .5882f); expanded.B = (HSL.B * .70588f); return expanded; } Float3 AdjustLightness(Float3 HSL, float brightness, float contrast) //Adjust the lightness of the HSL { HSL.B = (float)(Math.Pow(HSL.B, contrast) * contrast); HSL.B = brightness + ((1 - brightness) * HSL.; return HSL; } float OffsetHue(float hue, float hueOffset) { float H = frac(hue + hueOffset); return H; } float OffsetSaturation(float saturation, float satOffset) { float S = saturation; S = (float)Math.Pow(S, satOffset); S = S * (1 - satOffset); S = saturate(S); return S; } Float3 OffsetHSL(Float3 HSL, float hueOffset, float satOffset) { float H = OffsetHue(HSL.X, hueOffset); float S = OffsetSaturation(HSL.Y, satOffset); return new Float3(H, S, HSL.Z); } Float3 ConvertHSLToRGB(Float3 HSL) { const float fOneThird = 0.333333333f; const float fTwoThirds = 0.666666666f; Float3 color; float temp1, temp2; float H = HSL.R; float S = HSL.G; float L = HSL.B; //if (S == 0) // return float3(L, L, L); float LtimesS = L * S; if (L < 0.5f) temp2 = L + LtimesS; else temp2 = L + S - LtimesS; temp1 = 2.0f * L - temp2; Float3 temp3 = frac(new Float3(H + fOneThird, H, H - fOneThird)); Float3 temp3Times6 = 6.0f * temp3; Float3 temp3Times2 = 2.0f * temp3; Float3 temp3Times1point5 = 1.5f * temp3; Float3 firstEquation = temp1 + (temp2 - temp1) * 6.0f * temp3; Float3 secondEquation = temp1 + (temp2 - temp1) * (fTwoThirds - temp3) * 6.0f; if (temp3Times6.R < 1.0f) color.R = firstEquation.R; else if (temp3Times2.R < 1.0f) color.R = temp2; else if (temp3Times1point5.R < 1.0f) color.R = secondEquation.R; else color.R = temp1; if (temp3Times6.G < 1.0f) color.G = firstEquation.G; else if (temp3Times2.G < 1.0f) color.G = temp2; else if (temp3Times1point5.G < 1.0f) color.G = secondEquation.G; else color.G = temp1; if (temp3Times6.B < 1.0f) color.B = firstEquation.B; else if (temp3Times2.B < 1.0f) color.B = temp2; else if (temp3Times1point5.B < 1.0f) color.B = secondEquation.B; else color.B = temp1; return color; } Float3 ManipulateHSL(in Float3 HSL, float4 palette) { HSL = ExpandHSL(HSL); HSL = AdjustLightness(HSL, palette.z, palette.w); HSL = OffsetHSL(HSL.rgb, palette.x, palette.y); return HSL; } float ManipulateAO(in float ao, float brightness, float contrast) { brightness += 1; //brightness + ((1 - brightness) * HSL.; float ret = ao * (brightness + (1 - brightness) * ao); return saturate(ret); } void HuePixel( in float4 diffuseMapValue, in float4 specularMapValue, float4 paletteMaskMapValue, float4 paletteMapValue, out Float3 fragmentDiffuseColor, out float4 fragmentSpecularColor ) { fragmentDiffuseColor = diffuseMapValue.rgb; fragmentSpecularColor = specularMapValue; float paletteMaskSum = paletteMaskMapValue.x + paletteMaskMapValue.y; // Only use the palette that applies float4 palette; Float3 chosenSpecColor, chosenMetallicSpecColor; if (paletteMaskMapValue.x < paletteMaskMapValue.y) { palette = palette2; chosenSpecColor = palette2Specular.rgb; chosenMetallicSpecColor = palette2MetallicSpecular.rgb; } else { palette = palette1; chosenSpecColor = palette1Specular.rgb; chosenMetallicSpecColor = palette1MetallicSpecular.rgb; } // Get the palette map, apply the deltas, and convert it to RGB Float3 HSL = ManipulateHSL(new Float3(paletteMapValue.g, paletteMapValue.b, paletteMapValue.a), palette); float ambientOcclusion = ManipulateAO(paletteMapValue.r, palette.z, palette.w); HSL.z *= ambientOcclusion; Float3 RGB = ConvertHSLToRGB(HSL); //Blend the result into the original diffuse fragmentDiffuseColor = lerp(diffuseMapValue.rgb, RGB.rgb, paletteMaskSum); // Determine the hue specular color Float3 hueSpecColor; const Float3 white = new Float3(1, 1, 1); float metallicMask = paletteMaskMapValue.b; //1.0 uses chosenMetallicSpecColor, .5 uses white, 0.0 uses chosenSpecColor if (metallicMask > .5) { hueSpecColor = lerp(white, chosenMetallicSpecColor, (metallicMask - 0.5) * 2); } else { hueSpecColor = lerp(chosenSpecColor, white, metallicMask * 2); } hueSpecColor *= specularMapValue.r; fragmentSpecularColor.rgb = lerp(fragmentSpecularColor.rgb, hueSpecColor, paletteMaskSum); } } } Great work! And please do not give up, this plugin is not just for me, there's a community of people who would really like this plugin as well. Thank you for doing this. Edited March 5, 2016 by Nengalore Quote Link to comment Share on other sites More sharing options...
toe_head2001 Posted March 5, 2016 Share Posted March 5, 2016 I've found some relevant information on using HLSL in .NET via WPF. I look into it in the coming days when I have some time. http://mrpfister.com/journal/writing-hlsl-pixel-shaders-for-wpf/ https://msdn.microsoft.com/en-us/library/system.windows.media.effects.pixelshader%28v=vs.110%29.aspx Quote (September 25th, 2023) Sorry about any broken images in my posts. I am aware of the issue. My Gallery | My Plugin Pack Layman's Guide to CodeLab Link to comment Share on other sites More sharing options...
Nengalore Posted March 5, 2016 Author Share Posted March 5, 2016 I've found some relevant information on using HLSL in .NET via WPF. I look into it in the coming days when I have some time. http://mrpfister.com/journal/writing-hlsl-pixel-shaders-for-wpf/ https://msdn.microsoft.com/en-us/library/system.windows.media.effects.pixelshader%28v=vs.110%29.aspx Looks promising, thanks. Quote Link to comment Share on other sites More sharing options...
Nengalore Posted April 3, 2016 Author Share Posted April 3, 2016 If it helps at all, there's some of the HLSL shader code in JavaScript here: http://pastebin.com/HYw6w4ed Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.