Unity Shader 基础(2) Image Effect
Unity中 Image Effect 是Post Processing的一种方,Unity自身也提供很多Effect效果供使用。Image Effect的使用官方文档做了很多介绍,这里重点Post Processing 做一些介绍。
1. Post Processing workflow
- Render the scene to a render target / texture (screen-size, usually same format)
- Reset render target - either to another render target / texture or the actual backbuffer
- Set the pixel shader for post-processing, bind the scene texture to a sampler
- Draw a full-screen quad over the scene using a dummy vertex shader
具体可以参考文章:https://research.ncl.ac.uk/game/mastersdegree/graphicsforgames/postprocessing/Tutorial 10 - Post Processing.pdf,里面也提及到多个Image Effect串联在一起是如何实现的。
在使用中,Effect Shader的Shader中其实是处理和近剪裁面大小的四边形面板,渲染这个四边形的贴图是当前Color Buffer中的数据。 实际Pixel Shader中主要是每个像素或者一个区域进行各种处理。
2. Image Effect
涉及的方法:
- OnRenderImage
- Graphics.Blit
- Graphics.SetRenderTarget
**OnRenderImage **
‘OnRenderImage’ function receives two arguments: source image as a RenderTexture and destination it should render into, as a render texture as well. Typically a postprocessing effect uses Shaders that read the source image, do some calculations on it, and render the result into the provided destination (e.g using Graphics.Blit). It is expected that the image effect will fully replace all pixels of the destination texture.
多个效果
When multiple postprocessing effects are added on the camera, they are executed in the order they are shown in the inspector, topmost effect being rendered first. Result of one effect is passed as “source image” to the next one; and internally Unity creates one or more temporary render textures to keep these intermediate results in.
在Unity5.5之后加入了新的管理方式:https://github.com/Unity-Technologies/PostProcessing
需要注意:
Destination render texture can be null, which means “render to screen” (i.e. the backbuffer). This typically happens on the last image postprocessing effect on a camera.
When OnRenderImage finishes, it is expected that the destination render texture is the active render target. That is, generally a Graphics.Blit or manual rendering into destination texture should be the last rendering operation.
You generally want to turn off depth buffer writes and tests in your image effect shaders – otherwise can end up writing unintended values into destination Z buffer when doing Graphics.Blit. Almost all image effect shader passes should contain Cull Off ZWrite Off ZTest Always states.
If you wish to use stencil or depth buffer values from the original scene render, you should explicitly bind the depth buffer from the original scene render as your depth target. This can be done using Graphics.SetRenderTarget. You should pass the very first source image effects depth buffer as the depth buffer to bind.
渲染顺序
By default, an image effect is executed after whole scene is rendered. In some cases however, it is desirable to render an effect after all opaque objects are done (but before skybox or transparencies are rendered). Often depth-based effects like Depth of Field use this.
Adding an ImageEffectOpaque attribute on the OnRenderImage function allows to achieve that.
平台差异
主要是DirextX和OpenGl坐标方向问题个
https://docs.unity3d.com/550/Documentation/Manual/SL-PlatformDifferences.html
参考:
官方文档: https://docs.unity3d.com/550/Documentation/Manual/WritingImageEffects.html