怀这一些堕落和伤感写下这篇文章,今天写想用Shader写一个3D饼图效果,居然没有想到别的更高效的写法,功能实现了更效率不高。希望看到此文章有更好实现方式的请私信我,谢谢。
代码本身看起来很长,其实只是把自身坐标顶点传入片元着色器,再判断所以点与中心的连线,与中心点的夹角的度数,判断使用哪个颜色。使用了大量的if else…求指正。
只需要哒到如下效果即可。
下面是原代码:
Shader "Custom/PieGraph" {
Properties{
_element1("element%1",Range(0.00,100.00))=0
_element2("element%2",Range(0.00,100.00))=0
_element3("element%3",Range(0.00,100.00))=0
_element4("element%4",Range(0.00,100.00))=0
_element5("element%5",Range(0.00,100.00))=0
_element6("element%6",Range(0.00,100.00))=0
_element7("element%7",Range(0.00,100.00))=0
_element8("element%8",Range(0.00,100.00))=0
_element9("element%9",Range(0.00,100.00))=0
_Angle1Color("Color1",Color)=(1,1,1,1)
_Angle2Color("Color2",Color)=(1,1,1,1)
_Angle3Color("Color3",Color)=(1,1,1,1)
_Angle4Color("Color4",Color)=(1,1,1,1)
_Angle5Color("Color5",Color)=(1,1,1,1)
_Angle6Color("Color6",Color)=(1,1,1,1)
_Angle7Color("Color7",Color)=(1,1,1,1)
_Angle8Color("Color8",Color)=(1,1,1,1)
_Angle9Color("Color9",Color)=(1,1,1,1)
_Diffuse("Diffuse",Color)=(0.1,0.1,0.1,1)
_Specular("Specular",Color)=(1,1,1,1)
_Gloss("Gloss",Range(8,256))=20
}
SubShader{
Tags{"IgnoreProjector"="True"}
Pass{
Tags{"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Lighting.cginc"
fixed4 _Color;
float _element1;
float _element2;
float _element3;
float _element4;
float _element5;
float _element6;
float _element7;
float _element8;
float _element9;
fixed4 _Angle1Color;
fixed4 _Angle2Color;
fixed4 _Angle3Color;
fixed4 _Angle4Color;
fixed4 _Angle5Color;
fixed4 _Angle6Color;
fixed4 _Angle7Color;
fixed4 _Angle8Color;
fixed4 _Angle9Color;
fixed4 _Diffuse;
fixed4 _Specular;
float _Gloss;
struct a2v{
float4 vertex:POSITION;
float2 uv:TEXCOORD0;
float3 normal:NORMAL;
};
struct v2f{
float4 pos:SV_POSITION;
float2 uv:TEXCOORD0;
float4 objPos:TEXCOORD1;
float3 worldPos:TEXCOORD2;
float3 normal:TEXCOORD3;
};
v2f vert(a2v v){
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.objPos = v.vertex;
o.uv = v.uv;
o.worldPos =mul(unity_ObjectToWorld,v.vertex);
o.normal = normalize(mul(v.normal,(float3x3)unity_WorldToObject));
return o;
}
float4 frag(v2f i):SV_TARGET{
float2 thisline = i.objPos.zx;
float angle = atan2(thisline.y,thisline.x)*15.92;
_element1 = _element1-50;
_element2 +=_element1 ;
_element3 +=_element2 ;
_element4 +=_element3 ;
_element5 +=_element4 ;
_element6 +=_element5 ;
_element7 +=_element6 ;
_element8 +=_element7 ;
_element9 +=_element8 ;
fixed3 additionaryColor;
if(angle<_element1){
additionaryColor = _Angle1Color;
}else if(angle<_element2){
additionaryColor = _Angle2Color;
}else if(angle<_element3){
additionaryColor = _Angle3Color;
}else if(angle<_element4){
additionaryColor = _Angle4Color;
}else if(angle<_element5){
additionaryColor = _Angle5Color;
}else if(angle<_element6){
additionaryColor = _Angle6Color;
}else if(angle<_element7){
additionaryColor = _Angle7Color;
}else if(angle<_element8){
additionaryColor = _Angle8Color;
}else if(angle<_element9){
additionaryColor = _Angle9Color;
}
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
fixed3 diffuse = _LightColor0.rgb*_Diffuse.rgb*saturate(dot(i.normal,worldLightDir));
fixed3 reflectDir = normalize(reflect(-worldLightDir,i.normal));
fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz-i.worldPos.xyz);
fixed3 specular = _LightColor0.rgb * _Specular.rgb *pow(saturate(dot(reflectDir,viewDir)),_Gloss);
float3 color = (ambient+diffuse+specular)*additionaryColor;
return fixed4(color,1);
}
ENDCG
}
}
}