首页 > 解决方案 > 寻找一些方向和技巧来实现类似聚光灯的着色器,使 AR 视野中的其他一切变暗

问题描述

开发使用 Spotlights 的 AR 游戏,为了强调这种效果,着色器还必须使相机视图中的其他所有内容变暗。在 AR 中,我假设我需要一个图像效果着色器来减少屏幕上的颜色输出,以模拟用户周围区域的较低亮度;但是,为此添加聚光灯效果变得相当困难,我真的可以使用一些方向和/或技巧来实现。以下是我希望实现的最终结果的一些示例:

直截了当和有角度的例子

这是我目前使用着色器的地方,目前只提供一个对象位置,以后会担心多个位置。

Shader "Unlit/Spotlight"
{
    Properties
    {
        _MainTex("Texture", 2D) = "white" {}
        _PointOfInterest("POI Pos", vector) = (0,0,0,0)
        _CircleRadius("Spotlight size", Range(0,20)) = 3
        _RingSize("Ring Size", Range(0,5)) = 1
        _ColorTint("Room tint color", Color) = (0,0,0,0.5)
    }
    SubShader
    {
        Tags 
        {
            "Queue" = "Transparent"
            "RenderType"="Transparent"
        }

        LOD 100
        // Should be on for Post Process Effects
        ZWrite Off
        ZTest Always
        Cull Off
        // -----
        Blend SrcAlpha OneMinusSrcAlpha

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma alpha : blend


            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f 
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;

                // Have to bound the value somewhere on the GPU, texcoord can go up to 7
                float3 worldPos : TEXCOORD1;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            float4 _PointOfInterest;
            float _CircleRadius;
            float _RingSize;
            float4 _ColorTint;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);

                o.worldPos = mul(unity_WorldToObject, v.vertex).xyz;

                return o;

            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 darkShade = tex2D(_MainTex, i.uv) - _ColorTint;
                fixed4 col = tex2D(_MainTex, i.uv) - _ColorTint;
                float dist = distance(i.worldPos, _PointOfInterest.xyz);

                //*
                // Spotlight
                if(dist < _CircleRadius) 
                {
                    // inside the circle
                    col = tex2D(_MainTex, i.uv);
                }
                // Feathering
                else if (dist > _CircleRadius && dist < _CircleRadius + _RingSize) 
                {
                    float blendStrength = dist - _CircleRadius;
                    col = lerp(tex2D(_MainTex, i.uv), darkShade, blendStrength / _RingSize);
                }
                //*/

                return col;
            }
            ENDCG
        }
    }
}

不寻找直接的解决方案,只需要方向,这样我就不会花太多时间去追逐我可能要逃离的目的地。

标签: unity3dshaderaugmented-reality

解决方案


推荐阅读