Skip to main content
GameDev.net gamedev.net
🔒 Locked

A perlin noise function on the GPU

Started by Narf the Mouse Oct 20, 2010 at 8:31 AM 1 replies 2.8k views
Original Post
Narf the Mouse
Narf the Mouse
As an idle thought, I've written my perlin noise function in NVidia FX Composer. However, there's a slight problem...Outputting data. I'm limited to a GeForce 8800GT, so I'm using Shader Model 3.0. No dynamic array indexing, which means I can't just output to an array stored in the effect file. And Google doesn't seem to know about modifying a texture.

I suppose I could output the perlin noise to the screen and take a screenshot, but that's not really what I'm after...
Narf the Mouse
Narf the Mouse
Ok, I solved that, I think. Just output to a surface I create. However, I've got a new problem. In FX Composer, my code compiles fine. Try to load it as a SlimDX Effect and I get X3000 "Unexpected Token" on this: I've bolded the unexpected token.
uint MercenneOnce(uint seed){	return (1812433253 * (seed - (seed * (uint)pow(2, 30))) + 1); // 0x6c078965}float Noise2D(int x, int y){	int n = x + y * 1376312627;    n = (1 - ((n * (n * n * 15727 + 789181) + (int)1376312627) - (int)0x7fffffff) / (int)1073741827);    return MercenneOnce(n / 4294967295) * 2.0;}

How is that unexpected?
Narf the Mouse
Narf the Mouse
Alright, my GPU Perlin functions are returning the maximum float value as a negative and I don't know why.

texture Data;/* uint MercenneOnce(uint seed){	return (uint)abs((1812433253 * ((int)seed - (int)(seed * (int)pow(2, 30))) + 1)); // 0x6c078965} */int MercenneOnce(int seed){	return (1812433253 * (seed - (seed * (int)pow(2, 30))) + 1); // 0x6c078965}float Noise2D(int x, int y){	int n = x + y * 1376312627;    n = (1 - ((n * (n * n * 15727 + 789181) + (int)1376312627) - (int)0x7fffffff) / (int)1073741827);	// uint n2 = (uint)n / 4294967295;	// return MercenneOnce((uint)abs( (uint)abs(n) / 2147483647.0)) * 2.0;	// return MercenneOnce((uint)abs( n )) * 2.0;	// return n / 2147483647.0;	return MercenneOnce(n) / 2147483647.0;	// return 1.0;}float SmoothedNoise2D(int x, int y){	float corners = (Noise2D(x - 1, y - 1) + Noise2D(x + 1, y - 1) + Noise2D(x - 1, y + 1) + Noise2D(x + 1, y + 1)) / 16;	float sides = (Noise2D(x - 1, y) + Noise2D(x + 1, y) + Noise2D(x, y - 1) + Noise2D(x, y + 1)) / 8;    float center = Noise2D(x, y) / 4;    return corners + sides + center;}float CosineInterpolate(float a, float b, float interpolation){	float f = (1 - cos(interpolation * 3.1415926535897932384626433832795)) * .5;	return a * (1 - f) + b * f;}float InterpolatedNoise2D(float x, float y){	int integer_X = (int)x;    float fractional_X = x - integer_X;    int integer_Y = (int)y;    float fractional_Y = y - integer_Y;    float v1 = SmoothedNoise2D(integer_X, integer_Y);    float v2 = SmoothedNoise2D(integer_X + 1, integer_Y);    float v3 = SmoothedNoise2D(integer_X, integer_Y + 1);    float v4 = SmoothedNoise2D(integer_X + 1, integer_Y + 1);	float i1 = CosineInterpolate(v1, v2, fractional_X);    float i2 = CosineInterpolate(v3, v4, fractional_X);    return CosineInterpolate(i1, i2, fractional_Y);}float PerlinNoise2D(float x, float y, float persistance, int octaves, int shift){	float total = 0;    float p = persistance;    int n = octaves;	for (int i = 0; i < n; ++i)    {    	float frequency = pow(2, i + shift);        float amplitude = pow(p, i + shift);        total = total + InterpolatedNoise2D(x * frequency, y * frequency) * amplitude;    } 	return total / persistance;}struct VertexShader_Input{	float4 Position : Position0;};struct VertexShader_Output{	float4 Position : Position0;	float3 Pos : TexCoord0;	float4 Color : Color;};VertexShader_Output mainVS(VertexShader_Input input){	VertexShader_Output output;	output.Position = input.Position;	output.Pos = input.Position.xyz;	// data[(int)output.Pos.x][(int)output.Pos.z] = PerlinNoise2D(output.Pos.x / 512.0, output.Pos.z / 512.0, 5, 5, 0);	output.Color = float4(1.0, 1.0, 1.0, 1.0) * (PerlinNoise2D(output.Pos.x / 512.0, output.Pos.z / 512.0, 5, 5, 0));	return output;}float4 mainPS(VertexShader_Output input) : COLOR{		return input.Color;}technique technique0 {	pass p0 {		// CullMode = None;		VertexShader = compile vs_3_0 mainVS();		PixelShader = compile ps_3_0 mainPS();	}}

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.