收藏 分销(赏)

HLSL实现雾.doc

上传人:xrp****65 文档编号:7452041 上传时间:2025-01-05 格式:DOC 页数:14 大小:56KB
下载 相关 举报
HLSL实现雾.doc_第1页
第1页 / 共14页
HLSL实现雾.doc_第2页
第2页 / 共14页
点击查看更多>>
资源描述
这个问题通过图片来解答再合适不过了,下面是本文利用layerFog做的一个结果。 所谓layer fog,顾名思义就是被限制在某一层的雾,本文的目的就是描述如何实现了被限制在一定高度范围内的雾效。 1         Thanks to Programmable Pipeline 雾效增强场景真实感也不是一天半天了,但无论opengl还是d3d,无论linear(线性衰减)、exp(指数衰减)还是exp2(指数平方衰减),以往实现的雾效都是全局的,要么就都加雾效,要么都不加。在固定渲染流水线的统治时代,想做到“山谷烟雾弥漫,峰顶明月清风”是相当复杂而啰嗦的事。 感谢那些大牛公司和它们的图形精英,他们在享受创造的乐趣之余,想到了我们,给了我们参与创作的机会。可编程流水线的出现,让我们在做类似layer fog这类事情的时候可以直奔主题。 闲话少说,本文不介绍Programmable Pipeline,也不介绍vs,ps,HLSL和effect,相关知识可以参考Directx9 SDK,下面来开始介绍Layer fog。 1         Theory 我们知道雾效最终体现在一个颜色的融合因子上,根据这个融合因子的大小,可以确定雾化程度,如果融合因子为factor,雾的颜色为fogColor,场景点本身的颜色为sceneColor则最终雾化后的颜色finalColor应为:        finalColor = sceneColor+factor*(fogColor-sceneColor)                (0<=factor<=1)     该融合因子体现了颜色混合中雾的权重,假设雾的浓度函数为fuction(x,y,z), 以视线进入雾层为起点fStart,实现离开雾层(或到达场景物体表面)为结束点fEnd,则factor实际上是function(x,y,z)在从fStart到fEnd这段路径上的积分,如下: 本文的重点是描述layer fog的实现思想,所以采用了最简单的雾效方程,认为在雾层范围内,雾的浓度保持常数不变。则公式变为: distance(fStart,fEnd)是求两点之间距离的函数,在实际计算中,雾层定义在Y方向,此式往往可用以下公式表示 其中abs函数是取绝对值函数,θ角是射线与XOZ平面的夹角。 下面针对具体情况进行说明。     如图所示,layerFog有雾顶(y坐标为fFogTop),雾底(fFogEnd),雾在fFogEnd和fFogTop之间存在,需要保证fFogTop>fFogEnd。 由于layerfog的照相机位置存在三种情况 l         Camera.y>fFogTop l         fFogEnd<Camera.y<fFogTop l         fFogEnd<Camera.y 场景点ScenePoint位置也存在三种情况 l         ScenePoint.y>fFogTop l         fFogEnd< ScenePoint.y<fFogTop l         fFogEnd< ScenePoint.y 所以,实际上共有9种组合情况,每种的处理方法有所不同,实际上说白了就一句话“合法范围内积分,超出雾层范围之外不进行积分“,本着这个原则针对每种情况的不同确定积分上下限。 1 Code 本文采用Effect实现该算法,其主要代码如下:   texture g_MeshTexture;              // 纹理   float4x4 g_matWorld;                  // 物体的世界变换矩阵,由应用程序输入 float4x4 g_matWorldViewProj;    // World * View * Projection matrix,由应用程序输入 float4   g_FogParameter;//.x=fogHeight   .y = fogEnd  .z = fogRange,由应用程序输入 float4   g_vCamera;      //摄像机位置,由应用程序输入 float4   g_FogColor;     //雾颜色,由应用程序输入   //-------------------------------------------------------------------------------------- // 纹理采样器 //-------------------------------------------------------------------------------------- sampler MeshTextureSampler = sampler_state {     Texture = <g_MeshTexture>;     MipFilter = LINEAR;     MinFilter = LINEAR;     MagFilter = LINEAR; };     //-------------------------------------------------------------------------------------- // 顶点着色器输入结构体 //--------------------------------------------------------------------------------------   struct VS_INPUT {     float4 Position   : POSITION;   // 顶点位置     float4 Diffuse    : COLOR0;     // 顶点颜色     float2 TextureUV  : TEXCOORD0;  // 纹理坐标 }; //-------------------------------------------------------------------------------------- // 顶点着色器输出结构体 //--------------------------------------------------------------------------------------   struct VS_OUTPUT {     float4 Position   : POSITION;   // 顶点位置     float2 TextureUV  : TEXCOORD0;  // 纹理坐标      float4 FogVal     : COLOR0;      //雾化因子,仅使用x分量 };   //-------------------------------------------------------------------------------------- // 顶点着色器处理程序 //-------------------------------------------------------------------------------------- VS_OUTPUT RenderSceneVS( const VS_INPUT Input) {          float4 clpPos, camPos, worldPos;          float fDistance;                   // 初始化输出          VS_OUTPUT ut = (VS_OUTPUT) 0;                   // 计算顶点剪切空间的坐标          clpPos = mul(Input.Position, g_matWorldViewProj);          Out.Position = clpPos;                   // 输出纹理坐标          Out.TextureUV.xy = Input.TextureUV.xy;                   // 获得雾化参数          float fFogTop   = g_FogParameter.x;          float fFogEnd   = g_FogParameter.y;          float fFogRange = g_FogParameter.z;                            // 计算顶点在世界坐标系中的位置          worldPos = mul(Input.Position, g_matWorld);                   // 计算顶点和观测者之间的位置          fDistance = distance(worldPos, g_vCamera);                   // factor = 1/sinθ * fDensityFog ,其中fDensityFog = 1/fFogRange;          // 该值就是最后与deltaY相乘的系数,在一起计算,可以节省一次除法运算。                   float factor =fDistance/(fFogRange*(worldPos.y - g_vCamera.y));                 //fDeltaY 是经过雾层的线段在Y方向的距离,下面是分情况却定fDeltaY的代码           float fDeltaY ;          if(g_vCamera.y > fFogTop)               {                             if (worldPos.y > fFogTop) //                             {                                  fDeltaY = 0.0f;                             }                             else                             {                                  if( worldPos.y > fFogEnd)//fFogEnd< worldPos.y <fFogTop                                  {                                      fDeltaY = fFogTop - worldPos.y;                                  }                                  else                      //worldPos.y< fFogEnd                                  {                                      fDeltaY = fFogTop - fFogEnd;                                  }                             }               }               else               {                        if( g_vCamera.y > fFogEnd)                        {                                      if (worldPos.y > fFogTop)                                      {                                                                                     fDeltaY =fFogTop - g_vCamera.y;                                      }                                      else                                      {                                           if( worldPos.y > fFogEnd)//fFogEnd< worldPos.y <fFogTop                                           {                                                fDeltaY = worldPos.y - g_vCamera.y;                                           }                                           else                        //worldPos.y< fFogEnd                                           {                                                fDeltaY = fFogEnd -g_vCamera.y;                                           }                                      }                        }                        else//g_vCamera.y < fFogEnd                        {                                  if (worldPos.y > fFogTop)                                      {                                           fDeltaY = fFogTop - fFogEnd;                                      }                                      else                                      {                                           if( worldPos.y > fFogEnd) //fFogEnd< worldPos.y <fFogTop                                           {                                                fDeltaY =  worldPos.y - fFogEnd;                                             }                                           else                     //worldPos.y< fFogEnd                                           {                                                fDeltaY = 0.0f;                                           }                                      }                        }               }          Out.FogVal.x = abs(factor*fDeltaY);          return Out; }     //-------------------------------------------------------------------------------------- // 象素着色器输出结构体 //-------------------------------------------------------------------------------------- struct PS_OUTPUT {     float4 RGBColor : COLOR0;  // 象素颜色  }; struct PS_IUTPUT {     float2 TextureUV  : TEXCOORD0;  // 顶点纹理坐标     float4  FogVal    : COLOR0;      //雾化系数 }; //-------------------------------------------------------------------------------------- // This shader outputs the pixel's color by modulating the texture's //       color with diffuse material color //-------------------------------------------------------------------------------------- PS_OUTPUT RenderScenePS( const PS_IUTPUT In) {   PS_OUTPUT Output;     //获得纹理颜色   Output.RGBColor = tex2D(MeshTextureSampler, In.TextureUV);     //颜色混合   float f = In.FogVal.x;   Output.RGBColor = lerp(Output.RGBColor,g_FogColor,f);   return Output; }
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传
相似文档                                   自信AI助手自信AI助手

当前位置:首页 > 应用文书 > 其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:4009-655-100  投诉/维权电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服