kernel ChromaKey < namespace : "CTY"; vendor : "Yeung"; version : 2; description : "Chroma key"; > { input image4 src1; input image4 src2; output float4 dst; void evaluatePixel() { // Obtain the input pixel color float4 input1Color = sampleNearest(src2, outCoord()); float4 input2Color = sampleNearest(src1, outCoord()); float4 outputColor = input1Color; float Red; float Grn; float Blu; // The language implements matrices in column major order. This means // that mathematically, the transform will look like the following: // |Y| |0.299 0.587 0.114 0.0| |R| // |I| = |0.596 -0.275 -0.321 0.0| |G| // |Q| |0.212 -0.523 0.311 0.0| |B| // |A| |0.0 0.0 0.0 1.0| |A| float4x4 YIQMatrix = float4x4( 0.299, 0.596, 0.212, 0.000, 0.587, -0.275, -0.523, 0.000, 0.114, -0.321, 0.311, 0.000, 0.000, 0.000, 0.000, 1.000 ); // Similar to the above matrix, the matrix is in column order. Thus, // the transform will look like the following: // |R| |1.0 0.956 0.621 0.0| |Y| // |G| = |1.0 -0.272 -0.647 0.0| |I| // |B| |1.0 -1.11 1.70 0.0| |Q| // |A| |0.0 0.0 0.0 1.0| |A| float4x4 inverseYIQ = float4x4( 1.0, 1.0, 1.0, 0.0, 0.956, -0.272, -1.10, 0.0, 0.621, -0.647, 1.70, 0.0, 0.0, 0.0, 0.0, 1.0 ); Red = input1Color.r; Grn = input1Color.g; Blu = input1Color.b; // Bluish if ((Red < Grn)&&(Grn < Blu)) { input1Color = YIQMatrix * input1Color; input2Color = YIQMatrix * input2Color; input2Color[0] = (input1Color[0] + input2Color[0])/2.0; // Y value input2Color = inverseYIQ * input2Color; outputColor = input2Color; } dst = outputColor; } }