Unity正交相机下相交Line Renderer渲染异常问题求助
正交相机下Line Renderer按Y值分层显示的解决方案
核心原因
正交相机的深度计算逻辑和透视相机完全不同:透视相机基于实际空间距离排序渲染层级,而正交相机默认只参考物体的Transform.position.z或材质渲染队列,不会逐像素比较Y值——因为正交相机下所有物体在相机空间的"距离"是一致的,所以两条Y值有差异的线条会被判定为同一层级,导致完全覆盖的问题。
可行解决方案
方法1:自定义Shader逐像素判断Y值(最精准)
直接在Shader里对每个像素的世界空间Y值做判断,只保留当前线条Y值高于另一条的部分:
- 创建Unlit Shader,替换为以下代码:
Shader "Custom/LineDepthSort" { Properties { _MainColor ("Color", Color) = (1,1,1,1) _OtherLineStartY ("Other Line Start Y", Float) = 0.001 _OtherLineEndY ("Other Line End Y", Float) = 0.005 _LineStartXZ ("Line Start XZ", Vector) = (0,0,0,0) _LineEndXZ ("Line End XZ", Vector) = (1,0,1,0) } SubShader { Tags { "Queue"="Transparent" "RenderType"="Transparent" } LOD 100 Blend SrcAlpha OneMinusSrcAlpha ZWrite Off Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; float worldY : TEXCOORD1; float3 worldPos : TEXCOORD2; }; float4 _MainColor; float _OtherLineStartY; float _OtherLineEndY; float4 _LineStartXZ; float4 _LineEndXZ; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.worldPos = mul(unity_ObjectToWorld, v.vertex); o.worldY = o.worldPos.y; o.uv = v.uv; return o; } fixed4 frag (v2f i) : SV_Target { // 计算当前点在线段XZ方向的归一化位置(0=起点,1=终点) float3 lineDir = _LineEndXZ.xyz - _LineStartXZ.xyz; float3 pointDir = i.worldPos - _LineStartXZ.xyz; float t = dot(pointDir, lineDir) / dot(lineDir, lineDir); t = saturate(t); // 计算另一条线在当前XZ位置的Y值 float otherY = lerp(_OtherLineStartY, _OtherLineEndY, t); // 丢弃当前线条Y值低于对方的像素 if(i.worldY <= otherY) { discard; } return _MainColor; } ENDCG } } }
- 给两条Line Renderer分别赋值该Shader,对应设置参数:
- 线条1:
_OtherLineStartY设为0.001,_OtherLineEndY设为0.005,_LineStartXZ填(constStartX, 0, constStartZ),_LineEndXZ填(constEndX, 0, constEndZ) - 线条2:
_OtherLineStartY设为0.005,_OtherLineEndY设为0.001,_LineStartXZ和_LineEndXZ同上
- 线条1:
- 确保两条线的材质都开启
ZWrite Off,渲染队列设为Transparent。
方法2:手动拆分线段(无需Shader)
计算两条线的Y值交点,将每条线拆分为"高于对方"和"低于对方"的两段,只保留高于的部分:
- 计算交点:你的两条线Y值都是线性变化,线条1的Y(t)=0.005-0.004t,线条2的Y(t)=0.001+0.004t,令两者相等得
t=0.5,即交点在XZ中点:( (constStartX+constEndX)/2, _, (constStartZ+constEndZ)/2 ) - 修改Line Renderer的点数组:
- 线条1只保留起点到中点的两个点
- 线条2只保留中点到终点的两个点
- 若线条Y值变化非线性,需用通用线段交点算法计算拆分位置。
方法3:深度偏移(适合简单场景)
给两条线的材质设置不同的Depth Bias(在材质Inspector的Render Settings中),通过全局偏移强制层级,但这种方法是全局生效的,无法做到局部区域的精准控制,仅适合Y值全程有高低差的线条,不适合交叉场景。
内容的提问来源于stack exchange,提问作者INTODAN
相关产品推荐
相关产品推荐

