Generating normal map from noise on the fly in fragment shader

Started by
3 comments, last by denisve 6 years, 11 months ago

Hi, all.

I'm working on large landmass generation. Right now I'm using pregenerated normal maps, however this is getting costly and the goal is to have a good quality at any zoom level, so the best approach would be procedural. Let's presume the mesh is already generated, and I need to render it using predefined colors and normal map. I was thinking to write a function in GLSL that will return smooth normal map by UV coords, pretty much similar to how GLSL implementation of noise works. What I "invented" so far is generating height map from noise and then converting it to normal map. However, all implementations of such conversion I have found, rely on sampling the heightmap texture's neighbouring pixels to calculate normals. This is problematic in GLSL, since noise doesn't really have "pixels", it's generated on the fly per fragment using UV coords.

So how would you approach this problem? Basically I think this boils down to knowing pixel size in UV coords, so I can calculate neighbouring fragments UV coords to calculate normals per fragment. Is this realistic? Is this problematic performance-wise?

Thanks,

Denis.

Advertisement

I would recommend reading Bump Mapping Unparametrized Surfaces on the GPU.

Thanks, I've read it, but there's one catch. I'm using WebGL, which means no dFdxFine, which is used in fragment shader code there.

Any way around it in GLSL ES?

Not very sure how well this would work but...

Could you sample two noise functions, one for each dimension, and interpret the value as the angle around an axis in each dimension. Then use that to derive the normal.

I.e. It will give you a two angles around orthogonal axis, you can then rotate a unit vector to get your normal.

You might not even have to actually use angles and rotation, perhaps use three noise values to perturb a point in each direction and normalise the result.

I'm not too sure about the nature of the resulting noise however.

Not very sure how well this would work but...

Could you sample two noise functions, one for each dimension, and interpret the value as the angle around an axis in each dimension. Then use that to derive the normal.

I.e. It will give you a two angles around orthogonal axis, you can then rotate a unit vector to get your normal.

You might not even have to actually use angles and rotation, perhaps use three noise values to perturb a point in each direction and normalise the result.

I'm not too sure about the nature of the resulting noise however.

Could you elaborate a bit more? I'm not too good at math, so if you could put it as formulas, or any kind of code, that would be great.

Also sampling for 3 noise values and normalizing the vector just produces a nice colourful noise, which is cute, but not really what I need :) I aim for blueish normal map looks.

This topic is closed to new replies.

Advertisement