Skip to main content

Support Solid.js

Code Example

Live Editor
function Canvas() {
        const gl = useGL({
                frag: `
                #version 300 es
                precision highp float;
                uniform vec2 iResolution;
                uniform float height;
                uniform float radius;
                uniform vec3 color1;
                uniform vec3 color2;
                uniform vec3 eye;
                uniform float zoom;
                uniform float repeat;
                out vec4 fragColor;
                const float PI = 3.141592;
                const float focal = 500.0;
                const vec3 focus = vec3(0.0);
                const vec3 up = vec3(0.0, 1.0, 0.0);
                const float solidGap = 34.0;
                const float solidNorm = 1.64;
                const float solidScale = 1.83;
                const float solidPosZ = 2.6;
                mat3 scale(float x, float y, float z) {
                        return mat3(
                                1.0 / x, 0.0, 0.0,
                                0.0, 1.0 / y, 0.0,
                                0.0, 0.0, 1.0 / z
                        );
                }
                void repetition(inout vec3 p, vec3 x) {
                        if (repeat != 0.0) {
                                p = mod(p, x * repeat) - x * repeat * 0.5;
                        }
                }
                float cylinderSDF(vec3 p, float h, float r, float sign) {
                        p.y = p.y - sign * height;
                        float dShpere = length(p.xy) - r;
                        float dPlane = sign * dot(p.xy, normalize(vec2(-1.0, solidNorm)));
                        float dx = max(dShpere, dPlane);
                        float dy = abs(p.z) - h;
                        return min(max(dx, dy), 0.0) + length(vec2(max(dx, 0.0), max(dy, 0.0)));
                }
                float SDF(vec3 p) {
                        repetition(p, vec3(radius));
                        p = scale(solidScale, 1.0, 1.0) * p;
                        p.z = p.z + solidPosZ;
                        float d1 = cylinderSDF(p + vec3(0.0, 0.0, solidGap * 0.5), height, radius, -1.0);
                        float d2 = cylinderSDF(p + vec3(0.0, 0.0, -solidGap * 0.5), height, radius, 1.0);
                        return min(d1, d2);
                }
                void main() {
                        vec3 look = normalize(focus - eye);
                        vec3 right = normalize(cross(look, up));
                        vec2 scr = gl_FragCoord.xy - iResolution * 0.5;
                        vec3 dir = vec3(scr.x, scr.y, 0.0) / zoom;
                        vec3 p = eye + dir;
                        vec3 e = vec3(0.0005, 0.0, 0.0);
                        float d = SDF(p);
                        for (int i = 0; i < 100; i++) {
                                if (d <= e.x) {
                                        float dx = SDF(p + e.xyy) - d;
                                        float dy = SDF(p + e.yxy) - d;
                                        float dz = SDF(p + e.yyx) - d;
                                        vec3 norm = normalize(vec3(dx, dy, dz));
                                        float lighting = dot(norm, vec3(0.0, 1.0, 0.0)) + 0.5;
                                        vec3 color = p.z < 0.0 ? color2 : color1;
                                        fragColor = vec4(lighting * color, 1.0);
                                        return;
                                }
                                p = p + d * look;
                                d = SDF(p);
                        }
                }
                `,
                resize() {
                        resize(gl)
                },
        })
        gl.uniform(
                useControls({
                        height: { min: 0, value: 9.2, max: 18.4 },
                        radius: { min: 0, value: 14.5, max: 29 },
                        color1: [53 / 255, 97 / 255, 159 / 255],
                        color2: [74 / 255, 128 / 255, 191 / 255],
                        eye: [25, 44, 50],
                        zoom: { min: 0, value: 7.5, max: 15 },
                        repeat: { min: 0, value: 0, max: 50 },
                })
        )
        return <canvas ref={gl.ref} />
}
Result
Loading...