skydome.fx
上传用户:henghua
上传日期:2007-11-14
资源大小:7655k
文件大小:3k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. float4x4 mViewProj;
  2. float4x4 mInvViewProj;
  3. float4x4 mInvView;
  4. float4 view_position;
  5. float sun_alfa, sun_theta, sun_shininess, sun_strength;
  6. float intensity;
  7. float2 newuv;
  8. float4 skyinfo = float4(0.5, 0.7, 0.9, 0.15);
  9. float radius = 5000;
  10. float t ;
  11. float cloudiness = 1;
  12. float night_day;
  13. float fog;
  14. struct VS_INPUT
  15. {
  16.     float3  Pos      : POSITION;//顶点坐标
  17. };
  18. struct VS_OUTPUT
  19. {
  20.     float4  Pos     : POSITION;//顶点的投影坐标
  21. float2 v : TEXCOORD1;//云的纹理采样坐标
  22. float3  sun : TEXCOORD2;//太阳的位置
  23. float3  vvv : TEXCOORD4;//保存顶点坐标的变量
  24. };
  25. //云的纹理
  26. texture Clouds;
  27. //纹理采样器
  28. sampler2D clouds = sampler_state
  29. {
  30. texture = <Clouds>;
  31. MinFilter = LINEAR;
  32. MagFilter = LINEAR;
  33. AddressU = WRAP;
  34. AddressV = WRAP;
  35. };
  36. VS_OUTPUT VShader(VS_INPUT i)
  37. {
  38.     VS_OUTPUT   o;    
  39.        
  40.     //保存顶点坐标以在像素着色器中用以计算太阳的色彩
  41. o.vvv = i.Pos ;
  42. o.Pos = mul(float4(radius*(i.Pos - float3(0, 0, 0)),1), mViewProj);
  43. //计算云的纹理坐标
  44. newuv.x = (acos(i.Pos.x) * 1.0 + 1.0 ) / 2;
  45. newuv.y = (acos(i.Pos.z) * 1.0 + 1.0 ) / 2;
  46. newuv.xy *= 1.5;
  47. //令云的纹理坐标随时间变化以使云达到运动的效果
  48. o.v.x = newuv.x + t * 0.266;
  49. o.v.y = newuv.y + t * 0.033;
  50. //对太阳高度角进行变换以实现太阳升落的效果
  51. sun_theta = sun_theta * abs(night_day * 2 - 1) - 0.1;
  52. //计算太阳的位置
  53. o.sun.y = sin(sun_theta);
  54. o.sun.x = cos(sun_theta)*sin(sun_alfa);
  55. o.sun.z = cos(sun_theta)*cos(sun_alfa);
  56. //白天和黑夜时分别让太阳(月亮)在不同的位置(相对)
  57. if(night_day < 0.5)
  58. {
  59. o.sun.x = -o.sun.x;
  60. o.sun.z = -o.sun.z;
  61. }
  62. return o;
  63. }
  64. float4 PShader(VS_OUTPUT i) : COLOR
  65. {
  66.     float3 sunlight;
  67.     float4 ut;
  68. //判断当前点是否在海面以下,若是则不计算
  69. if(i.vvv.y < -1)
  70. ut.rgba = 0;
  71. else
  72. {
  73. //计算当前处理的顶点的太阳的色彩
  74. //为太阳月亮赋予不同色彩
  75. if(night_day > 0.5)
  76. sunlight = (sun_strength*pow(saturate(dot(normalize(i.vvv), i.sun)),sun_shininess)*float3(1.0, 0.4, 0.1)) * night_day;
  77. else
  78. sunlight = (sun_strength*pow(saturate(dot(normalize(i.vvv), i.sun)),sun_shininess)*float3(0.7, 0.7, 0.8)) * (1 - night_day);
  79. //读取云的纹理
  80. float4 noise1 = tex2D(clouds, float2(i.v.x, i.v.y));
  81. //计算云的色彩
  82. intensity = 0.65;
  83. float4 cloudFrag = noise1 * intensity;
  84. float4 cloudColor = float4((1.0 - intensity)*skyinfo.x, (1.0 - intensity)*skyinfo.y,intensity*skyinfo.z, 0.0);
  85. cloudColor = cloudColor * (1 - 0.9 * cloudiness) + float4(0.9, 0.9, 0.9, 1) * 0.7 *cloudiness;
  86. ut.a = 1;
  87. float night_day_sqr = night_day * night_day ;
  88. //计算天空色彩
  89. ut = (
  90. ( cloudColor * (1.0 - cloudFrag.x ) + cloudFrag ) //* ( 1 - cloudiness ) 
  91. )  * night_day_sqr * pow(i.vvv.y , 1.5)
  92.  + (1 - pow(i.vvv.y, 1.5) ) * float4(0.8, 0.8, 0.9, 1) * night_day_sqr * fog 
  93. + float4(sunlight, 1) ;
  94. }
  95. return ut;
  96. }
  97. technique T0
  98. {
  99.     pass P0
  100.     {        
  101.         pixelshader = compile ps_2_0 PShader();
  102. vertexshader = compile vs_1_1 VShader(); 
  103.     }
  104. }