I don't suppose anyone knows how to generate bump vectors for simplex noise...?

jrandom

eye kan kode gud
I can haz procedural texture!

View attachment 113766

It's far from feature complete -- not all the inputs/settings are implemented yet (Function, Octaves and related) and coordinate rotation doesn't work yet, but the thing that really has me stumped is the bump vector. My code is based on the implementation by Stefan Gustavson, and right now I'm just assigning the noise derivatives directly to the bump output after scaling by the bump height setting:

Code:
    // ---------------------------------------------------------------------------- Evaluate_Bump()
    void Simplex_Noise::Evaluate_Bump ( LWTypes::LWNodalAccess * nodal_access,
                                        LWTypes::NodeValue       node_value )
    {
        // Retrieve noise and bump height
        const Simplex_Result_t simplex    (             Get_Noise( nodal_access ) );
        const double           bump_height( Input_Bump_Height.Get( nodal_access ) );
        
        
        // TODO: Figure out how to actually do this
        LWTypes::LWDVector output_vector( simplex.Noise_dX * bump_height,
                                          simplex.Noise_dY * bump_height,
                                          simplex.Noise_dZ * bump_height );
        
        // Output computed bump map
        Output_Functions->setValue( node_value, output_vector );
    }

It almost works, but I get all these discontinuities:

View attachment 113767 View attachment 113768

Any of you experienced procedural texture devs know what causes this and how to avoid it?
 

Attachments

  • Simplex Noise Node.png
    Simplex Noise Node.png
    23.4 KB · Views: 610
  • Simplex Bump Problem.jpg
    Simplex Bump Problem.jpg
    34.3 KB · Views: 576
  • Simplex Bump Problem Color.jpg
    Simplex Bump Problem Color.jpg
    47.1 KB · Views: 600
Last edited:
If it helps, I've attached my version of the simplex noise functions. Ignore the region stuff -- that was just an experiment that didn't work out as well as I'd hoped.
 

Attachments

  • Simplex_Noise.h.zip
    5.1 KB · Views: 457
OMG, I'm a moron. :) Well, sort of.

Bug in line 531 of Simplex_Noise.h:

Code:
const value_t temp_3 = t3_squared * t3 * (x3_gradient * x3 + y2_gradient * y3 + z3_gradient * z3);

That middle bit needs to be y3_gradient, not y2_gradient:

Code:
const value_t temp_3 = t3_squared * t3 * (x3_gradient * x3 + y3_gradient * y3 + z3_gradient * z3);

Also, the derivatives appear to be in the range [-1, 1] and I get better results rescaling that to [0, 1] and then inverting it so outward bumps match the bright alpha areas.

Code:
    // ---------------------------------------------------------------------------- Evaluate_Bump()
    void Simplex_Noise::Evaluate_Bump ( LWTypes::LWNodalAccess * nodal_access,
                                        LWTypes::NodeValue       node_value )
    {
        // Retrieve noise and bump height
        const Simplex_Result_t simplex    (             Get_Noise( nodal_access ) );
        const double           bump_height( Input_Bump_Height.Get( nodal_access ) );
        
        
        // Calculate bump vector
        LWTypes::LWDVector output_vector( (1.0 - simplex.Noise_dX_01()) * bump_height,
                                          (1.0 - simplex.Noise_dY_01()) * bump_height,
                                          (1.0 - simplex.Noise_dZ_01()) * bump_height );
        
        // Output computed bump map
        Output_Functions->setValue( node_value, output_vector );
    }

Whee! Thanks for watching me spazz out on a weekend.
View attachment 113770
 

Attachments

  • Working_Simplex_Bump.jpg
    Working_Simplex_Bump.jpg
    67.7 KB · Views: 538
  • Simplex_Noise.h_FIXED.zip
    5.1 KB · Views: 481
Last edited:
All that remains is Invert, Contrast, Opacity, and Rotation, and this sucker's feature-complete!

Yeah, okay, it's just bog-standard Simplex noise, but it's my first procedural texture and I can use it as a base for more interesting stuff!

View attachment 113781

I still have no idea how to properly apply Rotation. I'm guessing I need to stuff it, along with Scale and Position, into a matrix (I'm manually applying Scale and Position at the moment), but I was hoping there was some sort of built-in routine that would construct such a thing for me. Can't seem to find one.
 

Attachments

  • Almost There.png
    Almost There.png
    361.2 KB · Views: 561
Last edited:
I have no idea what are you doing but you are on fire and it looks cool so keep it going :).
 
Put in what many of the procedurals don't.. a normal :D

Ditto with Lewis, but keep up the good work!
 
I thought about adding Normal output, but it's no longer strictly necessary with the Bump to Normal node, and I'd have to add two more inputs (Normal Foreground, Normal Background) and then figure out they would interact with the incoming bump vectors, etc. It's a trickier problem than it looks on the surface. (Ha! Punny!)

So I'll keep it in mind, but I'm not going to add Normals at this juncture.

What I really need is to get Rotation implemented. I'm flabbergasted that there doesn't seem to be a "generate transformation matrix from Scale, Position, and Rotation vectors" function in the SDK.
 
Although... well, now that I think about I, I can easily just add a Normal output and not worry about Normal inputs. :) I'll do that, then.
 
Fun Fact: this node uses internal caching so the noise algorithm is only ever run once per spot, regardless of how many of the node's outputs are used. When I add a Normal output, I'll add a bump vector cache so both can be used without incurring a doubling up on the mixing calculations.
 
Very nice. Does it also have any kind of determinism, to stop it from being different on different CPU's?
 
Very nice. Does it also have any kind of determinism, to stop it from being different on different CPU's?

Yes, Simplex noise is deterministic. It's similer to Perlin noise (designed by the same guy, actually), but exhibits isotropy in all dimensions and is faster to calculate. It also allows for the generation of the bump vector in a single evaluation w/out having to sample multiple nearby locations.
 
For nerdy definitions of "fun", yes!

I have to go write music for a commercial, but after that I'm back on node coding.
 
Very encouraging :)
I still haven't got around to port my AoN shaders to LW.
How did you start out? Any recommendations for tutorials or existing code to learn from (apart from the SDK itself?)?

Cheers and have fun! :)

Tom
 
There's no simple path to node coding. I read through the SDK docs, but the most helpful thing to study was the specular highlight node sample code in the SDK. Even with that, there was a lot of trial-and-error involved. I never would have got it to work had it not been the help of others in this forum.

My plug-ins come with source code, so you can study that if you like. I never did find any good tutorials.
 
Last edited:
Thanks a lot jrandom! I'll look into those shaders of yours.

The only link to a node coding tutorials I could find was dead (Aurorafx) ;-(

Well, I guess I'll have to see how it goes and come back here if I fail :)

Cheers,

Tom
 
I started from the same example, and once you see how you handle nodes the inputs etc, it is quite easy and productive, we bought your aon textures a long time ago for Messiah, looking forward to seeing them ported :)

creacon
 
Didn't know that you put the source available for others, thanks for that. I don't have any need for anything in particular but it's alaways great to learn from other people's code to improve my own.

creacon
 
Hey creacon!

Nice to hear there are still some of the old AoN:messiah users around ;-)

I developed some nice new stuff for Mental Ray and Arnold in the meantime and I miss some options in the LW nodes so I'll see how it goes.

Cheers!

Tom
 
Back
Top