该项目的目的是同时测试和演示来自 Unity DOTS 技术堆栈的多个新包。
您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

180 行
5.1 KiB

Shader "Instanced/DebugTextShader"
{
Properties
{
_FontTex ("Font (RGB)", 2D) = "white" {}
}
CGINCLUDE
uint GetUint(Texture2D tex, float4 size, uint x, uint y)
{
uint w,h;
tex.GetDimensions(w,h);
y = h - 1 - y;
float2 uv = (float2(x,y)+0.5) * size.xy;
uint4 bytes = tex.Load(uint3(x,y,0)) * 255;
return (bytes.z&0xff) | ((bytes.y&0xff)<<8) | ((bytes.x&0xff)<<16) | ((bytes.w&0xff)<<24);
}
uint GetUshort(Texture2D tex, float4 size, uint x, uint y)
{
int bits = (int)(x&1) * 16;
return (GetUint(tex, size, x/2,y) >> bits) & 0xFFFF;
}
ENDCG
SubShader
{
Pass
{
Tags{ "Queue" = "Transparent" "RenderType" = "Transparent" }
ZWrite off
ZTest Always
Cull off
//Blend One One
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdbase nolightmap nodirlightmap nodynlightmap novertexlight
#pragma target 4.5
#include "UnityCG.cginc"
Texture2D _CellTex;
Texture2D _FontTex;
uniform float4 _CellTex_TexelSize;
uniform float4 _FontTex_TexelSize;
// TODO: molokai or tango
float4 scales; // glyph scale in world (x,y) and on texture (z,w)
StructuredBuffer<float4> colorBuffer;
float4 Palette(uint index)
{
return colorBuffer[index];
}
uint textBufferWidth;
StructuredBuffer<uint> textBuffer;
struct Cell
{
uint code;
uint color;
uint side;
};
Cell GetCell(uint x, uint y)
{
uint u = textBuffer[y * (3840/8) + x];
Cell cell;
cell.code = (u & 0x7f) | ((u >> 16) << 7);
cell.color = (u >> 8) & 0x7f;
cell.side = (u >> 15) & 1;
return cell;
}
struct instanceData
{
float3 worldPosition;
float2 firstCell;
float2 cellSize;
uint useWorldMatrix;
};
StructuredBuffer<instanceData> positionBuffer;
struct v2f
{
float4 pos : SV_POSITION;
float2 screenPos : TEXCOORD0;
float instanceVal : TEXCOORD1;
};
v2f vert(uint vid : SV_VertexID, uint instanceID : SV_InstanceID)
{
// We just draw a bunch of vertices but want to pretend to
// be drawing two-triangle quads. Build inst/vert id for this:
int instID = vid / 6.0;
int vertID = vid - instID * 6;
// Generates (0,0) (1,0) (1,1) (1,1) (1,0) (0,0) from vertID
float4 v_pos = saturate(float4(2 - abs(vertID - 2), 2 - abs(vertID - 3), 0, 0));
// Read instance data
float2 screenPosition;
if (positionBuffer[instID].useWorldMatrix != 0)
{
float4 projectionPosition = mul(UNITY_MATRIX_VP, float4(positionBuffer[instID].worldPosition, 1));
screenPosition.x = (projectionPosition.x / projectionPosition.w) * 0.5 + 0.5;
screenPosition.y = -(projectionPosition.y / projectionPosition.w) * 0.5 + 0.5;
screenPosition.x /= scales.z;
screenPosition.y /= scales.w;
}
else
screenPosition = positionBuffer[instID].worldPosition.xy;
float2 pos = screenPosition * scales.zw;
float2 scale = positionBuffer[instID].cellSize * scales.xy;
// Generate position
float2 p = pos + v_pos * scale;
p.y = 1.0 - p.y;
p = float2(-1, -1) + p * 2.0;
v2f o;
o.pos = float4(p.xy, 1, 1);
o.screenPos = screenPosition;
o.instanceVal = instID;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
int instID = i.instanceVal;
int2 pixel_xy = i.pos.xy - i.screenPos;
pixel_xy.y = _ScreenParams.y-1 - pixel_xy.y;
// pixel_xy /= 2;
int2 cell_xy = int2(pixel_xy.x >> 3, pixel_xy.y >> 4);
int2 firstCell = positionBuffer[i.instanceVal].firstCell;
Cell cell = GetCell(firstCell.x + cell_xy.x, firstCell.y + cell_xy.y);
if((cell.color & 0xf) == (cell.color >> 4)&0x7)
discard;
uint coord_x = pixel_xy.x & 7;
uint coord_y = pixel_xy.y & 15;
uint coord_col = cell.code & 255;
uint coord_row = cell.code >> 8;
uint coord_side = cell.side;
uint bitInCell = coord_y * 8 + coord_x;
uint pixelInQuad = bitInCell >> 5;
uint pixelInQuadX = pixelInQuad & 1;
uint pixelInQuadY = pixelInQuad >> 1;
// each 32x32 pixels is a UNICODE row of 8x16 pixel cells (256 code points with the same high byte)
// inside each 32x32, each 2x2 is one 8x16 pixel cell of one code point. so it's 16x16 cells total
// code points wider than 8x16 (e.g. chinese) have the right half in another 32x32 pixels
uint encodedX = pixelInQuadX + 2 * (coord_col & 15) + 32 * (coord_row & 15);
uint encodedY = pixelInQuadY + 2 * (coord_col >> 4) + 32 * (coord_row >> 4) + coord_side * 512;
int2 encoded_xy = int2(encodedX, encodedY);
uint dwordVal = GetUint(_FontTex, _FontTex_TexelSize, encoded_xy.x, encoded_xy.y);
uint bitInDword = bitInCell & 31;
uint color = (dwordVal >> bitInDword) & 1;
if(color)
return Palette((cell.color >> 4) & 0x07);
else
return Palette((cell.color >> 0) & 0x0F);
}
ENDCG
}
}
}