Unity3d 根据屏幕大小正确计算圆的最大半径大小
我试着画一个圆圈,里面用红色填充,外面用黑色填充 我想根据代码设置圆的大小。Unity3d 根据屏幕大小正确计算圆的最大半径大小,unity3d,shader,shaderlab,Unity3d,Shader,Shaderlab,我试着画一个圆圈,里面用红色填充,外面用黑色填充 我想根据代码设置圆的大小。0是圆圈的最小尺寸,100是圆圈的最大尺寸,100表示圆圈必须覆盖屏幕 代码如下: Shader "Hidden/Circle" { Properties { _MainTex("Texture", 2D) = "white" {} _radius("Radius",Range(0, 100)) = 100 _radiusOffet("Offset",Range(0
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;
如何根据设备的屏幕大小正确计算圆的最大半径
这行代码只能在编辑器上正常工作。圆的最大半径是从屏幕中心到角落的距离。这将是:
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;
}
圆的最大半径是从屏幕中心到角落的距离。这将是:
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;
}
谢谢现在不在我的电脑上测试这个,但会在几个小时后尝试,然后接受这个答案。如果我想改变圆的中心位置呢?假设我想更改圆开始绘制的位置,此解决方案也有效吗?当然可以,但必须将maxradius设置为最大(距离(中心,左上角),距离(中心,右上角),…如果你想让它覆盖整个屏幕。我有时间尝试。它现在在Windows build上运行良好,但在Android上根本不起作用。Android本身没有可见的圆圈。这很奇怪。你可以自己试试看。它在Android上运行良好(GLES 2.0)。试试编辑过的版本,它会为你改变半径。我没有撒谎。我只是花了一整天的时间试图让它工作,但它没有。即使你的第二个代码也不能在Android和GLES 2.0上工作。屏幕上覆盖着红色,它不是动画。奇怪的是,它在Windows上完美工作。谢谢。我的电脑无法测试现在,但将在几个小时后尝试,然后接受此作为答案。同时,如果我想更改圆的中心位置,该怎么办?假设我想更改圆开始绘制的位置,该解决方案也会起作用吗?当然,但必须将maxradius设置为
max(距离(中心,左上角),距离(中间,右上角),…
如果你想让它覆盖整个屏幕。我有时间尝试。它现在在Windows build上运行良好,但在Android上根本不起作用。Android本身没有可见的圆圈。这很奇怪。你可以自己试试看。它在Android上运行良好(GLES 2.0)。试试编辑后的版本,它会为你改变半径。我没有撒谎。我只是花了一整天的时间试图让它正常工作,但事实并非如此。即使你的第二个代码也无法在Android和GLES 2.0上工作。屏幕被红色覆盖,不是动画。奇怪的是,它在Windows上完美工作。