diff options
| author | yum <yum.food.vr@gmail.com> | 2023-12-14 16:31:10 -0800 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2023-12-14 16:31:10 -0800 |
| commit | a5e0aaf10230c4690c6bf702b335edb700d5a8c5 (patch) | |
| tree | d6d085945ddc548020e780bc200bc588c7803127 | |
Initial commit
Basic functionality is complete.
| -rw-r--r-- | README.md | 36 | ||||
| -rw-r--r-- | disinfo.cginc | 101 | ||||
| -rw-r--r-- | disinfo.mat | 81 | ||||
| -rw-r--r-- | disinfo.shader | 55 | ||||
| -rw-r--r-- | disinfo.shader.meta | 9 | ||||
| -rw-r--r-- | disinfo_lighting.cginc | 52 | ||||
| -rw-r--r-- | font-ascii.png | bin | 0 -> 543838 bytes | |||
| -rw-r--r-- | font-ascii.png.meta | 116 | ||||
| -rw-r--r-- | interpolators.cginc | 24 |
9 files changed, 474 insertions, 0 deletions
diff --git a/README.md b/README.md new file mode 100644 index 0000000..31a0864 --- /dev/null +++ b/README.md @@ -0,0 +1,36 @@ +## DisInfo: a simple information display library for hlsl + +This contains HLSL library code to render text based information. This is +something I struggle with so I thought it would be nice to have a simple +abstraction. + +Core APIs: +``` +// uv: uv coordinates +// box_bounds: the left, right, top, and bottom bounds of the box, +// respectively. Bottom-left is (0,0) and top-right is (1, 1). +// res: the number of columns (width) and rows (height) in the box. +// pos [OUT]: the x, y coordinates of the box. +// box_uv [OUT]: the location we're rendering at, expressed in the box's UV +// coordinates. +// Returns true iff the UV is pointing within box_bounds. +bool getBoxLoc(float2 uv, float4 box_bounds, int2 res, out int2 pos, out float2 box_uv); + +// c: char to render +// pos: x,y coordinates of slot to render in +// res: the resolution of the box. +// box_uv: the UV coordinates of the box we're rendering at, on [0, 1]. +float4 renderInBox(char c, int2 pos, int2 res, float2 box_uv); + +// Remap a UV onto a smaller domain. +bool remapUVSmaller(float2 uv, float4 bounds, out float2 uvr); + +// Remaps a UV onto a larger domain. +bool remapUVBigger(float2 uv, float4 bounds, out float2 uvr); +``` + +### TODO + +1. Line wrapping + "string" interface. Strings could be a vector of chars. + Maybe use macros to make them look more like strings. + diff --git a/disinfo.cginc b/disinfo.cginc new file mode 100644 index 0000000..1567e9d --- /dev/null +++ b/disinfo.cginc @@ -0,0 +1,101 @@ +#ifndef __DISINFO_INC +#define __DISINFO_INC + +/* + * A small font rendering library. + * + * Sample usage: + * + * fixed4 frag(v2f i) : SV_Target + * { + * float2 uv = i.uv; + * int2 cell_pos; + * float2 cell_uv; + * float2 res = int2(4, 4); + * if (!getBoxLoc(uv, 0.1, 0.9, res, cell_pos, cell_uv)) { + * return float4(0, 0, 0, 1); + * } + * float2 duv = float2(ddx(i.uv.x), ddy(i.uv.y)) / 4; + * float4 font_color = renderInBox(67, cell_uv, duv); + * + * return font_color; + * } + */ + +// `_Font` should be an 8x16 (8 rows, 16 columns) grid of monospace ASCII +// glyphs. +Texture2D _Font; +float4 _Font_TexelSize; +SamplerState linear_clamp_sampler; + +// Returns false if `uv` does not fall within `bounds`. +bool remapUVSmaller(float2 uv, float2 bottom_left, float2 top_right, + out float2 uvr) { + if (!(uv.x > bottom_left.x && uv.x < top_right.x && + uv.y > bottom_left.y && uv.y < top_right.y)) { + return false; + } + + uvr = uv - bottom_left; + uvr = uvr / (top_right - bottom_left); + + return true; +} + +// bounds: the left/right/top/bottom bounds of the inner UV region, +// respectively. +// Always returns true. +bool remapUVBigger(float2 uv, float2 bottom_left, float2 top_right, + out float2 uvr) { + uvr = uv * (top_right - bottom_left) + bottom_left; + + return true; +} + +bool getBoxLoc(float2 uv, float2 bottom_left, float2 top_right, + int2 res, out int2 cell_pos, out float2 cell_uv) +{ + float2 box_uv; + if (!remapUVSmaller(uv, bottom_left, top_right, box_uv)) { + return false; + } + + // The integer index of the cell pointed to by `uv`, on the interval + // [0, res.x - 1] * [0, res.y - 1] + cell_pos = fmod(floor(box_uv * res), res); + + float2 box_sz = 1.0 / float2(res); + float2 cell_bot_left = cell_pos * box_sz; + float2 cell_top_right = (cell_pos + 1) * box_sz; + if (!remapUVSmaller(box_uv, cell_bot_left, cell_top_right, cell_uv)) { + // This should never happen Clueless + return false; + } + + return true; +} + +// `c` is a character encoded as ASCII. +// `duv` is float2(ddx(i.uv.x), ddy(i.uv.y)), where `i.uv` is the UV of the +// object we're rendering on. +float4 renderInBox(int c, float2 cell_uv, float2 duv) +{ + int2 bitmap_res = int2(16, 8); + int letter_idx = c; + int2 letter_pos = int2( + bitmap_res.x - (letter_idx % bitmap_res.x), + letter_idx / bitmap_res.x); + letter_pos.x = bitmap_res.x - letter_pos.x; + letter_pos.y = (bitmap_res.y - 1) - letter_pos.y; + float2 letter_box_sz = 1.0 / float2(bitmap_res); + float2 letter_bot_left = letter_pos * letter_box_sz; + float2 letter_top_right = (letter_pos + 1) * letter_box_sz; + float2 letter_uv; + remapUVBigger(cell_uv, letter_bot_left, letter_top_right, letter_uv); + + float4 font_color = _Font.SampleGrad(linear_clamp_sampler, letter_uv, duv.x, duv.y); + return font_color; +} + +#endif // __DISINFO_INC + diff --git a/disinfo.mat b/disinfo.mat new file mode 100644 index 0000000..af1cb4f --- /dev/null +++ b/disinfo.mat @@ -0,0 +1,81 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: disinfo + m_Shader: {fileID: 4800000, guid: 367d6c0dd4711124e8e20975949a2306, type: 3} + m_ShaderKeywords: + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Font: + m_Texture: {fileID: 2800000, guid: c257699adf45b4e48a6c0daf1c143fde, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _GlossMapScale: 1 + - _Glossiness: 0.5 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} diff --git a/disinfo.shader b/disinfo.shader new file mode 100644 index 0000000..74b8e5f --- /dev/null +++ b/disinfo.shader @@ -0,0 +1,55 @@ +Shader "yum_food/disinfo" +{ + Properties + { + _Font("Font", 2D) = "black" {} + } + SubShader + { + Pass { + Tags { + "RenderType"="Opaque" + "Queue"="AlphaTest+499" + "LightMode" = "ForwardBase" + } + Blend SrcAlpha OneMinusSrcAlpha + Cull Back + ZTest LEqual + + CGPROGRAM + #pragma target 5.0 + + #pragma multi_compile _ VERTEXLIGHT_ON + + #pragma vertex vert + #pragma fragment frag + + #define FORWARD_BASE_PASS + + #include "disinfo_lighting.cginc" + ENDCG + } + Pass { + Tags { + "RenderType" = "Opaque" + "LightMode" = "ForwardAdd" + "Queue"="AlphaTest+499" + } + Blend One One + Cull Back + ZTest LEqual + + CGPROGRAM + #pragma target 5.0 + + #pragma multi_compile_fwdadd + + #pragma vertex vert + #pragma fragment frag + + #include "disinfo_lighting.cginc" + ENDCG + } + } + //CustomEditor "TaSTTShaderGUI" +} diff --git a/disinfo.shader.meta b/disinfo.shader.meta new file mode 100644 index 0000000..70cfbcc --- /dev/null +++ b/disinfo.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 367d6c0dd4711124e8e20975949a2306 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/disinfo_lighting.cginc b/disinfo_lighting.cginc new file mode 100644 index 0000000..94fc667 --- /dev/null +++ b/disinfo_lighting.cginc @@ -0,0 +1,52 @@ +#ifndef DISINFO_LIGHTING +#define DISINFO_LIGHTING + +#include "AutoLight.cginc" +#include "UnityPBSLighting.cginc" + +#include "interpolators.cginc" +#include "disinfo.cginc" + +void getVertexLightColor(inout v2f i) +{ + #if defined(VERTEXLIGHT_ON) + i.vertexLightColor = Shade4PointLights( + unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0, + unity_LightColor[0].rgb, + unity_LightColor[1].rgb, + unity_LightColor[2].rgb, + unity_LightColor[3].rgb, + unity_4LightAtten0, i.worldPos, i.normal + ); + #endif +} + +v2f vert(appdata v) +{ + v2f o; + o.position = UnityObjectToClipPos(v.position); + o.worldPos = mul(unity_ObjectToWorld, v.position); + o.normal = UnityObjectToWorldNormal(v.normal); + + o.uv = v.uv; + getVertexLightColor(o); + + return o; +} + +fixed4 frag(v2f i) : SV_Target +{ + float2 uv = i.uv; + int2 cell_pos; + float2 cell_uv; + if (!getBoxLoc(uv, 0.1, 0.9, /*res=*/int2(4,4), cell_pos, cell_uv)) { + return float4(0, 0, 0, 1); + } + float2 duv = float2(ddx(i.uv.x), ddy(i.uv.y)) / 4; + float4 font_color = renderInBox(67, cell_uv, duv); + + return font_color; +} + +#endif // DISINFO_LIGHTING + diff --git a/font-ascii.png b/font-ascii.png Binary files differnew file mode 100644 index 0000000..1a8ba99 --- /dev/null +++ b/font-ascii.png diff --git a/font-ascii.png.meta b/font-ascii.png.meta new file mode 100644 index 0000000..4effb9f --- /dev/null +++ b/font-ascii.png.meta @@ -0,0 +1,116 @@ +fileFormatVersion: 2 +guid: c257699adf45b4e48a6c0daf1c143fde +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 2 + wrapV: 2 + wrapW: 2 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 2 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 2 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 2 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/interpolators.cginc b/interpolators.cginc new file mode 100644 index 0000000..3f278a7 --- /dev/null +++ b/interpolators.cginc @@ -0,0 +1,24 @@ +#ifndef __INTERPOLATORS_INC__ +#define __INTERPOLATORS_INC__ + +struct appdata +{ + float4 position : POSITION; + float2 uv : TEXCOORD0; + float3 normal : NORMAL; +}; + +struct v2f +{ + float4 position : SV_POSITION; + float2 uv : TEXCOORD0; + float3 normal : TEXCOORD1; + float4 worldPos : TEXCOORD2; + + #if defined(VERTEXLIGHT_ON) + float3 vertexLightColor : TEXCOORD3; + #endif +}; + +#endif // __INTERPOLATORS_INC__ + |
