///////////////////////////////////////////////////////////////////////////////////////////////////////
//Pixel shader where lighting is calculated, as well as the appropriate texture colour for the pixel.//
///////////////////////////////////////////////////////////////////////////////////////////////////////
float HeightMapTX_PS(POSITION_UV_PS_INPUT Input) : SV_TARGET
{
float3 vPosition = ((float3(Input.UV, 0.0f) - 0.5f) * 2.0f) * 23.0f;
return fBm(vPosition, 16, 2.0, 0.5) * 0.5f + 0.5f;
}
///////////////////////////////////////////
////////////////////////////////////////////////////////////
http://img834.images...erlinnoise.jpg/
I get the following texture If I only use positive coordinates:
///////////////////////////////////////////////////////////////////////////////////////////////////////
//Pixel shader where lighting is calculated, as well as the appropriate texture colour for the pixel.//
///////////////////////////////////////////////////////////////////////////////////////////////////////
float HeightMapTX_PS(POSITION_UV_PS_INPUT Input) : SV_TARGET
{
float3 vPosition = float3(Input.UV, 0.0f) * 46.0f;
return fBm(vPosition, 16, 2.0, 0.5) * 0.5f + 0.5f;
}
///////////////////////////////////////////
////////////////////////////////////////////////////////////
http://img859.images...rlinnoise2.jpg/
I'd appreciate if anyone could help me track down what I'm doing wrong. If you notice, in the top left of both of the above images (you will have to zoom in), there is some really weird lines going through the texture. Below is the full perlin noise effect file, as well as my texture generation functions:
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// TEXTURES - IMPORTANT! you must pass these textures to
// the effect before generating any values using the improved
// noise basis function (inoise()).
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Texture2D permTexture2d : register(t0);
Texture2D permGradTexture : register(t1);
SamplerState permSampler2d
{
AddressU = Wrap;
AddressV = Wrap;
MAGFILTER = POINT;
MINFILTER = POINT;
MIPFILTER = NONE;
};
SamplerState permGradSampler
{
AddressU = Wrap;
AddressV = Wrap;
MAGFILTER = POINT;
MINFILTER = POINT;
MIPFILTER = NONE;
};
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// FUNCTIONS
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
float3 fade(float3 t)
{
return t * t * t * (t * (t * 6 - 15) + 10); // new curve
}
float4 perm2d(float2 p)
{
return permTexture2d.Sample(permSampler2d, p);
}
float gradperm(float x, float3 p)
{
return dot(permGradTexture.Sample(permGradSampler, x), p);
}
// Improved 3d noise basis function
float inoise(float3 p)
{
float3 P = fmod(floor(p), 256.0); // FIND UNIT CUBE THAT CONTAINS POINT
p -= floor(p); // FIND RELATIVE X,Y,Z OF POINT IN CUBE.
float3 f = fade(p); // COMPUTE FADE CURVES FOR EACH OF X,Y,Z.
P = P / 256.0;
// HASH COORDINATES OF THE 8 CUBE CORNERS
float4 AA = perm2d(P.xy) + P.z;
// AND ADD BLENDED RESULTS FROM 8 CORNERS OF CUBE
return lerp( lerp( lerp( gradperm(AA.x, p ),
gradperm(AA.z, p + float3(-1, 0, 0) ), f.x),
lerp( gradperm(AA.y, p + float3(0, -1, 0) ),
gradperm(AA.w, p + float3(-1, -1, 0) ), f.x), f.y),
lerp( lerp( gradperm(AA.x+(1.0 / 256.0), p + float3(0, 0, -1) ),
gradperm(AA.z+(1.0 / 256.0), p + float3(-1, 0, -1) ), f.x),
lerp( gradperm(AA.y+(1.0 / 256.0), p + float3(0, -1, -1) ),
gradperm(AA.w+(1.0 / 256.0), p + float3(-1, -1, -1) ), f.x), f.y), f.z);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// FRACTAL FUNCTIONS
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// fractal sum
float fBm(float3 p, int octaves, float lacunarity = 2.0, float gain = 0.5)
{
float freq = 1.0f,
amp = 0.5f;
float sum = 0.0f;
for(int i=0; i < octaves; i++) {
sum += inoise(p*freq)*amp;
freq *= lacunarity;
amp *= gain;
}
return sum;
}
float turbulence(float3 p, int octaves, float lacunarity = 2.0, float gain = 0.5)
{
float sum = 0;
float freq = 1.0, amp = 1.0;
for(int i=0; i < octaves; i++) {
sum += abs(inoise(p*freq))*amp;
freq *= lacunarity;
amp *= gain;
}
return sum;
}
// Ridged multifractal
// See "Texturing & Modeling, A Procedural Approach", Chapter 12
float ridge(float h, float offset)
{
h = abs(h);
h = offset - h;
h = h * h;
return h;
}
float ridgedmf(float3 p, int octaves, float lacunarity, float gain = 0.05, float offset = 1.0)
{
float sum = 0;
float freq = 1.0;
float amp = 0.5;
float prev = 1.0;
for(int i=0; i < octaves; i++)
{
float n = ridge(inoise(p*freq), offset);
sum += n*amp*prev;
prev = n;
freq *= lacunarity;
amp *= gain;
}
return sum;
}
#include "PerlinNoiseShader.h"
#include "CommonFunctions.h"
#include "ErrorHandling.h"
UINT PerlinNoiseShader::Permutation[256] =
{
151,160,137,91,90,15,
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180
};
PerlinNoiseShader::PerlinNoiseShader()
{
mHR = S_OK;
//mPermutation1D = NULL;
mPermutation2D = NULL;
mGradient1D = NULL;
}
HRESULT PerlinNoiseShader::CreatePermutationTextures(ID3D11Device * pDevice)
{
D3D11_TEXTURE2D_DESC txDesc2D;
ZeroMemory(&txDesc2D, sizeof(D3D11_TEXTURE2D_DESC));
txDesc2D.Width = txDesc2D.Height = 256;
txDesc2D.MipLevels = 1;
txDesc2D.ArraySize = 1;
txDesc2D.SampleDesc.Count = 1;
txDesc2D.SampleDesc.Quality = 0;
txDesc2D.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
txDesc2D.Usage = D3D11_USAGE_IMMUTABLE;
txDesc2D.BindFlags = D3D11_BIND_SHADER_RESOURCE;
txDesc2D.CPUAccessFlags = 0;
XMFLOAT4 * PermutationTX2D = new XMFLOAT4[256*256];
for (int x = 0; x < 256; x++)
{
for(int y = 0; y < 256; y++)
{
int A = Permutation2DSample(x) + y;
int AA = Permutation2DSample(A);
int AB = Permutation2DSample(A + 1);
int B = Permutation2DSample(x + 1) + y;
int BA = Permutation2DSample(B);
int BB = Permutation2DSample(B + 1);
PermutationTX2D[x + (y * 256)] = XMFLOAT4(float(AA / 255.0f), float(AB / 255.0f), float(BA / 255.0f), float(BB / 255.0f));
}
}
D3D11_SUBRESOURCE_DATA InitialData;
ZeroMemory(&InitialData, sizeof(D3D11_SUBRESOURCE_DATA));
InitialData.pSysMem = PermutationTX2D;
InitialData.SysMemPitch = 256 * sizeof(XMFLOAT4);
InitialData.SysMemSlicePitch = 0;
if(SUCCEEDED(mHR))
pDevice->CreateTexture2D(&txDesc2D, &InitialData, &mPermutation2D);
delete[] PermutationTX2D;
if(SUCCEEDED(mHR))
mHR = pDevice->CreateShaderResourceView(mPermutation2D, NULL, &mPermutationView);
return mHR;
}
HRESULT PerlinNoiseShader::CreateGradientTextures(ID3D11Device * pDevice)
{
float Gradients3D[16][3] =
{
{1,1,0},
{-1,1,0},
{1,-1,0},
{-1,-1,0},
{1,0,1},
{-1,0,1},
{1,0,-1},
{-1,0,-1},
{0,1,1},
{0,-1,1},
{0,1,-1},
{0,-1,-1},
{1,1,0},
{0,-1,1},
{-1,1,0},
{0,-1,-1}
};
D3D11_TEXTURE1D_DESC txDesc1D;
ZeroMemory(&txDesc1D, sizeof(D3D11_TEXTURE1D_DESC));
txDesc1D.Width = 256;
txDesc1D.MipLevels = 1;
txDesc1D.ArraySize = 1;
txDesc1D.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
txDesc1D.Usage = D3D11_USAGE_IMMUTABLE;
txDesc1D.BindFlags = D3D11_BIND_SHADER_RESOURCE;
txDesc1D.CPUAccessFlags = 0;
XMFLOAT4 * GradientsInit3D = new XMFLOAT4[256];
for(int x = 0; x < 256; x++)
{
XMVECTOR Vec = XMVectorSet(Gradients3D[Permutation[x] % 16][0],
Gradients3D[Permutation[x] % 16][1],
Gradients3D[Permutation[x] % 16][2],
1.0f);
XMStoreFloat4(&GradientsInit3D[x], Vec);
}
D3D11_SUBRESOURCE_DATA InitialData;
ZeroMemory(&InitialData, sizeof(D3D11_SUBRESOURCE_DATA));
InitialData.pSysMem = GradientsInit3D;
InitialData.SysMemPitch = 256 * sizeof(XMFLOAT4);
InitialData.SysMemSlicePitch = 0;
mHR = pDevice->CreateTexture1D(&txDesc1D, &InitialData, &mGradient1D);
delete[] GradientsInit3D;
if(SUCCEEDED(mHR))
mHR = pDevice->CreateShaderResourceView(mGradient1D, NULL, &mGradientView);
return mHR;
}
HRESULT PerlinNoiseShader::InitialiseShader(ID3D11Device * pDevice)
{
mHR = CreateGradientTextures(pDevice);
if(SUCCEEDED(mHR))
mHR = CreatePermutationTextures(pDevice);
if(FAILED(mHR))
{
GeneralErrorHandler::OutputDxError(mHR, "PerlinNoiseShader::Initialise", NULL);
GeneralErrorHandler::LogErrorToFile("PerlinNoiseShader::Initialise", "Failed to create noise textures", "", "ErrorLog.txt");
}
return mHR;
}
void PerlinNoiseShader::SetBuffers(ID3D11DeviceContext * pDeviceContext)
{
pDeviceContext->PSSetShaderResources(0, 1, &mPermutationView);
pDeviceContext->PSSetShaderResources(1, 1, &mGradientView);
}