您的位置:首页 > 其它

3D图形学一:模仿草的运动 – GPU(Pixel Shader & Vertex Shader)实现

2006-06-27 14:26 761 查看
模仿草的运动 – GPUPixel Shader & Vertex Shader)实现

 

介绍
       随着硬件的不断更新模仿草的运动不在需要循环播放一个重复的动画了,GPU的强大性能使得模仿更真实的草的运动得以实现。所以(^_^ )下面介绍做一模仿草的运动的Demo。

 

原理


     
1.泰勒级数的定义
  


                    图1:泰勒级数公式

 
             


2.    泰勒级数在幂级数展开中的应用:
    


                      图2:泰勒级数在幂级数中的展开
     
3.    波动:

       草的波浪起伏运动用一个Vertex Shader完成。草片纹理是一个四方行(如图2),草的渲染可以通过随机放置交叉的草片纹理。对草片纹理通过Alpha测试(Alpha Test)处理让草片纹理上面黑色部分象素不能通过。草的运动通过给草片纹理所贴的四边形上面两点混合四个正弦波(Sinusoidal),正弦波通过泰勒级数来逼近(泰勒级数如图1、泰勒级数展开如图2),用不同频率产生混合正弦波所形成的草的自然波就不像固定动画那样死板。

 


图2:草片纹理
           

4.    光照模型

       草片纹理在风中飘动,它将会改变方向,随着太阳产生不同的颜色,面向太阳时草片的颜色比背向太阳时草片的颜色会亮一些。本例是通过一个草片纹理产生不同方向和位置的草片,所以不可能通过改变单个草片的光照来改变整个场景的草的颜色。而草片颜色的改变是发生在草片的运动过程中,所以可以通过正弦波来产生颜色,同一个正弦波根据光照方向可以产生两个颜色,通过改变绿通道的颜色使得草片颜色在微黄色和褐色之间变更(如图3、4)。

 



                 
图3:面向太阳的微黄色的草

 

 




 
                    图4:背向太阳的褐色的草

 

 

实现



1.  Vertex Shader

 Sinusoidal vertex motion for waving grass

 pos + sumOverI(wavedirI * texcoordy * sin( xdirI * (xpos+time)) + ydirI * (ypos+time)))

  v0 - Vertex Position

  v7 - Vertex Texture Data u,v

  c0 - commonConst ( 0.0, 0.5, 1.0, 2.0);

  c1 - appConst( time, 0.0, 0.0, 0.0);

  c4 - Composite World-View-Projection Matrix

  c8 - sin9 ( -1/3!, 1/5!, -1/7!, 1/9! )

 c10 - frcFixup ( 1.07, 0.0, 0.0, 0.0)

 c11 - waveDistortx ( 3.0, 0.4, 0.0, 0.3)

 c12 - waveDistorty ( 3.0, 0.4, 0.0, 0.3)

 c13 - waveDistortz ( -1.0, -0.133, -0.333, -0.10)

 c14 - waveDirx ( -0.006, -0.012, 0.024, 0.048)

 c15 - waveDiry ( -0.003, -0.006, -0.012, -0.048)

 c16 - waveSpeed ( 0.3, 0.6, 0.7, 1.4)

 c17 - piVector (4.0, pi/2, pi, pi*2)

 c18 - lightingWaveScale ( 0.35, 0.10, 0.10, 0.03);

 c19 - lightingScaleBias ( 0.6, 0.7, 0.2, 0.0);

 

// vs.2.x for grass

vs_2_x
   

dcl_position v0

dcl_texcoord v7

 

mul r0, c14, v0.x      // use vertex pos x as inputs to sinusoidal warp

mad r0, c15, v0.y, r0  // use vertex pos y as inputs to sinusoidal warp

 

mov r1, c1.x           // get current time

mad r0, r1, c16, r0    // add scaled time to move bumps according to speed

frc r0.xy, r0          // take frac of all 4 components

frc r1.xy, r0.zwzw     //

mov r0.zw, r1.xyxy     //

  

mul r0, r0, c10.x      // multiply by fixup factor (due to inaccuracy of taylor series)

sub r0, r0, c0.y       // subtract 0.5

mul r1, r0, c17.w      // r0 *= 2pi coords range from(-pi to pi)

 

mul r2, r1, r1         // (wave vec)^2

mul r3, r2, r1         // (wave vec)^3

mul r5, r3, r2         // (wave vec)^5

mul r7, r5, r2         // (wave vec)^7

mul r9, r7, r2         // (wave vec)^9

  

mad r0, r3, c8.x, r1   // (wave vec) - ((wave vec)^3)/3!

mad r0, r5, c8.y, r0   //  + ((wave vec)^5)/5!

mad r0, r7, c8.z, r0   //  - ((wave vec)^7)/7!

mad r0, r9, c8.w, r0   //  + ((wave vec)^9)/9!

 

dp4 r3.x,  r0, c11

dp4 r3.y,  r0, c12

dp4 r3.zw, r0, c13

 

sub r4, c0.z, v7.y

mul r4, r4, r4      

mul r3, r3, r4         // attenuate sinusoidal warping by (1-tex0.y)^2 

 

mov r2.w, v0

add r2.xyz, r3, v0     // add sinusoidal warping to grass position

 

m4x4 oPos, r2, c4

dp4  r1.x, r0, c18     // scale and add sin waves together
 
mad  oD0, c19.xzxz, -r1.x, c19.y
  

mov  oT0, v7           // scale and bias color values (green is scaled more than red and blue)
        

 

此段代码是用于渲染地面,如用上面的代码,那么地面也会跟着波动。
// vs.2.x for ground

vs_2_x
     

dcl_position v0

dcl_texcoord v7

 

m4x4 oPos, v0, c4
mov  oT0, v7

 

mov  r0, c20
add  oD0, r0, c21

 

2.  Pixel Shader
// ps.1.4 for grass

ps_1_4

 

texld  r0, t0
  

mul_x2 r0, r0, v0
 
感觉现在ps.3.x都出来了(虽然我的机器不支持),而我还用ps.1.4有点落后了,所以今天用ps.2.x重写了ps的渲染代码。
// ps.2.x for grass

ps_2_x
 

dcl_2d s0

dcl t0

dcl v0

 

texld r0, t0, s0

 

mul r0, r0, v0

add r0, r0, r0

 

mov oC0, r0

 
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐