虚幻4渲染编程(程序化纹理篇)【第一卷:UnrealSubstance工具节点搭建---噪波】...

我的专栏目录:

小IVan:专题概述及目录

本篇概述:

程序化纹理有着很多好处,第一可以方便修改,当我们的生成逻辑写好后,想要调整的话就是调调参数的事情。第二就是思路清晰,这张图是怎么来的,逻辑非常清晰,而不是传统的图像绘制,画到哪儿想到哪儿,思维是游走的,离散的。第三我们可以实时生成,可以让纹理和玩家产生互动等等。

现在主流的是用Substance来生成,但是其实引擎也能做,引擎本来就是用来操作这些素材的地方。想看引擎和Substance的对接的话可能你要失望了,对于目前的Substance而言,我个人极力反对目前版本的Substance和引擎直接结合。本章将在引擎里实现各种程序化纹理,不管是离线烘焙也好,还是实时生成也罢。

程序化纹理篇的大概规划是,先把程序化生成需要的节点我们自己全部开发一次,然后把这些工具节点撸好以后在开始用这些工具做纯程序化的纹理(在引擎中)。我们的核心目的是把材质编辑器拓展成引擎内置的“Substance”,像Substance一样能有几何生成,图像转换等功能。当然拓展材质编辑器有很多种办法,不止改引擎一个。

在开始本篇之前最好能熟练使用Substance软件。欢迎各路大神斧正错误。


Substance有很多噪波生成器,下面将从最基础的噪波开始,把Substance有的或者没有的噪波生成节点全部在Unreal种实现。使用噪波的组合,我们能做出很多效果。

要生成一个噪声,我们一般需要三步,第一步是构造随机发生器,第二步是插值,第三步是叠加。

噪声从生成方式上可以分为几种:

(1)white noise

(2)perlin noise

(3)value noise

(4)worley noise

【1】Fast Noise(White Noise)

效果:

v2-51e046a6b761b3b20b8b58ce28ca3ff0_b.jpg

公式代码:

        float RandFast( uint2 PixelPos, float Magic = 3571.0 )
{
	float2 Random2 = ( 1.0 / 4320.0 ) * PixelPos + float2( 0.25, 0.0 );
	float Random = frac( dot( Random2 * Random2, Magic ) );
	Random = frac( Random * Random * (2 * Magic) );
	return Random;
}
      

材质:

v2-fbe7579ecc83e5fcec6af23bc6c3f052_b.jpg

其实为啥这个算法是这样呢,并没有为啥,就是拟合得好所以就这样了。我把这些常用的函数封装到材质函数节点里,以后做程序化纹理的时候就能直接用了。

v2-3cf7e9e4b4faa839dc2c09e9069a2067_b.jpg
v2-3ee20596f1daa66279fc48d53daf110a_b.jpg

后面的很多介绍里的很多这种公用逻辑都会这样做,做完这些只会我们就能建立一个自己的工具库,就像Substance那样。这时有人就要说了,我们不是有noise节点么,为啥还要自己写呢?其实我们应该更多靠自己,我们需要知道原理之后才能根据需求来改进它和精进它,而不是一直拿来主义。

这一步就是只做了构造随机发生器这一步。


【2】Random With Scale(White Noise)

这种是对上面的改进,加入缩放因素,可以让我们做出棋盘格之类的纹理

效果:

v2-51e20fa1b1647d4e5d509cca96d772ca_b.jpg

代码:

        float2 Random(float2 uv)
{
    float Magic = 3571;
    float2 PixelPos = uv * 512;
    float2 Random2 = ( 1.0 / 4320.0 ) * PixelPos + float2( 0.25, 0.0 );
    float Random = frac( dot( Random2 * Random2, Magic ) );
    Random = frac( Random * Random * (2 * Magic) );
    return Random;
}

float main(float2 uv)
{
    return Random(floor(uv * 50));
}
      

材质:

v2-3b376f44ae4f903a52b05887501685e7_b.jpg
v2-9100bb7e94fa10d4303c3508013ac600_b.jpg

【3】Perlin Noise

想要生成柏林噪声,需要做以下几步:

(1)定义晶格,每个晶格的顶点有一个“伪随机”的梯度向量(其实就是个向量啦)。对于二维的Perlin噪声来说,晶格结构就是一个平面网格,三维的就是一个立方体网格。

(2)输入一个点(二维的话就是二维坐标,三维就是三维坐标,n维的就是n个坐标),我们找到和它相邻的那些晶格顶点(二维下有4个,三维下有8个,n维下有 2^{n} 个),计算该点到各个晶格顶点的距离向量,再分别与顶点上的梯度向量做点乘,得到 2^{n} 个点乘结果。

(3)使用缓和曲线来计算它们的权重和。

以二维为例主要代码如下(解释看注释)

        //随机数
float2 hash22(float2 p)
{
    p = float2( dot(p,float2(127.1,311.7)),
              dot(p,float2(269.5,183.3)));

    return -1.0 + 2.0 * frac(sin(p) * 43758.5453123);
}

//构造perlin noise,输入一个点
float perlin_noise(float 2p)
{
    //生成第二步:构建晶格
    float2 pi = floor(p);
    float2 pf = p - pi;
    float2 w = pf * pf * (3.0 - 2.0 * pf);

    //生成第三步:使用缓和曲线
    return lerp(lerp(dot(hash22(pi + float2(0.0, 0.0)), pf - float2(0.0, 0.0)), 
                   dot(hash22(pi + float2(1.0, 0.0)), pf - float2(1.0, 0.0)), w.x), 
               lerp(dot(hash22(pi + float2(0.0, 1.0)), pf - float2(0.0, 1.0)), 
                   dot(hash22(pi + float2(1.0, 1.0)), pf - float2(1.0, 1.0)), w.x),
               w.y);
}
      

把单一的perlin noise进行叠加即可出现很多有趣的效果。下面几个是多层叠加的柏林噪波

效果:

Noise itself

v2-4d6b6189df63d4bcf4c8589429d6a0ea_b.jpg

Noise_Sum

v2-1708299ca9ed9031fb33fb3d1001be03_b.jpg

noise_sum_abs

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值