Правильно рассчитать максимальный размер радиуса круга на основе размера экрана

Я пытаюсь нарисовать круг, залить внутри красным цветом, а снаружи - черным.

Я хочу установить размер круга из кода. С 0 будучи наименьшим размером и 100 максимальный размер круга и 100 означает, что круг должен покрывать экран.

Вот код:

Shader "Hidden/Circle"
{
    Properties
    {
        _MainTex("Texture", 2D) = "white" {}
    _radius("Radius",Range(0, 100)) = 100
        _radiusOffet("Offset",Range(0, 100)) = 72
        _discardedColor("Dicard Color", Color) = (0, 0, 0, 0) // color
    }
        SubShader
    {
        //Tags{ "Queue" = "Transparent" }
        // No culling or depth
        Cull Off ZWrite Off ZTest Always

        Pass
    {
        CGPROGRAM
#pragma vertex vert
#pragma fragment frag

#include "UnityCG.cginc"


    sampler2D _MainTex;
    float4 _discardedColor;

    float _radius;
    float _radiusOffet;

    float minMinSlide = 0; //0.314
    float minMaxSlide = 100.0;

    struct v2f
    {
        float2 uv : TEXCOORD0;
    };

    v2f vert(
        float4 vertex : POSITION, // vertex position input
        float2 uv : TEXCOORD0, // texture coordinate input
        out float4 outpos : SV_POSITION // clip space position output
    )
    {
        v2f o;
        o.uv = uv;
        outpos = UnityObjectToClipPos(vertex);
        return o;
    }

    float mapValue(float mainValue, float inValueMin, float inValueMax, float outValueMin, float outValueMax)
    {
        return (mainValue - inValueMin) * (outValueMax - outValueMin) / (inValueMax - inValueMin) + outValueMin;
    }

    fixed4 frag(v2f i, UNITY_VPOS_TYPE screenPos : VPOS) : SV_Target
    {
        //Set default values
        minMinSlide = 0;
    minMaxSlide = 100;

    //fixed4 col = tex2D(_MainTex, i.uv);

    float4 fragColor = 0;
    //float2 fragCoord = i.vertex.xy;
    float2 fragCoord = screenPos;
    float2 screenCoord = fragCoord.xy;

    float minOutRadius = 0;

    //THIS IS WRONG? WHAT'S THE PROPER WAY OF DOING THIS?
    float maxOutRadius = (_ScreenParams.x / 2) + _radiusOffet;

    //Calcuate the scaled radius
    float rad = mapValue(_radius, minMinSlide, minMaxSlide, minOutRadius, maxOutRadius);

    float2 middlePoint = _ScreenParams.xy * 0.5 - screenCoord;
    float middleLength = middlePoint.x * middlePoint.x + middlePoint.y * middlePoint.y;
    if (middleLength > rad * rad)
    {
        //Use black color
        fragColor = _discardedColor;
    }
    else {
        //Use red color
        fragColor = float4(1, 0, 0, 0);
    }
    return fragColor;
    }
        ENDCG
    }
    }
}

Этот код работает на 100% в редакторе.

В сборке Windows и Android есть небольшая проблема.

Проблема в том, что круг не полностью покрывает экран на 100%, когда значение должно быть установлено на 100, Это прекрасно работает в редакторе, хотя.

Я считаю, что проблема заключается в этой строке:

float maxOutRadius = (_ScreenParams.x / 2) + _radiusOffet;

Как правильно рассчитать максимальный радиус круга на основе размера экрана устройства?

Эта строка кода правильно работает только в редакторе.

1 ответ

Максимальный радиус круга - это расстояние от центра до угла экрана. Это было бы:

float x = _ScreenParams.x / 2;
float y = _ScreenParams.y / 2;
float maxOutRadius = sqrt(x*x+y*y); // + _radiusOffet; 

Кстати, вы можете сделать шейдер намного проще. Например:

uniform float _Percent;   
fixed4 frag (float4 pos:VPOS) : SV_Target
{
    float4 col;
    float2 center = _ScreenParams.xy/2;

    float maxradius = length(center); 
    float radius = maxradius * abs(sin(_Time.y)); // * (_Percent/100);

    if(distance(pos.xy, center) > radius){
        col = float4(0,0,0,1);
    }else{
        col = float4(1,0,0,1);
    }
    return col;
} 
Другие вопросы по тегам