You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity正交相机下相交Line Renderer渲染异常问题求助

正交相机下Line Renderer按Y值分层显示的解决方案

核心原因

正交相机的深度计算逻辑和透视相机完全不同:透视相机基于实际空间距离排序渲染层级,而正交相机默认只参考物体的Transform.position.z或材质渲染队列,不会逐像素比较Y值——因为正交相机下所有物体在相机空间的"距离"是一致的,所以两条Y值有差异的线条会被判定为同一层级,导致完全覆盖的问题。

可行解决方案

方法1:自定义Shader逐像素判断Y值(最精准)

直接在Shader里对每个像素的世界空间Y值做判断,只保留当前线条Y值高于另一条的部分:

  1. 创建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
        }
    }
}
  1. 给两条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同上
  2. 确保两条线的材质都开启ZWrite Off,渲染队列设为Transparent。

方法2:手动拆分线段(无需Shader)

计算两条线的Y值交点,将每条线拆分为"高于对方"和"低于对方"的两段,只保留高于的部分:

  1. 计算交点:你的两条线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 )
  2. 修改Line Renderer的点数组:
    • 线条1只保留起点到中点的两个点
    • 线条2只保留中点到终点的两个点
  3. 若线条Y值变化非线性,需用通用线段交点算法计算拆分位置。

方法3:深度偏移(适合简单场景)

给两条线的材质设置不同的Depth Bias(在材质Inspector的Render Settings中),通过全局偏移强制层级,但这种方法是全局生效的,无法做到局部区域的精准控制,仅适合Y值全程有高低差的线条,不适合交叉场景。


内容的提问来源于stack exchange,提问作者INTODAN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 11:42:45