radar-gi/src/shaders/font.rs
2024-08-21 22:00:45 +08:00

214 lines
5.8 KiB
Rust

use super::trackball::Trackball;
use super::CodePiece;
use crate::impl_code_piece;
use glsl::syntax::ShaderStage;
use glsl::syntax::TranslationUnit;
use glsl::transpiler::glsl::show_translation_unit;
use glsl_quasiquote::glsl;
pub struct FontVertex(pub ShaderStage);
pub struct FontFragment(pub ShaderStage);
pub struct FontGeometry(pub ShaderStage);
impl FontVertex {
pub fn new() -> Self {
let raw = glsl! {
// texcoord (left top, right bottom)
layout(location = 0) in vec4 texcoord;
// Relative position (x, y, width, height)
layout(location = 1) in vec4 relative_position;
out VS_OUT {
vec4 texcoord;
vec4 pos;
} vs_out;
void main() {
vs_out.texcoord = texcoord;
vs_out.pos = relative_position;
}
};
Self(raw)
}
}
impl FontGeometry {
pub fn new() -> Self {
let mut transform = Trackball::new().0;
let raw = glsl! {
layout(points) in;
layout(triangle_strip, max_vertices = 4) out;
// Uniforms
uniform vec3 location;
uniform vec3 anchor;
uniform vec2 viewport;
// Texture Shape
uniform vec2 atlas_shape;
out vec2 v_texCoord;
out vec2 UV_coord;
in VS_OUT {
vec4 texcoord;
vec4 pos;
} gs_in[];
void main() {
vec4 pos = gs_in[0].pos;
float x, y, width, hgt;
// Char position and size
x = pos.x;
y = pos.y;
width = pos.z;
hgt = pos.w;
// texcoord
vec2 tex_coord_lt = gs_in[0].texcoord.xy / atlas_shape;
vec2 tex_coord_rb = gs_in[0].texcoord.zw / atlas_shape;
// uv_coord
vec2 uv_coord_lt = gs_in[0].texcoord.xy;
vec2 uv_coord_rb = gs_in[0].texcoord.zw;
// Char Size
vec2 size = vec2(width, hgt);
// Base Text Location
vec3 base_pos = location + anchor;
// base_pos in NDC
vec4 ndc_base_pos = transform(position(base_pos));
// Screen Space
vec2 screen_base_pos = viewport * ((ndc_base_pos.xy / ndc_base_pos.w) + 1.0) / 2.0;
// Billboard Type
vec2 left_top = screen_base_pos + vec2(x, y);
vec2 right_bottom = left_top + size;
vec2 ndc_left_top = (2.0 * left_top / viewport - 1.0);
vec2 ndc_right_bottom = (2.0 * right_bottom / viewport - 1.0);
// Emit vertices
gl_Position = vec4(ndc_left_top.x, ndc_right_bottom.y, ndc_base_pos.z / ndc_base_pos.w, 1.0);
v_texCoord = vec2(tex_coord_lt.x, tex_coord_rb.y);
UV_coord = vec2(uv_coord_lt.x, uv_coord_rb.y);
EmitVertex();
gl_Position = vec4(ndc_right_bottom.xy, ndc_base_pos.z / ndc_base_pos.w, 1.0);
v_texCoord = tex_coord_rb;
UV_coord = uv_coord_rb;
EmitVertex();
gl_Position = vec4(ndc_left_top.xy, ndc_base_pos.z / ndc_base_pos.w, 1.0);
v_texCoord = tex_coord_lt;
UV_coord = uv_coord_lt;
EmitVertex();
gl_Position = vec4(ndc_right_bottom.x, ndc_left_top.y, ndc_base_pos.z / ndc_base_pos.w, 1.0);
v_texCoord = vec2(tex_coord_rb.x, tex_coord_lt.y);
UV_coord = vec2(uv_coord_rb.x, uv_coord_lt.y);
EmitVertex();
EndPrimitive();
}
};
transform.extend(raw);
Self(transform)
}
}
impl FontFragment {
pub fn new() -> Self {
let raw = glsl! {
uniform sampler2D atlas_data;
in vec2 v_texCoord;
in vec2 UV_coord;
uniform vec4 uClipUV;
uniform vec4 uSdfConfig;
uniform int uMode;
uniform vec4 uBorder;
uniform vec4 uStroke;
uniform vec4 uFill;
float getUVScale(vec2 sdfUV) {
float dx = dFdx(sdfUV.x);
float dy = dFdy(sdfUV.y);
return (sqrt(dx * dx + dy * dy) + sqrt(dy * dy + dx * dx)) * 0.5;
}
struct SDF {
float outer;
float inner;
};
vec4 getTexture(vec2 uv) {
return texture(atlas_data, uv);
}
vec4 getMask(vec4 color, vec2 uv, vec2 st) {
return color; // 默认不修改颜色
}
out vec4 fragColor;
void main() {
vec4 fillColor = uFill;
vec4 strokeColor = uStroke;
float scale = getUVScale(UV_coord);
vec4 texture = getTexture(v_texCoord);
float dis = texture.r;
// float sdfRaw = 0.0;
// float mark = 0.0;
// float sdf;
// float sdfRadius = uSdfConfig.x;
// float expand = uBorder.x;
// float bleed = uBorder.y;
// float d = (texture.r - 0.75) * sdfRadius;
// float s = (d + expand / uSdfConfig.y) / scale + 0.5 + bleed;
// sdf = s; // Assuming SDF returns a single float, adjust as necessary
// if (uMode == -2) {
// fillColor = vec4(texture.rgb, fillColor.a);
// }
// // Compute mask based on SDF
// float mask = clamp(sdf, 0.0, 1.0);
// Final color blending logic here
// fragColor = vec4(fillColor.rgb + mark, mask + mark);
fragColor = vec4(dis,dis,dis,dis);
}
};
Self(raw)
}
}
impl_code_piece!(FontVertex, 0);
impl_code_piece!(FontGeometry, 0);
impl_code_piece!(FontFragment, 0);