The gColor Colour Spline |
||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
||||||||||||||
Download: |
|
|||||||||||||
gColorSpline can help turn cloud-like Coherent Noise into sky, or terrain if a more complex spline like this is used:
The ButtonStencil page uses gColorSpline to add a metallic gold effect to rendered buttons. |
This is the code for the Terrain Colour Spline:// Deep Water Shallow Water Shore Foam Sand Rock Lowland Grass Highland Grass Highland Rock Snow double TerrainPositions[]={ 0.63, 0.67, 0.699, 0.7, 0.701, 0.705, 0.71, 0.85, 0.90, 1 }; gColor TerrainColors[]={gColor(20,60,75), gColor(70,120,100), gColor(220,230,230), gColor(230,230,240), gColor(235,205,190), gColor(120,90,70), gColor(120,135,70), gColor(70,70,30), gColor(100,100,105), gColor(250,250,255)}; gColorSpline TerrainSpline(sizeof(TerrainColors)/sizeof(gColor), TerrainColors, TerrainPositions);The following image shows how adding a greyscale color spline makes the original button image look metalic, and how adding a touch of colour makes the button look like gold:
The gColor files provide a gColorSpline primitive: a powerful means of automating colour selection; it interpolates an array of colours which a user would normally set using a Colour Bar. This version uses doubles throughout making it particularly suitable for generating complex procedural textures where the colours are being processed many times before rendering. If the array is simply black followed by white, t=0 will return black, t=0.3 will return dark grey, t=0.5 is mid grey, t=0.8 is light grey and t=1 will be white. The Alpha Channel is included in the Interpolation. There is a choice of interpolation method, the differences are discussed below.
enum SplineInterpolationType {LinearCSI,HermiteCSI,bSplineCSI,CatmullRomCSI}; static gColor Get(double t, int Count, gColor* Colors, double* Positions=0, SplineInterpolationType InterpolationType=CatmullRomCSI);The gColorSpline struct can be instantiated and used to hold pointers to Spline and Position arrays. The Get method takes the parameter, t (which should be in the interval [0,1]); The default constructor implies Greyscale: Get(0.5) will return grey, Get(0) will return black and Get(1), white. Count is the number of entries in the Colours array. If Positions is zero, the colours are equally spaced; otherwise Positions should point to an array of Count doubles which vary from zero to one. The entries do need to be in order, but do not need to include a value for the end positions (0 or 1).In the following images this array of colours was used: Black,Red,Yellow,White,Blue. The first set of images use all five colours with Positions=0, so they are equally spaced:
Linear is obviously a straight-line interpolation and results in a banded appearance. Hermite 'eases' the linear interpolation with a Hermite Step to the specified colour at the specified Position. CatmullRom still hits each colour at the correct position and smooths the rate of colour-change well by over-shooting, though this will be clipped for full brightness. The vertical lines on the bSpline method are the true colours at their Position, illustrating that although bSpline does a good job of blending the colours, it never reaches the defined colours: the whole image is darker than the others. In short, bSpine is smooth but not accurate and cannot reach the correct brightness; CatmullRom is accurate and smooth until it gets clipped; Hermite is accurate and fairly smooth; and linear is accurate but will have sharp changes in colour at each Colour Position.In this image, the positions have been set for each colour set as follows: Black=0; Red=0.2; Yellow=0.7; White=0.9; Blue=1;
The last image shows what happens if the first and last colours are not at positions 0 and 1. The colours were set as follows: Black=0.1; Red=0.2; Yellow=0.7; White=0.9;
Here's the code used to draw these images:gColor Colors[5]; double Positions[]={0, 0.2, 0.7, 0.9, 1}; Colors[0].Set(0x000000); // Black Colors[1].Set(0xC00000); // Dull Red Colors[2].Set(0xC0C000); // Dull Yellow Colors[3].Set(0xC0C0C0); // Dull White Colors[4].Set(0x0000C0); // Dull Blue gColorSpline ColorSpline(5, Colors,Positions, gColor::bSplineCSI); for(WORD x=GetWidth(); x--;) { double t=double(x)/GetWidth(); // t is how far along: range [0,1] DWORD dw=ColorSpline.Get(t).GetRGB(); for(WORD y=GetHeight(); y--;) SetPixel(x,y, dw); // Vertical colored line SetPixel(x, WORD(Round(gFilters::InterpolateLinear(( 0xC0)/255.0, GetHeight(),0))), 0xC0C0C0); // Horizontal grey line showing maximum level SetPixel(x, WORD(Round(gFilters::InterpolateLinear(( dw &0xFF)/255.0, GetHeight(),0))), 0x0000FF); // Red graph line SetPixel(x, WORD(Round(gFilters::InterpolateLinear(((dw>> 8)&0xFF)/255.0, GetHeight(),0))), 0x00FF00); // Green graph line SetPixel(x, WORD(Round(gFilters::InterpolateLinear(((dw>>16)&0xFF)/255.0, GetHeight(),0))), 0xFF0000); // Blue graph line }
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.