Godot 4 着色器 - Shader调试

我之前用OpenCV进行图像相关处理,觉得已经很不错,结合GDI可以实现流畅的动画效果

直到近来用Shader后才发现,着色器更上一层楼,原来这是入了GPU的坑

Shader编程限制很多,各种不支持,看在它性能不错功能炫酷的份上,忍了,努力增加一些自己需要的功能

最优先的功能是调试需要,Shader的过程信息也不能输出到文本日志中,也不能输出到调试窗口中。查了一下,一般的做法就是在画面中用一些颜色表示。这应该是比较低效的了。

琢磨了一下,调试信息还是只能在画面上显示,不过信息最好能以图形、文字等形式展现

图形信息展示

一般来说,能在画面上把点、线、矩形、圆展示出来就OK,当然,点可以通过圆画出来。

先来最简单的线。主要的几个参数:

uv: UV坐标系的点,当前像素点坐标,归一化表示

firstPoint、secondPoint:线段的两点

lineWidth:线宽

startColor、endColor:计划实现渐变的颜色填充,这是填充的首尾色

gradientMethod:渐变模式,水平/垂直/中心辐射

// 【图形信息】在指定位置(两点式+线宽)画出线段
vec4 metaLog_Line(vec2 uv, vec2 firstPoint, vec2 secondPoint, float lineWidth, vec4 startColor, vec4 endColor, int gradientMethod, out bool inFlag) {
	float distance = distancePointToLine(uv, firstPoint, secondPoint) / lineWidth;
	inFlag = (distance < 0.5 && 
		(length(uv - (firstPoint + secondPoint) / 2.0) <= length(firstPoint - secondPoint) / 2.0));
	if(inFlag) {
		float startDistance, endDistance;
		if((gradientMethod & DIR_VERT) == 0) {
			startDistance = length(uv - firstPoint);
			endDistance = length(uv - secondPoint);
		} else {
			bool atRightFlag = false; 
			if(firstPoint.x == secondPoint.x)
				atRightFlag = uv.x >= firstPoint.x;
			else {
				float m = (secondPoint.y - firstPoint.y) / (secondPoint.x - firstPoint.x);
				float v = uv.y - m * (uv.x - firstPoint.x) - firstPoint.y;
				atRightFlag = (v >= 0.0);
			}
			endDistance = atRightFlag ? 0.5 - distance : .5 + distance;
			startDistance = atRightFlag ? 0.5 + distance : 0.5 - distance;
		}
		float startWeight = 1.0 - startDistance / (startDistance + endDistance);
		if((gradientMethod & GRADIENT_MIDDLE) > 0)
			startWeight = abs(startDistance - endDistance);
		return startColor* startWeight + endColor * (1.0 - startWeight);
	}
	return vec4(0);
}

核心思路就是判断uv是否在指定线宽的线段上(决定输出的inFlag),如果在其上就根据填充方式与uv位置、两点位置计算出颜色融合权重,并据此算出最终颜色值。如果不在其上就不受影响。

则调试时加入相应调用即可,如在翻页时,展示出鼠标所在位置与相应基准角点连线

loggedColor = metaLog_Line(uv, mousePoint / pageSize, basePoint / pageSize, 0.002, vec4(1.0, 0.0, 0.0, 1.0), vec4(1.0, 0.0, 0.0, 1.0), DIR_HORZ, inFlag, !WHOLE_LINE);
if(inFlag) color = loggedColor;			

 运行效果如下

Godot 4 着色器 - Shader调试_第1张图片

 确认能达到调试效果。剩下的矩形、圆就轻松了。

// 【图形信息】在指定位置(p1、p2)画出矩形,
vec4 metaLog_Rect(vec2 uv, vec2 p1, vec2 p2, vec4 startColor, vec4 endColor, int gradientMethod, out bool inFlag) {
	vec2 leftTopPoint = vec2(min(p1.x, p2.x), min(p1.y, p2.y));
	vec2 rightBottomPoint = vec2(max(p1.x, p2.x), max(p1.y, p2.y));
	inFlag = isInRange(uv.x, leftTopPoint.x, rightBottomPoint.x) &&
	   		 isInRange(uv.y, leftTopPoint.y, rightBottomPoint.y);
	if(inFlag) {
		float startDistance, endDistance;
		if((gradientMethod & DIR_VERT) == 0) {
			startDistance = (uv.x - leftTopPoint.x);
			endDistance = (rightBottomPoint.x - uv.x);
		} else {
			startDistance = (uv.y - leftTopPoint.y);
			endDistance = (rightBottomPoint.y - uv.y);
		}
		float startWeight = 1.0 - startDistance / (startDistance + endDistance);
		if((gradientMethod & GRADIENT_MIDDLE) > 0)
			startWeight = abs(startDistance - endDistance);
		return startColor * startWeight + endColor * (1.0 - startWeight);
	}
	return vec4(0); 
}

// 【图形信息】在指定位置(圆心+半径)画出圆
vec4 metaLog_Circle(vec2 uv, vec2 centerPoint, float radius, vec4 startColor, vec4 endColor, int gradientMethod, out bool inFlag) {
	float distance = length(uv - centerPoint);
	inFlag = distance <= radius;
	if(inFlag) {
		float startWeight = 0.0;
		if( (gradientMethod & DIR_ZOOMIN) > 0 )
			startWeight = 1.0 - distance / radius;;
		if( (gradientMethod & DIR_ZOOMOUT) > 0)
			startWeight = distance / radius;
		return startColor * startWeight + endColor * (1.0 - startWeight);
	}
	return vec4(0);
}

思路差不多,根据当前像素点位置、待显示图形参数与渐变颜色,确定最终的颜色。

比如,折页碰到中间限制后,目标点就不能再为鼠标点了,需要调整,看起来才合理自然。

// 调整后的mousePoint输出显示
loggedColor = metaLog_Circle(uv, mousePoint / pageSize, 0.01, logFontColor, endColor, DIR_ZOOMIN, inFlag);
if(inFlag) color = loggedColor;

Godot 4 着色器 - Shader调试_第2张图片

在此思路基础上 ,想用任何图形信息调试均可较轻松实现。

 文字输出

文字输出,本质上也是画出来,所以,首先要自己做一个字模。

做字模也简单,先确认目标,32*32的位图即可。其次是范围,中文太多肯定不用,就把可打印的ASCII字符做出来。之后用Word用某种喜欢的字体把这些字符录入,缩放到合适比例大小,确保可以截下来的每个字符图片均为32*32

花了一点时间,生成所需要的ASCII字符图片

Godot 4 着色器 - Shader调试_第3张图片

 然后针对各图片逐行扫描,生成01码,每行32位,刚好一个int表示,这样一个字模用32个int表示。解析的C++代码:

TStrings * fileNames = new TStringList;
TStrings * results = new TStringList;
THelper::File::BrowseDir(fileNames, path, L"*.bmp", false);
for(int index = 0; index < fileNames->Count; ++index) {
	UnicodeString fileName = fileNames->Strings[index];
	cv::Mat mat = CvHelper::MatFromFile(fileName);
	mat = CvHelper::ToMat_GRAY(mat);
	threshold(mat, mat, 128, 255, cv::THRESH_BINARY);
	int v[32];
	UnicodeString valueInfo = L"";
	for(int row = 0; row < mat.rows; ++row) {
		int value = 0;
		UnicodeString s = L"";
		for(int col = 0; col < mat.cols; ++col) {
			value <<= 1;
			BYTE data = mat.at(row, col);
			if(data == 0)
				value += 1;
			s += data == 0 ? L"*" : L" ";
		}
		v[row] = value;
		THelper::Logi(L"%s > 0x%X", s, value);
		if(row)
			valueInfo += L", ";
		valueInfo += FORMAT(L"0x%X", value);
	}

	results->Add(FORMAT(L"if(asciiChar == 0x%02X) model.Model = int[](%s);",
		TTypeConvert::String2Int(THelper::File::ExtractPureFileName(fileName)), valueInfo));
}
THelper::Logi(L"result:\n%s", TTypeConvert::StringList2String(results, L"\n"));
delete results;
delete fileNames;

从而生成Shader可用字模代码:

int Model[32];
	 if(asciiChar == 0x21) Model = int[](0x0, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x3C000, 0x38000, 0x38000, 0x38000, 0x38000, 0x38000, 0x38000, 0x38000, 0x38000, 0x38000, 0x38000, 0x38000, 0x38000, 0x0, 0x0, 0x0, 0x0, 0x7C000, 0xFE000, 0xFE000, 0xFE000, 0xFE000, 0x7C000, 0x38000, 0x0);
else if(asciiChar == 0x22) Model = int[](0x0, 0x381C00, 0x7C3E00, 0xFE7F00, 0xFE7F00, 0xFE3F00, 0x7E3F00, 0xE0700, 0xE0700, 0x1C0E00, 0x1C0E00, 0x381C00, 0xF07C00, 0xE07000, 0x402000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0);
else if(asciiChar == 0x23) Model = int[](0x0, 0x0, 0xE0E00, 0xC0E00, 0xC0E00, 0x1C0C00, 0x1C0C00, 0x1C1C00, 0x1C1C00, 0x1C1C00, 0x1FFFF80, 0x1FFFF80, 0x1FFFF80, 0x381800, 0x381800, 0x383800, 0x383800, 0x383800, 0x383800, 0x3FFFF80, 0x3FFFF80, 0x3FFFF00, 0x703000, 0x707000, 0x707000, 0x707000, 0x707000, 0x707000, 0x607000, 0xE07000, 0x606000, 0x0);
else if(asciiChar == 0x24) Model = int[](0x0, 0x18000, 0x18000, 0x18000, 0x18000, 0x1C000, 0xFF000, 0x1FFC00, 0x3FFE00, 0x780C00, 0x780000, 0x780000, 0x780000, 0x3E0000, 0x3F8000, 0x1FF000, 0x7F800, 0xFC00, 0x3E00, 0x1F00, 0xF00, 0xF00, 0x700E00, 0xFC3E00, 0x7FFC00, 0x1FF800, 0x3C000, 0x18000, 0x18000, 0x18000, 0x18000, 0x18000);
else if(asciiChar == 0x25) Model = int[](0x0, 0x0, 0xF80000, 0x1FE0040, 0x3CF00E0, 0x38701E0, 0x70703C0, 0x7038380, 0x7038700, 0x7038E00, 0x7039C00, 0x7871800, 0x38F0000, 0x1FE0000, 0x1FC0000, 0x300000, 0x3F80, 0x7FC0, 0xC71E0, 0x1CE0E0, 0x38E0E0, 0x70E0F0, 0xE0E0F0, 0x1E0E0E0, 0x3C0E0E0, 0x780F0E0, 0x30079E0, 0x3FC0, 0x1F00, 0x0, 0x0, 0x0);
else if(asciiChar == 0x26) Model = int[](0x0, 0x0, 0x1F0000, 0x3FC000, 0x7FE000, 0x70E000, 0xF0E000, 0xE0E000, 0xE0E000, 0xE0E000, 0xF1C000, 0xF3C000, 0x7F8000, 0x7F0000, 0x7C01C0, 0xFC01C0, 0x1FE03C0, 0x3FF03C0, 0x3CF8780, 0x787C780, 0x783EF00, 0x781FF00, 0x780FE00, 0x7807E00, 0x7C07F00, 0x3E0FFC0, 0x1FFFFE0, 0xFFE3C0, 0x7F80C0, 0x0, 0x0, 0x0);
else if(asciiChar == 0x27) Model = int[](0x0, 0x3C000, 0x3E000, 0x7E000, 0x7E000, 0x3F000, 0x1F000, 0x6000, 0xE000, 0xE000, 0x1C000, 0x3C000, 0x78000, 0x20000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0);
else if(asciiChar == 0x28) Model = int[](0x1000, 0x7800, 0x7000, 0xE000, 0x1C000, 0x1C000, 0x38000, 0x38000, 0x70000, 0x70000, 0x60000, 0xE0000, 0xE0000, 0xE0000, 0xE0000, 0xE0000, 0xE0000, 0xE0000, 0xE0000, 0xE0000, 0x60000, 0x70000, 0x70000, 0x78000, 0x38000, 0x3C000, 0x1C000, 0xE000, 0x7000, 0x7800, 0x1000, 0x0);
else if(asciiChar == 0x29) Model = int[](0x40000, 0xF0000, 0x70000, 0x38000, 0x1C000, 0x1C000, 0xE000, 0xF000, 0x7000, 0x7000, 0x3000, 0x3800, 0x3800, 0x3800, 0x3800, 0x3800, 0x3800, 0x3800, 0x3800, 0x3800, 0x3000, 0x7000, 0x7000, 0xE000, 0xE000, 0x1C000, 0x1C000, 0x38000, 0x70000, 0xF0000, 0x40000, 0x0);
else if(asciiChar == 0x2A) Model = int[](0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x41C100, 0xF9CF80, 0x7FFF00, 0x1FFC00, 0x7E000, 0x3E000, 0x7F000, 0xF7800, 0xE3800, 0x1C1C00, 0x380C00, 0x180C00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0);
else if(asciiChar == 0x2B) Model = int[](0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1FFFFC0, 0x1FFFFC0, 0x1FFFFC0, 0x3C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0);
else if(asciiChar == 0x2C) Model = int[](0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3C000, 0x7E000, 0x7E000, 0x7E000, 0x7F000, 0x3F000, 0xF000, 0xE000, 0xE000, 0x1E000, 0x3C000, 0xF8000, 0xF0000, 0x40000);
else if(asciiChar == 0x2D) Model = int[](0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3FFFFF0, 0x3FFFFF0, 0x3FFFFF0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0);
else if(asciiChar == 0x2E) Model = int[](0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1C000, 0x7E000, 0x7E000, 0x7F000, 0x7E000, 0x3E000, 0x1C000, 0x0);
else if(asciiChar == 0x2F) Model = int[](0x700, 0xE00, 0xE00, 0x1E00, 0x1C00, 0x1C00, 0x3800, 0x3800, 0x3800, 0x7000, 0x7000, 0xF000, 0xE000, 0xE000, 0x1C000, 0x1C000, 0x1C000, 0x38000, 0x38000, 0x78000, 0x70000, 0x70000, 0xE0000, 0xE0000, 0xE0000, 0x1C0000, 0x1C0000, 0x3C0000, 0x380000, 0x380000, 0x700000, 0x0);
else if(asciiChar == 0x30) Model = int[](0x18000, 0x1FF800, 0x3FFC00, 0x7FFE00, 0xFC3F00, 0x1F80F80, 0x1F00780, 0x3E007C0, 0x3E003C0, 0x3C003C0, 0x3C003E0, 0x7C003E0, 0x7C081E0, 0x7C3C1E0, 0x7C7E1E0, 0x787E1E0, 0x787E1E0, 0x7C7E1E0, 0x7C3C1E0, 0x7C001E0, 0x7C003E0, 0x3C003E0, 0x3C003C0, 0x3E003C0, 0x3E007C0, 0x1F00780, 0x1F80F80, 0xFC3F00, 0x7FFE00, 0x3FFC00, 0x1FF800, 0x1C000);
else if(asciiChar == 0x31) Model = int[](0x0, 0x1F000, 0x7F000, 0xFFF000, 0xFFF000, 0xFFF000, 0x1F000, 0x1F000, 0x1F000, 0x1F000, 0x1F000, 0x1F000, 0x1F000, 0x1F000, 0x1F000, 0x1F000, 0x1F000, 0x1F000, 0x1F000, 0x1F000, 0x1F000, 0x1F000, 0x1F000, 0x1F000, 0x1F000, 0x1F000, 0x1F000, 0x1FFFFE0, 0x3FFFFE0, 0x3FFFFE0, 0x3FFFFE0, 0x0);
else if(asciiChar == 0x32) Model = int[](0x30000, 0x3FF000, 0xFFFC00, 0x1FFFE00, 0x3F87F00, 0x7C01F00, 0x3800F80, 0xF80, 0xF80, 0x780, 0x780, 0xF80, 0xF80, 0xF00, 0x1F00, 0x3E00, 0x7C00, 0x7C00, 0xF800, 0x1F000, 0x3E000, 0x7C000, 0xF8000, 0x1F0000, 0x7E0000, 0xFC0000, 0x1F80000, 0x3FFFFE0, 0x7FFFFE0, 0x7FFFFE0, 0x7FFFFE0, 0x0);
else if(asciiChar == 0x33) Model = int[](0x38000, 0x3FF800, 0xFFFE00, 0x1FFFF00, 0x3F87F00, 0x1E01F80, 0x1800F80, 0x780, 0x7C0, 0x780, 0xF80, 0xF80, 0x3F00, 0x1FE00, 0x1FF800, 0x1FF000, 0x1FFC00, 0x1FF00, 0x1F80, 0xFC0, 0x7C0, 0x3C0, 0x3E0, 0x3E0, 0x7C0, 0x30007C0, 0x7C00FC0, 0x7F87F80, 0x3FFFF00, 0x1FFFE00, 0x7FF800, 0x78000);
else if(asciiChar == 0x34) Model = int[](0x0, 0x3E00, 0x7E00, 0xFE00, 0x1FE00, 0x1FE00, 0x3DE00, 0x7DE00, 0xF9E00, 0xF1E00, 0x1F1E00, 0x3E1E00, 0x7C1E00, 0x781E00, 0xF81E00, 0x1F01E00, 0x3E01E00, 0x3C01E00, 0x7801E00, 0xFFFFFE0, 0xFFFFFF0, 0xFFFFFF0, 0xFFFFFF0, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x0);
else if(asciiChar == 0x35) Model = int[](0x0, 0xFFFF80, 0xFFFF80, 0xFFFF80, 0xFFFF80, 0xF00000, 0x1F00000, 0x1F00000, 0x1F00000, 0x1F00000, 0x1F00000, 0x1E00000, 0x1E7F000, 0x1FFFE00, 0x1FFFF00, 0x1FCFF80, 0xE01FC0, 0xFC0, 0x7C0, 0x3E0, 0x3E0, 0x3E0, 0x3E0, 0x3C0, 0x7C0, 0x3000FC0, 0x7C01F80, 0x7F07F80, 0x3FFFF00, 0x1FFFC00, 0x7FF800, 0x78000);
else if(asciiChar == 0x36) Model = int[](0x6000, 0x7FE00, 0x1FFF80, 0x3FFFC0, 0x7F8FC0, 0xFC0180, 0xF80000, 0x1F00000, 0x1E00000, 0x3E00000, 0x3E00000, 0x3C00000, 0x3C00000, 0x3C3FE00, 0x7CFFF00, 0x7DFFF80, 0x7FE0FC0, 0x7F007C0, 0x7E003E0, 0x3C003E0, 0x3C001E0, 0x3C001E0, 0x3C001E0, 0x3E001E0, 0x1E003E0, 0x1F003E0, 0xF807C0, 0xFE1FC0, 0x7FFF80, 0x3FFE00, 0xFFC00, 0x1C000);
else if(asciiChar == 0x37) Model = int[](0x0, 0x7FFFFE0, 0x7FFFFE0, 0x7FFFFE0, 0x7FFFFE0, 0x7C0, 0x780, 0xF00, 0x1F00, 0x1E00, 0x3C00, 0x7C00, 0x7800, 0xF800, 0xF000, 0x1F000, 0x1E000, 0x1E000, 0x3E000, 0x3C000, 0x3C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x78000, 0x78000, 0xF8000, 0xF8000, 0xF8000, 0xF8000, 0x0);
else if(asciiChar == 0x38) Model = int[](0x1C000, 0x1FF800, 0x3FFE00, 0x7FFF00, 0xFC1F80, 0x1F00F80, 0x1E007C0, 0x1E003C0, 0x1E003C0, 0x1E003C0, 0x1F00380, 0x1F80780, 0xFC0F00, 0x7F1F00, 0x3FFE00, 0x1FFC00, 0x3FFE00, 0xF8FF00, 0x1F01F80, 0x3E00FC0, 0x3C007E0, 0x78003E0, 0x78001E0, 0x78001E0, 0x7C001E0, 0x7C003E0, 0x3E007C0, 0x3F80FC0, 0x1FFFF80, 0xFFFF00, 0x3FFC00, 0x3C000);
else if(asciiChar == 0x39) Model = int[](0x30000, 0x3FF000, 0x7FFC00, 0xFFFE00, 0x1F83F00, 0x3E01F00, 0x3E00F80, 0x7C007C0, 0x7C007C0, 0x78003C0, 0x78003C0, 0x78003E0, 0x7C003E0, 0x7C007E0, 0x3E00FE0, 0x3F03FE0, 0x1FFFFE0, 0xFFF3E0, 0x7FE3E0, 0x603E0, 0x3C0, 0x3C0, 0x7C0, 0x780, 0xF80, 0x1F80, 0x1C03F00, 0x3F0FE00, 0x3FFFC00, 0x1FFF800, 0x7FE000, 0xF0000);
else if(asciiChar == 0x3A) Model = int[](0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1C000, 0x3E000, 0x7F000, 0x7F000, 0x7F000, 0x3E000, 0x3C000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1C000, 0x3E000, 0x7F000, 0x7F000, 0x7F000, 0x7E000, 0x3E000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0);
else if(asciiChar == 0x3B) Model = int[](0x0, 0x0, 0x0, 0x3C000, 0x7E000, 0x7E000, 0x7E000, 0x7E000, 0x7C000, 0x18000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3C000, 0x7E000, 0x7E000, 0x7F000, 0x7F000, 0x1F000, 0xE000, 0xE000, 0xE000, 0x1C000, 0x3C000, 0xF8000, 0xE0000, 0x0, 0x0, 0x0);
else if(asciiChar == 0x3C) Model = int[](0x0, 0x0, 0x0, 0x0, 0x200, 0x600, 0x1E00, 0x3E00, 0xFC00, 0x1F000, 0x7E000, 0xF8000, 0x3F0000, 0x7C0000, 0xF80000, 0xF00000, 0xF80000, 0x7C0000, 0x3F0000, 0xF8000, 0x7E000, 0x1F000, 0xFC00, 0x3E00, 0x1E00, 0x600, 0x200, 0x0, 0x0, 0x0, 0x0, 0x0);
else if(asciiChar == 0x3D) Model = int[](0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3FFFFF0, 0x3FFFFF0, 0x3FFFFF0, 0x3FFFFF0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3FFFFF0, 0x3FFFFF0, 0x3FFFFF0, 0x3FFFFF0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0);
else if(asciiChar == 0x3E) Model = int[](0x0, 0x0, 0x0, 0x0, 0x400000, 0x600000, 0x780000, 0x7C0000, 0x3F0000, 0xF8000, 0x7E000, 0x1F000, 0xFC00, 0x3E00, 0x1F00, 0xF00, 0x1F00, 0x3E00, 0xFC00, 0x1F000, 0x7E000, 0xF8000, 0x3F0000, 0x7C0000, 0x780000, 0x600000, 0x400000, 0x0, 0x0, 0x0, 0x0, 0x0);
else if(asciiChar == 0x3F) Model = int[](0x0, 0x0, 0x0, 0x7E000, 0x1FF800, 0x3FFC00, 0x7C3E00, 0x301E00, 0xE00, 0xE00, 0x1E00, 0x1E00, 0x3C00, 0x7800, 0xF000, 0x1E000, 0x3C000, 0x3C000, 0x38000, 0x38000, 0x0, 0x0, 0x0, 0x3C000, 0x7C000, 0x7E000, 0x7E000, 0x7E000, 0x3C000, 0x0, 0x0, 0x0);
else if(asciiChar == 0x40) Model = int[](0x0, 0x3F000, 0xFFC00, 0x3F3E00, 0x780700, 0x700700, 0xE00380, 0xE00380, 0x1C00380, 0x1C00180, 0x1800780, 0x3807F80, 0x381FF80, 0x383E380, 0x3878380, 0x3870380, 0x3870380, 0x3870380, 0x3870780, 0x387FF80, 0x383F980, 0x180E000, 0x1C00000, 0x1C00000, 0xE00000, 0xF00000, 0x700000, 0x3C0600, 0x1FFF00, 0xFFC00, 0x1F000, 0x0);
else if(asciiChar == 0x41) Model = int[](0x0, 0x0, 0xFC000, 0xFC000, 0xFC000, 0x1FE000, 0x1DE000, 0x1DE000, 0x3CF000, 0x3CF000, 0x38F000, 0x787800, 0x787800, 0x707800, 0xF07C00, 0xF03C00, 0xF03C00, 0x1E03E00, 0x1FFFE00, 0x1FFFE00, 0x3FFFF00, 0x3FFFF00, 0x3C00F00, 0x7800F80, 0x7800F80, 0x7800780, 0xF8007C0, 0xF0007C0, 0xF0003C0, 0x1F0003E0, 0x0, 0x0);
else if(asciiChar == 0x42) Model = int[](0x0, 0x7FFE000, 0x7FFF800, 0x7FFFE00, 0x7FFFE00, 0x7C03F00, 0x7C01F00, 0x7C00F00, 0x7C00F80, 0x7C00F00, 0x7C00F00, 0x7C01F00, 0x7C03E00, 0x7FFFC00, 0x7FFF800, 0x7FFF800, 0x7FFFE00, 0x7C07F00, 0x7C00F80, 0x7C007C0, 0x7C007C0, 0x7C003C0, 0x7C003C0, 0x7C007C0, 0x7C007C0, 0x7C00FC0, 0x7C01F80, 0x7FFFF80, 0x7FFFF00, 0x7FFFC00, 0x7FFF000, 0x0);
else if(asciiChar == 0x43) Model = int[](0x1FC00, 0xFFF00, 0x1FFFC0, 0x7FFFE0, 0x7F07E0, 0xFC01C0, 0x1F80000, 0x1F00000, 0x3E00000, 0x3E00000, 0x3C00000, 0x7C00000, 0x7C00000, 0x7C00000, 0x7C00000, 0x7C00000, 0x7C00000, 0x7C00000, 0x7C00000, 0x7C00000, 0x7C00000, 0x3E00000, 0x3E00000, 0x3F00000, 0x1F80040, 0xFC00E0, 0xFE03E0, 0x7FFFE0, 0x3FFFC0, 0xFFF80, 0x3FE00, 0x0);
else if(asciiChar == 0x44) Model = int[](0x0, 0x7FF8000, 0x7FFF000, 0x7FFFC00, 0x7FFFE00, 0x7C07F00, 0x7C03F00, 0x7C01F80, 0x7C00FC0, 0x7C007C0, 0x7C007C0, 0x7C003C0, 0x7C003E0, 0x7C003E0, 0x7C003E0, 0x7C003E0, 0x7C003E0, 0x7C003E0, 0x7C003E0, 0x7C003E0, 0x7C007C0, 0x7C007C0, 0x7C007C0, 0x7C00F80, 0x7C01F80, 0x7C03F00, 0x7C07F00, 0x7FFFE00, 0x7FFFC00, 0x7FFF000, 0x7FFC000, 0x0);
else if(asciiChar == 0x45) Model = int[](0x0, 0x3FFFF80, 0x3FFFF80, 0x3FFFF80, 0x3FFFF80, 0x3E00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x3FFFC00, 0x3FFFE00, 0x3FFFE00, 0x3FFFE00, 0x3E00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x3FFFF80, 0x3FFFF80, 0x3FFFF80, 0x3FFFF80, 0x0);
else if(asciiChar == 0x46) Model = int[](0x0, 0x1FFFFC0, 0x1FFFFC0, 0x1FFFFC0, 0x1FFFFC0, 0x1F00000, 0x1F00000, 0x1F00000, 0x1F00000, 0x1F00000, 0x1F00000, 0x1F00000, 0x1F00000, 0x1F00000, 0x1FFFF00, 0x1FFFF00, 0x1FFFF00, 0x1FFFF00, 0x1F00000, 0x1F00000, 0x1F00000, 0x1F00000, 0x1F00000, 0x1F00000, 0x1F00000, 0x1F00000, 0x1F00000, 0x1F00000, 0x1F00000, 0x1F00000, 0x1F00000, 0x0);
else if(asciiChar == 0x47) Model = int[](0x1FC00, 0xFFF00, 0x1FFFC0, 0x7FFFE0, 0xFF07C0, 0xFC0180, 0x1F80000, 0x1F00000, 0x3E00000, 0x3E00000, 0x3C00000, 0x7C00000, 0x7C00000, 0x7C00000, 0x7C00000, 0x7C07FE0, 0x7C07FE0, 0x7C07FE0, 0x7C03FE0, 0x7C001E0, 0x7C001E0, 0x3E001E0, 0x3E001E0, 0x3F001E0, 0x1F001E0, 0x1F801E0, 0xFE03E0, 0x7FFFE0, 0x3FFFC0, 0x1FFF80, 0x3FE00, 0x0);
else if(asciiChar == 0x48) Model = int[](0x0, 0x3E003E0, 0x3E003E0, 0x3E003E0, 0x3E003E0, 0x3E003E0, 0x3E003E0, 0x3E003E0, 0x3E003E0, 0x3E003E0, 0x3E003E0, 0x3E003E0, 0x3E003E0, 0x3FFFFE0, 0x3FFFFE0, 0x3FFFFE0, 0x3FFFFE0, 0x3E003E0, 0x3E003E0, 0x3E003E0, 0x3E003E0, 0x3E003E0, 0x3E003E0, 0x3E003E0, 0x3E003E0, 0x3E003E0, 0x3E003E0, 0x3E003E0, 0x3E003E0, 0x3E003E0, 0x3E003E0, 0x0);
else if(asciiChar == 0x49) Model = int[](0x0, 0x3FFFF80, 0x3FFFF80, 0x3FFFF80, 0x3FFFF80, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x3FFFF80, 0x3FFFF80, 0x3FFFF80, 0x3FFFF80, 0x0);
else if(asciiChar == 0x4A) Model = int[](0x0, 0xFFFFC0, 0xFFFFC0, 0xFFFFC0, 0x7FFFC0, 0x7C0, 0x7C0, 0x7C0, 0x7C0, 0x7C0, 0x7C0, 0x7C0, 0x7C0, 0x7C0, 0x7C0, 0x7C0, 0x7C0, 0x7C0, 0x7C0, 0x7C0, 0x7C0, 0x7C0, 0x7C0, 0x780, 0x800F80, 0x1C00F80, 0x3E01F80, 0x1F87F00, 0x1FFFE00, 0xFFFE00, 0x3FF800, 0x7C000);
else if(asciiChar == 0x4B) Model = int[](0x0, 0x7C007C0, 0x7C00FC0, 0x7C01F80, 0x7C01F00, 0x7C03E00, 0x7C07C00, 0x7C0F800, 0x7C1F800, 0x7C3F000, 0x7C3E000, 0x7C7C000, 0x7CF8000, 0x7DFC000, 0x7FFC000, 0x7FFE000, 0x7FFF000, 0x7F9F000, 0x7F0F800, 0x7F0F800, 0x7E07C00, 0x7C07C00, 0x7C03E00, 0x7C03E00, 0x7C01F00, 0x7C01F80, 0x7C00F80, 0x7C007C0, 0x7C007C0, 0x7C003E0, 0x7C003E0, 0x0);
else if(asciiChar == 0x4C) Model = int[](0x0, 0x3E00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x3FFFF80, 0x3FFFF80, 0x3FFFF80, 0x3FFFF80, 0x0);
else if(asciiChar == 0x4D) Model = int[](0x0, 0x7E007C0, 0x7E007C0, 0x7E00FC0, 0x7E00FC0, 0x7F00FC0, 0x7F01FC0, 0x7F01FC0, 0x7F81DC0, 0x7B83DC0, 0x7B83BC0, 0x7BC3BC0, 0x7BC7BC0, 0x79C73C0, 0x79E73C0, 0x79EF3C0, 0x78EE3C0, 0x78FE3C0, 0x78FE3C0, 0x787C3C0, 0x787C3C0, 0x783C3C0, 0x78383C0, 0x78003C0, 0x78003C0, 0x78003C0, 0x78003C0, 0x78003C0, 0x78003C0, 0x78003C0, 0x78003C0, 0x0);
else if(asciiChar == 0x4E) Model = int[](0x0, 0x3E003C0, 0x3F003C0, 0x3F003C0, 0x3F803C0, 0x3F803C0, 0x3FC03C0, 0x3FC03C0, 0x3DE03C0, 0x3DE03C0, 0x3DF03C0, 0x3CF03C0, 0x3CF83C0, 0x3C783C0, 0x3C7C3C0, 0x3C3C3C0, 0x3C3E3C0, 0x3C1E3C0, 0x3C1F3C0, 0x3C0F3C0, 0x3C0F3C0, 0x3C07BC0, 0x3C07BC0, 0x3C03FC0, 0x3C03FC0, 0x3C01FC0, 0x3C01FC0, 0x3C00FC0, 0x3C00FC0, 0x3C007C0, 0x3C007C0, 0x0);
else if(asciiChar == 0x4F) Model = int[](0xFE000, 0x3FF800, 0x7FFE00, 0xFFFF00, 0x1FC3F00, 0x3F01F80, 0x3E00FC0, 0x7C007C0, 0x7C007C0, 0x7C003E0, 0xF8003E0, 0xF8003E0, 0xF8001E0, 0xF8001E0, 0xF8001E0, 0xF8001F0, 0xF8001F0, 0xF8001E0, 0xF8001E0, 0xF8003E0, 0xF8003E0, 0x7C003E0, 0x7C003C0, 0x7C007C0, 0x3E00FC0, 0x3F00F80, 0x1F83F80, 0xFFFF00, 0xFFFE00, 0x3FFC00, 0xFF000, 0x0);
else if(asciiChar == 0x51) Model = int[](0xF0000, 0x3FE000, 0xFFF000, 0x1FFF800, 0x1E07C00, 0x3C03C00, 0x3C03C00, 0x7801E00, 0x7801E00, 0x7801E00, 0x7800E00, 0x7800E00, 0x7800F00, 0x7800F00, 0x7800E00, 0x7801E00, 0x7801E00, 0x7801E00, 0x7801E00, 0x3C03C00, 0x3C03C00, 0x1E07800, 0xFFF800, 0x7FF000, 0x3FC000, 0xF0000, 0x78000, 0x3C000, 0x3FE00, 0x1FF00, 0x7F00, 0x0);
else if(asciiChar == 0x52) Model = int[](0x0, 0x7FFF000, 0x7FFFC00, 0x7FFFF00, 0x7FFFF00, 0x7C01F80, 0x7C00F80, 0x7C007C0, 0x7C007C0, 0x7C007C0, 0x7C007C0, 0x7C007C0, 0x7C007C0, 0x7C00F80, 0x7C01F80, 0x7FFFF00, 0x7FFFE00, 0x7FFFC00, 0x7FFF000, 0x7C1F000, 0x7C1F800, 0x7C0F800, 0x7C0FC00, 0x7C07C00, 0x7C03E00, 0x7C03E00, 0x7C01F00, 0x7C01F80, 0x7C00F80, 0x7C00FC0, 0x7C007C0, 0x7C003E0);
else if(asciiChar == 0x53) Model = int[](0x7F000, 0x3FFE00, 0x7FFF80, 0xFFFFC0, 0x1FC0F80, 0x1F00380, 0x1E00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x1F00000, 0x1FC0000, 0xFF0000, 0xFFC000, 0x3FF800, 0x1FFE00, 0x3FF00, 0xFF80, 0x3FC0, 0xFE0, 0x7E0, 0x3E0, 0x3E0, 0x3E0, 0x18003E0, 0x3C007C0, 0x7F00FC0, 0x3FFFF80, 0x1FFFF00, 0x7FFE00, 0x1FF800, 0x0);
else if(asciiChar == 0x54) Model = int[](0x0, 0xFFFFFF8, 0xFFFFFF8, 0xFFFFFF8, 0xFFFFFF8, 0x3E000, 0x3E000, 0x3E000, 0x3E000, 0x3E000, 0x3E000, 0x3E000, 0x3E000, 0x3E000, 0x3E000, 0x3E000, 0x3E000, 0x3E000, 0x3E000, 0x3E000, 0x3E000, 0x3E000, 0x3E000, 0x3E000, 0x3E000, 0x3E000, 0x3E000, 0x3E000, 0x3E000, 0x3E000, 0x3E000, 0x3C000);
else if(asciiChar == 0x55) Model = int[](0x7C003C0, 0x7C003C0, 0x7C003C0, 0x7C003C0, 0x7C003C0, 0x7C003C0, 0x7C003C0, 0x7C003C0, 0x7C003C0, 0x7C003C0, 0x7C003C0, 0x7C003C0, 0x7C003C0, 0x7C003C0, 0x7C003C0, 0x7C003C0, 0x7C003C0, 0x7C003C0, 0x7C003C0, 0x7C003C0, 0x7C003C0, 0x7C007C0, 0x7C007C0, 0x7C007C0, 0x3E00780, 0x3F00F80, 0x3F83F80, 0x1FFFF00, 0xFFFE00, 0x7FFC00, 0x1FF000, 0x0);
else if(asciiChar == 0x56) Model = int[](0x0, 0xF8000F8, 0xF8000F0, 0x7C001F0, 0x7C001F0, 0x7C001E0, 0x3E001E0, 0x3E003E0, 0x3E003E0, 0x1E003C0, 0x1F007C0, 0x1F007C0, 0xF00780, 0xF80780, 0xF80F80, 0x780F00, 0x7C0F00, 0x7C1F00, 0x7C1E00, 0x3C1E00, 0x3E1E00, 0x3E3C00, 0x1E3C00, 0x1E3C00, 0x1F7C00, 0xF7800, 0xF7800, 0xFF800, 0x7F000, 0x7F000, 0x7F000, 0x3E000);
else if(asciiChar == 0x57) Model = int[](0x0, 0x3E0000F8, 0x3E0000F8, 0x3E0000F8, 0x3F0000F8, 0x1F0000F8, 0x1F0000F8, 0x1F0000F8, 0x1F0000F0, 0x1F03C0F0, 0x1F03C0F0, 0xF07E1F0, 0xF07E1F0, 0xF07E1F0, 0xF8FE1F0, 0xF8FF1E0, 0xF8EF1E0, 0xF8EF1E0, 0x79EF1E0, 0x79E79E0, 0x79E79E0, 0x79C7BE0, 0x7BC7BC0, 0x7BC3BC0, 0x7BC3FC0, 0x3F83FC0, 0x3F83FC0, 0x3F81FC0, 0x3F81FC0, 0x3F01F80, 0x3F01F80, 0x3F01F80);
else if(asciiChar == 0x58) Model = int[](0x0, 0x7C003E0, 0x7E007C0, 0x3E007C0, 0x1F00F80, 0x1F00F00, 0xF81F00, 0xF81E00, 0x7C3E00, 0x7C3C00, 0x3E7C00, 0x1E7800, 0x1FF000, 0xFF000, 0xFE000, 0x7E000, 0xFE000, 0xFF000, 0x1FF000, 0x1EF800, 0x3EF800, 0x7C7C00, 0x7C3C00, 0xF83E00, 0xF01F00, 0x1F01F00, 0x1E00F80, 0x3E00F80, 0x7C007C0, 0x7C007E0, 0xF8003E0, 0x0);
else if(asciiChar == 0x59) Model = int[](0x0, 0xF8000F0, 0x7C001F0, 0x7C001E0, 0x3E003E0, 0x3E003C0, 0x1F007C0, 0x1F00780, 0xF80F80, 0xF80F00, 0x7C1F00, 0x7C1E00, 0x3C3E00, 0x3E3C00, 0x1E7C00, 0x1F7800, 0xFF800, 0xFF000, 0x7F000, 0x7E000, 0x3E000, 0x3E000, 0x3E000, 0x3E000, 0x3E000, 0x3E000, 0x3E000, 0x3E000, 0x3E000, 0x3E000, 0x3E000, 0x0);
else if(asciiChar == 0x5A) Model = int[](0x0, 0x3FFFFE0, 0x3FFFFE0, 0x3FFFFE0, 0x3FFFFC0, 0x7C0, 0xF80, 0x1F00, 0x1F00, 0x3E00, 0x7C00, 0xFC00, 0xF800, 0x1F000, 0x3E000, 0x3E000, 0x7C000, 0xF8000, 0xF8000, 0x1F0000, 0x3E0000, 0x3E0000, 0x7C0000, 0xF80000, 0xF80000, 0x1F00000, 0x3E00000, 0x3FFFFE0, 0x7FFFFE0, 0x7FFFFE0, 0x7FFFFE0, 0x0);
else if(asciiChar == 0x5B) Model = int[](0x0, 0x1FF800, 0x1FF800, 0x1C0000, 0x1C0000, 0x1C0000, 0x1C0000, 0x1C0000, 0x1C0000, 0x1C0000, 0x1C0000, 0x1C0000, 0x1C0000, 0x1C0000, 0x1C0000, 0x1C0000, 0x1C0000, 0x1C0000, 0x1C0000, 0x1C0000, 0x1C0000, 0x1C0000, 0x1C0000, 0x1C0000, 0x1C0000, 0x1C0000, 0x1C0000, 0x1C0000, 0x1C0000, 0x1C0000, 0x1FF800, 0x1FF800);
else if(asciiChar == 0x5C) Model = int[](0x0, 0x700000, 0x380000, 0x380000, 0x3C0000, 0x1C0000, 0x1C0000, 0xE0000, 0xE0000, 0xF0000, 0x70000, 0x70000, 0x78000, 0x38000, 0x3C000, 0x1C000, 0x1C000, 0x1E000, 0xE000, 0xF000, 0x7000, 0x7000, 0x7800, 0x3800, 0x3800, 0x1C00, 0x1C00, 0x1E00, 0xE00, 0xE00, 0x700, 0x0);
else if(asciiChar == 0x5D) Model = int[](0x0, 0x1FF800, 0x1FF800, 0x3800, 0x3800, 0x3800, 0x3800, 0x3800, 0x3800, 0x3800, 0x3800, 0x3800, 0x3800, 0x3800, 0x3800, 0x3800, 0x3800, 0x3800, 0x3800, 0x3800, 0x3800, 0x3800, 0x3800, 0x3800, 0x3800, 0x3800, 0x3800, 0x3800, 0x3800, 0x3800, 0x1FF800, 0x1FF800);
else if(asciiChar == 0x5E) Model = int[](0x0, 0x1C000, 0x3E000, 0x3E000, 0x7E000, 0x77000, 0x77000, 0xE3800, 0xE3800, 0x1E3800, 0x1C1C00, 0x1C1C00, 0x381E00, 0x380E00, 0x780E00, 0x700700, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0);
else if(asciiChar == 0x5F) Model = int[](0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7FFFFC0, 0x7FFFFC0, 0x7FFFFC0, 0x0, 0x0, 0x0, 0x0);
else if(asciiChar == 0x60) Model = int[](0x0, 0x60000, 0xF0000, 0x1F8000, 0xFC000, 0x7C000, 0x3E000, 0x1F000, 0xF000, 0x6000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0);
else if(asciiChar == 0x61) Model = int[](0x0, 0x0, 0x0, 0x0, 0x0, 0xFF000, 0x3FFC00, 0xFFFE00, 0x1FFFF00, 0xE01F00, 0x800F80, 0xF80, 0x780, 0x7F80, 0xFFF80, 0x3FFF80, 0xFF0780, 0x1F80780, 0x1E00780, 0x3C00780, 0x3C00780, 0x3C00F80, 0x3E03F80, 0x3F8FF80, 0x1FFF780, 0xFFE780, 0x3F8380, 0x0, 0x0, 0x0, 0x0, 0x0);
else if(asciiChar == 0x62) Model = int[](0x1E00000, 0x1E00000, 0x1E00000, 0x1E00000, 0x1E00000, 0x1E00000, 0x1E00000, 0x1E00000, 0x1E00000, 0x1E1F800, 0x1E7FE00, 0x1FFFF00, 0x1FFFF80, 0x1FC0F80, 0x1F007C0, 0x1E007C0, 0x1E003C0, 0x1E003E0, 0x1E003E0, 0x1E003E0, 0x1E003E0, 0x1E003E0, 0x1E003C0, 0x1E003C0, 0x1E007C0, 0x1F00F80, 0x1F81F80, 0x1FFFF00, 0x1FFFE00, 0x1EFFC00, 0x1C1F000, 0x0);
else if(asciiChar == 0x63) Model = int[](0x0, 0x0, 0x0, 0x0, 0x0, 0x3F800, 0x1FFF00, 0x3FFF80, 0x7FFF80, 0xFC0380, 0x1F80000, 0x1F00000, 0x1E00000, 0x3E00000, 0x3E00000, 0x3C00000, 0x3C00000, 0x3E00000, 0x3E00000, 0x3E00000, 0x1F00000, 0x1F80000, 0xFC0380, 0x7F9FC0, 0x3FFF80, 0x1FFF00, 0x7F800, 0x0, 0x0, 0x0, 0x0, 0x0);
else if(asciiChar == 0x64) Model = int[](0x7C0, 0x7C0, 0x7C0, 0x7C0, 0x7C0, 0x7C0, 0x7C0, 0x7C0, 0x7C0, 0xFC7C0, 0x1FF7C0, 0x7FFFC0, 0xFFFFC0, 0xF80FC0, 0x1F007C0, 0x1F007C0, 0x3E007C0, 0x3E007C0, 0x3E007C0, 0x3C007C0, 0x3C007C0, 0x3C007C0, 0x3E007C0, 0x3E007C0, 0x1E007C0, 0x1F00FC0, 0x1F81FC0, 0xFFFFC0, 0x7FFBC0, 0x3FF3C0, 0xFC180, 0x0);
else if(asciiChar == 0x65) Model = int[](0x0, 0x0, 0x0, 0x0, 0x0, 0x3F800, 0x1FFE00, 0x3FFF00, 0x7FBF80, 0xF807C0, 0x1F003C0, 0x1F003C0, 0x1E001E0, 0x3E001E0, 0x3FFFFE0, 0x3FFFFE0, 0x3FFFFE0, 0x3FFFFC0, 0x3E00000, 0x3E00000, 0x1E00000, 0x1F00000, 0xF80000, 0xFE0380, 0x7FFFC0, 0x3FFF80, 0xFFE00, 0xE000, 0x0, 0x0, 0x0, 0x0);
else if(asciiChar == 0x66) Model = int[](0x7F80, 0x1FFE0, 0x3FFC0, 0x7F3C0, 0x7C000, 0xF8000, 0xF0000, 0xF0000, 0xF0000, 0xF0000, 0x3FFFF80, 0x3FFFF80, 0x3FFFF80, 0xF0000, 0xF0000, 0xF0000, 0xF0000, 0xF0000, 0xF0000, 0xF0000, 0xF0000, 0xF0000, 0xF0000, 0xF0000, 0xF0000, 0xF0000, 0xF0000, 0xF0000, 0xF0000, 0xF0000, 0xF0000, 0x0);
else if(asciiChar == 0x67) Model = int[](0x1FFFC0, 0x7FFFC0, 0xFFFFC0, 0x1F87FC0, 0x1E03C00, 0x3E03C00, 0x3C01E00, 0x3C01E00, 0x3C01E00, 0x3E01E00, 0x1E03C00, 0x1F07C00, 0xFFF800, 0xFFF000, 0x1EFC000, 0x1C00000, 0x3C00000, 0x3C00000, 0x3F80000, 0x1FFFF00, 0xFFFFC0, 0x1FFFFC0, 0x3C007C0, 0x78003E0, 0x78003C0, 0x78003C0, 0x78007C0, 0x7E01F80, 0x3FFFF00, 0x1FFFC00, 0x3FE000, 0x0);
else if(asciiChar == 0x68) Model = int[](0x0, 0x1E00000, 0x1E00000, 0x1E00000, 0x1E00000, 0x1E00000, 0x1E00000, 0x1E00000, 0x1E00000, 0x1E00000, 0x1E1FC00, 0x1E3FF00, 0x1EFFF00, 0x1FFFF80, 0x1FC0F80, 0x1F807C0, 0x1F007C0, 0x1E003C0, 0x1E003C0, 0x1E003C0, 0x1E003C0, 0x1E003C0, 0x1E003C0, 0x1E003C0, 0x1E003C0, 0x1E003C0, 0x1E003C0, 0x1E003C0, 0x1E003C0, 0x1E003C0, 0x1E003C0, 0x1E00380);
else if(asciiChar == 0x69) Model = int[](0x0, 0x3C00, 0x7E00, 0x7E00, 0x7E00, 0x7E00, 0x3C00, 0x0, 0x0, 0x0, 0x0, 0x7FFC00, 0x7FFC00, 0x7FFC00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x1C00);
else if(asciiChar == 0x6A) Model = int[](0x3800, 0x7C00, 0x7C00, 0x7C00, 0x3800, 0x0, 0x0, 0x0, 0x1FF800, 0x1FFC00, 0x1FFC00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3800, 0x3800, 0x7800, 0x1FF000, 0x3FF000, 0xFC000);
else if(asciiChar == 0x6B) Model = int[](0x0, 0x1E00000, 0x1E00000, 0x1E00000, 0x1E00000, 0x1E00000, 0x1E00000, 0x1E00000, 0x1E00000, 0x1E00000, 0x1E007C0, 0x1E00F80, 0x1E01F00, 0x1E03E00, 0x1E07C00, 0x1E0F800, 0x1E1F000, 0x1E3E000, 0x1E7C000, 0x1EFE000, 0x1FFF000, 0x1FEF000, 0x1FC7800, 0x1F87C00, 0x1F03E00, 0x1E01E00, 0x1E01F00, 0x1E00F80, 0x1E00780, 0x1E003C0, 0x1E003E0, 0x0);
else if(asciiChar == 0x6C) Model = int[](0x3FFC000, 0x3FFC000, 0x3FFC000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x7C000, 0x3E000, 0x3FFC0, 0x1FFC0, 0xFFC0, 0x7F00, 0x0);
else if(asciiChar == 0x6D) Model = int[](0x0, 0x0, 0x0, 0x0, 0x0, 0x71F0F00, 0x73F1FC0, 0x7FFBFC0, 0x7FFFFE0, 0x7E3E3E0, 0x7C3C1E0, 0x783C1E0, 0x783C1E0, 0x783C1E0, 0x783C1E0, 0x783C1E0, 0x783C1E0, 0x783C1E0, 0x783C1E0, 0x783C1E0, 0x783C1E0, 0x783C1E0, 0x783C1E0, 0x783C1E0, 0x783C1E0, 0x783C1E0, 0x78181C0, 0x0, 0x0, 0x0, 0x0, 0x0);
else if(asciiChar == 0x6E) Model = int[](0x0, 0x0, 0x0, 0x0, 0x0, 0x1C0FC00, 0x1E3FF00, 0x1EFFF00, 0x1FFFF80, 0x1FC0F80, 0x1F807C0, 0x1F007C0, 0x1E007C0, 0x1E003C0, 0x1E003C0, 0x1E003C0, 0x1E003C0, 0x1E003C0, 0x1E003C0, 0x1E003C0, 0x1E003C0, 0x1E003C0, 0x1E003C0, 0x1E003C0, 0x1E003C0, 0x1E003C0, 0x1E00380, 0x0, 0x0, 0x0, 0x0, 0x0);
else if(asciiChar == 0x6F) Model = int[](0x0, 0x0, 0x0, 0x0, 0x0, 0x7F000, 0x1FFC00, 0x3FFF00, 0x7FFF00, 0xF80F80, 0x1F007C0, 0x1E007C0, 0x3E003E0, 0x3E003E0, 0x3E003E0, 0x3C001E0, 0x3C001E0, 0x3C003E0, 0x3E003E0, 0x3E003E0, 0x1E003C0, 0x1F007C0, 0xF80F80, 0x7F7F80, 0x7FFF00, 0x1FFC00, 0x7F000, 0x0, 0x0, 0x0, 0x0, 0x0);
else if(asciiChar == 0x70) Model = int[](0x0, 0x383F000, 0x3CFFC00, 0x3DFFE00, 0x3FFFF00, 0x3F81F00, 0x3E00F80, 0x3C00F80, 0x3C00780, 0x3C00780, 0x3C007C0, 0x3C007C0, 0x3C007C0, 0x3C007C0, 0x3C00780, 0x3C00780, 0x3C00F80, 0x3E01F00, 0x3F03F00, 0x3FFFE00, 0x3FFFC00, 0x3DFF800, 0x3C7E000, 0x3C00000, 0x3C00000, 0x3C00000, 0x3C00000, 0x3C00000, 0x3C00000, 0x3C00000, 0x3C00000, 0x0);
else if(asciiChar == 0x71) Model = int[](0x0, 0xFC180, 0x1FF3C0, 0x7FFFC0, 0xFFFFC0, 0xF80FC0, 0x1F007C0, 0x1F007C0, 0x3E007C0, 0x3E007C0, 0x3E007C0, 0x3C007C0, 0x3C007C0, 0x3C007C0, 0x3E007C0, 0x3E007C0, 0x1E007C0, 0x1F00FC0, 0x1F81FC0, 0xFFFFC0, 0x7FFFC0, 0x3FF7C0, 0xFC7C0, 0x7C0, 0x7C0, 0x7C0, 0x7C0, 0x7C0, 0x7C0, 0x7C0, 0x7C0, 0x0);
else if(asciiChar == 0x72) Model = int[](0x0, 0x0, 0x0, 0x0, 0x0, 0x1C07F00, 0x1E1FF80, 0x1E3FF80, 0x1E7FF00, 0x1EF8100, 0x1FE0000, 0x1FC0000, 0x1F80000, 0x1F00000, 0x1F00000, 0x1F00000, 0x1F00000, 0x1F00000, 0x1F00000, 0x1F00000, 0x1F00000, 0x1F00000, 0x1F00000, 0x1F00000, 0x1F00000, 0x1F00000, 0x1F00000, 0x1E00000, 0x0, 0x0, 0x0, 0x0);
else if(asciiChar == 0x73) Model = int[](0x0, 0x0, 0x0, 0x0, 0x0, 0xFF000, 0x3FFE00, 0x7FFF00, 0xFC3F00, 0xF00700, 0x1F00000, 0x1F00000, 0x1F00000, 0xFE0000, 0x7FE000, 0x3FFC00, 0xFFF00, 0xFF80, 0x1FC0, 0x7C0, 0x3C0, 0x8003C0, 0x1E007C0, 0x3FC1F80, 0x1FFFF00, 0x7FFE00, 0xFF800, 0x0, 0x0, 0x0, 0x0, 0x0);
else if(asciiChar == 0x74) Model = int[](0x0, 0x0, 0xF0000, 0xF0000, 0xF0000, 0xF0000, 0xF0000, 0xF0000, 0xF0000, 0x3FFFFC0, 0x3FFFFC0, 0x3FFFFC0, 0xF0000, 0xF0000, 0xF0000, 0xF0000, 0xF0000, 0xF0000, 0xF0000, 0xF0000, 0xF0000, 0xF0000, 0xF0000, 0xF0000, 0xF8000, 0xF8000, 0x7E0C0, 0x7FFC0, 0x3FFE0, 0xFF80, 0x0, 0x0);
else if(asciiChar == 0x75) Model = int[](0x0, 0x0, 0x0, 0x0, 0x0, 0x1E007C0, 0x1E007C0, 0x1E007C0, 0x1E007C0, 0x1E007C0, 0x1E007C0, 0x1E007C0, 0x1E007C0, 0x1E007C0, 0x1E007C0, 0x1E007C0, 0x1E007C0, 0x1E007C0, 0x1E007C0, 0x1E007C0, 0x1F00FC0, 0x1F01FC0, 0xF83FC0, 0xFFFBC0, 0x7FF3C0, 0x3FC3C0, 0x60000, 0x0, 0x0, 0x0, 0x0, 0x0);
else if(asciiChar == 0x76) Model = int[](0x0, 0x0, 0x0, 0x0, 0x0, 0x7C001E0, 0x3C003C0, 0x3C003C0, 0x3E00780, 0x1E00780, 0x1E00780, 0xF00F00, 0xF00F00, 0xF81E00, 0x781E00, 0x781E00, 0x3C3C00, 0x3C3C00, 0x3E3800, 0x1E7800, 0x1E7800, 0xF7000, 0xFF000, 0x7E000, 0x7E000, 0x7E000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0);
else if(asciiChar == 0x77) Model = int[](0x0, 0x0, 0x0, 0x0, 0x0, 0x1E0000F0, 0x1E0000F0, 0xF03C0F0, 0xF07C0F0, 0xF07C1E0, 0xF07C1E0, 0xF07E1E0, 0x78EE1E0, 0x78EE1E0, 0x78EE3C0, 0x78EF3C0, 0x78E73C0, 0x3DC73C0, 0x3DC73C0, 0x3DC7B80, 0x3DC7F80, 0x3FC3F80, 0x1F83F80, 0x1F83F80, 0x1F83F00, 0x1F81F00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0);
else if(asciiChar == 0x78) Model = int[](0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x700E00, 0x381E00, 0x3C3C00, 0x1C3800, 0xE7800, 0xF7000, 0x7E000, 0x3C000, 0x7C000, 0x7E000, 0xEF000, 0x1E7800, 0x3C3800, 0x381C00, 0x781E00, 0xF00F00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0);
else if(asciiChar == 0x79) Model = int[](0x0, 0x0, 0x0, 0x0, 0x1E00700, 0xE00E00, 0xE00E00, 0x700E00, 0x701C00, 0x781C00, 0x383800, 0x3C3800, 0x1C3800, 0x1C7000, 0xE7000, 0xE6000, 0x7E000, 0x7E000, 0x3C000, 0x3C000, 0x38000, 0x38000, 0x78000, 0xF0000, 0xFE0000, 0xFC0000, 0xF80000, 0x0, 0x0, 0x0, 0x0, 0x0);
else if(asciiChar == 0x7A) Model = int[](0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7FFF00, 0x7FFF00, 0x3FFE00, 0x3C00, 0x7800, 0xF000, 0x1E000, 0x3C000, 0x78000, 0xF8000, 0x1F0000, 0x3E0000, 0x3C0000, 0x7FFF00, 0xFFFF00, 0xFFFF00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0);
else if(asciiChar == 0x7B) Model = int[](0x0, 0xFE00, 0x1FE00, 0x3C000, 0x38000, 0x38000, 0x38000, 0x38000, 0x38000, 0x38000, 0x38000, 0x38000, 0x38000, 0x38000, 0x78000, 0x7F0000, 0x7E0000, 0x7F0000, 0x78000, 0x38000, 0x38000, 0x38000, 0x38000, 0x38000, 0x38000, 0x38000, 0x38000, 0x38000, 0x38000, 0x3C000, 0x1FE00, 0x7E00);
else if(asciiChar == 0x7C) Model = int[](0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000);
else if(asciiChar == 0x7D) Model = int[](0x0, 0x7E0000, 0x7F8000, 0x3C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1E000, 0xFE00, 0x7E00, 0xFE00, 0x1E000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x1C000, 0x3C000, 0x7F8000, 0x7E0000);
else if(asciiChar == 0x7E) Model = int[](0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3C0180, 0x7F01C0, 0xFF83C0, 0x1E7E780, 0x1C1FF80, 0x380FF00, 0x1803C00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0);

为方便 后续使用,增加一些常量定义

// 各字符的ASCII值
#define CHAR_NOT 				0x21			// !
#define CHAR_QUOTE2 			0x22			// "
#define CHAR_SHARP 				0x23			// #
#define CHAR_DOLLAR 			0x24			// $
#define CHAR_PERCENT 			0x25			// %
#define CHAR_AND 				0x26			// &
#define CHAR_QUOTE1 			0x27			// '
#define CHAR_PARENTHESES_LEFT 	0x28			// (
#define CHAR_PARENTHESES_RIGHT 	0x29			// )
#define CHAR_STAR 				0x2A			// *
#define CHAR_PLUS 				0x2B			// +
#define CHAR_COMMA 				0x2C			// ,
#define CHAR_MINUS 				0x2D			// -
#define CHAR_DOT 				0x2E			// .
#define CHAR_SLASH 				0x2F			// /
#define CHAR_0 					0x30			// 0
#define CHAR_1 					0x31			// 1
#define CHAR_2 					0x32			// 2
#define CHAR_3 					0x33			// 3
#define CHAR_4 					0x34			// 4
#define CHAR_5 					0x35			// 5
#define CHAR_6 					0x36			// 6
#define CHAR_7 					0x37			// 7
#define CHAR_8 					0x38			// 8
#define CHAR_9 					0x39			// 9
#define CHAR_COLON 				0x3A			// :
#define CHAR_SEMICOLON 			0x3B			// ;
#define CHAR_LT 				0x3C			// <
#define CHAR_EQ 				0x3D			// =
#define CHAR_GT 				0x3E			// >
#define CHAR_QUESTION 			0x3F			// ?
#define CHAR_AT 				0x40			// @
#define CHAR_A 					0x41			// A
#define CHAR_B 					0x42			// B
#define CHAR_C 					0x43			// C
#define CHAR_D 					0x44			// D
#define CHAR_E 					0x45			// E
#define CHAR_F 					0x46			// F
#define CHAR_G 					0x47			// G
#define CHAR_H 					0x48			// H
#define CHAR_I 					0x49			// I
#define CHAR_J 					0x4A			// J
#define CHAR_K 					0x4B			// K
#define CHAR_L 					0x4C			// L
#define CHAR_M 					0x4D			// M
#define CHAR_N 					0x4E			// N
#define CHAR_O 					0x4F			// O
#define CHAR_P 					0x50			// P
#define CHAR_Q 					0x51			// Q
#define CHAR_R 					0x52			// R
#define CHAR_S 					0x53			// S
#define CHAR_T 					0x54			// T
#define CHAR_U 					0x55			// U
#define CHAR_V 					0x56			// V
#define CHAR_W 					0x57			// W
#define CHAR_X 					0x58			// X
#define CHAR_Y 					0x59			// Y
#define CHAR_Z 					0x5A			// Z
#define CHAR_BRACKET_LEFT 		0x5B			// [
#define CHAR_SLASH_BACK			0x5C			// \反斜杠
#define CHAR_BRACKET_RIGHT 		0x5D			// ]
#define CHAR_XOR 				0x5E			// ^
#define CHAR_UNDERLINE 			0x5F			// _
#define CHAR_QUOTE_JS 			0x60			// `
#define CHAR_a 					0x61 			// a
#define CHAR_b 					0x62  			// b
#define CHAR_c 					0x63  			// c
#define CHAR_d 					0x64  			// d
#define CHAR_e 					0x65  			// e
#define CHAR_f 					0x66  			// f
#define CHAR_g 					0x67  			// g
#define CHAR_h 					0x68  			// h
#define CHAR_i 					0x69  			// i
#define CHAR_j 					0x6A  			// j
#define CHAR_k 					0x6B  			// k
#define CHAR_l 					0x6C  			// l
#define CHAR_m 					0x6D  			// m
#define CHAR_n 					0x6E  			// n
#define CHAR_o 					0x6F  			// o
#define CHAR_p 					0x70  			// p
#define CHAR_q 					0x71  			// q
#define CHAR_r 					0x72 			// r
#define CHAR_s 					0x73  			// s
#define CHAR_t 					0x74  			// t
#define CHAR_u 					0x75  			// u
#define CHAR_v 					0x76  			// v
#define CHAR_w 					0x77  			// w
#define CHAR_x 					0x78  			// x
#define CHAR_y 					0x79  			// y
#define CHAR_z 					0x7A  			// z
#define CHAR_BRACE_LEFT 		0x7B  			// {
#define CHAR_OR 				0x7C  			// |
#define CHAR_BRACE_RIGHT 		0x7D  			// }
#define CHAR_WAVE 				0x7E  			// ~

现在,就可以画出字符

// 【文本信息】在指定位置(leftTopPoint)输出字符asciiChar,字体大小fontSizeRatio * 32,颜色fontColor
vec4 textLog_Char(vec2 uv, vec2 leftTopPoint, int asciiChar, int fontSizeRatio, vec4 fontColor, out bool inFlag) {
	float characterWidth = float(fontSizeRatio) * 32.0;
	inFlag = isInRange(uv.x, leftTopPoint.x, leftTopPoint.x + characterWidth / pageSize.x) &&
			 isInRange(uv.y, leftTopPoint.y, leftTopPoint.y + characterWidth / pageSize.y);
	if(inFlag) {
		int Model[32];
        if(...) // 字模代码
		else {
			inFlag = false;
			return vec4(0);
		}
		vec2 offset = uv - leftTopPoint;
		int col = int(offset.x * pageSize.x / float(fontSizeRatio) + 0.5);
		int row = int(offset.y * pageSize.y / float(fontSizeRatio) + 0.5);
		if(col > 31) col = 31;
		if(row > 31) row = 31;
		col = 31 - col;
		int value = Model[row];
		if(col > 0)
			value >>= col;
		if((value & 1) > 0) 
			return fontColor;
		else
			inFlag = false;
	}
	return vec4(0, 0, 0, 1);
}

比如,要输出翻页拆线与哪几边相交,就可以用L、T、R、B等字符指示

if(isInRange(solutionTop.x, pageLeft, pageRight)) {
	solutionPoints[pointIndex++] = solutionTop;
	loggedColor = textLog_Char(uv, vec2(0.55, 0.1 * float(pointIndex)), CHAR_T, 1, logFontColor, inFlag);
	if(inFlag) color = loggedColor;
	upDownNumber++;								
}
if(isInRange(solutionBottom.x, pageLeft, pageRight)) {
	solutionPoints[pointIndex++] = solutionBottom;
	loggedColor = textLog_Char(uv, vec2(0.55, 0.1 * float(pointIndex)), CHAR_B, 1, logFontColor, inFlag);
	if(inFlag) color = loggedColor;
	upDownNumber++;
}
if(isInRange(solutionLeft.y, pageTop, pageBottom)) {
	solutionPoints[pointIndex++] = solutionLeft;
	loggedColor = textLog_Char(uv, vec2(0.55, 0.1 * float(pointIndex)), CHAR_L, 1, logFontColor, inFlag);
	if(inFlag) color = loggedColor;
}
if(isInRange(solutionRight.y, pageTop, pageBottom)) {
	solutionPoints[pointIndex++] = solutionRight;
	loggedColor = textLog_Char(uv, vec2(0.55, 0.1 * float(pointIndex)), CHAR_R, 1, logFontColor, inFlag);
	if(inFlag) color = loggedColor;
}

则在翻页过程中,实时指示出计算结果,以查看运算过程与结果是否有误。 

Godot 4 着色器 - Shader调试_第4张图片

 相应扩展一下,可以直接输出整数、浮点数、向量、矩阵等信息,不再赘述。

Godot 4 着色器 - Shader调试_第5张图片

 

 

你可能感兴趣的:(godot,着色器,游戏引擎)