news 2026/7/13 14:38:10

Unity阴影

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Unity阴影

阴影纹理判断深度那些我们都懂。我的疑惑是对于平行光,如何确定阴影贴图要覆盖的范围。

豆包回答:

左右 / 上下范围:由Shadow Distance和主相机的视场角决定,以主相机为中心,向平行光方向扩展出一个覆盖主相机视锥在Shadow Distance内所有区域的立方体,确保主相机能看到的范围内,阴影都能被正确生成。

我感觉就是对场景的所有模型都判断深度,对于一个平行光方向,只用生成一次阴影纹理就能一直使用。如果转动光源,就会看见右下角有Global illumination processing,可能就是在重新生成ShadowMap。

豆包提供了这个脚本,用于标识平行光源阴影视锥。

using UnityEngine; using UnityEditor; [RequireComponent(typeof(Light))] public class DirectionalShadowFrustumVisualizer : MonoBehaviour { [Header("可视化设置")] [Tooltip("视锥线条颜色")] public Color frustumColor = Color.cyan; [Tooltip("线条宽度(仅Scene视图生效)")] public float lineWidth = 2f; private Light _dirLight; private Camera _mainCamera; // 视锥的8个顶点 private Vector3[] _frustumCorners = new Vector3[8]; private void OnEnable() { _dirLight = GetComponent<Light>(); // 校验是否为平行光 if (_dirLight.type != LightType.Directional) { Debug.LogError("该脚本仅支持平行光!"); enabled = false; return; } _mainCamera = Camera.main; } // Scene视图绘制视锥 private void OnDrawGizmos() { if (!_dirLight || !_mainCamera) return; // 获取全局Shadow Distance float shadowDistance = QualitySettings.shadowDistance; // 获取平行光的阴影近裁剪面 float shadowNearPlane = _dirLight.shadowNearPlane; // 1. 计算主相机在Shadow Distance范围内的视锥投影边界 CalculateMainCameraFrustumBounds(shadowDistance, out Vector3 camFrustumMin, out Vector3 camFrustumMax); // 2. 计算平行光虚拟相机的正交视锥参数 Vector3 lightDir = _dirLight.transform.forward; // 视锥中心:主相机位置 + 平行光方向 * 阴影距离的一半 Vector3 frustumCenter = _mainCamera.transform.position + lightDir * shadowDistance * 0.5f; // 视锥尺寸:基于主相机视锥的宽度、高度,以及阴影近/远裁剪面的距离 Vector3 frustumSize = new Vector3( camFrustumMax.x - camFrustumMin.x, camFrustumMax.y - camFrustumMin.y, shadowDistance - shadowNearPlane ); // 3. 计算视锥的8个顶点 BuildFrustumCorners(frustumCenter, lightDir, frustumSize, shadowNearPlane); // 4. 绘制视锥线条 Gizmos.color = frustumColor; Handles.color = frustumColor; //Handles.lineThickness = lineWidth; // 绘制视锥的12条边 DrawLine(0, 1); DrawLine(1, 3); DrawLine(3, 2); DrawLine(2, 0); DrawLine(4, 5); DrawLine(5, 7); DrawLine(7, 6); DrawLine(6, 4); DrawLine(0, 4); DrawLine(1, 5); DrawLine(2, 6); DrawLine(3, 7); } // 计算主相机在指定距离下的视锥投影边界 private void CalculateMainCameraFrustumBounds(float distance, out Vector3 min, out Vector3 max) { float halfFOV = _mainCamera.fieldOfView * 0.5f * Mathf.Deg2Rad; float aspect = _mainCamera.aspect; float halfHeight = Mathf.Tan(halfFOV) * distance; float halfWidth = halfHeight * aspect; min = new Vector3(-halfWidth, -halfHeight, distance); max = new Vector3(halfWidth, halfHeight, distance); // 转换到世界空间 min = _mainCamera.transform.TransformVector(min); max = _mainCamera.transform.TransformVector(max); } // 构建正交视锥的8个顶点 private void BuildFrustumCorners(Vector3 center, Vector3 lightDir, Vector3 size, float nearPlane) { Vector3 halfSize = size * 0.5f; Vector3 up = Vector3.up; Vector3 right = Vector3.Cross(lightDir, up).normalized; up = Vector3.Cross(right, lightDir).normalized; // 近裁剪面4个顶点 _frustumCorners[0] = center - right * halfSize.x - up * halfSize.y - lightDir * (halfSize.z - nearPlane); _frustumCorners[1] = center + right * halfSize.x - up * halfSize.y - lightDir * (halfSize.z - nearPlane); _frustumCorners[2] = center - right * halfSize.x + up * halfSize.y - lightDir * (halfSize.z - nearPlane); _frustumCorners[3] = center + right * halfSize.x + up * halfSize.y - lightDir * (halfSize.z - nearPlane); // 远裁剪面4个顶点 _frustumCorners[4] = center - right * halfSize.x - up * halfSize.y + lightDir * halfSize.z; _frustumCorners[5] = center + right * halfSize.x - up * halfSize.y + lightDir * halfSize.z; _frustumCorners[6] = center - right * halfSize.x + up * halfSize.y + lightDir * halfSize.z; _frustumCorners[7] = center + right * halfSize.x + up * halfSize.y + lightDir * halfSize.z; } // 绘制单条线段 private void DrawLine(int indexA, int indexB) { Handles.DrawLine(_frustumCorners[indexA], _frustumCorners[indexB]); } }

动了一下相机,视锥会跟着变化,规则挺复杂。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/1 21:37:24

3分钟极速上手Draft.js:React富文本编辑器的魔法之旅

3分钟极速上手Draft.js&#xff1a;React富文本编辑器的魔法之旅 【免费下载链接】draft-js A React framework for building text editors. 项目地址: https://gitcode.com/gh_mirrors/dra/draft-js 还在为React项目中集成富文本编辑器而头疼吗&#xff1f;&#x1f91…

作者头像 李华
网站建设 2026/7/1 3:39:23

Draft.js富文本编辑器:5分钟从零搭建React编辑体验

Draft.js富文本编辑器&#xff1a;5分钟从零搭建React编辑体验 【免费下载链接】draft-js A React framework for building text editors. 项目地址: https://gitcode.com/gh_mirrors/dra/draft-js 还在为React项目寻找合适的富文本编辑器而烦恼吗&#xff1f;Draft.js作…

作者头像 李华
网站建设 2026/7/1 21:37:19

3个简单步骤搞定QuickLook便携版:免安装配置终极指南

3个简单步骤搞定QuickLook便携版&#xff1a;免安装配置终极指南 【免费下载链接】QuickLook 项目地址: https://gitcode.com/gh_mirrors/qui/QuickLook 你是不是经常遇到这样的情况&#xff1a;在朋友电脑上想快速查看文件内容&#xff0c;却因为没有安装预览工具而束…

作者头像 李华
网站建设 2026/7/5 19:38:49

AI Agent通信架构的三大革新:从紧耦合到松耦合的智能进化之路

AI Agent通信架构的三大革新&#xff1a;从紧耦合到松耦合的智能进化之路 【免费下载链接】E2B Cloud Runtime for AI Agents 项目地址: https://gitcode.com/gh_mirrors/e2/E2B 你是否曾经为AI Agent之间的通信问题而头疼&#xff1f;当多个智能代理需要协作时&#xf…

作者头像 李华
网站建设 2026/7/11 21:27:00

Qwen3Guard-Gen-8B能否用于MyBatisPlus代码生成器安全检测?可以尝试

Qwen3Guard-Gen-8B 能否用于 MyBatisPlus 代码生成器安全检测&#xff1f;实践验证 在现代软件开发中&#xff0c;AI 辅助编程工具的普及正以前所未有的速度改变着工程师的工作方式。从 GitHub Copilot 到各类低代码平台&#xff0c;大模型驱动的代码生成已成为日常。然而&…

作者头像 李华
网站建设 2026/7/11 8:18:49

11.2 磁悬浮轴承:高端装备应用

11.2 高端装备应用 磁悬浮轴承技术凭借其无接触、无磨损、高速度、高精度、主动可控及无需润滑的卓越特性,已从最初的实验室研究和技术验证,稳步渗透并深刻变革了多个对性能、可靠性和寿命有极端要求的高端装备领域。在这些应用中,磁悬浮轴承不仅是实现核心功能的关键部件,…

作者头像 李华