在上文中,会发现,调用3维柏林实现海水的波动效果,实在是难为CPU了,在这里,我们用着色器Cg语言来把相关计算过程移到GPU,看下效果。

  先说下,原来纹理我们拿来只限于给模型着色,而在现代GPGPU中,有个比较重要的概念就是,纹理就是数组,想想也对,纹理原来我们放的是RGBA值,那么如果我们用来存取一些别的数据,而不是RGBA,在着色器中把纹理里数据取出来,而不是用于给模型着色,那能实现什么样的功能了。

  本文中主要功能都在着色器中,故下面先给出着色器代码,包含原来的noise计算,还有动画与着色,可以对比上文F#代码来看。

  1 //Fragment shader to write color for each pixel
  2 
  3 #define ONE 0.00390625
  4 #define ONEHALF 0.001953125
  5 
  6 float fade(float t) {
  7     //return t*t*(3.0-2.0*t); // Old fade
  8   return t*t*t*(t*(t*6.0-15.0)+10.0);
  9     // Improved fade
 10 }
 11  
 12 float noise(float3 P,sampler2D permTexture)
 13 {
 14     float3 Pi = ONE*floor(P)+ONEHALF;
 15     float3 Pf = P-floor(P);
 16     // Noise contributions from (x=0, y=0), z=0 and z=1
 17   float perm00 = tex2D(permTexture, Pi.xy).a ;
 18     float3  grad000 = tex2D(permTexture, float2(perm00, Pi.z)).rgb * 4.0 - 1.0;
 19     float n000 = dot(grad000, Pf);
 20     float3  grad001 = tex2D(permTexture, float2(perm00, Pi.z + ONE)).rgb * 4.0 - 1.0;
 21     float n001 = dot(grad001, Pf - float3(0.0, 0.0, 1.0));
 22     // Noise contributions from (x=0, y=1), z=0 and z=1
 23   float perm01 = tex2D(permTexture, Pi.xy + float2(0.0, ONE)).a ;
 24     float3  grad010 = tex2D(permTexture, float2(perm01, Pi.z)).rgb * 4.0 - 1.0;
 25     float n010 = dot(grad010, Pf - float3(0.0, 1.0, 0.0));
 26     float3  grad011 = tex2D(permTexture, float2(perm01, Pi.z + ONE)).rgb * 4.0 - 1.0;
 27     float n011 = dot(grad011, Pf - float3(0.0, 1.0, 1.0));
 28     // Noise contributions from (x=1, y=0), z=0 and z=1
 29   float perm10 = tex2D(permTexture, Pi.xy + float2(ONE, 0.0)).a ;
 30     float3  grad100 = tex2D(permTexture, float2(perm10, Pi.z)).rgb * 4.0 - 1.0;
 31     float n100 = dot(grad100, Pf - float3(1.0, 0.0, 0.0));
 32     float3  grad101 = tex2D(permTexture, float2(perm10, Pi.z + ONE)).rgb * 4.0 - 1.0;
 33     float n101 = dot(grad101, Pf - float3(1.0, 0.0, 1.0));
 34     // Noise contributions from (x=1, y=1), z=0 and z=1
 35   float perm11 = tex2D(permTexture, Pi.xy + float2(ONE, ONE)).a ;
 36     float3  grad110 = tex2D(permTexture, float2(perm11, Pi.z)).rgb * 4.0 - 1.0;
 37     float n110 = dot(grad110, Pf - float3(1.0, 1.0, 0.0));
 38     float3  grad111 = tex2D(permTexture, float2(perm11, Pi.z + ONE)).rgb * 4.0 - 1.0;
 39     float n111 = dot(grad111, Pf - float3(1.0, 1.0, 1.0));
 40     // Blend contributions along x
 41   float4 n_x = lerp(float4(n000, n001, n010, n011), float4(n100, n101, n110, n111), fade(Pf.x));
 42     // Blend contributions along y
 43   float2 n_xy = lerp(n_x.xy, n_x.zw, fade(Pf.y));
 44     // Blend contributions along z
 45   float n_xyz = lerp(n_xy.x, n_xy.y, fade(Pf.z));
 46     return n_xyz;
 47 }
 48 
 49 
 50 float turbulence(int octaves, float3 P, float lacunarity, float gain,sampler2D permTexture)
 51 {
 52     float sum = 0;
 53     float scale = 1;
 54     float totalgain = 1;
 55     for(int i=0;i<octaves;i++){
 56         sum += totalgain*noise(P*scale,permTexture);
 57         scale *= lacunarity;
 58         totalgain *= gain;
 59     }
 60 
 61   return abs(sum);
 62 }
 63 
 64 
 65 struct v_Output {
 66     float4 position : POSITION;
 67     float pc : TEXCOORD0;
 68 }
 69 ;
 70 v_Output main(float3 position : POSITION,   
 71                            uniform float4x4 mvp,
 72                            uniform float time,
 73                            uniform sampler2D permTexture)
 74 {
 75     v_Output OUT;
 76     float3 pf = float3(position.xz,time);
 77     //float ty = noise(pf,permTexture);
 78     // 79     //float ty = turbulence(4,pf,2,0.5,permTexture);
 80     //float yy = ty * 0.5 + 0.5;
 81     //
 82     float ty = turbulence(4,pf,0.6,4,permTexture);
 83     float yy = ty * 0.2 + 0.5;
 84     float4 pos = float4(position.x,yy,position.z,1);
 85     OUT.position = mul(mvp,pos);
 86     OUT.pc = yy;
 87     return OUT;
 88 }
 89 
 90 
 91 struct f_Output {
 92     float4 color : COLOR;
 93 }
 94 ;
 95 f_Output fragmentShader(v_Output vin)
 96 {
 97     f_Output OUT;    
 98     // 99     //float3 color1 = float3(0.5*vin.pc, 0.8*vin.pc, 0.9*vin.pc);
100     //
101     float3 color1 = float3(0.98*vin.pc, 0.6*vin.pc, 0.15*vin.pc);
102     OUT.color = float4(color1,1.0);
103     return OUT;
104 }
着色器 三维noise实现动画

相关文章:

  • 2023-03-30
  • 2021-09-25
  • 2022-02-08
  • 2021-04-29
  • 2021-09-20
  • 2021-06-11
  • 2023-03-31
猜你喜欢
  • 2021-09-11
  • 2021-06-13
  • 2021-08-11
  • 2021-11-07
  • 2022-12-23
  • 2022-12-23
  • 2021-11-11
相关资源
相似解决方案