当前位置:   article > 正文

Unity3d Camera 讲解_unity camera.main

unity camera.main

1. 摄像机组件

照相机是玩家观察世界的装置,屏幕空间点按像素定义,屏幕的左下为(0,0);右上是(pixelwidth,pixelHeight),z位置在照相机的世界单位中。

相机组件

  1. Clear Flags :
  2. 清除标识:确定了屏幕哪些部分将被清除,方便多个摄像机画不同的游戏元素
  3. Background:背景色
  4. Culling Mask:包含或省略要由相机呈现的对象层。在检查器中将图层分配给您的对象。
  5. Projection: 切换相机的功能来模拟透视。
  6. Perspective(透视): 相机将完整地呈现透视物体。拍摄角度为0-180°(最高)
  7. Field of View: 设置为“正交”时,“相机”的视口大小。
  8. Orthographic(正交): 相机将统一渲染对象,没有视角。注:正交模式下不支持延迟渲染。正向渲染总是被使用。
  9. Size:设置为“正交”时,“相机”的视口大小。
  10. Cliping Planes:从相机到开始和停止渲染的距离。
  11. Near :相对于相机的最近点将出现绘图。
  12. Far :相对于相机的最远点将出现绘图。
  13. ViewportRect:视口矩形 四个值指示屏幕上的相机视图将被绘制的位置。在视口坐标中测量(值为0-1)。
  14. Depth:相机的位置按照画图顺序。具有较大值的相机将被绘制在具有较小值的相机之上。
  15. Rendering Path:用于定义相机将使用什么渲染方法的选项
  16. 渲染路径 :定义什么绘制方法被用于相机的选项
  17. Use Graphics Settings 使用玩家设置:在玩家设置(Player Settings.)相机使用哪个渲染路径。
  18. Forward 正向渲染:所有对象每材质渲染只渲染一次,快速渲染
  19. Deferred 延迟照明:所有物体将在无光照的环境渲染一次,然后在渲染队列尾部将物体的光照一起渲染出来。
  20. Legacy Vertex Lit 顶点光照 :所有被这个相机渲染的物体都将渲染成Vertex-Lit物体。
  21. Legacy Deferred : 旧的延迟光照
  22. Target Texture : 目标纹理:渲染纹理 (Render Texture)包含相机视图输出。这会使相机渲染在屏幕上的能力被禁止。可用于实现画中画或者画面特效。
  23. Occlusion Culling : 是否剔除物体背向摄像机的部分
  24. Allow HDR:高动态光照渲染,启动相机高动态范围渲染功能。让场景更真实。
  25. Allow MSAA: 这台相机应该使用MSAA渲染目标吗?如果当前质量设置MSAA级别支持,将只使用MSAA。
  26. Allow Dynamic Resolution:动态分辨率缩放。
  27. 如果相机使用动态分辨率渲染,则为true,否则为false。即使此属性为true,动态分辨率也只能在当前图形设备支持的情况下使用。
  28. Target Display:设置此摄像机的目标显示。
  29. 此设置使摄像机呈现在指定的显示中。显示器(例如监视器)支持的最大数目是8.

Clear Flags

  1. Clear Flags :
  2. 清除标识:确定了屏幕哪些部分将被清除,方便多个摄像机画不同的游戏元素
  3. Skybox :
  4. 天空盒:这是默认设置。屏幕上的任何空的部分将显示当前相机的天空盒。
  5. 如果当前的相机没有设置天空盒,它会默认在渲染设置(Render Settings )选择天空盒
  6. Solid Color :
  7. 纯色,屏幕上的空白部分将显示当前摄像机的背景色
  8. Depth Only
  9. 深度相机,只渲染采集到的画面
  10. 如果你想绘制一个玩家的枪,又不让它内部环境被裁剪,你会设置深度为0的相机绘制环境,
  11. 和另一个深度为1的相机单独绘制武器。武器相机的清除标志(Clear Flags )应设置 为depth only
  12. Don't Clear :
  13. 不清除,此模式不清除颜色或深度缓存。每帧的渲染画面叠加在上一帧画面之上。

Culling Mask

  1. Culling Mask:包含或省略要由相机呈现的对象层。在检查器中将图层分配给您的对象。
  2. Nothing:什么层都不剔除
  3. Everything:什么层都剔除
  4. Default:默认层剔除
  5. TransparentFX:隐形层,系统不会渲染贴图和模型
  6. Ignore Raycast:射线层剔除
  7. Water:水层剔除
  8. UI:UI层剔除

Rendering Path

  1. Rendering Path:用于定义相机将使用什么渲染方法的选项
  2. 渲染路径 :定义什么绘制方法被用于相机的选项
  3. Use Graphics Settings 使用玩家设置:在玩家设置(Player Settings.)相机使用哪个渲染路径。
  4. Forward 正向渲染:所有对象每材质渲染只渲染一次,快速渲染
  5. Deferred 延迟照明:所有物体将在无光照的环境渲染一次,然后在渲染队列尾部将物体的光照一起渲染出来。
  6. Legacy Vertex Lit 顶点光照 :所有被这个相机渲染的物体都将渲染成Vertex-Lit物体。
  7. Legacy Deferred : 旧的延迟光照
  8. Traget Texture 目标纹理:渲染纹理 (Render Texture)包含相机视图输出。
  9. 这会使相机渲染在屏幕上的能力被禁止。可用于实现画中画或者画面特效与
  10. Occlusion Culling : 是否剔除物体背向摄像机的部分
  11. Allow HDR:高动态光照渲染,启动相机高动态范围渲染功能。让场景更真实。
  12. Allow MSAA: 这台相机应该使用MSAA渲染目标吗?如果当前质量设置MSAA级别支持,将只使用MSAA。
  13. Allow Dynamic Resolution:动态分辨率缩放。
  14. 如果相机使用动态分辨率渲染,则为true,否则为false。即使此属性为true,动态分辨率也只能在当前图形设备支持的情况下使用。
  15. Target Display:设置此摄像机的目标显示。
  16. 此设置使摄像机呈现在指定的显示中。显示器(例如监视器)支持的最大数目是8.

2. Camera实例

  • aspect : 获取或者设置Camera视口的宽高比例值。例如:camera.aspect =2.0f,则视口的宽度、高度 = 2.0f,当硬件显示器屏幕的宽度与高度比例不为2.0f时,视图的显示将会发生变形。aspect只处理摄像机camera可以看到的视图的宽高比例,而硬件显示屏的作用只是把摄像机camera看到的内容显示出来,当硬件显示屏的宽高比例与aspect的比例值不同时,视图将发生变形。

  1. using UnityEngine;
  2. public class aspect : MonoBehaviour {
  3. void Start () {
  4. Debug.Log("默认值" + Camera.main.aspect);
  5. }
  6. private void OnGUI()
  7. {
  8. if (GUI.Button(new Rect(10f, 10f, 200f, 45f), "aspect = 1.0"))
  9. {
  10. Camera.main.ResetAspect();
  11. Camera.main.aspect = 1.0f;
  12. }
  13. if (GUI.Button(new Rect(10f, 60f, 200f, 45f), "aspect = 2.0"))
  14. {
  15. Camera.main.ResetAspect();
  16. Camera.main.aspect = 2.0f;
  17. }
  18. if (GUI.Button(new Rect(10f, 110f, 200f, 45f), "aspect = 3.0"))
  19. {
  20. Camera.main.ResetAspect();
  21. Camera.main.aspect = 3.0f;
  22. }
  23. if (GUI.Button(new Rect(10f, 160f, 200f, 45f), "aspect = 0.0"))
  24. {
  25. Camera.main.ResetAspect();
  26. }
  27. }
  28. }
  • cameraToWorldMatrix : 变换矩阵

  1. using UnityEngine;
  2. public class cameratoworldmatrix : MonoBehaviour {
  3. // Use this for initialization
  4. void Start () {
  5. Debug.Log("Camera旋转前位置" + transform.position);
  6. Matrix4x4 m = Camera.main.cameraToWorldMatrix;
  7. // 向量的位置转换为世界坐标中的位置
  8. //v3 的值为沿着Camera局部坐标系的-z轴方向前移5个单位的位置在世界坐标系中的位置
  9. Vector3 v3 = m.MultiplyPoint(Vector3.forward * 5.0f);
  10. //v4 的值为沿着Camera世界坐标系的-z轴方向前移5个单位的位置在世界坐标系中的位置
  11. Vector3 v4 = m.MultiplyPoint(transform.forward * 5.0f);
  12. Debug.Log("旋转前,V3坐标值:"+v3);
  13. Debug.Log("旋转前,V4坐标值:"+v4);
  14. // 将摄像机沿着Y轴正向旋转90度(此时摄像机局部坐标系的z轴方向和世界坐标的X轴方向一致),
  15. transform.Rotate(Vector3.up * 90f);
  16. m = Camera.main.cameraToWorldMatrix;
  17. v3 = m.MultiplyPoint(Vector3.forward * 5.0f);
  18. v4 = m.MultiplyPoint(transform.forward * 5.0f);
  19. Debug.Log("旋转后, v3坐标值"+v3);
  20. Debug.Log("旋转后, v4坐标值"+v4);
  21. }
  22. }
  • CullingMask 按层渲染,此属性用于按层(GameObject.layer)有选择性地渲染场景中的物体。通过cullingMask可以使得当前摄像机有选择性地渲染场景中的部分物体,默认cullingMask =-1即渲染场景中的任何物体,cullingMask = 0时不渲染场景中的任何物体。若只渲染2,3,4,可以使用cullingMask = (1<<2)+ (1<<3)+(1<<4)来进行。

  1. using UnityEngine;
  2. public class cullingMask : MonoBehaviour {
  3. void Start () {
  4. Debug.Log("默认值" + Camera.main.aspect);
  5. }
  6. private void OnGUI()
  7. {
  8. if (GUI.Button(new Rect(10f, 10f, 200f, 45f), "CullingMask = -1"))
  9. {
  10. Camera.main.cullingMask = -1;
  11. }
  12. if (GUI.Button(new Rect(10f, 60f, 200f, 45f), "CullingMask = 0"))
  13. {
  14. Camera.main.cullingMask = 0;
  15. }
  16. if (GUI.Button(new Rect(10f, 110f, 200f, 45f), "aspect = 3.0"))
  17. {
  18. Camera.main.cullingMask =1 << 0;
  19. }
  20. if (GUI.Button(new Rect(10f, 160f, 200f, 45f), "aspect = 1<<8"))
  21. {
  22. Camera.main.cullingMask =1 << 8;
  23. }
  24. //渲染第8层与第0
  25. if (GUI.Button(new Rect(10f, 160f, 200f, 45f), "aspect = 0&&8"))
  26. {
  27. // 注意运算符优先排序
  28. Camera.main.cullingMask =1+1 << 8);
  29. }
  30. }
  31. }
  • eventMask属性:按层响应事件,选择哪个层(layer)的物体可以响应鼠标事件

1.必须满足两个条件:

  • 1.物体在摄像机的视野范围内。
  • 2.在2的layer次方的值与eventMask进行运算(&)后结果仍为2的layer次方的值,如:defalult ,layer值为0,2的0次方=1,如果1与eventMask进行与运算后扔为1,则此物体响应鼠标事件。由于EventMask为奇数时,与1的与运算结果都为1,所以若物体层为defalut并且eventMask为奇数时物体会响应鼠标事件。

2.如果想要多个不同层的物体响应鼠标事件,则需要把所有层的2的layer次方值相加,再与eventMask做与运算。例如,2个物体,layer值分贝为1,3,当event与9进行与运算后结果仍为9,则这两个物体都会响应鼠标事件。

3.此属性有一个特殊情况,但固体layer选择IgnoreRaycast(其为系统内置,值为2)时,无论EventMask值为多少,物体都无法响应鼠标事件。

  1. using UnityEngine;
  2. using System.Collections;
  3. public class EventMask_ts : MonoBehaviour
  4. {
  5. bool is_rotate = false;//控制物体旋转
  6. public Camera c;//指向场景中摄像机
  7. //记录摄像机的eventMask值,可以在程序运行时在Inspector面板中修改其值的大小
  8. public int eventMask_now = -1;
  9. //记录当前物体的层
  10. int layer_now;
  11. int layerTemp;//记录2的layer次方的值
  12. int ad;//记录与运算(&)的结果
  13. string str = null;
  14. void Update()
  15. {
  16. //记录当前对象的层,可以在程序运行时在Inspector面板中选择不同的层
  17. layer_now = gameObject.layer;
  18. //2的layer_now次方的值
  19. layerTemp= (int)Mathf.Pow(2.0f, layer_now);
  20. //与运算(&
  21. ad = eventMask_now & layerTemp;
  22. c.eventMask = eventMask_now;
  23. //is_rotate为true时旋转物体
  24. if (is_rotate)
  25. {
  26. transform.Rotate(Vector3.up * 15.0f * Time.deltaTime);
  27. }
  28. }
  29. //当鼠标左键按下时,物体开始旋转
  30. void OnMouseDown()
  31. {
  32. is_rotate = true;
  33. }
  34. //当鼠标左键抬起时,物体结束旋转
  35. void OnMouseUp()
  36. {
  37. is_rotate = false;
  38. }
  39. void OnGUI()
  40. {
  41. GUI.Label(new Rect(10.0f, 10.0f, 300.0f, 45.0f), "当前对象的layer值为:" + layer_now + " , 2的layer次方的值为" + layerTemp);
  42. GUI.Label(new Rect(10.0f, 60.0f, 300.0f, 45.0f), "当前摄像机eventMask的值为:" + eventMask_now);
  43. GUI.Label(new Rect(10.0f, 110.0f, 500.0f, 45.0f), "根据算法,当eventMask的值与" + layerTemp+ "进行与运算(&)后, 若结果为" + tp + ",则物体相应OnMousexxx方法,否则不响应!");
  44. if (ad == tp)
  45. {
  46. str = " ,所以物体会相应OnMouseDown方法!";
  47. }
  48. else
  49. {
  50. str = " ,所以物体不会相应OnMouseDown方法!";
  51. }
  52. GUI.Label(new Rect(10.0f, 160.0f, 500.0f, 45.0f), "而当前eventMask与" + layerTemp+ "进行与运算(&)的结果为" + ad + str);
  53. }
  54. }
  • LayerCullDistances:层消隐的距离

摄像机可以通过基于层(GameObject.layer)的方式来设置不同层物体的消隐距离,但这个距离必须小于或者等于摄像机的farClipPlane才有效。

  1. public class LayerCullDistances : MonoBehaviour
  2. {
  3. // 拿到要消除的物体
  4. public Transform obj;
  5. void Start()
  6. {
  7. //定义大小为32的一维数组,用来存储所有层的剔除距离
  8. float[] distances = new float[32];
  9. //设置第12层的剔除距离
  10. distances[11] = Vector3.Distance(transform.position,obj.position);
  11. //将数组赋给摄像机的layerCullDistances,首先这个获取的是layer所有的层距离
  12. Camera.main.layerCullDistances = distances;
  13. }
  14. void Update()
  15. {
  16. //摄像机远离物体,会发现设置了蹭的
  17. transform.Translate(transform.right * Time.deltaTime);
  18. }
  19. }
  • layerCullSpherical:基于球面距离剔除

基于球面距离的剔除方式。属性默认为false,即不使用球面剔除,表示只要有一点没有超出物体所在层的远视口平面,物体就是可见的。当设置此属性为True时,只要物体的世界坐标点Position与摄像机的距离大于所在层的剔除距离,物体就不可见。

  1. public class layerCullSpherical : MonoBehaviour
  2. {
  3. public Transform cb1, cb2, cb3;
  4. void Start()
  5. {
  6. //定义大小为32的一维数组,用来存储所有层的剔除距离
  7. float[] distances = new float[32];
  8. //设置第9层的剔除距离
  9. distances[8] = Vector3.Distance(transform.position, cb1.position);
  10. //将数组赋给摄像机的layerCullDistances
  11. Camera.main.layerCullDistances = distances;
  12. //打印出三个物体距离摄像机的距离
  13. Debug.Log("Cube1距离摄像机的距离:" + Vector3.Distance(transform.position, cb1.position));
  14. Debug.Log("Cube2距离摄像机的距离:" + Vector3.Distance(transform.position, cb2.position));
  15. Debug.Log("Cube3距离摄像机的距离:" + Vector3.Distance(transform.position, cb3.position));
  16. }
  17. void OnGUI()
  18. {
  19. //使用球形距离剔除
  20. if (GUI.Button(new Rect(10.0f, 20.0f, 180.0f, 45.0f), "使用球形距离剔除"))
  21. {
  22. Camera.main.layerCullSpherical = true;
  23. }
  24. //取消球形距离剔除
  25. if (GUI.Button(new Rect(10.0f, 70.0f, 180.0f, 45.0f), "取消球形距离剔除"))
  26. {
  27. Camera.main.layerCullSpherical = false;
  28. }
  29. }
  30. }
  • orthographic :摄像机投影模式

用来设置相机投影模式, 模式有两种:正交投影(orthographic),与透视投影模式(perspective)若值为true,正交模式,反之投影模式。正交模式下:物体在视口的代销至于正交视口的大小有关,与摄像机到物体的距离无关,主要呈现2D效果。透视模式下,有远小近大的效果。呈现3D效果

  1. public class orthographic : MonoBehaviour
  2. {
  3. float len = 5.5f;
  4. void OnGUI()
  5. {
  6. if (GUI.Button(new Rect(10.0f, 10.0f, 120.0f, 45.0f), "正交投影"))
  7. {
  8. Camera.main.orthographic = true;
  9. len = 4.5f;
  10. }
  11. if (GUI.Button(new Rect(150.0f, 10.0f, 120.0f, 45.0f), "透视投影"))
  12. {
  13. Camera.main.orthographic = false;
  14. len = 60.0f;
  15. }
  16. if (Camera.main.orthographic)
  17. {
  18. //正交投影模式下,物体没有远大近小的效果,
  19. //orthographicSize的大小无限制,当orthographicSize为负数时视口的内容会颠倒,
  20. //orthographicSize的绝对值为摄像机视口的高度值,即上下两条边之间的距离
  21. len = GUI.HorizontalSlider(new Rect(10.0f, 60.0f, 300.0f, 45.0f), len, -20.0f, 20.0f);
  22. Camera.main.orthographicSize = len;
  23. }
  24. else
  25. {
  26. //透视投影模式下,物体有远大近小的效果,
  27. //fieldOfViewd的取值范围为1.0-179.0
  28. len = GUI.HorizontalSlider(new Rect(10.0f, 60.0f, 300.0f, 45.0f), len, 1.0f, 179.0f);
  29. Camera.main.fieldOfView = len;
  30. }
  31. //实时显示len大小
  32. GUI.Label(new Rect(320.0f, 60.0f, 120.0f, 45.0f), len.ToString());
  33. }
  34. }
  • pixelRect:摄像机渲染区间
    设置Camera被渲染到屏幕中的坐标位置。以实际像素大小来设置显示视口的位置。如下图:A为原始平面大小,B为变换后的视口大小,则X0的值为视口右移的像素大小,Y0的值为视口上移的像素大小,w为Camera.pixelWidth,h的值为Camera.pixelHeight。这里要注意:Screen.width和Screen.height为模拟硬件屏幕的宽高值,不随Camera.pixelWidth和Camera.pixelHeight的改变而改变。

     

    pixelRect

  1. public class PixelRect : MonoBehaviour
  2. {
  3. int which_change = -1;
  4. float temp_x = 0.0f, temp_y = 0.0f;
  5. void Update()
  6. {
  7. //Screen.width和Screen.height为模拟硬件屏幕的宽高值,
  8. //其返回值不随camera.pixelWidth和camera.pixelHeight的改变而改变
  9. Debug.Log("Screen.width:" + Screen.width);
  10. Debug.Log("Screen.height:" + Screen.height);
  11. Debug.Log("pixelWidth:" + Camera.main.pixelWidth);
  12. Debug.Log("pixelHeight:" + Camera.main.pixelHeight);
  13. //通过改变Camera的坐标位置而改变视口的区间
  14. if (which_change == 0)
  15. {
  16. if (Camera.main.pixelWidth > 1.0f)
  17. {
  18. temp_x += Time.deltaTime * 20.0f;
  19. }
  20. //取消以下注释察看平移状况
  21. //if (Camera.main.pixelHeight > 1.0f)
  22. //{
  23. // temp_y += Time.deltaTime * 20.0f;
  24. //}
  25. Camera.main.pixelRect = new Rect(temp_x, temp_y, Camera.main.pixelWidth, Camera.main.pixelHeight);
  26. }
  27. //通过改变Camera的视口宽度和高度来改变视口的区间
  28. else if (which_change == 1)
  29. {
  30. if (Camera.main.pixelWidth > 1.0f)
  31. {
  32. temp_x = Camera.main.pixelWidth - Time.deltaTime * 20.0f;
  33. }
  34. //取消以下注释察看平移状况
  35. //if (camera.pixelHeight > 1.0f)
  36. //{
  37. // temp_y = camera.pixelHeight - Time.deltaTime * 20.0f;
  38. //}
  39. Camera.main.pixelRect = new Rect(0, 0, temp_x, temp_y);
  40. }
  41. }
  42. void OnGUI()
  43. {
  44. if (GUI.Button(new Rect(10.0f, 10.0f, 200.0f, 45.0f), "视口改变方式1"))
  45. {
  46. Camera.main.rect = new Rect(0.0f, 0.0f, 1.0f, 1.0f);
  47. which_change = 0;
  48. temp_x = 0.0f;
  49. temp_y = 0.0f;
  50. }
  51. if (GUI.Button(new Rect(10.0f, 60.0f, 200.0f, 45.0f), "视口改变方式2"))
  52. {
  53. Camera.main.rect = new Rect(0.0f, 0.0f, 1.0f, 1.0f);
  54. which_change = 1;
  55. temp_x = 0.0f;
  56. temp_y = Camera.main.pixelHeight;
  57. }
  58. if (GUI.Button(new Rect(10.0f, 110.0f, 200.0f, 45.0f), "视口还原"))
  59. {
  60. Camera.main.rect = new Rect(0.0f, 0.0f, 1.0f, 1.0f);
  61. which_change = -1;
  62. }
  63. }
  64. }
  • projectionMatrix属性:自定义投影矩阵
    此属性的功能是设置摄像机的自定义投影矩阵。此属性常在一些特效场景下用到,在切换变换矩阵是通常需要先用Camera.ResetProjectionMatrix()重置Camera的变换矩阵。

  1. public class ProjectionMatrix : MonoBehaviour
  2. {
  3. public Transform sp, cb;
  4. public Matrix4x4 originalProjection;
  5. float q=0.1f;//晃动振幅
  6. float p=1.5f;//晃动频率
  7. int which_change = -1;
  8. void Start()
  9. {
  10. //记录原始投影矩阵
  11. originalProjection = Camera.main.projectionMatrix;
  12. }
  13. void Update()
  14. {
  15. sp.RotateAround(cb.position, cb.up, 45.0f * Time.deltaTime);
  16. Matrix4x4 pr = originalProjection;
  17. switch (which_change)
  18. {
  19. case -1:
  20. break;
  21. case 0:
  22. //绕摄像机X轴晃动
  23. pr.m11 += Mathf.Sin(Time.time * p) * q;
  24. break;
  25. case 1:
  26. //绕摄像机Y轴晃动
  27. pr.m01 += Mathf.Sin(Time.time * p) * q;
  28. break;
  29. case 2:
  30. //绕摄像机Z轴晃动
  31. pr.m10 += Mathf.Sin(Time.time * p) * q;
  32. break;
  33. case 3:
  34. //绕摄像机左右移动
  35. pr.m02 += Mathf.Sin(Time.time * p) * q;
  36. break;
  37. case 4:
  38. //摄像机视口放缩运动
  39. pr.m00 += Mathf.Sin(Time.time * p) * q;
  40. break;
  41. }
  42. //设置Camera的变换矩阵
  43. Camera.main.projectionMatrix = pr;
  44. }
  45. void OnGUI()
  46. {
  47. if (GUI.Button(new Rect(10.0f, 10.0f, 200.0f, 45.0f), "绕摄像机X轴晃动"))
  48. {
  49. Camera.main.ResetProjectionMatrix();
  50. which_change = 0;
  51. }
  52. if (GUI.Button(new Rect(10.0f, 60.0f, 200.0f, 45.0f), "绕摄像机Y轴晃动"))
  53. {
  54. Camera.main.ResetProjectionMatrix();
  55. which_change = 1;
  56. }
  57. if (GUI.Button(new Rect(10.0f, 110.0f, 200.0f, 45.0f), "绕摄像机Z轴晃动"))
  58. {
  59. Camera.main.ResetProjectionMatrix();
  60. which_change = 2;
  61. }
  62. if (GUI.Button(new Rect(10.0f, 160.0f, 200.0f, 45.0f), "绕摄像机左右移动"))
  63. {
  64. Camera.main.ResetProjectionMatrix();
  65. which_change = 3;
  66. }
  67. if (GUI.Button(new Rect(10.0f, 210.0f, 200.0f, 45.0f), "视口放缩运动"))
  68. {
  69. Camera.main.ResetProjectionMatrix();
  70. which_change = 4;
  71. }
  72. }
  73. }
  • Rect属性:摄像机视图的位置和大小

  1. public class Rect : MonoBehaviour
  2. {
  3. int which_change = -1;
  4. float temp_x = 0.0f, temp_y = 0.0f;
  5. void Update()
  6. {
  7. //视口平移
  8. if (which_change == 0)
  9. {
  10. if (Camera.main.rect.x < 1.0f)
  11. {
  12. //沿着X轴平移
  13. temp_x = Camera.main.rect.x + Time.deltaTime * 0.2f;
  14. }
  15. //取消下面注释察看平移的变化
  16. //if (camera.rect.y< 1.0f)
  17. //{
  18. //沿着Y轴平移
  19. // temp_y = camera.rect.y + Time.deltaTime * 0.2f;
  20. //}
  21. Camera.main.rect = new Rect(temp_x, temp_y, Camera.main.rect.width, Camera.main.rect.height);
  22. }
  23. //视口放缩
  24. else if (which_change == 1)
  25. {
  26. if (Camera.main.rect.width > 0.0f)
  27. {
  28. //沿着X轴放缩
  29. temp_x = Camera.main.rect.width - Time.deltaTime * 0.2f;
  30. }
  31. if (Camera.main.rect.height > 0.0f)
  32. {
  33. //沿着Y轴放缩
  34. temp_y = Camera.main.rect.height - Time.deltaTime * 0.2f;
  35. }
  36. Camera.main.rect = new Rect(Camera.main.rect.x, Camera.main.rect.y, temp_x, temp_y);
  37. }
  38. }
  39. void OnGUI()
  40. {
  41. if (GUI.Button(new Rect(10.0f, 10.0f, 200.0f, 45.0f), "视口平移"))
  42. {
  43. //重置视口
  44. Camera.main.rect = new Rect(0.0f, 0.0f, 1.0f, 1.0f);
  45. which_change = 0;
  46. temp_y = 0.0f;
  47. }
  48. if (GUI.Button(new Rect(10.0f, 60.0f, 200.0f, 45.0f), "视口放缩"))
  49. {
  50. Camera.main.rect = new Rect(0.0f, 0.0f, 1.0f, 1.0f);
  51. which_change = 1;
  52. }
  53. if (GUI.Button(new Rect(10.0f, 110.0f, 200.0f, 45.0f), "视口还原"))
  54. {
  55. Camera.main.rect = new Rect(0.0f, 0.0f, 1.0f, 1.0f);
  56. which_change = -1;
  57. }
  58. }
  59. }
  • RenderingPath : 渲染路径

     

    RenderingPath

用于获取和设置摄像机渲染路径。Unity中渲染路径RenderingPath为枚举类型
VertexLit:使用顶点光照。最低消耗的渲染路径,不支持实时阴影,适用于移动及老式设备。
forward:使用正向光照,基于着色器的渲染路径。支持逐像素计算光照(包括法线贴图和灯光Cookies)和来自一个平行光的实时阴影。
DeferredLighting:使用延迟光照,支持实时阴影,计算消耗大,对硬件要求高,不支持移动设备,仅专业版可用。

  1. public class renderingPath: MonoBehaviour
  2. {
  3. void OnGUI()
  4. {
  5. if (GUI.Button(new Rect(10.0f, 10.0f, 120.0f, 45.0f), "UsePlayerSettings"))
  6. {
  7. Camera.main.renderingPath = RenderingPath.UsePlayerSettings;
  8. }
  9. if (GUI.Button(new Rect(10.0f, 60.0f, 120.0f, 45.0f), "VertexLit"))
  10. {
  11. Camera.main.renderingPath = RenderingPath.VertexLit;
  12. }
  13. if (GUI.Button(new Rect(10.0f, 110.0f, 120.0f, 45.0f), "Forward"))
  14. {
  15. Camera.main.renderingPath = RenderingPath.Forward;
  16. }
  17. if (GUI.Button(new Rect(10.0f, 160.0f, 120.0f, 45.0f), "DeferredLighting"))
  18. {
  19. Camera.main.renderingPath = RenderingPath.DeferredLighting;
  20. }
  21. }
  22. }
  • WorldToCameramatrix:变换矩阵

返回或设置当前从世界坐标系到当前Camera自身坐标系的变换矩阵。重设矩阵时,摄像机的Transform组件数据不会同步更新。如果想回到Transform的可控状态,需要调用ResetWorldToCameraMatrix方法重置摄像机旋转矩阵。

  1. public class WorldToCameraMatrix : MonoBehaviour
  2. {
  3. public Camera c_test;
  4. void OnGUI()
  5. {
  6. if (GUI.Button(new Rect(10.0f, 10.0f, 200.0f, 45.0f), "更改变换矩阵"))
  7. {
  8. //使用c_test的变换矩阵
  9. Camera.main.worldToCameraMatrix = c_test.worldToCameraMatrix;
  10. //也可使用如下代码实现同样功能
  11. // camera.CopyFrom(c_test);
  12. }
  13. if (GUI.Button(new Rect(10.0f, 60.0f, 200.0f, 45.0f), "重置变换矩阵"))
  14. {
  15. Camera.main.ResetWorldToCameraMatrix();
  16. }
  17. }
  18. }
  • RenderToCubMap:生成Cubemap静态贴图。
  • RenderWithShader:使用其他shader渲染
    使用指定shader来代替当前物体的shader渲染一帧。当replacementTag为空时会替换视口中所有物体的shader

  1. public class RenderWithShader : MonoBehaviour
  2. {
  3. bool is_use = false;
  4. void OnGUI()
  5. {
  6. if (is_use)
  7. {
  8. //使用高光shader:Specular来渲染Camera
  9. Camera.main.RenderWithShader(Shader.Find("Specular"), "RenderType");
  10. }
  11. if (GUI.Button(new Rect(10.0f, 10.0f, 300.0f, 45.0f), "使用RenderWithShader启用高光"))
  12. {
  13. //RenderWithShader每调用一次只渲染一帧,所以不可将其直接放到这儿
  14. //camera.RenderWithShader(Shader.Find("Specular"), "RenderType");
  15. is_use = true;
  16. }
  17. if (GUI.Button(new Rect(10.0f, 60.0f, 300.0f, 45.0f), "使用SetReplacementShader启用高光"))
  18. {
  19. //SetReplacementShader方法用来替换已有shader,调用一次即可
  20. Camera.main.SetReplacementShader(Shader.Find("Specular"), "RenderType");
  21. is_use = false;
  22. }
  23. if (GUI.Button(new Rect(10.0f, 110.0f, 300.0f, 45.0f), "关闭高光"))
  24. {
  25. Camera.main.ResetReplacementShader();
  26. is_use = false;
  27. }
  28. }
  29. }
  • SetReplacementShader 使用指定的shader来替换物体当前的shader,被替换后每一帧都会替换shader来渲染物体,与上面的方法刚好不同。
  • ScreenPointToRay:近视口到屏幕的射线

  1. public class ScreenPointToRay_ts : MonoBehaviour
  2. {
  3. Ray ray;
  4. RaycastHit hit;
  5. Vector3 v3 = new Vector3(Screen.width / 2.0f, Screen.height / 2.0f, 0.0f);
  6. Vector3 hitpoint = Vector3.zero;
  7. void Update()
  8. {
  9. //射线沿着屏幕X轴从左向右循环扫描
  10. v3.x = v3.x >= Screen.width ? 0.0f : v3.x + 1.0f;
  11. //生成射线
  12. ray = Camera.main.ScreenPointToRay(v3);
  13. if (Physics.Raycast(ray, out hit, 100.0f))
  14. {
  15. //绘制线,在Scene视图中可见
  16. Debug.DrawLine(ray.origin, hit.point, Color.green);
  17. //输出射线探测到的物体的名称
  18. Debug.Log("射线探测到的物体名称:" + hit.transform.name);
  19. }
  20. }
  21. }
  • ScreenToViewPortPoint 坐标系转换
    实现坐标点从屏幕坐标系向摄像机视口的单元化坐标系转换。但是是像素

  1. public class ScreenToViewportPoint_ts : MonoBehaviour
  2. {
  3. void Start()
  4. {
  5. transform.position = new Vector3(0.0f, 0.0f, 1.0f);
  6. transform.rotation = Quaternion.identity;
  7. //从屏幕的实际坐标点向视口的单位化比例值转换
  8. Debug.Log("1:" + Camera.main.ScreenToViewportPoint(new Vector3(Screen.width / 2.0f, Screen.height / 2.0f, 100.0f)));
  9. //从视口的单位化比例值向屏幕的实际坐标点转换
  10. Debug.Log("2:" + Camera.main.ViewportToScreenPoint(new Vector3(0.5f, 0.5f, 100.0f)));
  11. Debug.Log("屏幕宽:" + Screen.width + " 屏幕高:" + Screen.height);
  12. }
  13. }
  • ScreenToworldPoint : 坐标系转换,从屏幕坐标系到世界坐标系,实际单位像素组值,而非比例值。

  1. public class ScreenToWorldPoint_ts : MonoBehaviour
  2. {
  3. void Start()
  4. {
  5. transform.position = new Vector3(0.0f, 0.0f, 1.0f);
  6. Camera.main.fieldOfView = 60.0f;
  7. Camera.main.aspect = 16.0f / 10.0f;
  8. //Z轴前方100处对应的屏幕的左下角的世界坐标值
  9. Debug.Log("1:" + Camera.main.ScreenToWorldPoint(new Vector3(0.0f, 0.0f, 100.0f)));
  10. //Z轴前方100处对应的屏幕的中间的世界坐标值
  11. Debug.Log("2:" + Camera.main.ScreenToWorldPoint(new Vector3(Screen.width / 2.0f, Screen.height / 2.0f, 100.0f)));
  12. //Z轴前方100处对应的屏幕的右上角的世界坐标值
  13. Debug.Log("3:" + Camera.main.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, 100.0f)));
  14. }
  15. }
  • ViewPortToWorldpoint 视口坐标点向世界坐标点转换。

此方法的返回值受当前摄像机在世界坐标系的位置Camera的FieldOfView的值以及Position的共同影响

  1. ublic class ViewportToWorldPoint : MonoBehaviour
  2. {
  3. void Start()
  4. {
  5. transform.position = new Vector3(1.0f, 0.0f, 1.0f);
  6. Camera.main.fieldOfView = 60.0f;
  7. Camera.main.aspect = 16.0f / 10.0f;
  8. //屏幕左下角
  9. Debug.Log("1:" + Camera.main.ViewportToWorldPoint(new Vector3(0.0f, 0.0f, 100.0f)));
  10. //屏幕中间
  11. Debug.Log("2:" + Camera.main.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, 100.0f)));
  12. //屏幕右上角
  13. Debug.Log("3:" + Camera.main.ViewportToWorldPoint(new Vector3(1.0f, 1.0f, 100.0f)));
  14. }
  15. }
  • WorldToScreenPoint:世界坐标转成屏幕坐标。

  1. public class WorldToScreenPoint : MonoBehaviour
  2. {
  3. public Transform cb, sp;
  4. public Texture2D t2;
  5. Vector3 v3 = Vector3.zero;
  6. float sg;
  7. void Start()
  8. {
  9. //记录屏幕高度
  10. sg = Screen.height;
  11. }
  12. void Update()
  13. {
  14. //sp绕着cb的Y轴旋转
  15. sp.RotateAround(cb.position, cb.up, 30.0f * Time.deltaTime);
  16. //获取sp在屏幕上的坐标点
  17. v3 = Camera.main.WorldToScreenPoint(sp.position);
  18. }
  19. void OnGUI()
  20. {
  21. //绘制纹理
  22. GUI.DrawTexture(new Rect(0.0f, sg - v3.y, v3.x, sg), t2);
  23. }
  24. }
  • WorldToViewPoint:从世界坐标转换屏幕单位化坐标中。

  1. public class WorldToViewportPoint : MonoBehaviour
  2. {
  3. public Transform cb, sp;
  4. public Texture2D t2;
  5. Vector3 v3 = Vector3.zero;
  6. float sw, sh;
  7. void Start()
  8. {
  9. //记录屏幕的宽度和高度
  10. sw = Screen.width;
  11. sh = Screen.height;
  12. }
  13. void Update()
  14. {
  15. //物体sp始终绕cb的Y轴旋转
  16. sp.RotateAround(cb.position, cb.up, 30.0f * Time.deltaTime);
  17. //记录sp映射到屏幕上的比例值
  18. v3 = Camera.main.WorldToViewportPoint(sp.position);
  19. }
  20. void OnGUI()
  21. {
  22. //绘制纹理,由于方法WorldToViewportPoint的返回值的y分量是从屏幕下方向上方递增的,
  23. //所以需要先计算1.0f - v3.y的值,然后再和sh相乘。
  24. GUI.DrawTexture(new Rect(0.0f, sh * (1.0f - v3.y), sw * v3.x, sh), t2);
  25. }
  26. }
  • SetTargetBuffers:重设摄像机到TargetTexture的渲染

SetTargetBuffers(RenderBuffer colorBuffer,RenderBuffer depthBuffer)其中参数ColorBuffer为纹理颜色缓存,depthBuffer为纹理的深度缓存。

SetTargetBuffers(RenderBuffer [] colorBuffer,RenderBuffer depthBuffer)其中参数ColorBuffer为纹理颜色缓存,depthBuffer为纹理的深度缓存,这个方法可以将摄像机的渲染一次赋给多个colorBuffer.

  1. public class SetTargetBuffers : MonoBehaviour
  2. {
  3. //声明两个RendererTexture变量
  4. public RenderTexture RT_1, RT_2;
  5. public Camera c;//指定Camera
  6. void OnGUI()
  7. {
  8. //设置RT_1的buffer为摄像机c的渲染
  9. if (GUI.Button(new Rect(10.0f, 10.0f, 180.0f, 45.0f), "set target buffers"))
  10. {
  11. c.SetTargetBuffers(RT_1.colorBuffer, RT_1.depthBuffer);
  12. }
  13. //设置RT_2的buffer为摄像机c的渲染,此时RT_1的buffer变为场景中Camera1的渲染
  14. if (GUI.Button(new Rect(10.0f, 60.0f, 180.0f, 45.0f), "Reset target buffers"))
  15. {
  16. c.SetTargetBuffers(RT_2.colorBuffer, RT_2.depthBuffer);
  17. }
  18. }
  19. }



作者:雷潮
链接:https://www.jianshu.com/p/547ef7f4a313
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/127617
推荐阅读
相关标签
  

闽ICP备14008679号