博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
疑难杂症小记
阅读量:4224 次
发布时间:2019-05-26

本文共 2815 字,大约阅读时间需要 9 分钟。

  

  说来其实也不算什么疑难杂症,原因后面再叙,只是最近遇到个代码问题确实令我犯了好一阵疑难,在此简单一记,算作总结吧~

 

  起因颇为简单,平时工作时无意瞟了一眼的UILabel实现,其中有段实现字体阴影的代码,原理来说其实挺清晰的,就是将原先用以渲染文本的顶点数据原样拷贝一份,然后做些位置偏移和颜色改变即可,代码大概是这副样子~

// generate original vertex dataNGUIText.Print(text, verts, uvs, cols);// apply an effect if one was requestedif (effectStyle != Effect.None){	// apply shadow vertex data	ApplyShadow(verts, uvs, cols, offset, end, pos.x, -pos.y);}

  浮光掠影的看了一下,突然想到一个问题:既然ApplyShadow整体复制了一份文本顶点数据,那么最终生成的顶点数据大概就是:

 

  v1, v2, v3, ... , c1, c2, c3, ... 

  (其中v1, v2, v3, ... 为原始顶点数据、c1, c2, c3, ... 为复制后的顶点数据)

 

  那么问题来了,既然这些顶点是在同一个drawcall中进行绘制的,那么为何c1, c2, c3, ...的绘制结果总是在v1, v2, v3, ... 之后呢?如果不能保证这个绘制顺序,那么自然也不能正确的实现文本阴影的渲染~

 

  依着这个疑问,首先瞅了下相关的NGUI Shader实现,大概来看还是相对简单的,代码大抵是这样:

// shader headerSubShader{	Tags	{		"Queue" = "Transparent"		"IgnoreProjector" = "True"		"RenderType" = "Transparent"	}	Cull Off	Lighting Off	ZWrite Off	Offset -1, -1	Fog { Mode Off }	Blend SrcAlpha OneMinusSrcAlpha	Pass	{		CGPROGRAM			#pragma vertex vert			#pragma fragment frag			#include "UnityCG.cginc"			struct appdata_t			{				float4 vertex : POSITION;				half4 color : COLOR;				float2 texcoord : TEXCOORD0;			};			struct v2f			{				float4 vertex : POSITION;				half4 color : COLOR;				float2 texcoord : TEXCOORD0;			};			sampler2D _MainTex;			v2f vert (appdata_t v)			{				v2f o;				o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);				o.texcoord = v.texcoord;				o.color = v.color;				return o;			}			half4 frag (v2f i) : COLOR			{				half4 col = i.color;				col.a *= tex2D(_MainTex, i.texcoord).a;				return col;			}		ENDCG	}}// other SubShaders

  简单上张图~

  值得注意的就是Shader关闭了ZWrite,这将导致所有的顶点都会被渲染至framebuffer,如果我们尝试打开下ZWrite便如期而至了~

  但是目前虽然确定了所有顶点都会被渲染,但是各个顶点间的渲染顺序还不能确定,普通渲染一般都会打开ZWrite,那么这时的渲染顺序其实并不重要,因为最终的绘制顺序会由ZBuffer来保证,可惜这里的ZWrite被关闭了~

 

  继续Google了一阵,觉得还是请教下熟悉这块的同事效率更高,于是问了下引擎组的同事,几次询问讨论下来,确定了渲染顺序的问题:

 

  即顶点的渲染顺序与其提交至GPU的顺序是一致的(至少“看上去”是的,GPU可以在保证渲染结果正确性的基础上进行优化),所以如果那上面的例子来说的话:

 

   v1, v2, v3, ... , 会首先绘制,然后绘制c1, c2, c3, ... 

 

  WTF,如果是这样的话,文本的阴影就会一直显示在文本之上!但是同事的一个简单示例又确实说明了这种渲染顺序的正确性,没办法,事实证明还有猫腻的地方,得再细查一下~

 

  重新回头深入看了一下之前那个想当然的ApplyShadow,终于发现了蹊跷:

/// /// Apply a shadow effect to the buffer./// public void ApplyShadow (BetterList
verts, BetterList
uvs, BetterList
cols, int start, int end, float x, float y){ // implementation details ... for (int i = start; i < end; ++i) { // add copy buffer data verts.Add(verts.buffer[i]); uvs.Add(uvs.buffer[i]); cols.Add(cols.buffer[i]); // update verts.buffer[i] Vector3 v = verts.buffer[i]; v.x += x; v.y += y; verts.buffer[i] = v; // implementation details ... // update cols.buffer[i] }}

  原来该方法是将阴影顶点数据加到了原顶点数据之前!还是按照之前的示例来说,正确的顶点数据应该是:

 

  c1, c2, c3, ..., v1, v2, v3, ...

  (其中v1, v2, v3, ... 为原始顶点数据、c1, c2, c3, ... 为复制后的顶点数据)

 

  看到此,终算是全身通畅了,上也有相关的解答(好像还提到了例外的情况,不是十分熟悉),也大概了浏览了一下,不过暂时没有定位到十分相关的说明,有 了解的童鞋可以告之一下~

 

  就这样吧~

你可能感兴趣的文章
学习人必看!空军老兵自学编程,仅隔一年成为国土安全部的数据库分析师
查看>>
皱眉细节完美复刻,阿尔伯塔大学团队标星2.5K的项目生成超逼真的肖像画
查看>>
微软亚研院副院长周明:从语言智能到代码智能
查看>>
不到1000行代码,GitHub 1400星,天才黑客开源深度学习框架tinygrad
查看>>
Nature:科研PUA太严重,过半博士后打算逃离
查看>>
数据科学很性感?不,其实它非常枯燥!
查看>>
李宏毅强化学习完整笔记!开源项目《LeeDeepRL-Notes》发布
查看>>
赵劲松:预知潜在风险,做化工安全科技创新的引领者
查看>>
王者荣耀AI绝悟完全体对战开启:英雄随便选,论文已被NeurIPS收录
查看>>
原创 | 人工智能的人文主义,如何让AI更有爱
查看>>
三维人脸识别研究进展综述(附pdf)
查看>>
Kaggle神器LightGBM最全解读!
查看>>
通知 | 2020年度“RONG”奖学金入围答辩名单公布
查看>>
2020 Kaggle年度报告发布:美国公司最容易「人均百万」,90%数据科学家坚持终生学习...
查看>>
基于Dijkstra算法的武汉地铁路径规划!(附下载)
查看>>
外卖平台涉嫌大数据杀熟,处理不能“自说自话”
查看>>
AI把爱豆变胖视频火遍B站,我们找到了背后的技术团队:你是怎么把刘亦菲变胖的?...
查看>>
斯坦福被炮轰:用算法分配5000支新冠疫苗,医护人员只有7支
查看>>
人工智能基准(Benchmarking)再思考
查看>>
原创 | 一文了解人工智能对精准扶贫的作用及数字乡村建设现状
查看>>