Обрезать область в форме эллипса с помощью ShaderLab в Unity - PullRequest
1 голос
/ 11 марта 2020

Я пытаюсь нарисовать эллипсоид с помощью шейдеров в Unity

. Следуя инструкциям 1. Я написал собственный шейдер с помощью некоторого учебника по inte rnet 2. Добавлен шейдер на материал 3. Нанесен этот материал на объект

Shader "Custom/HoleMaker" {
    Properties{
            _Position("Position", Vector) = (0,0,0,0)
            _Radius("Radius", Range(0,1)) = 0.01
            _Color("Color", Color) = (1,1,1,1)
            _CutawayColor("Cutaway Color", Color) = (1,1,1,1)
    }
            SubShader{
                    Tags { "RenderType" = "Opaque"}
                    LOD 200
                    Cull Front

                    CGPROGRAMtypes
                    #pragma surface surf MonoColor fullforwardshadows vertex:vert

                    // Use shader model 3.0 target, to get nicer looking lighting
                    #pragma target 3.0

                    fixed4 _CutawayColor;

                    float4 _Position;
                    float _Radius;

                    struct Input
                    {
                            float2 uv_MainTex;
                            float3 worldPos;
                    };

                    void vert(inout appdata_full v, out Input o)
                    {
                            UNITY_INITIALIZE_OUTPUT(Input, o);
                            v.normal *= -1;
                    }

                    half4 LightingMonoColor(SurfaceOutput s, half3 lightDir, half atten) {
                            return _CutawayColor;
                    }

                    void surf(Input IN, inout SurfaceOutput o)
                    {

                            //spherical clipping
                            float dist = distance(IN.worldPos.xyz, _Position.xyz);
                            if (dist < _Radius)
                                    clip(-1);


                            o.Albedo = _CutawayColor.rgb;
                    }
                    ENDCG
            }
                    FallBack "Diffuse"
   }

Этот код работает для создания круга, но когда я пытаюсь использовать функцию clip () для создания эллипсоида, он не работает. Согласно документации, клипса (float4 x) также доступна для использования для скрепления поверхности. Переменная _Radius создает идеальную сферу в World Space, но когда я пытаюсь использовать _Radius.x и _Radius.y, код не работает. Пожалуйста, обратитесь к приложенному изображению.

enter image description here

1 Ответ

2 голосов
/ 11 марта 2020

_Radius.x и _Radius.y ломают шейдер, потому что _Radius - это float. Он не имеет x или y членов. Как это может иметь значение для _Radius.y?

Вместо этого рассмотрите возможность добавления свойства Scale, а затем масштабируйте разницу между мировой позицией и _Position на эту величину, прежде чем сравнивать величину разницы. до _radius:

Shader "Custom/HoleMaker" {
    Properties{
            _Position("Position", Vector) = (0,0,0,0)
            _Scale("Scale", Vector) = (1,1,1,0)
            _Radius("Radius", Range(0,1)) = 0.01
            _Color("Color", Color) = (1,1,1,1)
            _CutawayColor("Cutaway Color", Color) = (1,1,1,1)
    }
            SubShader{
                    Tags { "RenderType" = "Opaque"}
                    LOD 200
                    Cull Front

                    CGPROGRAMtypes
                    #pragma surface surf MonoColor fullforwardshadows vertex:vert

                    // Use shader model 3.0 target, to get nicer looking lighting
                    #pragma target 3.0

                    fixed4 _CutawayColor;

                    float4 _Position;
                    float4 _Scale;
                    float _Radius;

                    struct Input
                    {
                            float2 uv_MainTex;
                            float3 worldPos;
                    };

                    void vert(inout appdata_full v, out Input o)
                    {
                            UNITY_INITIALIZE_OUTPUT(Input, o);
                            v.normal *= -1;
                    }

                    half4 LightingMonoColor(SurfaceOutput s, half3 lightDir, half atten) {
                            return _CutawayColor;
                    }

                    void surf(Input IN, inout SurfaceOutput o)
                    {

                            //spherical clipping
                            float dist = length(_Scale.xyz * IN.worldPos.xyz - _Position.xyz);
                            if (dist < _Radius)
                                    clip(-1);


                            o.Albedo = _CutawayColor.rgb;
                    }
                    ENDCG
            }
                    FallBack "Diffuse"
   }
...