Hello,
I recently decided to switch from creating heightmaps in openCL to a pixel shader. While this makes things easier to work with I have one major issue. For terrain I am relying primarily on this ridged multifractal function:
float RMF(in vec3 v) {
float result, frequency, signal, weight;
float H = 1.0;
float lacunarity = 2.143212;
int octaves = 12;
float offset = 1.0;
float gain = 2.1;
int i;
bool first = true;
float exponentArray[12];
frequency =.6;
if(first){
for (i=0; i<octaves; i++) {
exponentArray[i] = pow(frequency, -H);
frequency *= lacunarity;
}
first = false;
}
signal = inoise(v);
if (signal < 0.0) signal = -signal;
signal = offset - signal;
signal *=signal;
result = signal;
weight = 1.0;
for (i = 1; i < octaves; i++) {
v*=lacunarity;
weight = signal * gain;
if ( weight > 1.0 ) weight = 1.0;
if ( weight < 0.0 ) weight = 0.0;
signal = (inoise(v));
if ( signal < 0.0 ) signal = -signal;
signal = offset - signal;
signal *= signal;
signal *= weight;
result += signal * exponentArray[i];
}
return (result - 1.0) / 2.0;
}
Using openCl I could produce heightmap such as the following:
This resulted in "strong" terrain features and rough mountains yet smooth valleys.
Using a pixel shader I cannot reproduce such quality.
At best I can create something like below:
Which is far too rough and lacks the height features of the other implementation.
I can think of no other cause of these disparities than the actual perlin noise function being used.
For the pixel shader I am using the noise described here: http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter26.html
while in openCL I was using the following function:
float sgnoise2d(float2 position)
{
float2 p = position;
float2 pf = floor(p);
int2 ip = (int2)((int)pf.x, (int)pf.y);
float2 fp = p - pf;
ip &= P_MASK;
const int2 I00 = (int2)(0, 0);
const int2 I01 = (int2)(0, 1);
const int2 I10 = (int2)(1, 0);
const int2 I11 = (int2)(1, 1);
const float2 F00 = (float2)(0.0f, 0.0f);
const float2 F01 = (float2)(0.0f, 1.0f);
const float2 F10 = (float2)(1.0f, 0.0f);
const float2 F11 = (float2)(1.0f, 1.0f);
float n00 = gradient2d(ip + I00, fp - F00);
float n10 = gradient2d(ip + I10, fp - F10);
float n01 = gradient2d(ip + I01, fp - F01);
float n11 = gradient2d(ip + I11, fp - F11);
const float2 n0001 = (float2)(n00, n01);
const float2 n1011 = (float2)(n10, n11);
float2 n2 = mix2d(n0001, n1011, smooth(fp.x));
float n = mix1d(n2.x, n2.y, smooth(fp.y));
return n * (1.0f / 0.7f);
}
float ugnoise2d(float2 position)
{
return (0.5f - 0.5f * sgnoise2d(position));
}
I would like to keep using the improved glsl noise that I am using but I was wondering if anyone had any experience with good ridged multifractal functions to use in a pixel shader. Thanks for any help whatsoever.