Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opengl 将二维噪波转换为三维噪波_Opengl_Glsl_Fragment Shader - Fatal编程技术网

Opengl 将二维噪波转换为三维噪波

Opengl 将二维噪波转换为三维噪波,opengl,glsl,fragment-shader,Opengl,Glsl,Fragment Shader,我最近开始尝试使用噪波(简单的柏林噪波),但在设置它的动画时遇到了一个小问题。到目前为止,我遇到了一个非常棒的3d noise(),我可以在我的项目中使用它,但我对它一无所知,还有一系列教程解释了如何创建简单的2d noise 对于2d噪波,我最初使用了以下片段着色器: uniform sampler2D al_tex; varying vec4 varying_pos; //Actual coords varying vec2 varying_texcoord; //Normalized co

我最近开始尝试使用噪波(简单的柏林噪波),但在设置它的动画时遇到了一个小问题。到目前为止,我遇到了一个非常棒的3d noise(),我可以在我的项目中使用它,但我对它一无所知,还有一系列教程解释了如何创建简单的2d noise

对于2d噪波,我最初使用了以下片段着色器:

uniform sampler2D al_tex;
varying vec4 varying_pos; //Actual coords
varying vec2 varying_texcoord; //Normalized coords

uniform float time;

float rand(vec2 co) { return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453); }

float ease(float p) { return 3*p*p - 2*p*p*p; }

float cnoise(vec2 p, int wavelength)
{
    int ix1 = (int(varying_pos.x) / wavelength) * wavelength;
    int iy1 = (int(varying_pos.y) / wavelength) * wavelength;
    int ix2 = (int(varying_pos.x) / wavelength) * wavelength + wavelength;
    int iy2 = (int(varying_pos.y) / wavelength) * wavelength + wavelength;

    float x1 = ix1 / 1280.0f;
    float y1 = iy1 / 720.0f;
    float x2 = ix2 / 1280.0f;
    float y2 = iy2 / 720.0f;

    float xOffset = (varying_pos.x - ix1) / wavelength;
    float yOffset = (varying_pos.y - iy1) / wavelength;

    xOffset = ease(xOffset);
    yOffset = ease(yOffset);

    float t1 = rand(vec2(x1, y1));
    float t2 = rand(vec2(x2, y1));
    float t3 = rand(vec2(x2, y2));
    float t4 = rand(vec2(x1, y2));

    float tt1 = mix(t1, t2, xOffset);
    float tt2 = mix(t4, t3, xOffset);

    return mix(tt1, tt2, yOffset);
}

void main()
{
    float t = 0;

    int minFreq = 0;
    int noIterations = 8;

    for (int i = 0; i < noIterations; i++)
        t += cnoise(varying_texcoord, int(pow(2, i + minFreq))) / pow(2, noIterations - i);

    gl_FragColor = vec4(vec3(t), 1);
}
2d-al_-tex统一采样器;
可变向量4可变位置//实际坐标
可变矢量2可变坐标//规范化坐标
均匀浮动时间;
float rand(vec2-co){返回分形(sin(dot(co,vec2(12.9898,78.233)))*43758.5453;}
float-ease(float-p){return 3*p*p-2*p*p*p;}
浮动cnoise(vec2 p,int波长)
{
int ix1=(int(变化位置x)/波长)*波长;
int iy1=(int(变化位置y)/波长)*波长;
intix2=(int(变化位置x)/波长)*波长+波长;
int iy2=(int(变化位置y)/波长)*波长+波长;
浮动x1=ix1/1280.0f;
浮动y1=iy1/720.0f;
浮动x2=ix2/1280.0f;
浮动y2=iy2/720.0f;
float xOffset=(变化位置x-ix1)/波长;
浮动y偏移=(变化位置y-iy1)/波长;
xOffset=易用性(xOffset);
yOffset=轻松(yOffset);
浮点数t1=rand(vec2(x1,y1));
浮点数t2=rand(vec2(x2,y1));
浮动t3=rand(vec2(x2,y2));
浮点数t4=rand(vec2(x1,y2));
浮动tt1=混合(t1、t2、xOffset);
浮动tt2=混合(t4、t3、xOffset);
返回混音(tt1、tt2、yOffset);
}
void main()
{
浮动t=0;
int minFreq=0;
int-noIterations=8;
for(int i=0;i
我得到的结果是:

现在,我想用时间来制作动画。我的第一个想法是将rand函数改为vec3而不是vec2,然后相应地修改cnoise函数,在z方向上插值。考虑到这一目标,我做出了以下决定:

sampler2D al_tex;
varying vec4 varying_pos;
varying vec2 varying_texcoord;

uniform float time;

float rand(vec3 co) { return fract(sin(dot(co, vec3(12.9898, 78.2332, 58.5065))) * 43758.5453); }

float ease(float p) { return 3*p*p - 2*p*p*p; }

float cnoise(vec3 pos, int wavelength)
{
    ivec3 iPos1 = (ivec3(pos) / wavelength) * wavelength; //The first value that I'll sample to interpolate
    ivec3 iPos2 = iPos1 + wavelength; //The second value

    vec3 transPercent = (pos - iPos1) / wavelength; //Transition percent - A float in [0-1) indicating how much of each of the above values will contribute to final result
    transPercent.x = ease(transPercent.x);
    transPercent.y = ease(transPercent.y);
    transPercent.z = ease(transPercent.z);

    float t1 = rand(vec3(iPos1.x, iPos1.y, iPos1.z));
    float t2 = rand(vec3(iPos2.x, iPos1.y, iPos1.z));
    float t3 = rand(vec3(iPos2.x, iPos2.y, iPos1.z));
    float t4 = rand(vec3(iPos1.x, iPos2.y, iPos1.z));
    float t5 = rand(vec3(iPos1.x, iPos1.y, iPos2.z));
    float t6 = rand(vec3(iPos2.x, iPos1.y, iPos2.z));
    float t7 = rand(vec3(iPos2.x, iPos2.y, iPos2.z));
    float t8 = rand(vec3(iPos1.x, iPos2.y, iPos2.z));

    float tt1 = mix(t1, t2, transPercent.x);
    float tt2 = mix(t4, t3, transPercent.x);
    float tt3 = mix(t5, t6, transPercent.x);
    float tt4 = mix(t8, t7, transPercent.x);

    float tt5 = mix(tt1, tt2, transPercent.y);
    float tt6 = mix(tt3, tt4, transPercent.y);

    return mix(tt5, tt6, transPercent.z);
}

float fbm(vec3 p)
{
    float t = 0;

    int noIterations = 8;

    for (int i = 0; i < noIterations; i++)
        t += cnoise(p, int(pow(2, i))) / pow(2, noIterations - i);

    return t;
}

void main()
{
    vec3 p = vec3(varying_pos.xy, time);

    float t = fbm(p);

    gl_FragColor = vec4(vec3(t), 1);
}
2d-al_-tex;
可变向量4可变位置;
可变矢量2可变坐标;
均匀浮动时间;
float rand(vec3co){返回分形(sin(dot(co,vec3(12.9898,78.2332,58.5065)))*43758.5453;}
float-ease(float-p){return 3*p*p-2*p*p*p;}
浮动cnoise(vec3位置,内部波长)
{
ivec3 iPos1=(ivec3(pos)/波长)*波长;//我将采样以插值的第一个值
ivec3 iPos2=iPos1+波长;//第二个值
vec3 transPercent=(pos-iPos1)/wavelength;//转换百分比-在[0-1]中的一个浮点数,表示上述每个值对最终结果的贡献程度
transPercent.x=轻松(transPercent.x);
transPercent.y=轻松(transPercent.y);
transPercent.z=轻松(transPercent.z);
float t1=rand(vec3(iPos1.x,iPos1.y,iPos1.z));
浮点t2=rand(vec3(iPos2.x,iPos1.y,iPos1.z));
浮点数t3=rand(vec3(iPos2.x,iPos2.y,iPos1.z));
浮动t4=兰德(vec3(iPos1.x,iPos2.y,iPos1.z));
float t5=兰德(vec3(iPos1.x,iPos1.y,iPos2.z));
float t6=rand(vec3(iPos2.x,iPos1.y,iPos2.z));
float t7=rand(vec3(iPos2.x,iPos2.y,iPos2.z));
float t8=rand(vec3(iPos1.x,iPos2.y,iPos2.z));
浮动tt1=混合(t1,t2,透明度x);
浮动tt2=混合(t4、t3、透明度x);
浮动tt3=混合(t5、t6、透明度x);
浮动tt4=混合(t8,t7,transPercent.x);
浮动tt5=混合(tt1,tt2,透明度y);
浮动tt6=混合(tt3,tt4,透明度y);
返混(tt5、tt6、transPercent.z);
}
浮动fbm(vec3 p)
{
浮动t=0;
int-noIterations=8;
for(int i=0;i

然而,在这样做的时候,动画感觉…奇怪。这就像我在看柏林噪音幻灯片的幻灯片,单个幻灯片逐渐消失。我尝试过的所有其他柏林噪音示例(如)实际上是随着时间的推移而动画化的-你可以看到它正在动画化,而不仅仅是感觉图像正在淡入,而不是真正的动画化。我知道我可以只使用webgl噪波着色器,但我想为自己制作一个,由于某些原因,我失败得很惨。有人能告诉我哪里出了问题,或者建议我吗关于如何随时间正确设置动画?

您应该在sin函数中包含z:

float rand(vec3 co) { return fract(sin(dot(co.xy ,vec2(12.9898,78.233)) + co.z) * 43758.5453); }
显然,有些随机数是素数。这是为了避免噪声中的模式。我找到了另一个素数94418953,并将其包含在sin/dot函数中。尝试以下方法:

float rand(vec3 co) { return fract(sin(dot(co.xyz ,vec3(12.9898,78.233, 9441.8953))) * 43758.5453); }
编辑:不考虑z轴上的波长。这意味着您的所有迭代都将具有相同的插值距离。换句话说,您将获得所描述的淡入效果。请尝试以与计算x和y相同的方式计算z:

int iz1 = (int(p.z) / wavelength) * wavelength;
int iz2 = (int(p.z) / wavelength) * wavelength + wavelength;

float z1 = iz1 / 720.0f;
float z2 = iz2 / 720.0f;

float zOffset = (varying_pos.z - iz1) / wavelength;

但是,这意味着z值的变化率将与y值的变化率相同。因此,如果希望它从0缩放到1,则应在将z与720相乘后再将其传递到噪波函数中。

检查此代码。这是3d噪波的一个简单版本:

// Here are some easy to understand noise gens... the D line in cubic interpolation (rounding) 


function rndng ( n: float ): float
{//random proportion -1, 1   ... many people use Sin to take 
 //linearity out of a pseudo random, exp n*n is faster on central processor.
    var e = ( n *321.9234)%1;
    return  (e*e*111.07546)%2-1;
}

function lerps(o:float, v:float, alpha:float):float
{
    o += ( v - o ) * alpha;
    return o;
}

 //3d ----------------
function lnz ( vtx: Vector3 ): float //3d perlin noise code fast
{  
    vtx= Vector3 ( Mathf.Abs(vtx.x) , Mathf.Abs(vtx.y) , Mathf.Abs(vtx.z) ) ;
    var I = Vector3 (Mathf.Floor(vtx.x),Mathf.Floor(vtx.y),Mathf.Floor(vtx.z));
    var D = Vector3(vtx.x%1,vtx.y%1,vtx.z%1);
    D = Vector3(D.x*D.x*(3.0-2.0*D.x),D.y*D.y*(3.0-2.0*D.y),D.z*D.z*(3.0-2.0*D.z));
    var W = I.x + I.y*71.0 + 125.0*I.z;

    return lerps(          
                lerps( lerps(rndng(W+0.0),rndng(W+1.0),D.x) , lerps(rndng(W+71.0),rndng(W+72.0),D.x) , D.y)
                ,
                lerps( lerps(rndng(W+125.0),rndng(W+126.0),D.x) , lerps(rndng(W+153.0),rndng(W+154.0),D.x) , D.y)
                ,
                D.z
                );
}

 //1d ----------------
function lnzo ( vtx: Vector3 ): float //perlin noise, same as unityfunction version
{
    var total = 0.0;  
    for (var i:int = 1; i < 5; i ++)
    {
        total+= lnz2(Vector3 (vtx.x*(i*i),0.0,vtx.z*(i*i)))/(i*i);
    }

    return total*5;

}

 //2d 3 axis  honeycombe noise ----------------
function lnzh ( vtx: Vector3 ): float // perlin noise, 2d, with 3 axes at 60'instead of 2 x y axes
{  
    vtx= Vector3 ( Mathf.Abs(vtx.z) , Mathf.Abs(vtx.z*.5-vtx.x*.866) , Mathf.Abs(vtx.z*.5+vtx.x*.866) ) ;
    var I = Vector3 (Mathf.Floor(vtx.x),Mathf.Floor(vtx.y),Mathf.Floor(vtx.z));
    var D = Vector3(vtx.x%1,vtx.y%1,vtx.z%1);
   //D = Vector3(D.x*D.x*(3.0-2.0*D.x),D.y*D.y*(3.0-2.0*D.y),D.z*D.z*(3.0-2.0*D.z));
    var W = I.x + I.y*71.0 + 125.0*I.z;

    return lerps(          
                lerps( lerps(rndng(W+0.0),rndng(W+1.0),D.x) , lerps(rndng(W+71.0),rndng(W+72.0),D.x) , D.y)
                ,
                lerps( lerps(rndng(W+125.0),rndng(W+126.0),D.x) , lerps(rndng(W+153.0),rndng(W+154.0),D.x) , D.y)
                ,
                D.z
                );
}

 //2d ----------------
function lnz2 ( vtx: Vector3 ): float // i think this is 2d perlin noise
{  
    vtx= Vector3 ( Mathf.Abs(vtx.x) , Mathf.Abs(vtx.y) , Mathf.Abs(vtx.z) ) ;
    var I = Vector3 (Mathf.Floor(vtx.x),Mathf.Floor(vtx.y),Mathf.Floor(vtx.z));
    var D = Vector3(vtx.x%1,vtx.y%1,vtx.z%1);
    D = Vector3(D.x*D.x*(3.0-2.0*D.x),D.y*D.y*(3.0-2.0*D.y),D.z*D.z*(3.0-2.0*D.z));
    var W = I.x + I.y*71.0 + 125.0*I.z;

    return lerps(      
                lerps( lerps(rndng(W+0.0),rndng(W+1.0),D.x) , lerps(rndng(W+71.0),rndng(W+72.0),D.x) , D.z)
                ,
                lerps( rndng(W+125.0), rndng(W+126.0),D.x)
                ,
                D.z
                );                  
}
//这里有一些易于理解的噪声源……三次插值(舍入)中的D线
功能rndng(n:浮动):浮动
{//随机比例-1,1…许多人利用罪来获取
//在伪随机的情况下,exp n*n在中央处理器上的速度更快。
变量e=(n*321.9234)%1;
回报率(e*e*111.07546)%2-1;
}
函数LERP(o:浮点,v:浮点,alpha:浮点):浮点
{
o+=(v-o)*α;
返回o;
}
//三维----------------
函数lnz(vtx:Vector3):浮点//3d柏林噪声代码快速
{  
vtx=Vector3(Mathf.Abs(vtx.x)、Mathf.Abs(vtx.y)、Mathf.Abs(vtx.z));
变量I=矢量3(数学层(vtx.x),数学层(