GKNoiseMap interpolatedValueAtPosition - how does it work?

I'm trying to understand the interpolated version of GKNoiseMap's valueAtPosition, but it's giving me an exceedingly hard time.


When I set up a Noise Map to sampla with a size (1,1) starting at (0,0) using 256 samples, I can get the value of the sample with valueAtPosition.


Now, however, I want to sample the values in-between (imaginge I'm walking between the sample points and the value represents the height of the floor). The documentation is quite explicit: I am to sample the position which is to be between the origin and size (not samplesize) - in my case the position must be between (0..1), (0..1). But no matter what I do, all values return -1.


So, I though, mabe the docs are wrong, and I need to use positional values (floats) in the range of 0..sampleSize. But no, all I receive is -1 as values, with a few exceptions.


So clearly I'm doing something wrong. What is the correct way to use interpolatedValueAtPosition?


Thanks for anyhelp.

Replies

Please show your code.

Thanks for looking into this! Here's a demo method that demonstartes the issue:


- (void) testNoiseMap{
   GKNoiseSource *theSource;
   float freq = 1;
   NSInteger octaves = 3;
   float pers = 0.75;
   float lacu = 4.2;
   int32_t seed = 0;
  
   theSource = [GKPerlinNoiseSource perlinNoiseSourceWithFrequency:freq octaveCount:octaves persistence:pers lacunarity:lacu seed:seed];
  
   NSDictionary *theGrads;
           theGrads = @{
              @-1   : [[self color0] color], // black
               @1   : [[self color1] color], // white
           };
  
   GKNoise *theNoise = [GKNoise noiseWithNoiseSource:theSource gradientColors:theGrads];
   
    vector_double2 vSize;
    vSize.x = 256;
    vSize.y = 256;
    vector_double2 vSizeFixed = {1.0, 1.0};
    vector_int2 sampleSize = {vSize.x, vSize.y};
    vector_double2 orig = {0, 0};
    GKNoiseMap *theMap = [GKNoiseMap noiseMapWithNoise:theNoise
                                                  size:vSizeFixed
                                                origin:orig
                                           sampleCount:sampleSize
                                              seamless:NO];

    // this works: returns perlin values -1..+1
    int x = 0;
    while (x < 20) {
        vector_int2 pos = {x, 0};
        NSLog(@"sample val is %f", [theMap valueAtPosition:pos]);
        x++;
    }

    // does NOT work
    // always returns -1
    x = 0;
    while (x < 20) {
        vector_float2 fpos = {x / 256.0, 0};
        NSLog(@"sample val is %f", [theMap interpolatedValueAtPosition:fpos]);
        x++;
    }

}


When you run it, you'll see that the valueAtPosition works flawlessly, but sampling via interpolated always returns -1


020-04-06 19:54:15.658556+0200 noiseexplorer[1994:711977] sample val is 0.000000

2020-04-06 19:54:19.946082+0200 noiseexplorer[1994:711977] sample val is -0.031727

2020-04-06 19:54:21.450169+0200 noiseexplorer[1994:711977] sample val is -0.059578

2020-04-06 19:54:22.360135+0200 noiseexplorer[1994:711977] sample val is -0.083551


etc.


2020-04-06 19:54:46.453443+0200 noiseexplorer[1994:711977] sample val is -1.000000

2020-04-06 19:54:47.783488+0200 noiseexplorer[1994:711977] sample val is -1.000000

2020-04-06 19:54:48.541423+0200 noiseexplorer[1994:711977] sample val is -1.000000

2020-04-06 19:54:49.337322+0200 noiseexplorer[1994:711977] sample val is -1.000000


Thanks for any hints on what I'm doing wrong.


-ch

Thanks for showing your code. Your code can easily reproduce the issue on iOS simulatros, some actual iPhone and macOS app.


I'm not sure if I may be mistaking the spec of the method, but for me this issue seems to be a bug of GameplayKit.

I cannot find any faults in your code and you should better try sending a bug report to Apple.

The range of position is the same for both interpolatedValueAtPosition and valueAtPosition. What happens if you don't divide x by 256?
Oh never mind, I'm wrong about that.