当前位置:   article > 正文

unity学习之URP多相机以及多通道渲染_unity_initialize_vertex_output_stereo

unity_initialize_vertex_output_stereo

 默认已经创建好一个URP工程,不知道怎么创建可以看这里

  • 摄像机堆叠

  • 摄像机堆叠允许将多个摄像机的结果合成在一起。摄像机堆叠由一个基础 (Base) 摄像机和任意数量的额外叠加 (Overlay) 摄像机组成。当摄像机堆叠中的多个摄像机渲染到同一个渲染目标时,Unity 会为摄像机堆叠中的每个摄像机绘制渲染目标中的每个像素。此外,如果多个基础摄像机或摄像机堆叠渲染到同一渲染目标的同一区域,则 Unity 会再次在重叠区域中绘制所有像素,渲染次数与每个基础摄像机或摄像机堆叠所需的渲染次数相同。

 必须小心操作,确保摄像机的顺序不会导致过度绘制。

URP中有两种类型的摄像机:

  • 基础摄像机(Base Camera)是一种渲染到渲染目标(屏幕或渲染纹理)的通用摄像机。新建URP项目默认的Main Camera就是Base Camera.
  • 叠加摄像机(Overlay Camera)渲染在另一个摄像机的输出之上。基础摄像机的输出可以和一个或多个叠加摄像机的输出结合起来。这种技术称为摄像机堆叠 (Camera stacking)。使用叠加摄像机可以做 分层渲染、渲染层级调整、内景外景融合等等比较实用的功能。
  • 使用摄像机的 Render Type 属性可使摄像机成为基础摄像机或叠加摄像机。

 代码中动态修改摄像机类型

  1. var cameraData = camera.GetUniversalAdditionalCameraData();
  2. cameraData.renderType = CameraRenderType.Base;

使用叠加摄像机: 

 叠加效果:

创景(Scene)中的布局,五辆汽车并没有放在一起,但是在 Game视图中观看的时候,如下图所示:

单独看一下两个相机的视图:

Base:

Overlay:

 必须通过摄像机堆叠系统将叠加摄像机与一个或多个基础摄像机结合使用。不能单独使用叠加摄像机。不在摄像机堆叠中的叠加摄像机不会执行其渲染循环的任何步骤。

可点击Stack下方的+号添加其他的Overlay相机,-号删除,选中上下拖动调整渲染顺序。

  • 多通道渲染

渲染器功能是一种资源,可让您将额外的渲染通道添加到 URP 渲染器并配置其行为。

URP 包含预构建的名为渲染对象 (Render Objects) 的渲染器功能。

下面讲述使用Render Objects 实现上面汽车的描边

在Project窗口选中URP的配置文件UniversalRenderPipelineAsset_Renderer(我用的默认名字),在Inspector创建一个Render Objects.

 创建好需要进行一些设置,这里来两张贴图简单解释一下面板参数:

 我的Layer Mask 选中的是Car这个层,也就是说我当前的Render Objects只针对Car层的物体生效,那么可以看到上面的Game视图中只有前面两辆汽车有描边,其他的车我选的都是默认Default,所以不会被描边。

 Toon_Basic Outline 这个材质引用的是官方demo里面的一段shader代码(选中shader文件右键新建Material 建好的材质会自动引用当前Shader),下面贴的就是:

  1. Shader "Toon/Basic Outline"
  2. {
  3. Properties
  4. {
  5. _OutlineColor ("Outline Color", Color) = (0,0,0,1)
  6. _Outline ("Outline width", Range (.002, 0.09)) = .005
  7. }
  8. SubShader
  9. {
  10. Tags { "RenderType"="Opaque" }
  11. Cull Front
  12. ZWrite On
  13. ColorMask RGB
  14. Blend SrcAlpha OneMinusSrcAlpha
  15. Pass
  16. {
  17. Name "OUTLINE"
  18. HLSLPROGRAM
  19. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
  20. #pragma vertex vert
  21. #pragma fragment frag
  22. #pragma multi_compile_fog
  23. CBUFFER_START(UnityPerMaterial)
  24. float _Outline;
  25. float4 _OutlineColor;
  26. CBUFFER_END
  27. struct Attributes
  28. {
  29. float4 positionOS : POSITION;
  30. float3 normalOS : NORMAL;
  31. UNITY_VERTEX_INPUT_INSTANCE_ID
  32. };
  33. struct Varyings
  34. {
  35. float4 positionCS : SV_POSITION;
  36. half fogCoord : TEXCOORD0;
  37. half4 color : COLOR;
  38. UNITY_VERTEX_OUTPUT_STEREO
  39. };
  40. Varyings vert(Attributes input)
  41. {
  42. Varyings output = (Varyings)0;
  43. UNITY_SETUP_INSTANCE_ID(input);
  44. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
  45. input.positionOS.xyz += input.normalOS.xyz * _Outline;
  46. VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);
  47. output.positionCS = vertexInput.positionCS;
  48. output.color = _OutlineColor;
  49. output.fogCoord = ComputeFogFactor(output.positionCS.z);
  50. return output;
  51. }
  52. half4 frag(Varyings i) : SV_Target
  53. {
  54. i.color.rgb = MixFog(i.color.rgb, i.fogCoord);
  55. return i.color;
  56. }
  57. ENDHLSL
  58. }
  59. }
  60. }

设置好之后,所有被选为Car层的物体都会被描边。(利用Render Objects也可以实现分层渲染、层级调整等等功能,自己去实验一下哦) 

  • 相机输出到纹理

如果有一个摄像机渲染到渲染纹理,必须有另一个摄像机随后将该渲染纹理渲染到屏幕。在 URP 中,所有渲染到渲染纹理的摄像机将在所有渲染到屏幕的摄像机之前执行它们的渲染循环。这样可以确保渲染纹理已准备好渲染到屏幕。

下面讲述使用相机输入纹理做一个倒车镜功能。

如图所示,要做的事情就是让红车在倒车镜中可以看得到黄色的车,话不多说上步骤,首先我们将主相机放到可以观察到红车后视镜的位置(汽车模型是商店找的单面材质,凑合看)

 

 其次新建一个相机,放到合适位置(可以观察到后车)

还需要一个操作,将Camera1输出到纹理。(Project窗口右键Create->Render Texture命名为rearview)在相机Inspector引用纹理。

 接下来要做的事情就是讲这张纹理渲染到屏幕上,如果模型是拆分的,可以直接修改倒车镜材质shader应用到倒车镜模型上。

这边使用另一种方法,通过Image引用纹理来渲染。

最后将建好的Image放到倒车镜的位置,到这里功能就实现了。 

注意:主相机Culling Mask一定要勾选纹理所在的层级

 代码中动态设置

  1. yUniversalAdditionalCameraData.cameraOutput = CameraOutput.Texture;
  2. myCamera.targetTexture = myRenderTexture;

  • 分屏渲染

如果多个基础摄像机或摄像机堆叠渲染到某个渲染目标的同一区域,则 Unity 会多次绘制重叠区域中的每个像素。Unity 最后绘制具有最高优先级的基础摄像机或摄像机堆叠,位于先前绘制的像素之上。

下面讲述实现左右分屏

首先新建两个相机(Camera),在相机的Inspector窗口,修改Output->Viewport Rect 来实现分屏。

相机一:

相机二:

接着在Game视图中查看:

就这么实现了。 当然也可以自己去调整x.y.w.h来实现多宫格分屏。

其次也可以在代码中动态设置分屏

  1. var cameraData = camera.GetUniversalAdditionalCameraData();
  2. cameraData.rect = new Rect(0.5f, 0f, 0.5f, 0f);

完结!

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/101313?site
推荐阅读
相关标签
  

闽ICP备14008679号