• FEATURED

View more

View more

View more

Image of the Day Submit

IOTD | Top Screenshots

The latest, straight to your Inbox.

Subscribe to GameDev.net Direct to receive the latest updates and exclusive content.

Sign up now

How to reproduce the 3ds Max Gradient Ramp effect?

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

4 replies to this topic

#1enigmagame  Members

Posted 07 August 2012 - 01:27 AM

The material definition of a mesh is composed of these three components: Self-Illumunation, Refletcion and Refraction. Each of these components has a Gradient Ramp as a map and the mapping mode is set to spherical environment.
I'm searching for a way to reproduce these effects in a shader (the shader language doesn't matter). Is it possible?
My first idea was to save the Gradient Ramp as a texture: you can see the result in the image below:

It seems to be a Blinn/Newell Latitude Map instead of a Spherical Map, but using the math behind the first, the result isn't correct.
Thanks.

#2Nik02  Members

Posted 07 August 2012 - 04:55 AM

In general, gradient ramps are implemented by simply interpolating between colors, given a scalar parameter. This is very easy in shaders.

Think of a color ramp as a spline, where the control points represent colors instead of positions. The spline algorithms are literally the exact same ones in either case.

The simplest possible ramp is one that contains two control points (colors) that are used in linear interpolation:

// simple example
float4 red = float4(1,0,0,1);
float4 blue= float4(0,0,1,1);
float parameter = normal.y * 0.5f + 0.5f; // map normal's y direction to 0...1 for use as interpolation parameter
float4 finalcolor = lerp(red, blue, parameter); // when normal points down, red is used more; conversely, up means more blue
// lerp is defined as v1*(1-param) + v2*param where v1 and v2 are the original values to interpolate between


You can extend this basic idea to introduce more colors in the ramp.

Edited by Nik02, 07 August 2012 - 05:09 AM.

Niko Suni

#3enigmagame  Members

Posted 07 August 2012 - 09:14 AM

Nik02 thanks for the hint, you're absolutely right: thinking on the texture maps has completely moved my focus on the problem.
I've just tried with two control points and the result is correct.

Just another question: I've ramps with four, five or six control points, what is the best way to interpolate these control points and achieve a correct result? Bézier curve?
Thanks.

Edited by enigmagame, 07 August 2012 - 09:42 AM.

#4Nik02  Members

Posted 07 August 2012 - 11:03 PM

Any spline will do, but Bézier will provide smoother transitions between colors than linear. The "best" way depends on what you want to do with the ramp; in some cases, linear is the correct and elegant way to go, but higher-order splines tend to get more "organic" results.

You can handle any number of control points by taking n nearest control points of the parameter (where n is the degree of the curve + 1), and doing the interpolation between those found points. This effectively means that the minimum amount of control points is also defined as degree + 1.

Here is a simple example of piecewise linear handling of arbitrary number of points:
float4 colors[] = {float4(1,0,0,1), float4(0,1,0,1), float4(0,0,1,1), float4(0,0,0,1), float4(1,1,1,1)}; // red, green, blue, black, white
int numColors = 5; // must match the actual number of control points <img src='http://public.gamedev.net//public/style_emoticons/<#EMO_DIR#>/smile.png' class='bbc_emoticon' alt=':)' />
float parameter; // initialized earlier to 0...1

float index = parameter * (float)numColors;
int nearestLeftIndex = (int)index; // effectively take the whole number part of the scaled parameter to find the first control point
int nearestRightIndex = nearestLeftIndex + 1; // the next control point is adjacent in the array
// If nearest indices are the same or greater than numColors or less than 0, we should take the nearest point as is, because we're past the color array.
// To extend beyond piecewise linear, find more nearest points like this and perform the next steps with those.

float4 left = colors[nearestLeftIndex];
float4 right = colors[nearestRightIndex];
float fraction = index - (float)nearestLeftIndex; // find the decimal portion of the scaled parameter in between the nearest points
float4 finalColor = lerp (left, right, fraction); // then interpolate between the nearest points


Niko Suni

#5Nik02  Members

Posted 08 August 2012 - 12:08 AM

Also, it is worth noting that you could pre-calculate and store the ramp as a 1-d texture, and sample it in the shader to effectively emulate any 1-dimensional function (such as a spline with parameter u).

This is useful if you want to decrease register or ALU pressure, at the cost of using a little bit of memory bandwidth. Also, textures tend to be more easy to author than arrays of shader constants.

Niko Suni

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.