feat: glsl simula text shaders

This commit is contained in:
Nova
2023-06-25 10:04:37 -04:00
parent b3247f5ba8
commit 23fe6ead25
9 changed files with 239 additions and 8 deletions

2
Cargo.lock generated
View File

@@ -1951,7 +1951,7 @@ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
[[package]]
name = "smithay"
version = "0.3.0"
source = "git+https://github.com/technobaboo/smithay.git#2a03e6c9100a158c6ea30fff76d1c3658bef0c6d"
source = "git+https://github.com/smithay/smithay.git#da5c1b9d4dc21c8fe4037e216a82419cab124a77"
dependencies = [
"appendlist",
"bitflags 2.3.1",

View File

@@ -66,8 +66,8 @@ features = ["linux-egl"]
version = "0.16.7"
[dependencies.smithay]
git = "https://github.com/technobaboo/smithay.git" # Until we get stereokit to understand OES samplers and external textures
# git = "https://github.com/smithay/smithay.git" # Until we get stereokit to understand OES samplers and external textures
# git = "https://github.com/technobaboo/smithay.git" # Until we get stereokit to understand OES samplers and external textures
git = "https://github.com/smithay/smithay.git" # Until we get stereokit to understand OES samplers and external textures
# path = "../smithay"
default-features = false
features = ["desktop", "renderer_gl", "wayland_frontend"]

View File

@@ -1,5 +1,6 @@
pub mod lines;
pub mod model;
pub mod shaders;
pub mod text;
use self::{

View File

@@ -0,0 +1,54 @@
use std::{ffi::CString, mem::transmute};
use smithay::backend::renderer::gles::ffi::{Gles2, FRAGMENT_SHADER, VERTEX_SHADER};
use stereokit::Shader;
struct FfiAssetHeader {
asset_type: i32,
asset_state: i32,
id: u64,
index: u64,
refs: i32,
}
struct FfiSkgShader {
meta: *mut u8,
vertex: u32,
pixel: u32,
program: u32,
compute: u32,
}
struct FfiShader {
header: FfiAssetHeader,
shader: FfiSkgShader,
}
unsafe fn load_shader(c: &Gles2, source: &str, stage: u32) -> u32 {
let shader = c.CreateShader(stage);
let shader_source = CString::new(source).unwrap();
c.ShaderSource(shader, 1, &shader_source.as_ptr(), std::ptr::null());
c.CompileShader(shader);
shader
}
unsafe fn link_program(c: &Gles2, vert: u32, frag: u32) -> u32 {
let program = c.CreateProgram();
c.AttachShader(vert, VERTEX_SHADER);
c.AttachShader(frag, FRAGMENT_SHADER);
c.LinkProgram(program);
program
}
pub unsafe fn shader_inject(c: &Gles2, sk_shader: &mut Shader, vert_str: &str, frag_str: &str) {
let gl_vert = load_shader(c, vert_str, VERTEX_SHADER);
let gl_frag = load_shader(c, frag_str, FRAGMENT_SHADER);
let gl_prog = link_program(c, gl_vert, gl_frag);
let shader: *mut FfiShader = transmute(sk_shader.0.as_mut());
if let Some(shader) = shader.as_mut() {
shader.shader.vertex = gl_vert;
shader.shader.pixel = gl_frag;
shader.shader.program = gl_prog;
}
}

View File

@@ -5,3 +5,9 @@
// Simula shader with fancy lanzcos sampling
pub const PANEL_SHADER_BYTES: &[u8] = include_bytes!("shader_unlit_simula.sks");
// Simula text shader (fragment)
pub const SIMULA_FRAG_STR: &str = include_str!("simula.frag");
// Simula text shader (vertex)
pub const SIMULA_VERT_STR: &str = include_str!("simula.vert");

View File

@@ -0,0 +1,158 @@
// #version 320 es
// #extension GL_OES_EGL_image_external : require
// precision highp float;
// in vec2 vUV;
// uniform samplerExternalOES diffuse;
// uniform vec4 diffuse_i;
// uniform vec2 uv_scale;
// uniform vec2 uv_offset;
// uniform float fcFactor;
// uniform float ripple;
// uniform float alpha_min;
// uniform float alpha_max;
// float map(float value, float min1, float max1, float min2, float max2) {
// return min2 + (value - min1) * (max2 - min2) / (max1 - min1);
// }
// // float gaussian(float x, float t) {
// // float PI = 3.14159265358;
// // return exp(-x*x/(2.0 * t*t))/(sqrt(2.0*PI)*t);
// // }
// float besselI0(float x) {
// return 1.0 + pow(x, 2.0) * (0.25 + pow(x, 2.0) * (0.015625 + pow(x, 2.0) * (0.000434028 + pow(x, 2.0) * (6.78168e-6 + pow(x, 2.0) * (6.78168e-8 + pow(x, 2.0) * (4.7095e-10 + pow(x, 2.0) * (2.40281e-12 + pow(x, 2.0) * (9.38597e-15 + pow(x, 2.0) * (2.8969e-17 + 7.24226e-20 * pow(x, 2.0))))))))));
// }
// float kaiser(float x, float alpha) {
// if (x > 1.0) {
// return 0.0;
// }
// return besselI0(alpha * sqrt(1.0-x*x));
// }
// vec4 lowpassFilter(samplerExternalOES tex, samplerExternalOES texSampler, vec2 uv, float alpha) {
// float PI = 3.14159265358;
// vec4 q = vec4(0.0);
// vec2 dx_uv = dFdx(uv);
// vec2 dy_uv = dFdy(uv);
// //float width = sqrt(max(dot(dx_uv, dx_uv), dot(dy_uv, dy_uv)));
// vec2 width = abs(vec2(dx_uv.x, dy_uv.y));
// vec2 pixelWidth = floor(width * diffuse_i.xy);
// vec2 aspectRatio = normalize(pixelWidth);
// vec2 xyf = uv * diffuse_i.xy;
// ivec2 xy = ivec2(xyf);
// pixelWidth = clamp(pixelWidth, vec2(1.0), vec2(2.0));
// ivec2 start = xy - ivec2(pixelWidth);
// ivec2 end = xy + ivec2(pixelWidth);
// vec4 outColor = vec4(0.0);
// float qSum = 0.0;
// for (int v = start.y; v <= end.y; v++) {
// for (int u = start.x; u <= end.x; u++) {
// float kx = fcFactor * (xyf.x - float(u))/pixelWidth.x;
// float ky = fcFactor * (xyf.y - float(v))/pixelWidth.y;
// //float lanczosValue = gaussian(kx, fcx);
// float lanczosValue = kaiser(sqrt(kx*kx + ky*ky), alpha);
// q += texture2D(tex, (vec2(u, v)+vec2(0.5))/diffuse_i.xy) * lanczosValue;
// // q += tex.Load(int3(u, v, 0)) * lanczosValue;
// qSum += lanczosValue;
// }
// }
// return q/qSum;
// }
void main() {
//gl_FragColor = texture2D(diffuse, vec2(1.0 - vUV.x, vUV.y)); //to turn off
gl_FragColor = lowpassFilter(diffuse, vec2(1.0 - vUV.x, vUV.y), ripple);
gl_FragColor.a = map(col.a, 0, 1, alpha_min, alpha_max);
}
#version 320 es
#extension GL_OES_EGL_image_external : require
precision mediump float;
precision highp int;
layout(binding = 0, std140) uniform _Global
{
highp vec4 diffuse_i;
highp vec2 uv_scale;
highp vec2 uv_offset;
highp float fcFactor;
highp float ripple;
highp float alpha_min;
highp float alpha_max;
} uniforms;
layout(binding = 0) uniform highp samplerExternalOES diffuse;
layout(location = 0) in highp vec2 fs_uv;
layout(location = 0) out highp vec4 gl_FragColor;
void main()
{
highp vec2 dx_uv = dFdx(fs_uv);
highp vec2 dy_uv = dFdy(fs_uv);
highp vec2 width = fs_uv * uniforms.diffuse_i.xy;
ivec2 _475 = ivec2(width);
highp vec2 _477 = clamp(floor(abs(vec2(dx_uv.x, dy_uv.y)) * uniforms.diffuse_i.xy), vec2(1.0), vec2(2.0));
ivec2 _480 = ivec2(_477);
ivec2 _481 = _475 - _480;
ivec2 _485 = _475 + _480;
int _487 = _481.y;
highp vec4 _671;
highp float _672;
_672 = 0.0;
_671 = vec4(0.0);
highp vec4 _679;
highp float _681;
for (int _670 = _487; _670 <= _485.y; _672 = _681, _671 = _679, _670++)
{
int _496 = _481.x;
_681 = _672;
_679 = _671;
highp vec4 _553;
highp float _556;
for (int _673 = _496; _673 <= _485.x; _681 = _556, _679 = _553, _673++)
{
highp float _509 = float(_673);
highp float _514 = (uniforms.fcFactor * (width.x - _509)) / _477.x;
highp float _520 = float(_670);
highp float _525 = (uniforms.fcFactor * (width.y - _520)) / _477.y;
highp float _533 = sqrt((_514 * _514) + (_525 * _525));
highp float _675;
do
{
if (_533 > 1.0)
{
_675 = 0.0;
break;
}
highp float _592 = pow(uniforms.ripple * sqrt(1.0 - (_533 * _533)), 2.0);
_675 = 1.0 + (_592 * (0.25 + (_592 * (0.015625 + (_592 * (0.00043402801384218037128448486328125 + (_592 * (6.7816799855791032314300537109375e-06 + (_592 * (6.7816799287356843706220388412476e-08 + (_592 * (4.709500012189948847662890329957e-10 + (_592 * (2.4028099388645474121517509047408e-12 + (_592 * (9.3859703944590075486154034933861e-15 + (_592 * (2.8968999943407451927966655969016e-17 + (7.242260299760125752555485045131e-20 * _592)))))))))))))))))));
break;
} while(false);
_553 = _679 + (texture(diffuse, (vec2(_509, _520) + vec2(0.5)) / uniforms.diffuse_i.xy) * _675);
_556 = _681 + _675;
}
}
highp vec4 _568 = _671 / vec4(_672);
highp vec3 _417 = pow(_568.xyz, vec3(2.2000000476837158203125));
highp vec4 _669 = vec4(_417.x, _417.y, _417.z, _568.w);
_669.w = uniforms.alpha_min + (_568.w * (uniforms.alpha_max - uniforms.alpha_min));
gl_FragColor = _669;
}

View File

@@ -0,0 +1,7 @@
#version 320 es
in vec2 UV;
out vec2 vUV;
void main() {
vUV = UV;
}

View File

@@ -60,7 +60,6 @@ pub struct WaylandState {
pub shm_state: ShmState,
pub dmabuf_state: DmabufState,
pub dmabuf_global: DmabufGlobal,
pub pending_dmabufs: Vec<Dmabuf>,
pub output: Output,
pub seats: FxHashMap<ClientId, Arc<SeatData>>,
}
@@ -120,7 +119,6 @@ impl WaylandState {
shm_state,
dmabuf_state,
dmabuf_global,
pending_dmabufs: Vec::new(),
output,
seats: FxHashMap::default(),
})

View File

@@ -1,7 +1,10 @@
use super::{shaders::PANEL_SHADER_BYTES, state::WaylandState};
use super::{
shaders::{PANEL_SHADER_BYTES, SIMULA_FRAG_STR, SIMULA_VERT_STR},
state::WaylandState,
};
use crate::{
core::{delta::Delta, destroy_queue, registry::Registry},
nodes::drawable::model::ModelPart,
nodes::drawable::{model::ModelPart, shaders::shader_inject},
};
use mint::Vector2;
use once_cell::sync::OnceCell;
@@ -95,7 +98,11 @@ impl CoreSurface {
SendWrapper::new(sk.tex_create(TextureType::IMAGE_NO_MIPS, TextureFormat::RGBA32))
});
self.sk_mat.get_or_init(|| {
let shader = sk.shader_create_mem(&PANEL_SHADER_BYTES).unwrap();
let mut shader = sk.shader_create_mem(&PANEL_SHADER_BYTES).unwrap();
let _ = renderer.with_context(|c| unsafe {
shader_inject(c, &mut shader, SIMULA_VERT_STR, SIMULA_FRAG_STR)
});
let mat = sk.material_create(&shader);
sk.material_set_texture(&mat, "diffuse", sk_tex.as_ref());
sk.material_set_transparency(&mat, Transparency::Blend);