GLSL 2D柏林噪声看起来很奇怪

GLSL 2D柏林噪声看起来很奇怪,glsl,fragment-shader,noise,perlin-noise,Glsl,Fragment Shader,Noise,Perlin Noise,作为大学作业的一部分,我必须在GLSL中实施柏林噪声。我使用此幻灯片作为参考: 还有这个 我的课程说我应该得到这样的东西: 不幸的是,我在运行代码时遇到了以下问题: 通过向噪波值添加0.5,我得到: 我觉得奇怪的是,从一个细胞到另一个细胞的插值似乎效果不太好。好像插值函数没有C2连续性。这很奇怪,因为我用于插值的函数f确实有这个属性。你知道这个问题是从哪里来的吗 这是我的片段着色器代码: #版本330 在vec2uv中; 输出vec3颜色; 统一的整数宽度; 统一的内部高度; 浮动简单随

作为大学作业的一部分,我必须在GLSL中实施柏林噪声。我使用此幻灯片作为参考:

还有这个

我的课程说我应该得到这样的东西:

不幸的是,我在运行代码时遇到了以下问题:

通过向噪波值添加0.5,我得到:

我觉得奇怪的是,从一个细胞到另一个细胞的插值似乎效果不太好。好像插值函数没有C2连续性。这很奇怪,因为我用于插值的函数f确实有这个属性。你知道这个问题是从哪里来的吗

这是我的片段着色器代码:

#版本330
在vec2uv中;
输出vec3颜色;
统一的整数宽度;
统一的内部高度;
浮动简单随机数(vec2 co){
返回分数(sin(dot(co.xy,vec2(12.9898,78.233)))*43758.5453);
}
vec2兰德(vec2公司){
浮动角度=3.141592654*2*简单随机数(co);
返回向量2(sin(角度),cos(角度));
}
//混合功能如幻灯片中所述
浮动lerp(浮动x、浮动y、浮动alpha){
返回值(1-α)*x+α*y;
}
//如幻灯片中所述的插值函数
浮点数f(浮点数t){
返回t*t*t*(t*(6.0*t-15.0)+10.0);
}
vec3噪声(vec2 vec){
//每个单元的像素数
int cell_px=50;
//获取当前单元格角点的坐标并计算随机梯度
//网格坐标
int cx=int(地板(向量x*宽度/单元x));
int cy=int(地板(向量y*高度/单元X));
//绝对坐标
vec2 x0y0=vec2(cx*单元x,cy*单元x);
vec2x1y1=vec2(x0y0.x+单元x,x0y0.y+单元x);
vec2x0y1=vec2(x0y0.x,x1y1.y);
vec2x1y0=vec2(x1y1.x,x0y0.y);
//相对于x0y0转换为内部单元坐标的向量必须介于0和1之间
vec2 cell_vec=vec2((vec.x*宽度-x0y0.x)/cell_px,(vec.y*高度-x0y0.y)/cell_px);
//计算差分向量
vec2a=vec2(cell_-vec);
vec2b=vec2(1.0-单元向量x,单元向量y);
vec2c=vec2(cell_-vec.x,1.0-cell_-vec.y);
vec2d=vec2(1.0-细胞向量x,1.0-细胞向量y);
//点积从角点获取标量值
浮点数s=点(兰特(x0y0),a);
浮动t=点(兰特(x1y0),b);
浮点数u=点(兰特(x0y1),c);
浮点数v=点(兰特(x1y1),d);
float st_uu=lerp(s,t,f(cell_vec.x));
浮动uv=lerp(u,v,f(单元格向量x));
浮动噪声=lerp(标准、紫外、f(单元向量y));
返回向量3(噪声);
}
void main(){
颜色=噪声(uv);
}
vec2 cell_vec=vec2((vec.x*宽度-x0y0.x)/cell_px,(vec.y*高度-x0y0.y)/cell_px)


int
除以
int
可以做一些奇怪的事情。您可以先尝试将
单元格px
转换为
浮点

错误来自翻转向量的方向。你应该计算从角点到角点的向量,但是你正在计算从角点到角点的向量

这将解决它:

vec2 a = vec2(cell_vec);
vec2 b = vec2(cell_vec.x, -1.0+cell_vec.y);
vec2 c = vec2(-1.0+cell_vec.x, cell_vec.y);
vec2 d = vec2(-1.0 + cell_vec.x, -1.0 + cell_vec.y);