IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> 菜ji瞎逼逼:基于UGUI的图文混排(续) -> 正文阅读

[游戏开发]菜ji瞎逼逼:基于UGUI的图文混排(续)

上一篇 图文混排

时至今日又有到这个需求 就又把这个捡起来,顺便发现有了更好的理解。以做记录
直接上shader


//	Author:zouchunyi
//	E-mail:zouchunyi@kingsoft.com

Shader "UI/EmojiText" {
	Properties {
		[PerRendererData] _MainTex ("Font Texture", 2D) = "white" {}
		_Color ("Tint", Color) = (1,1,1,1)
		
		_StencilComp ("Stencil Comparison", Float) = 8
		_Stencil ("Stencil ID", Float) = 0
		_StencilOp ("Stencil Operation", Float) = 0
		_StencilWriteMask ("Stencil Write Mask", Float) = 255
		_StencilReadMask ("Stencil Read Mask", Float) = 255
		
		_ColorMask ("Color Mask", Float) = 15
		
		[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0

		_EmojiTex ("Emoji Texture", 2D) = "white" {}
		_EmojiDataTex ("Emoji Data", 2D) = "white" {}
		_EmojiSize ("Emoji count of every line",float) = 200
		_FrameSpeed ("FrameSpeed",Range(0,10)) = 3
	}
	
	SubShader
	{
		Tags
		{ 
			"LightMode"="UniversalForward"
			"Queue"="Transparent" 
			"IgnoreProjector"="True" 
			"RenderType"="Transparent" 
			"PreviewType"="Plane"
			"CanUseSpriteAtlas"="True"
		}
		
		Stencil
		{
			Ref [_Stencil]
			Comp [_StencilComp]
			Pass [_StencilOp] 
			ReadMask [_StencilReadMask]
			WriteMask [_StencilWriteMask]
		}

		Cull Off
		Lighting Off
		ZWrite Off
		ZTest [unity_GUIZTestMode]
		Blend SrcAlpha OneMinusSrcAlpha
		ColorMask [_ColorMask]

		Pass
		{
			Name "Default"
		CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#pragma target 2.0

			#include "UnityCG.cginc"
			#include "UnityUI.cginc"

			#pragma multi_compile __ UNITY_UI_ALPHACLIP
			
			struct appdata_t
			{
				float4 vertex   : POSITION;
				float4 color    : COLOR;
				float2 texcoord : TEXCOORD0;
				float2 texcoord1 : TEXCOORD1;
			};

			struct v2f
			{
				float4 vertex   : SV_POSITION;
				fixed4 color    : COLOR;
				half2 texcoord  : TEXCOORD0;
				half2 texcoord1 : TEXCOORD1;
			};
			
			fixed4 _Color;
			fixed4 _TextureSampleAdd;
			float4 _ClipRect;

			v2f vert(appdata_t IN)

			{
				v2f OUT;
				OUT.vertex = UnityObjectToClipPos(float4(IN.vertex.x, IN.vertex.y, IN.vertex.z, 1.0));

				OUT.texcoord = IN.texcoord;
				OUT.texcoord1 = IN.texcoord1;
				
				#ifdef UNITY_HALF_TEXEL_OFFSET
				OUT.vertex.xy += (_ScreenParams.zw-1.0) * float2(-1,1) * OUT.vertex.w;
				#endif
				
				OUT.color = IN.color * _Color;
				return OUT;
			}

			sampler2D _MainTex;
			sampler2D _EmojiTex;
			sampler2D _EmojiDataTex;
		    float _EmojiSize;
			float _FrameSpeed;

			fixed4 frag(v2f IN) : SV_Target
			{
				fixed4 color;
				if (IN.texcoord1.x >0 && IN.texcoord1.y > 0)
				{
					// it's an emoji

					// compute the size of emoji
					half size = (1 / _EmojiSize);
					// compute the center uv of per pixel in the emoji
					half2 uv = half2(floor(IN.texcoord1.x * _EmojiSize) * size + 0.5 * size,floor(IN.texcoord1.y * _EmojiSize) * size + 0.5 * size);
					// read data
					fixed4 data = tex2D(_EmojiDataTex, uv);
					// compute the frame count of emoji
					half frameCount = 1 + sign(data.r) + sign(data.g) * 2 + sign(data.b) * 4;
					// compute current frame index of emoji
					half index = abs(fmod(floor(_Time.x * _FrameSpeed * 50), frameCount));
					// judge current frame is in the next line or not.
					half flag = (1 + sign(IN.texcoord1.x + index * size - 1)) * 0.5;
					// compute the final uv
					IN.texcoord1.x += index * size - flag;
					IN.texcoord1.y += size * flag;

					color = tex2D(_EmojiTex, IN.texcoord1);
				}else
				{
					// it's a text, and render it as normal ugui text
					color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;
				}

				#ifdef UNITY_UI_ALPHACLIP
				clip (color.a - 0.001);
				#endif

				return color;
			}
		ENDCG
		}
	}
}

重要的就两部分
在这里插入图片描述
在片源着色器里 用if判断这个这个片元有没有第二套uv坐标(因为通过之前写的自定义text组件里把需要渲染图片的位置赋值了第二套uv坐标,而普通文字没有,所以是默认0)来区分是图片还是文字。是图片就走_emojiTex(之前生成的图片合集),并且用texcoord1(第二套uv坐标), 是文字就走下边默认的,用第一套uv。就这么简单。
至于中间那些是实现帧动画计算张数的,我暂时没用到,可以直接注释掉,不再赘述。

碰到过的难点
把这个shader放进工程里发现没有效果,甚至连正常文字都渲染不出来。
问题所在:
我们工程用了urp管线,我这个shader用的cg代码没有加上
"LightMode" = "UniversalForward
在tags里加上这个就好了

难点2
当输入的文字里有空格,制表符,回车之类的东西时候表情就会渲染失败,变成初始的“%%”
问题所在:是在自定义imagetext组件里计算图片所在顶点序号的时候把空格什么的也算进去了,但是生成渲染网格的时候空格什么的又不渲染,不在verts里面,所以就造成没对上
解决办法,给输入字符串匹配表情符号的时候先去空格,如图
在这里插入图片描述
好了大概就这样~

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-01-28 12:15:50  更:2022-01-28 12:17:53 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 18:25:32-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码