res-avatar-unity/Assets/_PoiyomiShaders/Scripts/ThryEditor/Editor/ThryTexturePacker.compute
2023-07-15 19:51:23 -07:00

286 lines
8.9 KiB
Plaintext
Executable file

#pragma kernel CSMain
RWTexture2D<float4> Result;
float Width;
float Height;
float Rotation;
float Hue;
float Saturation;
float Brightness;
float2 Scale;
float2 Offset;
Texture2D<float4> R_Input_0;
Texture2D<float4> R_Input_1;
Texture2D<float4> R_Input_2;
Texture2D<float4> R_Input_3;
SamplerState sampler_R_Input_0;
SamplerState sampler_R_Input_1;
SamplerState sampler_R_Input_2;
SamplerState sampler_R_Input_3;
int R_Channel_0;
int R_Channel_1;
int R_Channel_2;
int R_Channel_3;
int R_Count;
int R_BlendMode;
float R_Fallback;
bool R_Invert;
Texture2D<float4> G_Input_0;
Texture2D<float4> G_Input_1;
Texture2D<float4> G_Input_2;
Texture2D<float4> G_Input_3;
SamplerState sampler_G_Input_0;
SamplerState sampler_G_Input_1;
SamplerState sampler_G_Input_2;
SamplerState sampler_G_Input_3;
int G_Channel_0;
int G_Channel_1;
int G_Channel_2;
int G_Channel_3;
int G_Count;
int G_BlendMode;
float G_Fallback;
bool G_Invert;
Texture2D<float4> B_Input_0;
Texture2D<float4> B_Input_1;
Texture2D<float4> B_Input_2;
Texture2D<float4> B_Input_3;
SamplerState sampler_B_Input_0;
SamplerState sampler_B_Input_1;
SamplerState sampler_B_Input_2;
SamplerState sampler_B_Input_3;
int B_Channel_0;
int B_Channel_1;
int B_Channel_2;
int B_Channel_3;
int B_Count;
int B_BlendMode;
float B_Fallback;
bool B_Invert;
Texture2D<float4> A_Input_0;
Texture2D<float4> A_Input_1;
Texture2D<float4> A_Input_2;
Texture2D<float4> A_Input_3;
SamplerState sampler_A_Input_0;
SamplerState sampler_A_Input_1;
SamplerState sampler_A_Input_2;
SamplerState sampler_A_Input_3;
int A_Channel_0;
int A_Channel_1;
int A_Channel_2;
int A_Channel_3;
int A_Count;
int A_BlendMode;
float A_Fallback;
bool A_Invert;
// blendmodes
// 0 = add
// 1 = multiply
// 3 = max
// 4 = min
float SampleTexture(Texture2D<float4> tex, SamplerState texSampler, int channel, float2 uv)
{
float4 pixelColor = tex.SampleLevel(texSampler,uv,0);
if (channel == 0) return pixelColor.r;
else if (channel == 1) return pixelColor.g;
else if (channel == 2) return pixelColor.b;
else if (channel == 3) return pixelColor.a;
else return max(pixelColor.r, max(pixelColor.g, pixelColor.b));
}
float SampleAndBlendTexture(float value, Texture2D<float4> tex, SamplerState texSampler, int blendMode, int channel, float2 uv)
{
float newValue = SampleTexture(tex, texSampler, channel, uv);
if (blendMode == 0) return value + newValue;
else if (blendMode == 1) return value * newValue;
else if (blendMode == 2) return max(value, newValue);
else if (blendMode == 3) return min(value, newValue);
else return newValue;
}
float SampleAndBlendTextures(Texture2D<float4> tex1, Texture2D<float4> tex2, Texture2D<float4> tex3, Texture2D<float4> tex4,
int channel1, int channel2, int channel3, int channel4,
SamplerState texSampler1, SamplerState texSampler2, SamplerState texSampler3, SamplerState texSampler4,
int count, int blendMode, float2 uv)
{
float value = SampleTexture(tex1, texSampler1, channel1, uv);
if(count > 1) value = SampleAndBlendTexture(value, tex2, texSampler2, blendMode, channel2, uv);
if(count > 2) value = SampleAndBlendTexture(value, tex3, texSampler3, blendMode, channel3, uv);
if(count > 3) value = SampleAndBlendTexture(value, tex4, texSampler4, blendMode, channel4, uv);
return value;
}
float SampleInput(Texture2D<float4> tex1, Texture2D<float4> tex2, Texture2D<float4> tex3, Texture2D<float4> tex4,
int channel1, int channel2, int channel3, int channel4,
SamplerState texSampler1, SamplerState texSampler2, SamplerState texSampler3, SamplerState texSampler4,
int count, int blendMode, float fallback, bool doInvert, float2 uv) {
float value = fallback;
if(count > 0)
{
value = SampleAndBlendTextures(tex1, tex2, tex3, tex4, channel1, channel2, channel3, channel4, texSampler1, texSampler2, texSampler3, texSampler4, count, blendMode, uv);
if(doInvert) value = 1 - value;
}
return value;
}
float3 rgb2hsv(float3 rgb){
float4 p = (rgb.g < rgb.b) ? float4(rgb.bg, -1.0, 2.0/3.0) : float4(rgb.gb, 0.0, -1.0/3.0);
float4 q = (rgb.r < p.x) ? float4(p.xyw, rgb.r) : float4(rgb.r, p.yzx);
float d = q.x - min(q.w, q.y);
float e = 1.0e-10;
return float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}
float3 hsv2rgb(float3 hsv){
float4 K = float4(1.0, 2.0/3.0, 1.0/3.0, 3.0);
float3 p = abs(frac(hsv.xxx + K.xyz) * 6.0 - K.www);
return hsv.z * lerp(K.xxx, saturate(p - K.xxx), hsv.y);
}
float4 ApplyHSV(float4 pixel, float hue, float saturation, float value){
float3 hsv = rgb2hsv(pixel.rgb);
hsv.r += hue;
hsv.g *= saturation;
hsv.b *= value;
return float4(hsv2rgb(hsv.rgb), pixel.a);
}
[numthreads(8, 8, 1)]
void CSMain(uint3 id : SV_DispatchThreadID)
{
float2 uv = float2(id.x / Width, id.y / Height) + Offset;
// Rotate uv by Rotation around 0.5 0.5 and scale by Scale
float2 center = float2(0.5, 0.5);
float2 rotated = float2(0, 0);
rotated.x = (uv.x - center.x) * cos(Rotation) - (uv.y - center.y) * sin(Rotation);
rotated.y = (uv.x - center.x) * sin(Rotation) + (uv.y - center.y) * cos(Rotation);
uv = rotated * Scale + center;
float4 pixel = float4(1, 1, 1, 1);
pixel.r = SampleInput(R_Input_0, R_Input_1, R_Input_2, R_Input_3, R_Channel_0, R_Channel_1, R_Channel_2, R_Channel_3, sampler_R_Input_0, sampler_R_Input_1, sampler_R_Input_2, sampler_R_Input_3, R_Count, R_BlendMode, R_Fallback, R_Invert, uv);
pixel.g = SampleInput(G_Input_0, G_Input_1, G_Input_2, G_Input_3, G_Channel_0, G_Channel_1, G_Channel_2, G_Channel_3, sampler_G_Input_0, sampler_G_Input_1, sampler_G_Input_2, sampler_G_Input_3, G_Count, G_BlendMode, G_Fallback, G_Invert, uv);
pixel.b = SampleInput(B_Input_0, B_Input_1, B_Input_2, B_Input_3, B_Channel_0, B_Channel_1, B_Channel_2, B_Channel_3, sampler_B_Input_0, sampler_B_Input_1, sampler_B_Input_2, sampler_B_Input_3, B_Count, B_BlendMode, B_Fallback, B_Invert, uv);
pixel.a = SampleInput(A_Input_0, A_Input_1, A_Input_2, A_Input_3, A_Channel_0, A_Channel_1, A_Channel_2, A_Channel_3, sampler_A_Input_0, sampler_A_Input_1, sampler_A_Input_2, sampler_A_Input_3, A_Count, A_BlendMode, A_Fallback, A_Invert, uv);
pixel = ApplyHSV(pixel, Hue, Saturation, Brightness);
Result[id.xy] = pixel;
}
#pragma kernel CS_Kernel
Texture2D<float4> Kernel_Input;
float4 Kernel_X[25];
float4 Kernel_Y[25];
bool Kernel_Grayscale;
bool Kernel_TwoPass;
float4 Kernel_Channels;
[numthreads(8, 8, 1)]
void CS_Kernel(uint3 id : SV_DispatchThreadID)
{
float4 pixel_x = float4(0, 0, 0, 0);
float4 pixel_y = float4(0, 0, 0, 0);
for (int x = -2; x <= 2; x++)
{
for (int y = -2; y <= 2; y++)
{
float4 p = Kernel_Input.Load(int3(id.xy + int2(x,y), 0));
[branch]
if(Kernel_Grayscale)
{
float gray = dot(p.rgb, float3(0.2126, 0.7152, 0.0722));
pixel_x += float4(gray * Kernel_X[x + 2 + (y + 2) * 5].x, 0, 0, 0);
[branch]
if(Kernel_TwoPass)
{
pixel_y += float4(gray * Kernel_Y[x + 2 + (y + 2) * 5].x, 0, 0, 0);
}
}else
{
pixel_x += p * Kernel_X[x + 2 + (y + 2) * 5].x;
[branch]
if(Kernel_TwoPass)
{
pixel_y += p * Kernel_Y[x + 2 + (y + 2) * 5].x;
}
}
}
}
float4 color = Kernel_Input.Load(int3(id.xy, 0));
float4 res = color;
[branch]
if(Kernel_Grayscale)
{
color = float4(dot(color.rgb, float3(0.2126, 0.7152, 0.0722)), 0, 0, color.a);
[branch]
if(Kernel_TwoPass)
{
res = sqrt((pixel_x * pixel_x + pixel_y * pixel_y)).x;
}
else
{
res = pixel_x.x;
}
}else
{
[branch]
if(Kernel_TwoPass)
{
res = sqrt((pixel_x * pixel_x + pixel_y * pixel_y));
}
else
{
res = pixel_x;
}
}
color.r = lerp(color.r, res.r, Kernel_Channels.x);
color.g = lerp(color.g, res.g, Kernel_Channels.y);
color.b = lerp(color.b, res.b, Kernel_Channels.z);
color.a = lerp(color.a, res.a, Kernel_Channels.w);
Result[id.xy] = color;
}
#pragma kernel CS_ChannelLerper
Texture2D<float4> Unpacker_Input;
float4 Channels_Strength_R;
float4 Channels_Strength_G;
float4 Channels_Strength_B;
float4 Channels_Strength_A;
[numthreads(8, 8, 1)]
void CS_ChannelLerper(uint3 id : SV_DispatchThreadID)
{
float4 color = Unpacker_Input.Load(int3(id.xy, 0));
float4 res = color;
res.r = lerp(0, color.r, Channels_Strength_R.x)
+ lerp(0, color.g, Channels_Strength_R.y)
+ lerp(0, color.b, Channels_Strength_R.z)
+ lerp(0, color.a, Channels_Strength_R.w);
res.g = lerp(0, color.r, Channels_Strength_G.x)
+ lerp(0, color.g, Channels_Strength_G.y)
+ lerp(0, color.b, Channels_Strength_G.z)
+ lerp(0, color.a, Channels_Strength_G.w);
res.b = lerp(0, color.r, Channels_Strength_B.x)
+ lerp(0, color.g, Channels_Strength_B.y)
+ lerp(0, color.b, Channels_Strength_B.z)
+ lerp(0, color.a, Channels_Strength_B.w);
res.a = lerp(0, color.r, Channels_Strength_A.x)
+ lerp(0, color.g, Channels_Strength_A.y)
+ lerp(0, color.b, Channels_Strength_A.z)
+ lerp(0, color.a, Channels_Strength_A.w);
Result[id.xy] = res;
}