实现了基础的圆形遮罩;灯塔使用MagicaVoxel搭建,模仿光柱追踪效果(虽然灯塔本身导入后似乎没有发光效果
脚本部分核心代码(与教材同):
#region 圆环内容 radiusMaterial.SetVector("_Center", transform.position); radiusMaterial.SetColor("_RadiusColor", color); radiusMaterial.SetFloat("_Radius", radius); #endregion
shader部分核心代码:
//圆环------ //最后再进行圆环的处理,直接覆盖在原有的地表 float d = distance(_Center, IN.worldPos); if(d<_Radius) { //在半径内的区域显示指定环贴图部分;半径外为地表部分 finalColor = radiusTex.rgb * _RadiusColor; } o.Albedo = finalColor; o.Alpha = 1;
完整shader代码:
Shader "Custom/sd_snow" { Properties { _MainColor("Main Color", Color) = (1,1,1,1) _MainTex("Base(RGB)",2D) = "white"{} _Bump("Bump", 2D) = "bump"{} _Level("Level of Snow", Range(0,1)) = 0.2 _SnowDepth("Depth of Snow",Range(0,1)) = 0.3 _SnowDirection("Direction of Snow",Vector) = (0,1,0) //角色圆环 _Center("Center", Vector) = (0,0,0,0) //player位置 _Radius("Radius", Float) = 0.5 //图案半径 _RadiusColor("Radius Color", Color) = (1,0,0,1) //图案染色 _RadiusTex("Radius Tex", 2D) = ""{} //图案贴图 } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM #pragma surface surf Standard vertex:vert #pragma target 3.0 sampler2D _MainTex; sampler2D _Bump; sampler2D _RadiusTex; struct Input { float2 uv_MainTex; float2 uv_Bump; float3 worldNormal; INTERNAL_DATA float2 uv_RadiusTex; float3 worldPos; }; fixed4 _MainColor; float _SnowDepth; fixed _Level; float4 _SnowDirection; //圆环 float3 _Center; float _Radius; float3 _RadiusColor; UNITY_INSTANCING_BUFFER_START(Props) UNITY_INSTANCING_BUFFER_END(Props) void surf (Input IN, inout SurfaceOutputStandard o) { fixed4 c = tex2D (_MainTex, IN.uv_MainTex); fixed3 radiusTex = tex2D(_RadiusTex, IN.uv_RadiusTex).rgb; //圆环图案 float3 finalColor; //雪 if(dot(WorldNormalVector(IN, o.Normal),_SnowDirection.xyz) >= (1 - _Level)) { //有雪的情况 finalColor = _MainColor; o.Normal = UnpackNormal(tex2D(_Bump, IN.uv_Bump));; } else finalColor = c.rgb; //圆环------ //最后再进行圆环的处理,直接覆盖在原有的地表 float d = distance(_Center, IN.worldPos); if(d<_Radius) { //在半径内的区域显示指定环贴图部分;半径外为地表部分 finalColor = radiusTex.rgb * _RadiusColor; } o.Albedo = finalColor; o.Alpha = 1; } void vert(inout appdata_full v) { float4 sn = mul(UNITY_MATRIX_IT_MV, _SnowDirection); if(dot(v.normal, sn.xyz)>=_Level) v.vertex.xyz += (sn.xyz + v.normal) * _SnowDepth * _Level; } ENDCG } FallBack "Diffuse" }