클래스
클래스는 함수를 두른 구조체입니다. 디스패치가 정적이라 상속과 믹스인과 제네릭은 파일을 컴파일하는 동안 다 정해집니다.
-
기반 타입 자리에 쓰는 파생 값
기반 타입으로 읽기만 하며 메서드 선택이 같다고 입증하면 기반 표현을 한 번 구성합니다. 메서드 재정의, 수신 객체의 변경이나 별칭을 통한 관찰 가능한 변경은 이 입증 범위 밖입니다.
TypeScript class Material {color: f32 = 0.5;response(): f32 { return this.color; }}class LeafMaterial extends Material {thickness: f32 = 1.;}function response(material: Material): f32 {return material.response();}export function leafResponse(): f32 {const material = new LeafMaterial();return response(material);}생성된 WGSL struct Material {color: f32,}struct LeafMaterial {color: f32,thickness: f32,}fn response(material: Material) -> f32 {return Material_response(material);}fn leafResponse() -> f32 {let material = LeafMaterial_new();return response(LeafMaterial_as_Material(material));} -
필드 없는 클래스
인스턴스 필드 없이도 생성하고 메서드를 호출할 수 있습니다. 호스트 값은
{}이며, GPU에는 소스 값에 없는 내부 저장 멤버를 둡니다.TypeScript class Counter {next(value: f32): f32 { return value + 1.; }}export function next(value: f32): f32 {return new Counter().next(value);}생성된 WGSL struct Counter {_empty: u32,}fn Counter_new() -> Counter {var self_: Counter = Counter(0u);return self_;}fn Counter_next(self_: Counter, value: f32) -> f32 {return (value + 1.0);}fn next(value: f32) -> f32 {return Counter_next(Counter_new(), value);} -
constructor와newnew는Ray_new호출입니다. 구조체를 지어 돌려줍니다.TypeScript class Ray {origin: vec3dir: vec3constructor(origin: vec3, dir: vec3) {this.origin = originthis.dir = dir}}생성된 WGSL fn Ray_new(origin: vec3<f32>, dir: vec3<f32>) -> Ray {let _cse0 = vec3<f32>(0.0, 0.0, 0.0);var self_: Ray = Ray(_cse0, _cse0);self_.origin = origin;self_.dir = dir;return self_;} -
메서드
첫 매개변수가 구조체인 함수가 되고,
this는 그 매개변수로 읽힙니다.TypeScript class Ray {origin: vec3dir: vec3at(t: f32): vec3 {return this.origin + this.dir * t}}생성된 WGSL fn Ray_at(self_: Ray, t: f32) -> vec3<f32> {return (self_.origin + (self_.dir * t));}fn hit(r: Ray) -> vec3<f32> {return Ray_at(r, 1.0);} -
static메서드수신자가 없는 함수가 되며, 클래스 이름을 앞에 답니다.
TypeScript class Ray {origin: vec3dir: vec3static up(): vec3 {return vec3(0., 1., 0.)}}생성된 WGSL fn Ray_up() -> vec3<f32> {return vec3<f32>(0.0, 1.0, 0.0);} -
this를 바꾸는 메서드객체를 바꾸는 메서드는 WGSL에서 포인터로, GLSL ES 3.00에서
inout으로 객체를 받습니다. orbit-inoutTypeScript class Body {pos: vec3vel: vec3step(dt: f32): void {this.pos = this.pos + this.vel * dt}}생성된 WGSL fn Body_step(self_: ptr<function, Body>, dt: f32) {(*self_).pos = ((*self_).pos + ((*self_).vel * dt));} -
extends와super기반 클래스의 필드가 앞에 오고, 물려받은 메서드는 다시 하향 변환됩니다.
super는 자기 함수가 됩니다. shape-inheritanceTypeScript class Ring extends Circle {width: f32sdf(p: vec2): f32 {return abs(super.sdf(p)) - this.width}}생성된 WGSL struct Ring {center: vec2<f32>,radius: f32,width: f32,}fn Ring_sdf(self_: Ring, p: vec2<f32>) -> f32 {return (abs(Ring_super_Circle_sdf(self_, p)) - self_.width);} -
abstract클래스abstract 클래스에는 구조체가 없습니다. 하위 클래스가 저마다 필드와 메서드 복사본을 가집니다.
TypeScript abstract class Shape {center: vec2abstract sdf(p: vec2): f32offset(p: vec2): vec2 {return p - this.center}}생성된 WGSL struct Disc {center: vec2<f32>,radius: f32,}fn Disc_offset(self_: Disc, p: vec2<f32>) -> vec2<f32> {return (p - self_.center);} -
implementsTypeScript만 검사합니다. 구조체는 그 클래스 자신의 필드입니다.
TypeScript class Disc implements Placed {center: vec2radius: f32}생성된 WGSL struct Disc {center: vec2<f32>,radius: f32,} -
접근 제어자
받아들이지만 셰이더에는 아무 뜻이 없습니다. 강제하는 쪽은 TypeScript입니다.
TypeScript class Sphere {private center: vec3readonly radius: f32public hit(p: vec3): f32 {return length(p - this.center) - this.radius}}생성된 WGSL struct Sphere {center: vec3<f32>,radius: f32,}fn Sphere_hit(self_: Sphere, p: vec3<f32>) -> f32 {return (length((p - self_.center)) - self_.radius);} -
게터와 세터
각각 모듈의 함수
Disc_get_area와Disc_set_area가 되고, 읽기와 쓰기가 그 함수를 부릅니다. class-syntaxTypeScript class Disc {radius: f32get area(): f32 {return this.radius * this.radius}}생성된 WGSL struct Disc {radius: f32,}fn Disc_get_area(self_: Disc) -> f32 {return (self_.radius * self_.radius);} -
믹스인 함수
함수는 컴파일하는 동안 실행됩니다. 멤버는 클래스에 끼워 넣고,
Tinted는 어디에도 생성되지 않습니다. mixin-surfaceTypeScript function Tinted<T extends AnyClass>(Base: T) {return class extends Base {tint: vec3lit(cover: f32): vec3 {return this.tint * cover}}}class TintedDisc extends Tinted(Disc) {}생성된 WGSL struct TintedDisc {center: vec2<f32>,radius: f32,tint: vec3<f32>,}fn TintedDisc_lit(self_: TintedDisc, cover: f32) -> vec3<f32> {return (self_.tint * cover);} -
제네릭 함수
프로그램이 쓰는 타입 인자 조합마다 함수가 하나씩 생기고,
pick이라는 이름은 없습니다. generic-helpersTypeScript function pick<T>(a: T, b: T, c: bool): T {return c ? a : b}생성된 WGSL fn pick_f32(a: f32, b: f32, c: bool) -> f32 {return select(b, a, c);}fn pick_vec3(a: vec3<f32>, b: vec3<f32>, c: bool) -> vec3<f32> {return select(b, a, c);} -
제네릭 클래스
타입 인자 조합마다 구조체가 하나씩 생기고, 메서드도 조합마다 따로 생깁니다. generic-class
TypeScript class Slot<T> {a: Tb: Tfirst(): T {return this.a}}생성된 WGSL struct Slot_f32 {a: f32,b: f32,}struct Slot_vec3 {a: vec3<f32>,b: vec3<f32>,}