286 lines
8.9 KiB
Plaintext
Executable file
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;
|
|
} |