<languageVersion : 1.0;> 
kernel ThreePointGradient 

    namespace : "Petri Leskinen::Example"
    vendor : "Petri Leskinen"
    version : 1
    description : "Creates a gradient fill using three specified points and colors."


    parameter float2 point1 // coordinates of the first point
    < 
        minValue:float2(00); 
        maxValue:float2(40004000); 
    >; 
     
    parameter float4 color1 // color at the first point, opaque red by default
    < 
        defaultValue:float4(1.00.00.01.0); 
    >; 
     
    parameter float2 point2 // coordinates of the second point
    < 
        minValue:float2(00); 
        maxValue:float2(40004000);
        defaultValue:float2(500);
    >; 
     
    parameter float4 color2 // color at the second point, opaque green by default
    < 
        defaultValue:float4(0.01.00.01.0); 
    >; 
     
    parameter float2 point3 // coordinates of the third point
    < 
        minValue:float2(00); 
        maxValue:float2(40004000); 
        defaultValue:float2(0,500);
    >; 
     
    parameter float4 color3 // color at the third point, opaque blue by default
    < 
        defaultValue:float4(0.00.01.01.0); 
    >; 
     
    output pixel4 dst; 
    
    // for checking the output in pb-toolkit,
    // comment where exporting to flash
    region generated() { return region(float4(0.0, 0.0, 512.0, 512.0)); }
    
    void evaluatePixel() 
    { 
        float2 d2 = point2 - point1; 
        float2 d3 = point3 - point1; 
         
        // transformation to a new coordinate system
        // transforms point 1 to origin, point2 to (1, 0), and point3 to (0, 1)
        float2x2 mtrx = float2x2(d3.y, -d2.y, -d3.x, d2.x) / (d2.x * d3.y - d3.x * d2.y); 
        float2 pNew = mtrx * (outCoord() - point1); 
         
        // repeat the edge colors on the outside
        pNew.xy = clamp(pNew.xy, 0.01.0); // set the range to 0.0 ... 1.0
         
        // interpolating the output color or alpha value
        dst = mix(mix(color1, color2, pNew.x), color3, pNew.y); 
    } 
}