Jump to content
  • Advertisement
Sign in to follow this  

[solved] Perlin noise shader: almost there, but some minor discontinuities

This topic is 3010 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've been working on a shader to create a perlin noise texture. I've got it almost working, but I can still see some minor discontinuities in the higher octaves and I can't quite place what is the issue :S Anyway here is my best result so far. You can see that the cloud texture is almost like I want it, but I can still see minor grids of discontinuity where the texture is repeating (you can see it in the fullsize image): Free Image Hosting at www.ImageShack.us How I create the texture: On CPU I generate a small texture of the gradients used for perlin shader.Each texel of the texture represents a 2d vector in a random direction. To enable tiling, I duplicate the vectors around the edge: Free Image Hosting at www.ImageShack.us Finally the pixel shader. For this shader I'm just drawing a fullscreen quad, with texture coordinates from (0..numGradients, 0..numGradients). maxTex is the same as numGradients, and allows me to wrap the texcoord for higher octaves.
uniform sampler2D gradientTex;
uniform vec2 maxTex;
in vec2 vTexCoord;

void main()
	float finalval=0;
	for(int i=0;i<4;i++){ //Four Octaves of Noise
		//Mod the texture coordinate for tiling
		//Each octave is 2x the frequency of the last
		vec2 modTex = mod(vTexCoord*pow(2,float(i)), maxTex);
		vec2 whole;
		vec2 fraction;
		//Split into whole and fractional parts
		fraction = modf(modTex ,whole);
		ivec2 texindex00 = ivec2(whole);
		//Get the four gradients surrounding the pixel
	 	vec2 texel00 = texelFetch2D(gradientTex,texindex00,0).rg;
		vec2 texel10 = texelFetch2D(gradientTex,ivec2(texindex00.x+1,texindex00.y),0).rg;
		vec2 texel01 = texelFetch2D(gradientTex,ivec2(texindex00.x,texindex00.y+1),0).rg;
		vec2 texel11 = texelFetch2D(gradientTex,ivec2(texindex00.x+1,texindex00.y+1),0).rg;
		//Compute the value at the four corners
		float val00 = dot(fraction, texel00);
		float val10 = dot(fraction-vec2(1,0), texel10);
		float val01 = dot(fraction-vec2(0,1), texel01);
		float val11 = dot(fraction-vec2(1,1), texel11);
		//Smooth polynomial bi-lerp
		float interp0 = val00 + (3*pow(fraction.x,2)-2*pow(fraction.x,3))*(val10-val00);
		float interp1 = val01 + (3*pow(fraction.x,2)-2*pow(fraction.x,3))*(val11-val01);
		float interp2 = interp0 + (3*pow(fraction.y,2)-2*pow(fraction.y,3))*(interp1-interp0);
		//Let the first octave be between 0-1
		//successive octaves between -1/2^n,1/2^n
			finalval += (interp2+1)/2;
		} else {
			finalval += interp2/pow(2,float(i));
	gl_FragColor = vec4(finalval,finalval,finalval,1.0);

Thanks to anyone who has any ideas on where my miscalculation might be! [Edited by - karwosts on April 25, 2010 7:00:48 PM]

Share this post

Link to post
Share on other sites
Found the issue. When uploading my gradients through OpenGL I used the wrong texture type, causing the x and y components of the gradients to be clamped to [0,1], when they should have been [-1,1]. Whenever either component of the gradient vector was negative it was zeroing it causing lots of bad visual artifacts.

Looks great now!

Free Image Hosting at www.ImageShack.us

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!