public static bool BoundSpereInCamera_UseMVP(SoftSpere spere, SoftCamera camera) { Vector3 localPt = camera.WorldToViewportPoint(spere.position, false); float left = localPt.x - spere.radius; float right = localPt.x + spere.radius; if (right <= -1 || left >= 1) { return(false); } float top = localPt.y + spere.radius; float bottom = localPt.y - spere.radius; if (bottom >= 1 || top <= -1) { return(false); } float front = localPt.z + spere.radius; float back = localPt.z - spere.radius; if (back >= 1 || front <= -1) { return(false); } return(true); }
// 判断是否需要Cull(这里是世界坐标剔除) public static bool IsCulled(SoftCamera camera, CullMode mode, Triangle tri) { if (mode == CullMode.none) { return(false); } if (camera == null) { return(true); } Vector3 v1 = tri.p3 - tri.p2; Vector3 v2 = tri.p2 - tri.p1; Vector3 n = Vector3.Cross(v1, v2); Vector3 lookAt = camera.LookAt; bool isFront = Vector3.Dot(lookAt, n) < 0; switch (mode) { case CullMode.front: { return(isFront); } case CullMode.back: { return(!isFront); } } return(false); }
/* * 原理,点在平面上 AX + BY + CZ + D > 0,平面下 < 0。只要被包裹着,就是在视锥体里。 */ public static bool PtInCamera(Vector3 pt, SoftCamera camera) { SoftPlane[] planes = camera.WorldPlanes; if (planes != null && planes.Length >= 6) { float ret = PtInPlane(pt, planes[SoftCameraPlanes.NearPlane]) * PtInPlane(pt, planes[SoftCameraPlanes.FarPlane]); if (ret < 0) { return(false); } ret = PtInPlane(pt, planes[SoftCameraPlanes.LeftPlane]) * PtInPlane(pt, planes[SoftCameraPlanes.RightPlane]); if (ret < 0) { return(false); } ret = PtInPlane(pt, planes[SoftCameraPlanes.UpPlane]) * PtInPlane(pt, planes[SoftCameraPlanes.DownPlane]); if (ret < 0) { return(false); } return(true); } return(false); }
// 排序 internal override bool DoCameraRender(SoftCamera camera, Dictionary <int, SoftRenderObject> objMap) { if (camera == null || objMap == null) { return(false); } NativeList <int> visibleList; camera.DoCameraPreRender(); camera.Cull(objMap, out visibleList); bool ret = false; if (visibleList != null && visibleList.Count > 0) { DoVisibleRenderObjectsSort(camera, visibleList); for (int i = 0; i < visibleList.Count; ++i) { SoftRenderObject obj = camera.GetRenderObject(visibleList[i]); if (obj != null) { // 后面考虑排序和后面模拟可编程。。。 if (obj.Render(camera, m_DefaultPassMode)) { ret = true; } } } } camera.DoCameraPostRender(m_DefaultPassMode); return(ret); }
// 排序(非透明排序) protected virtual void DoVisibleRenderObjectsSort(SoftCamera camera, NativeList <int> visibleList) { if (visibleList == null || visibleList.Count <= 0) { return; } m_VisiableListSort.currentCamera = camera; visibleList.Sort(m_VisiableListSort); }
public void RemoveRenderObject(SoftRenderObject obj) { if (obj != null && m_RenderObjMap != null) { int instanceId = obj.InstanceId; m_RenderObjMap.Remove(instanceId); SoftCamera cam = obj as SoftCamera; if (cam != null) { m_CamList.Remove(cam); } obj.Dispose(); } }
// 添加 public SoftCamera AddOCamera(OCameraInfo info, Vector3 pos, Vector3 up, Vector3 lookAt, int depth, bool isMainCamera = false) { SoftCamera cam = new SoftCamera(this); cam.Position = pos; cam.Up = up; cam.LookAt = lookAt; cam.Depth = depth; cam.SetOCamera(info); if (AddCamera(cam)) { cam.IsMainCamera = isMainCamera; return(cam); } return(null); }
// 提交到渲染队列中 public override bool Render(SoftCamera camera, RenderPassMode passMode) { if (camera == null || passMode == null || m_Mesh == null) { return(false); } UpdateGlobalToLocalMatrix(); CullMode old = passMode.Cull; passMode.Cull = this.cullMode; int oldMainTex = passMode.mainTex; passMode.mainTex = m_MainTex; bool ret = camera.RenderMesh(m_Mesh, m_MeshAxisToGlobalMatrix, passMode); passMode.Cull = old; passMode.mainTex = oldMainTex; return(ret); }
private bool CameraRender(SoftCamera cam) { if (cam == null) { return(false); } var target = cam.Target; if (target != null) { target.Prepare(); if (m_RenderPipline != null) { return(m_RenderPipline.DoCameraRender(cam, m_RenderObjMap)); } } return(false); }
public void GetPlanePoints(int deviceWidth, int deviceHeight, SoftCamera camera, out Vector3 a, out Vector3 b, out Vector3 c, out Vector3 d, out Vector3 e, out Vector3 f, out Vector3 g, out Vector3 h) { // 8个顶点 float halfNearHeight; float halfNearWidth; GetNearWidthAndHeight(deviceWidth, deviceHeight, out halfNearWidth, out halfNearHeight); halfNearWidth = halfNearWidth / 2.0f; halfNearHeight = halfNearHeight / 2.0f; Vector3 forward = camera.LookAt; Vector3 nearCenter = camera.Position + forward * nearPlane; /* e h * f g * | | * a d * b c */ // 近平面4个点 // a, b, c, d; // 远平面4个点 // e, f, g, h; a = nearCenter + new Vector3(-halfNearWidth, halfNearHeight, 0f); b = nearCenter + new Vector3(-halfNearWidth, -halfNearHeight, 0f); c = nearCenter + new Vector3(halfNearWidth, -halfNearHeight, 0f); d = nearCenter + new Vector3(halfNearWidth, halfNearHeight, 0f); float halfFarWidth, halfFarHeight; GetFarWidthAndHeight(deviceWidth, deviceHeight, out halfFarWidth, out halfFarHeight); halfFarWidth = halfFarWidth / 2.0f; halfFarHeight = halfFarHeight / 2.0f; Vector3 farCenter = camera.Position + forward * farPlane; e = farCenter + new Vector3(-halfFarWidth, halfFarHeight, 0f); f = farCenter + new Vector3(-halfFarWidth, -halfFarHeight, 0f); g = farCenter + new Vector3(halfFarWidth, -halfFarHeight, 0f); h = farCenter + new Vector3(halfFarWidth, halfFarHeight, 0f); }
// 摄影机剔除 // visiableList: 可见列表 public void CameraCull(SoftCamera camera, Dictionary <int, SoftRenderObject> objs, out NativeList <int> visiableList) { visiableList = null; if (camera == null) { return; } if (objs == null || objs.Count <= 0) { m_Objs.Clear(false); return; } m_Objs.Clear(false); // 简单处理,直接干 var iter = objs.GetEnumerator(); while (iter.MoveNext()) { SoftRenderObject obj = iter.Current.Value; if (obj != null && obj.CanRenderer) { switch (obj.ObjType) { case SoftRenderObjType.MeshRender: SoftSpere spere = (obj as SoftMeshRenderer).WorldBoundSpere; // if (!camera.IsOpenCameraSpereCull || SoftMath.BoundSpereInCamera(spere, camera)) { if (!camera.IsOpenCameraSpereCull || SoftMath.BoundSpereInCamera_UseMVP(spere, camera)) { m_Objs.Add(obj.InstanceId); } break; } } } iter.Dispose(); if (m_Objs.Count > 0) { visiableList = m_Objs; } }
protected bool AddCamera(SoftCamera cam) { if (cam == null) { return(false); } if (m_CamList == null) { m_CamList = new List <SoftCamera>(); } if (RegisterRenderObject(cam) > 0) { m_CamList.Add(cam); } else { if (cam != null) { cam.Dispose(); } } return(true); }
public void InitPlanes(SoftPlane[] planes, int deviceWidth, int deviceHeight, SoftCamera camera) { if (camera == null || planes == null || planes.Length < 6) { return; } Vector3 forward = camera.LookAt; Vector3 right = camera.Right; Vector3 up = camera.Up; float cameraHeight = this.CameraHeight; float cameraWidth = GetCameraWidth(deviceWidth, deviceHeight); Vector3 nearCenter = camera.Position + forward * nearPlane; // near plane Vector3 n = forward; float d = -n.x * nearCenter.x - n.y * nearCenter.y - n.z * nearCenter.z; planes[SoftCameraPlanes.NearPlane] = new SoftPlane(n, d); // far plane Vector3 pos = camera.Position + forward * farPlane; n = -forward; d = -n.x * pos.x - n.y * pos.y - n.z * pos.z; planes[SoftCameraPlanes.FarPlane] = new SoftPlane(n, d); // Left plane n = right; pos = nearCenter + (-right * cameraWidth / 2.0f); d = -n.x * pos.x - n.y * pos.y - n.z * pos.z; planes[SoftCameraPlanes.LeftPlane] = new SoftPlane(n, d); // right plane n = -right; pos = nearCenter + (right * cameraWidth / 2.0f); d = -n.x * pos.x - n.y * pos.y - n.z * pos.z; planes[SoftCameraPlanes.RightPlane] = new SoftPlane(n, d); // up plane n = -up; pos = nearCenter + (up * cameraHeight / 2.0f); d = -n.x * pos.x - n.y * pos.y - n.z * pos.z; planes[SoftCameraPlanes.UpPlane] = new SoftPlane(n, d); // down plane n = up; pos = nearCenter - (up * cameraHeight / 2.0f); d = -n.x * pos.x - n.y * pos.y - n.z * pos.z; planes[SoftCameraPlanes.DownPlane] = new SoftPlane(n, d); }
// 六大平面 public void InitPlanes(SoftPlane[] planes, int deviceWidth, int deviceHeight, SoftCamera camera) { Vector3 a, b, c, d; Vector3 e, f, g, h; GetPlanePoints(deviceWidth, deviceHeight, camera, out a, out b, out c, out d, out e, out f, out g, out h); Vector3 camPos = camera.Position; // near plane Vector3 n = camera.LookAt; float dd = -n.x * a.x - n.y * a.y - n.z * a.z; planes[SoftCameraPlanes.NearPlane] = new SoftPlane(n, dd); // far plane n = -camera.LookAt; dd = -n.x * e.x - n.y * e.y - n.z * e.z; planes[SoftCameraPlanes.FarPlane] = new SoftPlane(n, dd); // left plane Vector3 v1 = a - camPos; Vector3 v2 = b - camPos; n = Vector3.Cross(v1, v2).normalized; dd = -n.x * a.x - n.y * a.y - n.z * a.z; planes[SoftCameraPlanes.LeftPlane] = new SoftPlane(n, dd); // right plane v1 = d - camPos; v2 = c - camPos; n = Vector3.Cross(v2, v1).normalized; planes[SoftCameraPlanes.RightPlane] = new SoftPlane(n, dd); // up plane v1 = e - a; v2 = d - a; n = Vector3.Cross(v2, v1).normalized; planes[SoftCameraPlanes.UpPlane] = new SoftPlane(n, dd); // down plane v1 = g - c; v2 = d - c; n = Vector3.Cross(v1, v2).normalized; planes[SoftCameraPlanes.DownPlane] = new SoftPlane(n, dd); }
public virtual bool Render(SoftCamera camera, RenderPassMode passMode) { return(false); }
internal virtual bool DoCameraRender(SoftCamera camera, Dictionary <int, SoftRenderObject> objMap) { return(false); }