UnityShader实例(1) 基于2DSprite实现圆环

您所在的位置:网站首页 像素如何画圆圈 UnityShader实例(1) 基于2DSprite实现圆环

UnityShader实例(1) 基于2DSprite实现圆环

2024-07-16 22:20| 来源: 网络整理| 查看: 265

想要在Unity2D中实现一个漂亮的圆环,但是除了前面做过的各种笔记和自学,啥都不会, 但是成功摸索出来,在这里记录一下理解流程。 源代码和使用方式在最下面。

2D圆环的最简单实现

圆环最简单的实现就是自己画一个背景色透明的圆环: (下面是一张图片,不信你把浏览器背景色调一下) BigCircleEdge

然后直接往场景里一放就行: 20220130134430

当然这种方式很不行,拉伸大了之后模糊感太大,很难看,而且不易控制大小: 在这里插入图片描述

使用Shader实现 2DShader的简单探索(最终代码在最后)

首先2D中用的都是Sprite做渲染,所有显然不适合直接用Mesh顶点作图的方案, 当然如果用Mesh的话也有现成的方案: https://blog.csdn.net/liuzonrze/article/details/83280463

但只要涉及到渲染肯定就用到Shader, 所以先看看Sprite中怎么用上Shader吧。

首先在场景中创建一个新的2D正方形。 新建一个Shader和材质作用到它上面,编写Shader代码进行探索。

这里就是用到Shader的一种主要调试方式:将值直接当作颜色输出来。 下面这一段代码做的工作就是, 试图将模型顶点在裁剪空间中的坐标输出, 结果是输出全白:

Shader "Custom/CircleEdgeShader" { Properties{ _MainTex ("Main Tex", 2D) = "white" {} } SubShader { // No culling or depth Cull Off ZWrite Off ZTest Always // 开启透明度 Blend SrcAlpha OneMinusSrcAlpha // 设置渲染队列 Tags { "Queue"="Transparent" "RenderType"="Opaque" } Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" sampler2D _MainTex; struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; // 顶点着色获取 v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } // 片元着色 fixed4 frag (v2f i) : SV_Target { return i.vertex; } ENDCG } } }

20220130145805

那看来从模型顶点入手是不行了, 毕竟二维精灵也没听说过顶点的说法, 那就是原理上与生成Mesh顶点并调整顶点颜色完全不同。

下面看看从程序导入着色器的另一个参数uv坐标, 将片元着色器代码调整如下:

fixed4 frag (v2f i) : SV_Target { return fixed4(i.uv.x, i.uv.y, 0, 1); }

输出结果如下: 20220130150429

虽然是混乱的色彩,但我很开心, 这说明决定2维精灵各个像素颜色的变量就在其中。 我们可以通过取色器对各个像素取色,得出uv坐标的分布规律: 20220130150712

左上角是绿色RGB(0, 1, 0), 右上角是黄色RGB(1, 1, 0), 中间显然就是RGB(0.5, 0.5, 0)。

知道uv的分布规律后,我们直接就可以写出代码来画我们需要的一个高清圆弧了! 将片元着色器代码修改如下:

fixed4 frag (v2f i) : SV_Target { float disToCenter = (i.uv.x-0.5)*(i.uv.x-0.5) + (i.uv.y-0.5)*(i.uv.y-0.5); if( 0.5*0.5 > disToCenter && disToCenter > 0.45*0.45 ) return fixed4(1, 1, 1, 1); else return fixed4(1, 1, 1, 0); }

20220130151016 不管放多大,这种像素级的色彩定位是不会出现模糊的现象的: 20220130151210

接下来就把代码精进,提供参数接口给C#脚本即可

源代码

主要是两个参数: 一是Color,用来确定圆环颜色, 二是CircleEdge,用来确定圆环宽度占半径的比例(0~1)

Shader "Custom/CircleEdgeShader" { Properties{ _MainTex ("Main Tex", 2D) = "white" {} _ColorTint ("Color", Color) = (1, 1, 1, 1) _CircleEdge ("CircleEdge", float) = 0.1 } SubShader { // No culling or depth Cull Off ZWrite Off ZTest Always // 开启透明度 Blend SrcAlpha OneMinusSrcAlpha // 设置渲染队列 Tags { "Queue"="Transparent" "RenderType"="Opaque" } Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" sampler2D _MainTex; fixed4 _ColorTint; float _CircleEdge; struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; // 顶点着色获取 v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } // 片元着色 fixed4 frag (v2f i) : SV_Target { float _CircleEdgeInFrag = (1 - _CircleEdge)*0.5; float disToCenter = (i.uv.x-0.5)*(i.uv.x-0.5) + (i.uv.y-0.5)*(i.uv.y-0.5); if( 0.5*0.5 > disToCenter && disToCenter > _CircleEdgeInFrag*_CircleEdgeInFrag ) return fixed4(_ColorTint.xyz, 1); else return fixed4(_ColorTint.xyz, 0); } ENDCG } } } 使用注意

圆环整体的大小通过Transform\Scale进行控制, Scale为1时,可以在场景中看到圆环外环半径刚好是网格线的一半。 在这里插入图片描述

例 让圆环缩放时,宽度保持不变的C#脚本如下,主要是控制Scale和CircleEdge的比例关系。

using System.Collections; using System.Collections.Generic; using UnityEngine; public class FixedEdgeWidth : MonoBehaviour { public Material circleEdgeMaterial; float rate; void Start() { rate = circleEdgeMaterial.GetFloat("_CircleEdge"); rate *= transform.localScale.x; } void Update() { circleEdgeMaterial.SetFloat("_CircleEdge", rate / transform.localScale.x); if(Input.GetKeyDown(KeyCode.UpArrow)){ transform.localScale = new Vector3(transform.localScale.x+0.5f, transform.localScale.y+0.5f, transform.localScale.z); } if(Input.GetKeyDown(KeyCode.DownArrow)){ transform.localScale = new Vector3(transform.localScale.x-0.5f, transform.localScale.y-0.5f, transform.localScale.z); } } }

20220130160604 20220130160619



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3