- Home /
[Compute Shader] Porting an Image Effect Shader - Kuwahara Filter
Hi All I am trying to port an image Effect Shader to Compute Shader because I want to learn compute shaders. I chose to port Kuwahara Filter because I am generally interested in image filtering. Below is my port which give a black screen. Any help will be appreciated as I am very new to this and there isn't much info on the subject around. The original image effect shader is in the link above.
//
#pragma kernel CSMain
#include "UnityCG.cginc"
// Create a RenderTexture with enableRandomWrite flag and set it
// with cs.SetTexture
Texture2D<float4> Source;
RWTexture2D<float4> Destination;
int Radius = 5;
SamplerState samplerSource;
[numthreads(8,8,1)]
void CSMain(uint3 id : SV_DispatchThreadID)
{
float3 mean[4] = {
{ 0, 0, 0 },
{ 0, 0, 0 },
{ 0, 0, 0 },
{ 0, 0, 0 }
};
float3 sigma[4] = {
{ 0, 0, 0 },
{ 0, 0, 0 },
{ 0, 0, 0 },
{ 0, 0, 0 }
};
float2 start[4] = { { -Radius, -Radius },{ -Radius, 0 },{ 0, -Radius },{ 0, 0 } };
float2 pos;
float3 col;
uint width;
uint height;
uint levels;
Source.GetDimensions(0, width, height, levels);
float widthf = (float)width;
float heightf = (float)height;
for (int k = 0; k < 4; k++) {
for (int i = 0; i <= Radius; i++) {
for (int j = 0; j <= Radius; j++) {
pos = float2(i, j) + start[k];
col = Source.SampleLevel(samplerSource, float2(pos.x * 1.0/width, pos.y * 1.0/height), 0);
mean[k] += col;
sigma[k] += col * col;
}
}
}
float sigma2;
float n = pow(Radius + 1, 2);
float4 color = Source[id.xy];
float min = 1;
for (int l = 0; l < 4; l++) {
mean[l] /= n;
sigma[l] = abs(sigma[l] / n - mean[l] * mean[l]);
sigma2 = sigma[l].r + sigma[l].g + sigma[l].b;
if (sigma2 < min) {
min = sigma2;
color.rgb = mean[l].rgb;
}
}
Destination[id.xy] = color;
}
Answer by jister · Nov 11, 2021 at 12:21 AM
bit of a late reply, but this works for me:
#pragma kernel CSMain
#include "UnityCG.cginc"
Texture2D<float4> source;
RWTexture2D<float4> output;
int _Radius = 10;
SamplerState sampler_source;
[numthreads(8, 8, 1)]
void CSMain(uint3 id : SV_DispatchThreadID)
{
float3 mean[4] = {
{ 0, 0, 0 },
{ 0, 0, 0 },
{ 0, 0, 0 },
{ 0, 0, 0 }
};
float3 sigma[4] = {
{ 0, 0, 0 },
{ 0, 0, 0 },
{ 0, 0, 0 },
{ 0, 0, 0 }
};
float2 start[4] = { { -_Radius * .5, -_Radius * .5},{ -_Radius * .5, 0 },{ 0, -_Radius * .5},{ 0, 0 } };
float2 pos;
float3 col;
for (int k = 0; k < 4; k++) {
for (int i = 0; i <= _Radius; i++) {
for (int j = 0; j <= _Radius; j++) {
pos = float2(i, j) + start[k];
col = source[id.xy + uint2(pos.x, pos.y)];
mean[k] += col;
sigma[k] += col * col;
}
}
}
float sigma2;
float n = pow(_Radius + 1, 2);
float4 color = source[id.xy];
float min = 1;
for (int l = 0; l < 4; l++) {
mean[l] /= n;
sigma[l] = abs(sigma[l] / n - mean[l] * mean[l]);
sigma2 = sigma[l].r + sigma[l].g + sigma[l].b;
if (sigma2 < min) {
min = sigma2;
color.rgb = mean[l].rgb;
}
}
output[id.xy] = color;
}
Answer by RisingMos · Nov 11, 2021 at 04:51 AM
Not too late :) Thanks! I will check it out. Also, you another new thing that you might want to Check out is a library called ComputeSharp (not unity related)
Your answer
Follow this Question
Related Questions
Is it possible to profile compute shaders? 2 Answers
Custom colliders on the GPU 0 Answers
Compute Shader not work on older GPU with DX11 0 Answers
Shader to a Camera 1 Answer
How to get pixel coordinates in an image effect shader 2 Answers