// Copyright 2020 Google LLC Texture2D inputImage : register(t0); RWTexture2D resultImage : register(u1); float conv(in float kernel[9], in float data[9], in float denom, in float offset) { float res = 0.0; for (int i=0; i<9; ++i) { res += kernel[i] * data[i]; } return saturate(res/denom + offset); } [numthreads(16, 16, 1)] void main(uint3 GlobalInvocationID : SV_DispatchThreadID) { float r[9]; float g[9]; float b[9]; // Fetch neighbouring texels int n = -1; for (int i=-1; i<2; ++i) { for(int j=-1; j<2; ++j) { n++; float3 rgb = inputImage[uint2(GlobalInvocationID.x + i, GlobalInvocationID.y + j)].rgb; r[n] = rgb.r; g[n] = rgb.g; b[n] = rgb.b; } } float kernel[9]; kernel[0] = -1.0; kernel[1] = -1.0; kernel[2] = -1.0; kernel[3] = -1.0; kernel[4] = 9.0; kernel[5] = -1.0; kernel[6] = -1.0; kernel[7] = -1.0; kernel[8] = -1.0; float4 res = float4( conv(kernel, r, 1.0, 0.0), conv(kernel, g, 1.0, 0.0), conv(kernel, b, 1.0, 0.0), 1.0); resultImage[int2(GlobalInvocationID.xy)] = res; }