我正在尝试编写一个基于C#代码的计算着色器柏林噪音代码。
问题是我只得到了光滑的点。
左侧C#工作,右侧计算着色器,
均具有此值
如果我降低频率,点会变大:
这是我用的密码
#pragma kernel CSMain
RWTexture2D<float> Result;
RWStructuredBuffer<float> resfloat;
float res;
float frequency;
float octaves;
float lacunarity;
float persistence;
StructuredBuffer<float3> gradients3D;
StructuredBuffer<int> hash;
float lerp(float v0, float v1, float t);
float Dot(float3 g, float x, float y, float z);
float Smooth(float t);
float Perlin3D(float3 v, float frequency);
float noise(float3 v, float frequency, int octaves, float lacunarity, float persistence);
int hashMask = 255;
int gradientsMask3D = 15;
[numthreads(8, 8, 1)]
void CSMain(uint3 id : SV_DispatchThreadID)
{
float3 v = float3(id.x, id.y, id.z) / res;
float h = 0.0;
h = noise(v, frequency, octaves, lacunarity, persistence);
Result[id.xy] = float4(h, 0, 0, 0);
resfloat[id.x + id.y * res] = h;
}
float lerp(float v0, float v1, float t) {
return v0 + t * (v1 - v0);
}
float Smooth(float t) {
return t * t * t * (t * (t * (float) 6 - (float) 15) + (float) 10);
}
float Perlin3D(float3 v, float frequency) {
v *= frequency;
int ix0 = (int) floor(v.x);
int iy0 = (int) floor(v.y);
int iz0 = (int) floor(v.z);
float tx0 = v.x - ix0;
float ty0 = v.y - iy0;
float tz0 = v.z - iz0;
float tx1 = tx0 - (float) 1;
float ty1 = ty0 - (float) 1;
float tz1 = tz0 - (float) 1;
ix0 &= hashMask;
iy0 &= hashMask;
iz0 &= hashMask;
int ix1 = ix0 + (float) 1;
int iy1 = iy0 + (float) 1;
int iz1 = iz0 + (float) 1;
int h0 = hash[ix0];
int h1 = hash[ix1];
int h00 = hash[h0 + iy0];
int h10 = hash[h1 + iy0];
int h01 = hash[h0 + iy1];
int h11 = hash[h1 + iy1];
float3 g000 = gradients3D[hash[h00 + iz0] & gradientsMask3D];
float3 g100 = gradients3D[hash[h10 + iz0] & gradientsMask3D];
float3 g010 = gradients3D[hash[h01 + iz0] & gradientsMask3D];
float3 g110 = gradients3D[hash[h11 + iz0] & gradientsMask3D];
float3 g001 = gradients3D[hash[h00 + iz1] & gradientsMask3D];
float3 g101 = gradients3D[hash[h10 + iz1] & gradientsMask3D];
float3 g011 = gradients3D[hash[h01 + iz1] & gradientsMask3D];
float3 g111 = gradients3D[hash[h11 + iz1] & gradientsMask3D];
float v000 = dot(g000, float3(tx0, ty0, tz0));
float v100 = dot(g100, float3(tx1, ty0, tz0));
float v010 = dot(g010, float3(tx0, ty1, tz0));
float v110 = dot(g110, float3(tx1, ty1, tz0));
float v001 = dot(g001, float3(tx0, ty0, tz1));
float v101 = dot(g101, float3(tx1, ty0, tz1));
float v011 = dot(g011, float3(tx0, ty1, tz1));
float v111 = dot(g111, float3(tx1, ty1, tz1));
float tx = Smooth(tx0);
float ty = Smooth(ty0);
float tz = Smooth(tz0);
return lerp(
lerp(lerp(v000, v100, tx), lerp(v010, v110, tx), ty),
lerp(lerp(v001, v101, tx), lerp(v011, v111, tx), ty),
tz);
}
float noise(float3 v, float frequency, int octaves, float lacunarity, float persistence)
{
float sum = Perlin3D(v, frequency);
float amplitude = 1;
float range = 1;
for (int o = 1; o < octaves; o++) {
frequency *= lacunarity;
amplitude *= persistence;
range += amplitude;
sum += Perlin3D(v, frequency) * amplitude;
}
return sum / range;
}
This is the C# working code
And this is the C# code that calls the shader
我已经检查了StructuredBuffer
(gradients3D和hash)和float
参数是否正确加载。
有什么想法吗?
1条答案
按热度按时间wxclj1h51#
问题是,由于某种原因,当函数
Perlin3D
,使用hashMask
和gradientsMask3D
时,它们有一个0
。所以我把定义移到了函数上: