SHADE_Y3/Assets/Shaders/Kirsch_CS.glsl

168 lines
4.1 KiB
GLSL

//#version 450
//
//layout(local_size_x = 16, local_size_y = 16) in;
//layout(set = 4, binding = 0, rgba8) uniform image2D targetImage;
//
//
//void main()
//{
// ivec2 imageSize = imageSize (targetImage);
//
// if (gl_GlobalInvocationID.x >= imageSize.x && gl_GlobalInvocationID.y >= imageSize.y)
// return;
//
// // load the image
// vec4 color = imageLoad (targetImage, ivec2 (gl_GlobalInvocationID));
//
// // get the average
// float average = 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b;
//
// // store result into result image
// imageStore(targetImage, ivec2(gl_GlobalInvocationID), vec4(average, average, average, 1.0f));
//
//}
//
//
//
//
/* Start Header *****************************************************************/
/*! \file (e.g. kirsch.comp)
\author William Zheng, william.zheng, 60001906. Brandon Mak, brandon.hao 390003920.
\par william.zheng\@digipen.edu. brandon.hao\@digipen.edu.
\date Sept 20, 2022
\brief Copyright (C) 20xx DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent of DigiPen Institute of Technology is prohibited. */
/* End Header *******************************************************************/
#version 450
#define MASK_WIDTH 3
#define HALF_M_WIDTH MASK_WIDTH / 2
#define SHM_WIDTH 18
#define NUM_MASKS 8
layout(local_size_x = 16, local_size_y = 16) in;
layout(set = 3, binding = 0, rgba8) uniform image2D inputImage;
layout(set = 3, binding = 1, rgba8) uniform image2D resultImage;
const float kirsch[8][3][3] = {
{
{5, 5, 5},
{-3, 0, -3}, /*rotation 1 */
{-3, -3, -3}
},
{
{5, 5, -3},
{5, 0, -3}, /*rotation 2 */
{-3, -3, -3}
},
{
{5, -3, -3},
{5, 0, -3}, /*rotation 3 */
{5, -3, -3}
},
{
{-3, -3, -3},
{5, 0, -3}, /*rotation 4 */
{5, 5, -3}
},
{
{-3, -3, -3},
{-3, 0, -3}, /*rotation 5 */
{5, 5, 5}
},
{
{-3, -3, -3},
{-3, 0, 5}, /*rotation 6 */
{-3, 5, 5}
},
{
{-3, -3, 5},
{-3, 0, 5}, /*rotation 7 */
{-3, -3, 5}
},
{
{-3, 5, 5},
{-3, 0, 5}, /*rotation 8 */
{-3, -3, -3}
}
};
vec3 GetImageValues(ivec2 uv, ivec2 inputImageSize)
{
if (uv.x >= 0 && uv.y >= 0 && uv.x < inputImageSize.x && uv.y < inputImageSize.y)
{
return imageLoad(inputImage, uv).rgb;
}
else
return vec3(0.0f);
}
//two extra row/col
shared vec3 sData[16 + 2][16 + 2];
void main()
{
// convenient variables
ivec3 globalThread = ivec3(gl_GlobalInvocationID);
ivec3 localThread = ivec3(gl_LocalInvocationID);
ivec2 inputImageSize = imageSize(inputImage);
// load shared memory
ivec2 start = ivec2(gl_WorkGroupID) * ivec2(gl_WorkGroupSize) - ivec2(HALF_M_WIDTH);
for (int i = localThread.x; i < SHM_WIDTH; i += int(gl_WorkGroupSize.x))
{
for (int j = localThread.y; j < SHM_WIDTH; j += int(gl_WorkGroupSize.y))
{
// get from source image (either real values or 0)
vec3 sourceValue = GetImageValues(start + ivec2(i, j), inputImageSize);
sData[i][j] = sourceValue;
}
}
// wait for shared memory to finish loading
barrier();
// max (between all 8 masks)
vec3 maxSum = vec3(0.0f);
// loop through all masks
for (int i = 0; i < NUM_MASKS; ++i)
{
vec3 sum = vec3(0.0f);
// start of shared memory
ivec2 shmStart = ivec2(localThread + HALF_M_WIDTH);
for (int j = -1; j < HALF_M_WIDTH + 1; ++j)
{
for (int k = -1; k < HALF_M_WIDTH + 1; ++k)
{
// Perform convolution using shared_memory
sum += sData[shmStart.x + j][shmStart.y + k] * kirsch[i][j + 1][k + 1];
}
}
// Get highest sum
maxSum = max(sum, maxSum);
}
// average the max sum
maxSum = min(max(maxSum / 8, 0), 1.0f);
// store result into result image
imageStore(resultImage, ivec2(gl_GlobalInvocationID.xy), vec4(maxSum, 1.0f));
}