## Linearly interpolate colors in a triangle using SVG (Gouraud shading)

After a long battle with the SVG documentation here is a triangle colored by linearly interpolated colors specified at each vertex.


<g transform="matrix(1 0 0 -1 0 86.600000)">
<defs>

<stop offset="0%" stop-color="#FF0000"/>
<stop offset="100%" stop-color="#000000" />
<stop offset="0%" stop-color="#00FF00"/>
<stop offset="100%" stop-color="#000000" />
<stop offset="0%" stop-color="#0000FF"/>
<stop offset="100%" stop-color="#000000" />

<path id="pathA-1" d="M 50.000000,0.000000 L 0.000000,86.600000 100.000000,86.600000 Z" fill="url(#fadeA-1)"/>
<path id="pathB-1" d="M 50.000000,0.000000 L 0.000000,86.600000 100.000000,86.600000 Z" fill="url(#fadeB-1)"/>
<filter id="Default">
<feImage xlink:href="#pathA-1" result="layerA" x="0" y="0" />
<feImage xlink:href="#pathB-1" result="layerB" x="0" y="0" />
<feComposite in="layerA" in2="layerB" operator="arithmetic" k1="0" k2="1.0" k3="1.0" k4="0" result="temp"/>
<feComposite in="temp" in2="SourceGraphic"   operator="arithmetic" k1="0" k2="1.0" k3="1.0" k4="0"/>
</filter>
</defs>
<g stroke="none" stroke-width="0" shape-rendering="crispEdges" >
<path d="M 50.000000,0.000000 L 0.000000,86.600000 100.000000,86.600000 Z" fill="url(#fadeC-1)" filter="url(#Default)" />
</g>
</g>
</svg>



### JPG rasterization

What you should see above if your browser supports SVG

Update: This still isn’t quite linear interpolation. For some reason I get a tendency toward black in the middle. I tried using fancier arithmetic (multiplication) with masks but this made things worse (quantization artifacts). There is also a nasty relative coordinates issue with the filters I used above.

Update: For reference, here’s what I’d like to see:

### 5 Responses to “Linearly interpolate colors in a triangle using SVG (Gouraud shading)”

1. Ebbs says:

Actually, this is linear interpolation. The color you’ll en up with in the middle is (in hex code) about 0x7F7F7F which is some dark gray color. The reason for this is that the color in the middle of the triangle will be composed of half of the max value of each starting color. This exact interpolation (actually called barycentric interpolation) is used by your hardware rasterizer to interpolate colors inside triangles.
This image shows a triangle where its vertices are given the same starting colors as you are using and then the hardware rasterizer have automatically interpolated the colors inside the triangle:
http://www.arcsynthesis.org/gltut/Basics/VertexColors.png

2. ajx says:

@Ebbs, The SVG code above is not explicitly doing linear interpolation. I guess you’ve rendered a triangle with vertex colors in OpenGL/DirectX, but this feature is exactly what’s missing in the SVG format. Hence this hack to get something close.

3. Ben says:

The triangle looks dark in the center because this is “linear” interpolation in nonlinear sRGB space. The center of the triangle is #555555, which is much darker than linear (1/3, 1/3, 1/3), which would be about #9C9C9C.

You could make the gradients actually linear by adding a bunch of additional stops using the formula at https://en.wikipedia.org/wiki/sRGB, or maybe approximate it with a gamma of 2.2, if that’s possible in SVG.

4. Ben says: