ComputeShader基础用法系列之三
这节我们看一下ComputeShader最常用的例子:生成噪波纹理。
首先给出参考链接:https://zhuanlan.zhihu.com/p/68507311
以下代码相当于把此文章的噪声纹理计算方法移植到了compute shader中。
CSMain函数如下:
[numthreads(8,8,1)] void CSMain (uint3 id : SV_DispatchThreadID) { float2 uv = id.xy/TEXTURE_WIDTH*NOISE_SCALE; float colorFactor = NoiseGenerate(uv); Result[id.xy] = float4(colorFactor,colorFactor, colorFactor, 1); }
其中,NoiseGenerate中生成的是perlin:
float NoiseGenerate(float2 p) { float2 i = floor(p); float2 f = frac(p); float a = dot(RandomDir(i),f); float b = dot(RandomDir(i+float2(1,0)),f-float2(1,0)); float c = dot(RandomDir(i+float2(0,1)),f-float2(0,1)); float d = dot(RandomDir(i+float2(1,1)),f-float2(1,1)); float2 u = PerlinLerp(f); return lerp(lerp(a,b,u.x),lerp(c,d,u.x),u.y)+0.5; } float2 PerlinLerp(float2 x){ //x = clamp(a,0,1); return 6*pow5(x)-15*pow4(x)+10*pow3(x); }
思路可以看给出的链接,这里只为了展示在ComputeShader中的实现代码(只做了略微修改)。
perlin效果如下:
celluar如下:
float NoiseCellGenerate(float2 p){ float2 i = floor(p); float2 f = frac(p); float F1 = 1.0; for(int j = -1;j<=1;j++) { for(int k = -1;k<=1;k++) { float2 neighbour = float2(j,k); float2 pos = RandomPos(i + neighbour); float d = length(pos + neighbour - f); F1 = min(F1,d); } } return F1; }
celluar效果如下:
fbm代码如下:
float FBM_Noise(float2 p) { float f = 0; float a = 1; for(int i = 0;i<OCTAVE_NUM;i++) { f+=a*NoiseGenerate(p); p *= 4.0; a /= 4.0; } return f; }
fbm效果如下:
Turbulence代码如下:
float Turbulence(float2 p) { float f = 0; float a = 1; p*=4; for(int i = 0;i<OCTAVE_NUM;i++) { f+=a*abs(NoiseGenerate(p)); p *= 4.0; a /= 4.0; } return f; }
效果如下:
DomainWrapping代码如下:
float Domain_Wraping(float2 p) { float fbmP = FBM_Noise(p); float2 q = float2(fbmP,fbmP); float fbmQP = FBM_Noise(q+p); float2 r = float2(fbmQP,fbmQP); return FBM_Noise(p+r); }
效果如下:
强烈建议先看完链接里对于噪波纹理的讲解后再直接使用这些代码。还有很多其他噪波纹理,具体在ComputeShader中的实现模仿以上代码即可。
这节主要是展示一下compute shader的用途,下节具体讲述一下基于ComputeShader的GPU culling。