1
2pub use makepad_shader_ast::*;
5pub use crate::cx::*;
6pub use crate::math::*;
7pub use crate::colors::*;
8use std::any::TypeId;
9
10#[derive(Hash, PartialEq, Copy, Clone)]
11pub struct InstanceColor(pub TypeId);
12
13#[derive(Hash, PartialEq, Copy, Clone)]
14pub struct InstanceVec4(pub TypeId);
15
16#[derive(Hash, PartialEq, Copy, Clone)]
17pub struct InstanceVec3(pub TypeId);
18
19#[derive(Hash, PartialEq, Copy, Clone)]
20pub struct InstanceVec2(pub TypeId);
21
22#[derive(Hash, PartialEq, Copy, Clone)]
23pub struct InstanceFloat(pub TypeId);
24
25#[derive(Hash, PartialEq, Copy, Clone)]
26pub struct UniformColor(pub TypeId);
27
28#[derive(Hash, PartialEq, Copy, Clone)]
29pub struct UniformVec4(pub TypeId);
30
31#[derive(Hash, PartialEq, Copy, Clone)]
32pub struct UniformVec3(pub TypeId);
33
34#[derive(Hash, PartialEq, Copy, Clone)]
35pub struct UniformVec2(pub TypeId);
36
37#[derive(Hash, PartialEq, Copy, Clone)]
38pub struct UniformFloat(pub TypeId);
39
40pub struct UniqueId(pub TypeId);
41
42#[macro_export]
43macro_rules!uid {
44 () => {{
45 struct Unique{};
46 UniqueId(std::any::TypeId::of::<Unique>()).into()
47 }}
48}
49
50impl InstanceColor{
51 pub fn shader_type(&self) -> String{"vec4".to_string()}
52 pub fn instance_type(&self) -> InstanceType{InstanceType::Color(*self)}
53 pub fn var_store(&self) -> ShVarStore{ShVarStore::Instance(self.instance_type())}
54}
55
56impl Into<InstanceColor> for UniqueId{
57 fn into(self) -> InstanceColor{InstanceColor(self.0)}
58}
59
60impl InstanceVec4{
61 pub fn shader_type(&self) -> String{"vec4".to_string()}
62 pub fn instance_type(&self) -> InstanceType{InstanceType::Vec4(*self)}
63 pub fn var_store(&self) -> ShVarStore{ShVarStore::Instance(self.instance_type())}
64}
65
66impl Into<InstanceVec4> for UniqueId{
67 fn into(self) -> InstanceVec4{InstanceVec4(self.0)}
68}
69
70impl InstanceVec3{
71 pub fn shader_type(&self) -> String{"vec3".to_string()}
72 pub fn instance_type(&self) -> InstanceType{InstanceType::Vec3(*self)}
73 pub fn var_store(&self) -> ShVarStore{ShVarStore::Instance(self.instance_type())}
74}
75
76impl Into<InstanceVec3> for UniqueId{
77 fn into(self) -> InstanceVec3{InstanceVec3(self.0)}
78}
79
80impl InstanceVec2{
81 pub fn shader_type(&self) -> String{"vec2".to_string()}
82 pub fn instance_type(&self) -> InstanceType{InstanceType::Vec2(*self)}
83 pub fn var_store(&self) -> ShVarStore{ShVarStore::Instance(self.instance_type())}
84}
85
86impl Into<InstanceVec2> for UniqueId{
87 fn into(self) -> InstanceVec2{InstanceVec2(self.0)}
88}
89
90impl InstanceFloat{
91 pub fn shader_type(&self) -> String{"float".to_string()}
92 pub fn instance_type(&self) -> InstanceType{InstanceType::Float(*self)}
93 pub fn var_store(&self) -> ShVarStore{ShVarStore::Instance(self.instance_type())}
94}
95
96impl Into<InstanceFloat> for UniqueId{
97 fn into(self) -> InstanceFloat{InstanceFloat(self.0)}
98}
99
100impl UniformColor{
101 pub fn shader_type(&self) -> String{"vec4".to_string()}
102 pub fn uniform_type(&self) -> UniformType{UniformType::Color(*self)}
103 pub fn var_store(&self) -> ShVarStore{ShVarStore::Uniform(self.uniform_type())}
104}
105
106impl Into<UniformColor> for UniqueId{
107 fn into(self) -> UniformColor{UniformColor(self.0)}
108}
109
110impl UniformVec4{
111 pub fn shader_type(&self) -> String{"vec4".to_string()}
112 pub fn uniform_type(&self) -> UniformType{UniformType::Vec4(*self)}
113 pub fn var_store(&self) -> ShVarStore{ShVarStore::Uniform(self.uniform_type())}
114}
115
116impl Into<UniformVec4> for UniqueId{
117 fn into(self) -> UniformVec4{UniformVec4(self.0)}
118}
119
120impl UniformVec3{
121 pub fn shader_type(&self) -> String{"vec3".to_string()}
122 pub fn uniform_type(&self) -> UniformType{UniformType::Vec3(*self)}
123 pub fn var_store(&self) -> ShVarStore{ShVarStore::Uniform(self.uniform_type())}
124}
125
126impl Into<UniformVec3> for UniqueId{
127 fn into(self) -> UniformVec3{UniformVec3(self.0)}
128}
129
130impl UniformVec2{
131 pub fn shader_type(&self) -> String{"vec2".to_string()}
132 pub fn uniform_type(&self) -> UniformType{UniformType::Vec2(*self)}
133 pub fn var_store(&self) -> ShVarStore{ShVarStore::Uniform(self.uniform_type())}
134}
135
136impl Into<UniformVec2> for UniqueId{
137 fn into(self) -> UniformVec2{UniformVec2(self.0)}
138}
139
140impl UniformFloat{
141 pub fn shader_type(&self) -> String{"float".to_string()}
142 pub fn uniform_type(&self) -> UniformType{UniformType::Float(*self)}
143 pub fn var_store(&self) -> ShVarStore{ShVarStore::Uniform(self.uniform_type())}
144}
145
146impl Into<UniformFloat> for UniqueId{
147 fn into(self) -> UniformFloat{UniformFloat(self.0)}
148}
149
150#[derive(Default, Copy, Clone, PartialEq)]
151pub struct Shader {
152 pub shader_id: Option<(usize, usize)>,
153}
154
155#[derive(Default, Clone)]
156pub struct RectInstanceProps {
157 pub x: Option<usize>,
158 pub y: Option<usize>,
159 pub w: Option<usize>,
160 pub h: Option<usize>,
161}
162
163impl RectInstanceProps {
164 pub fn construct(sg: &ShaderGen, instances: &Vec<ShVar>) -> RectInstanceProps {
165 let mut x = None;
166 let mut y = None;
167 let mut w = None;
168 let mut h = None;
169 let mut slot = 0;
170 for inst in instances {
171 match inst.name.as_ref() {
172 "x" => x = Some(slot),
173 "y" => y = Some(slot),
174 "w" => w = Some(slot),
175 "h" => h = Some(slot),
176 _ => ()
177 }
178 slot += sg.get_type_slots(&inst.ty);
179 };
180 RectInstanceProps {
181 x: x,
182 y: y,
183 w: w,
184 h: h
185 }
186 }
187}
188
189#[derive(Clone)]
190pub struct InstanceProp {
191 pub name: String,
192 pub ident: InstanceType,
193 pub offset: usize,
194 pub slots: usize
195}
196
197#[derive(Default, Clone)]
198pub struct InstanceProps {
199 pub props: Vec<InstanceProp>,
200 pub total_slots: usize,
201}
202
203#[derive(Clone)]
204pub struct UniformProp {
205 pub name: String,
206 pub ident: UniformType,
207 pub offset: usize,
208 pub slots: usize
209}
210
211#[derive(Default, Clone)]
212pub struct UniformProps {
213 pub props: Vec<UniformProp>,
214 pub total_slots: usize,
215}
216
217#[derive(Clone)]
218pub struct NamedProp {
219 pub name: String,
220 pub offset: usize,
221 pub slots: usize
222}
223
224#[derive(Default, Clone)]
225pub struct NamedProps {
226 pub props: Vec<NamedProp>,
227 pub total_slots: usize,
228}
229
230impl NamedProps {
231 pub fn construct(sg: &ShaderGen, in_props: &Vec<ShVar>)->NamedProps{
232 let mut offset = 0;
233 let mut out_props = Vec::new();
234 for prop in in_props {
235 let slots = sg.get_type_slots(&prop.ty);
236 out_props.push(NamedProp {
237 name: prop.name.clone(),
238 offset: offset,
239 slots: slots
240 });
241 offset += slots
242 };
243 NamedProps {
244 props: out_props,
245 total_slots: offset
246 }
247 }
248}
249
250impl InstanceProps {
251 pub fn construct(sg: &ShaderGen, in_props: &Vec<ShVar>)->InstanceProps{
252 let mut offset = 0;
253 let mut out_props = Vec::new();
254 for prop in in_props {
255 let slots = sg.get_type_slots(&prop.ty);
256 match &prop.store{
257 ShVarStore::Instance(t)=>{
258 out_props.push(InstanceProp {
259 ident: t.clone(),
260 name: prop.name.clone(),
261 offset: offset,
262 slots: slots
263 })
264 },
265 _=>panic!("Non instance in props")
266 }
267 offset += slots
268 };
269 InstanceProps {
270 props: out_props,
271 total_slots: offset
272 }
273 }
274}
275
276impl UniformProps{
277 pub fn construct(sg: &ShaderGen, in_props: &Vec<ShVar>)->UniformProps{
278 let mut out_props = Vec::new();
279 let mut offset = 0;
280
281 for prop in in_props {
282 let slots = sg.get_type_slots(&prop.ty);
283
284 if (offset & 3) + slots > 4 { offset += 4 - (offset & 3); }
287 if slots == 2 && (offset & 1) != 0 {
288 panic!("Please re-order uniform {} to be size-2 aligned", prop.name);
289 }
290 match &prop.store{
291 ShVarStore::Uniform(t)=>{
292 out_props.push(UniformProp {
293 ident:t.clone(),
294 name: prop.name.clone(),
295 offset: offset,
296 slots: slots
297 })
298 },
299 _=>panic!("Non uniform in props")
300 }
301 offset += slots
302 };
303 if offset & 3 > 0 {
304 offset += 4 - (offset & 3);
305 }
306 UniformProps {
307 props: out_props,
308 total_slots: offset
309 }
310 }
311
312 pub fn find_zbias_uniform_prop(&self) -> Option<usize> {
313 for prop in &self.props {
314 if prop.name == "zbias" {
315 return Some(prop.offset)
316 }
317 }
318 return None
319 }
320}
321
322#[derive(Default, Clone)]
323pub struct CxShaderMapping {
324 pub instance_slots: usize,
325 pub geometry_slots: usize,
326 pub geometries: Vec<ShVar>,
327 pub instances: Vec<ShVar>,
328 pub draw_uniforms: Vec<ShVar>,
329 pub view_uniforms: Vec<ShVar>,
330 pub pass_uniforms: Vec<ShVar>,
331 pub uniforms: Vec<ShVar>,
332 pub texture_slots: Vec<ShVar>,
333 pub rect_instance_props: RectInstanceProps,
334 pub uniform_props: UniformProps,
335 pub instance_props: InstanceProps,
336}
337
338#[derive(Default, Clone)]
339pub struct CxShader {
340 pub name: String,
341 pub shader_gen: ShaderGen,
342 pub platform: Option<CxPlatformShader>,
343 pub mapping: CxShaderMapping
344}
345
346impl CxShader {
347
348 pub fn def_builtins(sg: ShaderGen) -> ShaderGen {
349 sg.compose(
350 ShAst {
351 types: vec![
352 ShType {name: "float".to_string(), slots: 1, prim: true, fields: Vec::new()},
353 ShType {name: "int".to_string(), slots: 1, prim: true, fields: Vec::new()},
354 ShType {name: "bool".to_string(), slots: 1, prim: true, fields: Vec::new()},
355 ShType {
356 name: "vec2".to_string(),
357 slots: 2,
358 prim: true,
359 fields: vec![ShTypeField::new("x", "float"), ShTypeField::new("y", "float")]
360 },
361 ShType {
362 name: "vec3".to_string(),
363 slots: 3,
364 prim: true,
365 fields: vec![ShTypeField::new("x", "float"), ShTypeField::new("y", "float"), ShTypeField::new("z", "float")]
366 },
367 ShType {
368 name: "vec4".to_string(),
369 slots: 4,
370 prim: true,
371 fields: vec![ShTypeField::new("x", "float"), ShTypeField::new("y", "float"), ShTypeField::new("z", "float"), ShTypeField::new("w", "float")]
372 },
373 ShType {
374 name: "mat2".to_string(),
375 slots: 4,
376 prim: true,
377 fields: vec![
378 ShTypeField::new("a", "float"),
379 ShTypeField::new("b", "float"),
380 ShTypeField::new("c", "float"),
381 ShTypeField::new("d", "float")
382 ]
383 },
384 ShType {
385 name: "mat3".to_string(),
386 slots: 9,
387 prim: true,
388 fields: vec![
389 ShTypeField::new("a", "float"),
390 ShTypeField::new("b", "float"),
391 ShTypeField::new("c", "float"),
392 ShTypeField::new("d", "float"),
393 ShTypeField::new("e", "float"),
394 ShTypeField::new("f", "float"),
395 ShTypeField::new("g", "float"),
396 ShTypeField::new("h", "float"),
397 ShTypeField::new("i", "float")
398 ]
399 },
400 ShType {
401 name: "mat4".to_string(),
402 slots: 16,
403 prim: true,
404 fields: vec![
405 ShTypeField::new("a", "float"),
406 ShTypeField::new("b", "float"),
407 ShTypeField::new("c", "float"),
408 ShTypeField::new("d", "float"),
409 ShTypeField::new("e", "float"),
410 ShTypeField::new("f", "float"),
411 ShTypeField::new("g", "float"),
412 ShTypeField::new("h", "float"),
413 ShTypeField::new("i", "float"),
414 ShTypeField::new("j", "float"),
415 ShTypeField::new("k", "float"),
416 ShTypeField::new("l", "float"),
417 ShTypeField::new("m", "float"),
418 ShTypeField::new("n", "float"),
419 ShTypeField::new("o", "float"),
420 ShTypeField::new("p", "float")
421 ]
422 },
423 ],
424 vars: Vec::new(),
425 fns: vec![
426 ShFn {name: "sizeof".to_string(), args: vec![ShFnArg::new("type", "T")], ret: "int".to_string(), block: None},
433 ShFn {name: "color".to_string(), args: vec![ShFnArg::new("color", "string")], ret: "vec4".to_string(), block: None},
434
435 ShFn {name: "radians".to_string(), args: vec![ShFnArg::new("x", "T")], ret: "T".to_string(), block: None},
436 ShFn {name: "degrees".to_string(), args: vec![ShFnArg::new("x", "T")], ret: "T".to_string(), block: None},
437
438 ShFn {name: "sin".to_string(), args: vec![ShFnArg::new("x", "T")], ret: "T".to_string(), block: None},
439 ShFn {name: "cos".to_string(), args: vec![ShFnArg::new("x", "T")], ret: "T".to_string(), block: None},
440 ShFn {name: "tan".to_string(), args: vec![ShFnArg::new("x", "T")], ret: "T".to_string(), block: None},
441 ShFn {name: "asin".to_string(), args: vec![ShFnArg::new("x", "T")], ret: "T".to_string(), block: None},
442 ShFn {name: "acos".to_string(), args: vec![ShFnArg::new("x", "T")], ret: "T".to_string(), block: None},
443 ShFn {name: "atan".to_string(), args: vec![ShFnArg::new("x", "T"), ShFnArg::new("y", "T")], ret: "T".to_string(), block: None},
444
445 ShFn {name: "pow".to_string(), args: vec![ShFnArg::new("x", "T"), ShFnArg::new("y", "T")], ret: "T".to_string(), block: None},
446 ShFn {name: "exp".to_string(), args: vec![ShFnArg::new("x", "T")], ret: "T".to_string(), block: None},
447 ShFn {name: "log".to_string(), args: vec![ShFnArg::new("x", "T")], ret: "T".to_string(), block: None},
448 ShFn {name: "exp2".to_string(), args: vec![ShFnArg::new("x", "T")], ret: "T".to_string(), block: None},
449 ShFn {name: "log2".to_string(), args: vec![ShFnArg::new("x", "T")], ret: "T".to_string(), block: None},
450
451 ShFn {name: "sqrt".to_string(), args: vec![ShFnArg::new("x", "T")], ret: "T".to_string(), block: None},
452 ShFn {name: "inversesqrt".to_string(), args: vec![ShFnArg::new("x", "T")], ret: "T".to_string(), block: None},
453
454 ShFn {name: "abs".to_string(), args: vec![ShFnArg::new("x", "T")], ret: "T".to_string(), block: None},
455 ShFn {name: "sign".to_string(), args: vec![ShFnArg::new("x", "T")], ret: "T".to_string(), block: None},
456 ShFn {name: "floor".to_string(), args: vec![ShFnArg::new("x", "T")], ret: "T".to_string(), block: None},
457 ShFn {name: "ceil".to_string(), args: vec![ShFnArg::new("x", "T")], ret: "T".to_string(), block: None},
458 ShFn {name: "fract".to_string(), args: vec![ShFnArg::new("x", "T")], ret: "T".to_string(), block: None},
459
460 ShFn {name: "fmod".to_string(), args: vec![ShFnArg::new("x", "T"), ShFnArg::new("y", "T")], ret: "T".to_string(), block: None},
461 ShFn {name: "min".to_string(), args: vec![ShFnArg::new("x", "T"), ShFnArg::new("y", "T")], ret: "T".to_string(), block: None},
462 ShFn {name: "max".to_string(), args: vec![ShFnArg::new("x", "T"), ShFnArg::new("y", "T")], ret: "T".to_string(), block: None},
463 ShFn {name: "clamp".to_string(), args: vec![ShFnArg::new("x", "T"), ShFnArg::new("mi", "T"), ShFnArg::new("ma", "T")], ret: "T".to_string(), block: None},
464
465 ShFn {name: "mix".to_string(), args: vec![ShFnArg::new("x", "T"), ShFnArg::new("y", "T"), ShFnArg::new("t", "F")], ret: "T".to_string(), block: None},
466 ShFn {name: "step".to_string(), args: vec![ShFnArg::new("e", "T"), ShFnArg::new("x", "T")], ret: "T".to_string(), block: None},
467 ShFn {name: "smoothstep".to_string(), args: vec![ShFnArg::new("e0", "F"), ShFnArg::new("e1", "F"), ShFnArg::new("x", "T")], ret: "T".to_string(), block: None},
468
469 ShFn {name: "length".to_string(), args: vec![ShFnArg::new("x", "T")], ret: "float".to_string(), block: None},
470 ShFn {name: "distance".to_string(), args: vec![ShFnArg::new("p0", "T"), ShFnArg::new("p1", "T")], ret: "float".to_string(), block: None},
471 ShFn {name: "dot".to_string(), args: vec![ShFnArg::new("x", "T"), ShFnArg::new("y", "T")], ret: "float".to_string(), block: None},
472 ShFn {name: "cross".to_string(), args: vec![ShFnArg::new("x", "vec3"), ShFnArg::new("y", "vec3")], ret: "vec3".to_string(), block: None},
473 ShFn {name: "normalize".to_string(), args: vec![ShFnArg::new("x", "T")], ret: "T".to_string(), block: None},
474
475 ShFn {name: "faceforward".to_string(), args: vec![ShFnArg::new("n", "T"), ShFnArg::new("i", "T"), ShFnArg::new("nref", "T")], ret: "T".to_string(), block: None},
476 ShFn {name: "reflect".to_string(), args: vec![ShFnArg::new("i", "T"), ShFnArg::new("n", "T")], ret: "T".to_string(), block: None},
477 ShFn {name: "refract".to_string(), args: vec![ShFnArg::new("i", "T"), ShFnArg::new("n", "T"), ShFnArg::new("eta", "T")], ret: "T".to_string(), block: None},
478
479 ShFn {name: "matrix_comp_mult".to_string(), args: vec![ShFnArg::new("a", "mat4"), ShFnArg::new("b", "mat4")], ret: "mat4".to_string(), block: None},
480
481 ShFn {name: "less_than".to_string(), args: vec![ShFnArg::new("x", "T"), ShFnArg::new("y", "T")], ret: "B".to_string(), block: None},
482 ShFn {name: "less_than_equal".to_string(), args: vec![ShFnArg::new("x", "T"), ShFnArg::new("y", "T")], ret: "B".to_string(), block: None},
483 ShFn {name: "greater_than".to_string(), args: vec![ShFnArg::new("x", "T"), ShFnArg::new("y", "T")], ret: "B".to_string(), block: None},
484 ShFn {name: "greater_than_equal".to_string(), args: vec![ShFnArg::new("x", "T"), ShFnArg::new("y", "T")], ret: "B".to_string(), block: None},
485 ShFn {name: "equal".to_string(), args: vec![ShFnArg::new("x", "T"), ShFnArg::new("y", "T")], ret: "B".to_string(), block: None},
486 ShFn {name: "not_equal".to_string(), args: vec![ShFnArg::new("x", "T"), ShFnArg::new("y", "T")], ret: "B".to_string(), block: None},
487
488 ShFn {name: "any".to_string(), args: vec![ShFnArg::new("x", "B")], ret: "bool".to_string(), block: None},
489 ShFn {name: "all".to_string(), args: vec![ShFnArg::new("x", "B")], ret: "bool".to_string(), block: None},
490 ShFn {name: "not".to_string(), args: vec![ShFnArg::new("x", "B")], ret: "B".to_string(), block: None},
491
492 ShFn {name: "dfdx".to_string(), args: vec![ShFnArg::new("x", "T")], ret: "T".to_string(), block: None},
493 ShFn {name: "dfdy".to_string(), args: vec![ShFnArg::new("x", "T")], ret: "T".to_string(), block: None},
494 ShFn {name: "fwidth".to_string(), args: vec![ShFnArg::new("x", "T")], ret: "T".to_string(), block: None},
495
496 ShFn {name: "sample2d".to_string(), args: vec![ShFnArg::new("texture", "texture2d"), ShFnArg::new("coord", "vec2")], ret: "vec4".to_string(), block: None},
497 ],
505 consts: Vec::new()
506 }
507 )
508 }
509
510 pub fn def_df(sg: ShaderGen) -> ShaderGen {
511 sg.compose(shader_ast!({
512 const PI: float = 3.141592653589793;
513 const E: float = 2.718281828459045;
514 const LN2: float = 0.6931471805599453;
515 const LN10: float = 2.302585092994046;
516 const LOG2E: float = 1.4426950408889634;
517 const LOG10E: float = 0.4342944819032518;
518 const SQRT1_2: float = 0.70710678118654757;
519 const TORAD: float = 0.017453292519943295;
520 const GOLDEN: float = 1.618033988749895;
521
522 let df_pos: vec2<Local>;
523 let df_result: vec4<Local>;
524 let df_last_pos: vec2<Local>;
525 let df_start_pos: vec2<Local>;
526 let df_shape: float<Local>;
527 let df_clip: float<Local>;
528 let df_has_clip: float<Local>;
529 let df_old_shape: float<Local>;
530 let df_blur: float<Local>;
531 let df_aa: float<Local>;
532 let df_scale: float<Local>;
533 let df_field: float<Local>;
534
535 fn df_iq_pal(t: float, a: vec3, b: vec3, c: vec3, d: vec3) -> vec3 {
536 return a + b * cos(6.28318 * (c * t + d));
537 }
538
539 fn df_iq_pal0(t: float) -> vec3 {
540 return mix(vec3(0., 0., 0.), vec3(1., 1., 1.), cos(t * PI) * 0.5 + 0.5)
541 }
542
543 fn df_iq_pal1(t: float) -> vec3 {
544 return df_iq_pal(t, vec3(0.5, 0.5, 0.5), vec3(0.5, 0.5, 0.5), vec3(1., 1., 1.), vec3(0., 0.33, 0.67));
545 }
546
547 fn df_iq_pal2(t: float) -> vec3 {
548 return df_iq_pal(t, vec3(0.5, 0.5, 0.5), vec3(0.5, 0.5, 0.5), vec3(1., 1., 1.), vec3(0., 0.1, 0.2));
549 }
550
551 fn df_iq_pal3(t: float) -> vec3 {
552 return df_iq_pal(t, vec3(0.5, 0.5, 0.5), vec3(0.5, 0.5, 0.5), vec3(1., 1., 1.), vec3(0.3, 0.2, 0.2));
553 }
554
555 fn df_iq_pal4(t: float) -> vec3 {
556 return df_iq_pal(t, vec3(0.5, 0.5, 0.5), vec3(0.5, 0.5, 0.5), vec3(1., 1., 0.5), vec3(0.8, 0.9, 0.3));
557 }
558
559 fn df_iq_pal5(t: float) -> vec3 {
560 return df_iq_pal(t, vec3(0.5, 0.5, 0.5), vec3(0.5, 0.5, 0.5), vec3(1., 0.7, 0.4), vec3(0, 0.15, 0.20));
561 }
562
563 fn df_iq_pal6(t: float) -> vec3 {
564 return df_iq_pal(t, vec3(0.5, 0.5, 0.5), vec3(0.5, 0.5, 0.5), vec3(2., 1.0, 0.), vec3(0.5, 0.2, 0.25));
565 }
566
567 fn df_iq_pal7(t: float) -> vec3 {
568 return df_iq_pal(t, vec3(0.8, 0.5, 0.4), vec3(0.2, 0.4, 0.2), vec3(2., 1.0, 1.0), vec3(0., 0.25, 0.25));
569 }
570
571 fn df_viewport(pos: vec2) -> vec2 {
572 df_pos = pos;
573 df_result = vec4(0., 0., 0., 0.);
574 df_old_shape =
575 df_shape = 1e+20;
576 df_clip = -1e+20;
577 df_blur = 0.00001;
578 df_aa = df_antialias(pos);
579 df_scale = 1.0;
580 df_field = 0.0;
581 df_clip = 0.0;
582 df_has_clip = 0.0;
583 return df_pos;
584 }
585
586 fn df_antialias(p: vec2) -> float {
587 return 1.0 / length(vec2(length(dfdx(p)), length(dfdy(p))));
588 }
589
590 fn df_translate(x: float, y: float) -> vec2 {
591 df_pos -= vec2(x, y);
592 return df_pos;
593 }
594
595 fn df_rotate(a: float, x: float, y: float) {
596 let ca: float = cos(-a);
597 let sa: float = sin(-a);
598 let p: vec2 = df_pos - vec2(x, y);
599 df_pos = vec2(p.x * ca - p.y * sa, p.x * sa + p.y * ca) + vec2(x, y);
600 }
601
602 fn df_scale(f: float, x: float, y: float) {
603 df_scale *= f;
604 df_pos = (df_pos - vec2(x, y)) * f + vec2(x, y);
605 }
606
607 fn df_clear(color: vec4) {
608 df_result = vec4(color.rgb * color.a + df_result.rgb * (1.0 - color.a), color.a);
609 }
610
611 fn df_calc_blur(w: float) -> float {
612 let wa: float = clamp(-w * df_aa, 0.0, 1.0);
613 let wb: float = 1.0;
614 if df_blur > 0.001 {
615 wb = clamp(-w / df_blur, 0.0, 1.0)
616 }
617 return wa * wb;
618 }
619
620 fn df_fill_keep(color: vec4) -> vec4 {
621 let f: float = df_calc_blur(df_shape);
622 let source: vec4 = vec4(color.rgb * color.a, color.a);
623 df_result = source * f + df_result * (1. - source.a * f);
624 if df_has_clip > 0.5 {
625 let f2: float = 1. - df_calc_blur(-df_clip);
626 df_result = source * f2 + df_result * (1. - source.a * f2);
627 }
628 return df_result;
629 }
630
631 fn df_fill(color: vec4) -> vec4 {
632 df_fill_keep(color);
633 df_old_shape = df_shape = 1e+20;
634 df_clip = -1e+20;
635 df_has_clip = 0.;
636 return df_result;
637 }
638
639 fn df_stroke_keep(color: vec4, width: float) -> vec4 {
640 let f: float = df_calc_blur(abs(df_shape) - width / df_scale);
641 let source: vec4 = vec4(color.rgb * color.a, color.a);
642 let dest: vec4 = df_result;
643 df_result = source * f + dest * (1.0 - source.a * f);
644 return df_result;
645 }
646
647 fn df_stroke(color: vec4, width: float) -> vec4 {
648 df_stroke_keep(color, width);
649 df_old_shape = df_shape = 1e+20;
650 df_clip = -1e+20;
651 df_has_clip = 0.;
652 return df_result;
653 }
654
655 fn df_glow_keep(color: vec4, width: float) -> vec4 {
656 let f: float = df_calc_blur(abs(df_shape) - width / df_scale);
657 let source: vec4 = vec4(color.rgb * color.a, color.a);
658 let dest: vec4 = df_result;
659 df_result = vec4(source.rgb * f, 0.) + dest;
660 return df_result;
661 }
662
663 fn df_glow(color: vec4, width: float) -> vec4 {
664 df_glow_keep(color, width);
665 df_old_shape = df_shape = 1e+20;
666 df_clip = -1e+20;
667 df_has_clip = 0.;
668 return df_result;
669 }
670
671 fn df_union() {
672 df_old_shape = df_shape = min(df_field, df_old_shape);
673 }
674
675 fn df_intersect() {
676 df_old_shape = df_shape = max(df_field, df_old_shape);
677 }
678
679 fn df_subtract() {
680 df_old_shape = df_shape = max(-df_field, df_old_shape);
681 }
682
683 fn df_gloop(k: float) {
684 let h: float = clamp(0.5 + 0.5 * (df_old_shape - df_field) / k, 0.0, 1.0);
685 df_old_shape = df_shape = mix(df_old_shape, df_field, h) - k * h * (1.0 - h);
686 }
687
688 fn df_blend(k: float) {
689 df_old_shape = df_shape = mix(df_old_shape, df_field, k);
690 }
691
692 fn df_circle(x: float, y: float, r: float) {
693 let c: vec2 = df_pos - vec2(x, y);
694 df_field = (length(c.xy) - r) / df_scale;
695 df_old_shape = df_shape;
696 df_shape = min(df_shape, df_field);
697 }
698
699 fn df_box(x: float, y: float, w: float, h: float, r: float) {
700 let p: vec2 = df_pos - vec2(x, y);
701 let size: vec2 = vec2(0.5 * w, 0.5 * h);
702 let bp: vec2 = max(abs(p - size.xy) - (size.xy - vec2(2. * r, 2. * r).xy), vec2(0., 0.));
703 df_field = (length(bp) - 2. * r) / df_scale;
704 df_old_shape = df_shape;
705 df_shape = min(df_shape, df_field);
706 }
707
708 fn df_rect(x: float, y: float, w: float, h: float) {
709 let s: vec2 = vec2(w, h) * 0.5;
710 let d: vec2 = abs(vec2(x, y) - df_pos + s) - s;
711 let dm: vec2 = min(d, vec2(0., 0.));
712 df_field = max(dm.x, dm.y) + length(max(d, vec2(0., 0.)));
713 df_old_shape = df_shape;
714 df_shape = min(df_shape, df_field);
715 }
716
717 fn df_move_to(x: float, y: float) {
718 df_last_pos =
719 df_start_pos = vec2(x, y);
720 }
721
722 fn df_line_to(x: float, y: float) {
723 let p: vec2 = vec2(x, y);
724
725 let pa: vec2 = df_pos - df_last_pos;
726 let ba: vec2 = p - df_last_pos;
727 let h: float = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0);
728 let s: float = sign(pa.x * ba.y - pa.y * ba.x);
729 df_field = length(pa - ba * h) / df_scale;
730 df_old_shape = df_shape;
731 df_shape = min(df_shape, df_field);
732 df_clip = max(df_clip, df_field * s);
733 df_has_clip = 1.0;
734 df_last_pos = p;
735 }
736
737 fn df_close_path() {
738 df_line_to(df_start_pos.x, df_start_pos.y);
739 }
740
741 fn df_hsv2rgb(c: vec4) -> vec4 { let K: vec4 = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
743 let p: vec4 = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
744 return vec4(c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y), c.w);
745 }
746
747 fn df_rgb2hsv(c: vec4) -> vec4 {
748 let K: vec4 = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
749 let p: vec4 = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
750 let q: vec4 = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
751
752 let d: float = q.x - min(q.w, q.y);
753 let e: float = 1.0e-10;
754 return vec4(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x, c.w);
755 }
756 }))
757 }
758}