Procedural volumetric texture generated from a script
If the available Maths nodes aren't up to the job of creating your required procedural volumetric you can use OSL to create a new shader node to generate your volume. OSL is based on C/C++ syntax and a wide range of maths functions are available (including vector maths, noise generating functions, etc.).

See Blender Manual - OSL, OSL Github, OSL Language Spec within Github

To demonstrate this in action, ensure you have a version of Blender that has been compiled to support OSL - if so you'll have the option to enable Open Shader Language on the main Render properties panel. Enable Open Shader Language and paste the following code into a new Text Editor block named 'simple_generated_volumetrics.osl' :

shader generated_volume(
    color Color1 = color(0.8,0.2,0.2),
    color Color2 = color(0.2,0.8,0.2),
    color Color3 = color(0.2,0.2,0.8),
    float Frequency = 12,
    float Falloff = 8,
    float Bias = 0.3,
    output closure color BSDF = diffuse(N))
{

    float distFromCentre = pow(P[0]*P[0]+P[1]*P[1],0.5);
    float height = cos(distFromCentre * Frequency)/(distFromCentre+Bias)/Falloff;

    color pointColor = mix(mix(Color2, Color1, min(max(0,height*6),1)), Color3, min(max(0,-height*6),1));  
    color invertedColor = color(1-pointColor[0], 1-pointColor[1], 1-pointColor[2]);

    BSDF = (invertedColor*absorption() + Color1*henyey_greenstein(0))*(P[2]&lt;height)*30;
}


In the Node Editor, add a Script node and set the text to the newly created text block. This should automatically compile the OSL and the node should be updated to include new input/output sockets as defined in the OSL code. Connect the BSDF output to the Volume of a Material Output node.

Assign the material to a Cube (or other mesh to act as the volumetric domain) and this should produce a result similar to the following :



The above example is produced by calculating the distance from the origin and generating a Cosine wave based on this distance, scaled by the distance. The colour of each pixel is determined by the height and mixed between the three input colours. Obviously the calculation can be amended to whatever you desire.

Note that in my example I amended some of the render settings to get better results. In particular, I swapped to Branched Path Tracing (with increased Volume samples), reduced the Volume Sampling Step to 0.05 (lower values give sharper results but at the expense of render time), and increased the Volume light path bounces to 4.

The 'surface' itself is created using a combination of Volume Absorption and Volume Scatter (henyey_greenstein) to simulate a rough diffuse surface - similar to that used in Give this mesh a uniform thickness on all the tubes and unions

Note also that the ‘30’ at the end of the ‘BSDF =...’ line represents the ‘solid’ density and this could be similarly varied throughout the volume, depending on your requirements (for this I just used it to demonstrate a generated solid volume).