12 第1页 | 共2 页下一页
返回列表 发新帖
查看: 5079|回复: 11
打印 上一主题 下一主题

[经验分享] 使用粒子系统来创建景深效果

[复制链接]

1023

主题

3

听众

359

积分

设计实习生

Rank: 2

纳金币
335582
精华
0

最佳新人

跳转到指定楼层
楼主
发表于 2011-10-14 08:28:00 |只看该作者 |倒序浏览


           原标题:“High-Speed, Off-Screen Particles” in Unity
         

           很巧妙的优化替代方案,用粒子系统来制作景深效果,不知实际应用起来如何。
         

           After***nning into fill-rate problems with dust/dirt particles in Raptor Safari we decided to implement High-Speed, Off-Screen Particles, as outlined by
           
            NVIDIA’s GPU Gems 3
           
           . Without getting too technical, the article shows how to render particles into a smaller render target (RenderTexture in Unity) and then blend the particles back into screen. This works well for dust, dirt, and smoke like particles because they have low frequency textures. This low frequency masks the natural “blurring” that occurs from upscaling the smaller render target to the screen’s resolution.
         

           Rendering Depth
         

           First thing we’ll need is a depth buffer. By rendering to a separate render texture we can no longer take advantage of the GPU’s built-in z-testing. Having a depth buffer will allow us to do our own z-testing. Unity made it stupid easy to get a depth buffer of the scene with version 2.6.0. On the main camera***n this line somewhere in Awake:
         
          this.camera.depthTextureMode = DepthTextureMode.Depth;
         
           However, for our purposes the depth buffer given to us by Unity is a bit overkill. Unity will render everything that the main camera can see. We only have dust-like particles near the camera, so there’s no reason for Unity to render depth information at far distances. So instead of taking advantage of Unity’s one-liner solution, we render our own depth buffer with a different far-clip plane. This isn’t as straight forward as setting the camera’s far-clip plane and is slightly outside of this article’s scope. We’ll address this in a future article.
         

           Rendering the Particles
         

           Here comes the hard part. First we’ll outline the steps we need to take to render the particles. All of this happens in the camera’s OnRenderImage function.
         


            Create/Setup the render texture that we will render our particles into
           

            Create/Setup the camera that will render our particles
           

            Render the particles with a replacement shader
           

            Blend the particles back into the screen with a composite shader
           


           First we’ll create and setup the render texture that will hold our particles.
         
          // get the downsample factor
         

          var downsampleFactor:int = this.offScreenParticlesOptions.downsampleFactor;
         

               
         

          // create the off-screen particles texture
         

          var particlesRT:RenderTexture = RenderTexture.GetTemporary(Screen.width / downsampleFactor, Screen.height / downsampleFactor, 0);
         
           The downsampleFactor determines the quality of the off-screen particles. Higher numbers will give worse quality, but better performance.
         

           Next, we’ll create and setup the camera.
         
          var ppCamera:Camera = PostProcessingHelper.GetPPCamera();
         

          ppCamera.depthTextureMode = DepthTextureMode.None;
         

          ppCamera.cullingMask = this.offScreenParticlesOptions.layerMask.value;
         

          ppCamera.targetTexture = particlesRT;
         

          ppCamera.clearFlags = CameraClearFlags.SolidColor;
         

          ppCamera.backgroundColor = Color.black;
         
           And the PostProcessingHelper.GetPPCamera() function:
         
          private static var ppCameraGO:GameObject;
         
           static function GetPPCamera():Camera
           

           {
           

              // Create the shader camera if it doesn’t exist yet
           

              if(!ppCameraGO) {
           

                 ppCameraGO = new GameObject(“Post Processing Camera”, Camera);
           

                 ppCameraGO.camera.enabled = false;
           

                 ppCameraGO.hideFlags = HideFlags.HideAndDontSave;
           

              }
         

              return ppCameraGO.camera;
           

           }
         

           Notice how we are setting the layer that the particles are on. This is how the camera determines which renderers in the scene are the particles that we wish to render off-screen.
         

           Next we render the actual particles. Telling the camera to render is easy enough.
         
          Shader.SetGlobalVector(“
         


           _
         
          CameraDepthTexture
         
           _
         
          Size”, Vector4(this.camera.pixelWidth, this.camera.pixelHeight, 0.0, 0.0)); // some data about the depth buffer we need to send the shaders
         

          depthCamera.RenderWithShader(Shader.Find(“Hidden/Off-Screen Particles Replace”), “RenderType”);
         
           The replacement shader is a bit unwieldy, so here it is as a
           
            file
           
           . Don’t worry too much about what’s going on in the replacement shader. Just make sure to place this shader in a Resources folder.
         

           Lastly, we blend the particles back into the scene.
         
          var blendMaterial:Material = PostProcessingHelper.GetMaterial(Shader.Find(“Hidden/Off-Screen Particles Composite”));
         

          var ***lOffset:Vector2 = Vector2.Scale(source.Get***lOffset(), Vector2(source.width, source.height));
         

          Graphics.BlitMultiTap(particlesRT, source, blendMaterial, ***lOffset);
         
           And the Composite shader (again, place this in a Resources folder):
         
          Shader “Hidden/Off-Screen Particles Composite” {
         

          Properties {
         


           _
         
          MainTex (”Base (RGB)”, RECT) = “white” {}
         

          }
         

          SubShader {
         

          Pass {
         

          ZTest Always Cull Off ZWrite Off Fog { Mode Off }
         

          Blend One SrcAlpha
         

          SetTexture[
         
           _
         
          MainTex] {combine texture}
         

          }
         

          }
         

          Fallback Off
         

          }
         
           Don’t forget to release the particles render texture!
         
          RenderTexture.ReleaseTemporary(particlesRT);
         
           And after you finish doing any other post processing effects you may be doing, output to the destination RenderTexture:
         
          Graphics.Blit(source, destination);
         
           PRETTY PICTURES!
         

           Click for bigger images. These all should be pixel perfect if you want to flip through or diff them.
         




           Off-Screen Particles Disabled
         

            
         




           Off-Screen Particles Enabled
         

            
         




           Off-Screen Particles RGB
         

            
         




           Off-Screen Particles Alpha
         

           Notes
         

           Separate Alpha Blend Function: As of Unity 2.6.1, there is no way to blend alpha channels with a different blending function. So this replacement shader takes two passes on the particles. Once to render to the RGB channel and once to render to the Alpha channel. Apparently, this will be
           
            fixed
           
           in a future release of Unity and the separate pass will not be necessary. I’ll update this replacement shader if someone reminds me when that happens. Update: Looks like this can be accomplished with a single blending function if you premultiply the alpha into the rgb channel in the pixel shader. The new blending function for rendering the particles is One OneMinusSrcAlpha. The new blending function for blending the particle RT back into the screen buffer is One OneMinusSrcAlpha. And your particle RT will need to be cleared to (0,0,0,0) instead of (0,0,0,1).
         

           Mixed Resolution: We decided that mixed resolution particles wasn’t necessary for us. The scene is too fast moving to notice the depth sampling artifacts. Plus the performance overhead from needing a second pass for the alpha channel made mixed resolution rendering just too expensive.
         

           Soft Particles: Soft Particles are extremely easy to implement with the off-screen particles, but we didn’t see much of a difference in the final render. We decided to just use discard instead of soft particles in the end.
         

           Anti-aliasing: This is untested with Anti-aliasing on directx. I really doubt it’ll work correctly as is. Shouldn’t be too difficult to get it to work though.
         
分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖0 收藏收藏0 支持支持0 反对反对0
回复

使用道具 举报

   

671

主题

1

听众

3247

积分

中级设计师

Rank: 5Rank: 5

纳金币
324742
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

沙发
发表于 2012-1-30 23:27:53 |只看该作者
美酒令人回味,音乐让人陶醉,好书百读不悔,情意形影相随,节日问候最可贵。又到年终岁尾,愿你幸福健康作陪,笑得合不拢嘴,预祝春节快乐!
回复

使用道具 举报

1023

主题

3

听众

359

积分

设计实习生

Rank: 2

纳金币
335582
精华
0

最佳新人

板凳
发表于 2012-2-2 23:26:01 |只看该作者
我来顶个
回复

使用道具 举报

5969

主题

1

听众

39万

积分

首席设计师

Rank: 8Rank: 8

纳金币
-1
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

地板
发表于 2012-2-11 23:19:35 |只看该作者
有意思!学习了!
回复

使用道具 举报

1023

主题

3

听众

359

积分

设计实习生

Rank: 2

纳金币
335582
精华
0

最佳新人

5#
发表于 2012-3-31 23:29:41 |只看该作者
不错 非常经典  实用
回复

使用道具 举报

1023

主题

3

听众

359

积分

设计实习生

Rank: 2

纳金币
335582
精华
0

最佳新人

6#
发表于 2012-6-28 23:22:13 |只看该作者
有意思!学习了!
回复

使用道具 举报

tc    

5089

主题

1

听众

33万

积分

首席设计师

Rank: 8Rank: 8

纳金币
-1
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

7#
发表于 2012-6-30 23:19:55 |只看该作者
凡系斑竹滴话要听;凡系朋友滴帖要顶!
回复

使用道具 举报

462

主题

1

听众

31万

积分

首席设计师

Rank: 8Rank: 8

纳金币
2
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

8#
发表于 2012-8-8 23:52:04 |只看该作者
凡系斑竹滴话要听;凡系朋友滴帖要顶!
回复

使用道具 举报

tc    

5089

主题

1

听众

33万

积分

首席设计师

Rank: 8Rank: 8

纳金币
-1
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

9#
发表于 2012-9-10 23:19:08 |只看该作者
水……生命之源……灌……
回复

使用道具 举报

tc    

5089

主题

1

听众

33万

积分

首席设计师

Rank: 8Rank: 8

纳金币
-1
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

10#
发表于 2012-9-19 23:20:11 |只看该作者
既来之,则看之!
回复

使用道具 举报

12 第1页 | 共2 页下一页
返回列表 发新帖
您需要登录后才可以回帖 登录 | 立即注册

手机版|纳金网 ( 闽ICP备2021016425号-2/3

GMT+8, 2025-7-20 23:57 , Processed in 0.068319 second(s), 29 queries .

Powered by Discuz!-创意设计 X2.5

© 2008-2019 Narkii Inc.

回顶部