├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .gitignore
├── .prettierignore
├── .prettierrc
├── .vscode
└── settings.json
├── LICENSE
├── README.md
├── bili.config.js
├── docs
├── 1-white-clouds-png-image_400x400.2471b47f.png
├── 3d.2d1ce79b.css
├── 3d.b302f3ed.js
├── api
│ ├── .nojekyll
│ ├── assets
│ │ ├── highlight.css
│ │ ├── icons.css
│ │ ├── icons.png
│ │ ├── icons@2x.png
│ │ ├── main.js
│ │ ├── search.js
│ │ ├── style.css
│ │ ├── widgets.png
│ │ └── widgets@2x.png
│ ├── classes
│ │ ├── Bloom.html
│ │ ├── Blur.html
│ │ ├── Godray.html
│ │ ├── GodrayLight.html
│ │ ├── KglAuto.html
│ │ ├── KglEffect.html
│ │ ├── ObjectGl.html
│ │ ├── Program.html
│ │ ├── Specular.html
│ │ ├── Vec2.html
│ │ ├── Vec3.html
│ │ ├── Vec4.html
│ │ ├── Zoomblur.html
│ │ └── default.html
│ ├── index.html
│ ├── interfaces
│ │ ├── _internal_.ANGLE_instanced_arrays.html
│ │ ├── _internal_.ARIAMixin.html
│ │ ├── _internal_.AbstractRange.html
│ │ ├── _internal_.AddEventListenerOptions.html
│ │ ├── _internal_.Animatable.html
│ │ ├── _internal_.Animation.html
│ │ ├── _internal_.AnimationEffect.html
│ │ ├── _internal_.AnimationEvent.html
│ │ ├── _internal_.AnimationEventMap.html
│ │ ├── _internal_.AnimationFrameProvider.html
│ │ ├── _internal_.AnimationPlaybackEvent.html
│ │ ├── _internal_.AnimationTimeline.html
│ │ ├── _internal_.ArrayBufferView.html
│ │ ├── _internal_.ArrayLike.html
│ │ ├── _internal_.AssignedNodesOptions.html
│ │ ├── _internal_.AsyncIterableIterator.html
│ │ ├── _internal_.AsyncIterator.html
│ │ ├── _internal_.Attr.html
│ │ ├── _internal_.AudioBuffer.html
│ │ ├── _internal_.AudioProcessingEvent.html
│ │ ├── _internal_.BarProp.html
│ │ ├── _internal_.BeforeUnloadEvent.html
│ │ ├── _internal_.BlobCallback.html
│ │ ├── _internal_.BlobEvent.html
│ │ ├── _internal_.Body.html
│ │ ├── _internal_.Buffer.html
│ │ ├── _internal_.BufferConstructor.html
│ │ ├── _internal_.CDATASection.html
│ │ ├── _internal_.CSSRule.html
│ │ ├── _internal_.CSSStyleSheet.html
│ │ ├── _internal_.CacheQueryOptions.html
│ │ ├── _internal_.CacheStorage.html
│ │ ├── _internal_.CanvasCompositing.html
│ │ ├── _internal_.CanvasDrawImage.html
│ │ ├── _internal_.CanvasDrawPath.html
│ │ ├── _internal_.CanvasFillStrokeStyles.html
│ │ ├── _internal_.CanvasFilters.html
│ │ ├── _internal_.CanvasGradient.html
│ │ ├── _internal_.CanvasImageData.html
│ │ ├── _internal_.CanvasImageSmoothing.html
│ │ ├── _internal_.CanvasPath.html
│ │ ├── _internal_.CanvasPattern.html
│ │ ├── _internal_.CanvasRect.html
│ │ ├── _internal_.CanvasRenderingContext2D.html
│ │ ├── _internal_.CanvasRenderingContext2DSettings.html
│ │ ├── _internal_.CanvasShadowStyles.html
│ │ ├── _internal_.CanvasState.html
│ │ ├── _internal_.CanvasText.html
│ │ ├── _internal_.CanvasTextDrawingStyles.html
│ │ ├── _internal_.CanvasTransform.html
│ │ ├── _internal_.CanvasUserInterface.html
│ │ ├── _internal_.CharacterData.html
│ │ ├── _internal_.ChildNode.html
│ │ ├── _internal_.ClipboardEvent.html
│ │ ├── _internal_.CloseEvent.html
│ │ ├── _internal_.Comment.html
│ │ ├── _internal_.CompositionEvent.html
│ │ ├── _internal_.ComputedEffectTiming.html
│ │ ├── _internal_.ConcatArray.html
│ │ ├── _internal_.ConstrainBooleanParameters.html
│ │ ├── _internal_.ConstrainDOMStringParameters.html
│ │ ├── _internal_.ConstrainDoubleRange.html
│ │ ├── _internal_.ConstrainULongRange.html
│ │ ├── _internal_.Crypto.html
│ │ ├── _internal_.CustomElementConstructor.html
│ │ ├── _internal_.CustomElementRegistry.html
│ │ ├── _internal_.CustomEvent.html
│ │ ├── _internal_.DOMException.html
│ │ ├── _internal_.DOMImplementation.html
│ │ ├── _internal_.DOMMatrix.html
│ │ ├── _internal_.DOMMatrix2DInit.html
│ │ ├── _internal_.DOMMatrixInit.html
│ │ ├── _internal_.DOMMatrixReadOnly.html
│ │ ├── _internal_.DOMPoint.html
│ │ ├── _internal_.DOMPointInit.html
│ │ ├── _internal_.DOMPointReadOnly.html
│ │ ├── _internal_.DOMRect.html
│ │ ├── _internal_.DOMRectInit.html
│ │ ├── _internal_.DOMRectReadOnly.html
│ │ ├── _internal_.DOMStringMap.html
│ │ ├── _internal_.DataTransfer.html
│ │ ├── _internal_.DeviceMotionEvent.html
│ │ ├── _internal_.DeviceMotionEventAcceleration.html
│ │ ├── _internal_.DeviceMotionEventRotationRate.html
│ │ ├── _internal_.DeviceOrientationEvent.html
│ │ ├── _internal_.Document.html
│ │ ├── _internal_.DocumentAndElementEventHandlers.html
│ │ ├── _internal_.DocumentAndElementEventHandlersEventMap.html
│ │ ├── _internal_.DocumentEventMap.html
│ │ ├── _internal_.DocumentFragment.html
│ │ ├── _internal_.DocumentOrShadowRoot.html
│ │ ├── _internal_.DocumentTimeline.html
│ │ ├── _internal_.DocumentType.html
│ │ ├── _internal_.DoubleRange.html
│ │ ├── _internal_.DragEvent.html
│ │ ├── _internal_.EXT_blend_minmax.html
│ │ ├── _internal_.EXT_color_buffer_float.html
│ │ ├── _internal_.EXT_color_buffer_half_float.html
│ │ ├── _internal_.EXT_float_blend.html
│ │ ├── _internal_.EXT_frag_depth.html
│ │ ├── _internal_.EXT_sRGB.html
│ │ ├── _internal_.EXT_shader_texture_lod.html
│ │ ├── _internal_.EXT_texture_filter_anisotropic.html
│ │ ├── _internal_.EffectTiming.html
│ │ ├── _internal_.Element.html
│ │ ├── _internal_.ElementCSSInlineStyle.html
│ │ ├── _internal_.ElementContentEditable.html
│ │ ├── _internal_.ElementCreationOptions.html
│ │ ├── _internal_.ElementDefinitionOptions.html
│ │ ├── _internal_.ElementEventMap.html
│ │ ├── _internal_.ElementInternals.html
│ │ ├── _internal_.Error.html
│ │ ├── _internal_.ErrorCallback.html
│ │ ├── _internal_.ErrorEvent.html
│ │ ├── _internal_.Event.html
│ │ ├── _internal_.EventEmitter.html
│ │ ├── _internal_.EventListener.html
│ │ ├── _internal_.EventListenerObject.html
│ │ ├── _internal_.EventListenerOptions.html
│ │ ├── _internal_.EventTarget.html
│ │ ├── _internal_.External.html
│ │ ├── _internal_.File.html
│ │ ├── _internal_.FileSystem.html
│ │ ├── _internal_.FileSystemDirectoryEntry.html
│ │ ├── _internal_.FileSystemDirectoryReader.html
│ │ ├── _internal_.FileSystemEntriesCallback.html
│ │ ├── _internal_.FileSystemEntry.html
│ │ ├── _internal_.FileSystemEntryCallback.html
│ │ ├── _internal_.FileSystemFlags.html
│ │ ├── _internal_.FocusEvent.html
│ │ ├── _internal_.FocusOptions.html
│ │ ├── _internal_.FontFace.html
│ │ ├── _internal_.FontFaceSetLoadEvent.html
│ │ ├── _internal_.FontFaceSource.html
│ │ ├── _internal_.FormDataEvent.html
│ │ ├── _internal_.FrameRequestCallback.html
│ │ ├── _internal_.FullscreenOptions.html
│ │ ├── _internal_.Gamepad.html
│ │ ├── _internal_.GamepadButton.html
│ │ ├── _internal_.GamepadEvent.html
│ │ ├── _internal_.GamepadHapticActuator.html
│ │ ├── _internal_.GetAnimationsOptions.html
│ │ ├── _internal_.GetRootNodeOptions.html
│ │ ├── _internal_.GlobalEventHandlers.html
│ │ ├── _internal_.GlobalEventHandlersEventMap.html
│ │ ├── _internal_.HTMLAnchorElement.html
│ │ ├── _internal_.HTMLAreaElement.html
│ │ ├── _internal_.HTMLAudioElement.html
│ │ ├── _internal_.HTMLBRElement.html
│ │ ├── _internal_.HTMLBaseElement.html
│ │ ├── _internal_.HTMLBodyElement.html
│ │ ├── _internal_.HTMLBodyElementEventMap.html
│ │ ├── _internal_.HTMLButtonElement.html
│ │ ├── _internal_.HTMLCanvasElement.html
│ │ ├── _internal_.HTMLCollection.html
│ │ ├── _internal_.HTMLDListElement.html
│ │ ├── _internal_.HTMLDataElement.html
│ │ ├── _internal_.HTMLDataListElement.html
│ │ ├── _internal_.HTMLDetailsElement.html
│ │ ├── _internal_.HTMLDialogElement.html
│ │ ├── _internal_.HTMLDirectoryElement.html
│ │ ├── _internal_.HTMLDivElement.html
│ │ ├── _internal_.HTMLElement.html
│ │ ├── _internal_.HTMLElementDeprecatedTagNameMap.html
│ │ ├── _internal_.HTMLElementEventMap.html
│ │ ├── _internal_.HTMLElementTagNameMap.html
│ │ ├── _internal_.HTMLEmbedElement.html
│ │ ├── _internal_.HTMLFieldSetElement.html
│ │ ├── _internal_.HTMLFontElement.html
│ │ ├── _internal_.HTMLFrameElement.html
│ │ ├── _internal_.HTMLFrameSetElement.html
│ │ ├── _internal_.HTMLFrameSetElementEventMap.html
│ │ ├── _internal_.HTMLHRElement.html
│ │ ├── _internal_.HTMLHeadElement.html
│ │ ├── _internal_.HTMLHeadingElement.html
│ │ ├── _internal_.HTMLHtmlElement.html
│ │ ├── _internal_.HTMLHyperlinkElementUtils.html
│ │ ├── _internal_.HTMLIFrameElement.html
│ │ ├── _internal_.HTMLImageElement.html
│ │ ├── _internal_.HTMLInputElement.html
│ │ ├── _internal_.HTMLLIElement.html
│ │ ├── _internal_.HTMLLabelElement.html
│ │ ├── _internal_.HTMLLegendElement.html
│ │ ├── _internal_.HTMLLinkElement.html
│ │ ├── _internal_.HTMLMapElement.html
│ │ ├── _internal_.HTMLMarqueeElement.html
│ │ ├── _internal_.HTMLMediaElement.html
│ │ ├── _internal_.HTMLMediaElementEventMap.html
│ │ ├── _internal_.HTMLMenuElement.html
│ │ ├── _internal_.HTMLMetaElement.html
│ │ ├── _internal_.HTMLMeterElement.html
│ │ ├── _internal_.HTMLModElement.html
│ │ ├── _internal_.HTMLOListElement.html
│ │ ├── _internal_.HTMLObjectElement.html
│ │ ├── _internal_.HTMLOptGroupElement.html
│ │ ├── _internal_.HTMLOptionElement.html
│ │ ├── _internal_.HTMLOrSVGElement.html
│ │ ├── _internal_.HTMLOutputElement.html
│ │ ├── _internal_.HTMLParagraphElement.html
│ │ ├── _internal_.HTMLParamElement.html
│ │ ├── _internal_.HTMLPictureElement.html
│ │ ├── _internal_.HTMLPreElement.html
│ │ ├── _internal_.HTMLProgressElement.html
│ │ ├── _internal_.HTMLQuoteElement.html
│ │ ├── _internal_.HTMLScriptElement.html
│ │ ├── _internal_.HTMLSlotElement.html
│ │ ├── _internal_.HTMLSourceElement.html
│ │ ├── _internal_.HTMLSpanElement.html
│ │ ├── _internal_.HTMLStyleElement.html
│ │ ├── _internal_.HTMLTableCaptionElement.html
│ │ ├── _internal_.HTMLTableCellElement.html
│ │ ├── _internal_.HTMLTableColElement.html
│ │ ├── _internal_.HTMLTableElement.html
│ │ ├── _internal_.HTMLTableRowElement.html
│ │ ├── _internal_.HTMLTableSectionElement.html
│ │ ├── _internal_.HTMLTemplateElement.html
│ │ ├── _internal_.HTMLTextAreaElement.html
│ │ ├── _internal_.HTMLTimeElement.html
│ │ ├── _internal_.HTMLTitleElement.html
│ │ ├── _internal_.HTMLTrackElement.html
│ │ ├── _internal_.HTMLUListElement.html
│ │ ├── _internal_.HTMLVideoElement.html
│ │ ├── _internal_.HTMLVideoElementEventMap.html
│ │ ├── _internal_.HashChangeEvent.html
│ │ ├── _internal_.History.html
│ │ ├── _internal_.IDBCursor.html
│ │ ├── _internal_.IDBCursorWithValue.html
│ │ ├── _internal_.IDBDatabaseInfo.html
│ │ ├── _internal_.IDBFactory.html
│ │ ├── _internal_.IDBIndex.html
│ │ ├── _internal_.IDBKeyRange.html
│ │ ├── _internal_.IDBOpenDBRequest.html
│ │ ├── _internal_.IDBOpenDBRequestEventMap.html
│ │ ├── _internal_.IDBRequest.html
│ │ ├── _internal_.IDBRequestEventMap.html
│ │ ├── _internal_.IDBTransaction.html
│ │ ├── _internal_.IDBTransactionEventMap.html
│ │ ├── _internal_.IDBVersionChangeEvent.html
│ │ ├── _internal_.IdleDeadline.html
│ │ ├── _internal_.IdleRequestCallback.html
│ │ ├── _internal_.IdleRequestOptions.html
│ │ ├── _internal_.ImageBitmap.html
│ │ ├── _internal_.ImageBitmapOptions.html
│ │ ├── _internal_.ImageBitmapRenderingContext.html
│ │ ├── _internal_.ImageBitmapRenderingContextSettings.html
│ │ ├── _internal_.ImageData.html
│ │ ├── _internal_.ImageDataSettings.html
│ │ ├── _internal_.InnerHTML.html
│ │ ├── _internal_.InputEvent.html
│ │ ├── _internal_.Iterable.html
│ │ ├── _internal_.IterableIterator.html
│ │ ├── _internal_.Iterator.html
│ │ ├── _internal_.IteratorReturnResult.html
│ │ ├── _internal_.IteratorYieldResult.html
│ │ ├── _internal_.KHR_parallel_shader_compile.html
│ │ ├── _internal_.KeyboardEvent.html
│ │ ├── _internal_.Keyframe.html
│ │ ├── _internal_.KeyframeAnimationOptions.html
│ │ ├── _internal_.KeyframeEffectOptions.html
│ │ ├── _internal_.LinkStyle.html
│ │ ├── _internal_.Location.html
│ │ ├── _internal_.MIDIConnectionEvent.html
│ │ ├── _internal_.MIDIMessageEvent.html
│ │ ├── _internal_.MIDIPort.html
│ │ ├── _internal_.MIDIPortEventMap.html
│ │ ├── _internal_.MediaEncryptedEvent.html
│ │ ├── _internal_.MediaError.html
│ │ ├── _internal_.MediaKeyMessageEvent.html
│ │ ├── _internal_.MediaKeySession.html
│ │ ├── _internal_.MediaKeySessionEventMap.html
│ │ ├── _internal_.MediaKeys.html
│ │ ├── _internal_.MediaQueryList.html
│ │ ├── _internal_.MediaQueryListEvent.html
│ │ ├── _internal_.MediaQueryListEventMap.html
│ │ ├── _internal_.MediaRecorderErrorEvent.html
│ │ ├── _internal_.MediaSource.html
│ │ ├── _internal_.MediaSourceEventMap.html
│ │ ├── _internal_.MediaStream.html
│ │ ├── _internal_.MediaStreamEventMap.html
│ │ ├── _internal_.MediaStreamTrack.html
│ │ ├── _internal_.MediaStreamTrackEvent.html
│ │ ├── _internal_.MediaStreamTrackEventMap.html
│ │ ├── _internal_.MediaTrackCapabilities.html
│ │ ├── _internal_.MediaTrackConstraintSet.html
│ │ ├── _internal_.MediaTrackConstraints.html
│ │ ├── _internal_.MediaTrackSettings.html
│ │ ├── _internal_.MessagePort.html
│ │ ├── _internal_.MessagePortEventMap.html
│ │ ├── _internal_.MouseEvent.html
│ │ ├── _internal_.MultiCacheQueryOptions.html
│ │ ├── _internal_.MutationEvent.html
│ │ ├── _internal_.Node.html
│ │ ├── _internal_.NodeIterator.html
│ │ ├── _internal_.NonDocumentTypeChildNode.html
│ │ ├── _internal_.NonElementParentNode.html
│ │ ├── _internal_.OES_element_index_uint.html
│ │ ├── _internal_.OES_standard_derivatives.html
│ │ ├── _internal_.OES_texture_float.html
│ │ ├── _internal_.OES_texture_float_linear.html
│ │ ├── _internal_.OES_texture_half_float.html
│ │ ├── _internal_.OES_texture_half_float_linear.html
│ │ ├── _internal_.OES_vertex_array_object.html
│ │ ├── _internal_.OVR_multiview2.html
│ │ ├── _internal_.OfflineAudioCompletionEvent.html
│ │ ├── _internal_.OnErrorEventHandlerNonNull.html
│ │ ├── _internal_.OptionalEffectTiming.html
│ │ ├── _internal_.PageTransitionEvent.html
│ │ ├── _internal_.ParentNode.html
│ │ ├── _internal_.Path2D.html
│ │ ├── _internal_.PaymentCurrencyAmount.html
│ │ ├── _internal_.PaymentDetailsBase.html
│ │ ├── _internal_.PaymentDetailsModifier.html
│ │ ├── _internal_.PaymentDetailsUpdate.html
│ │ ├── _internal_.PaymentItem.html
│ │ ├── _internal_.PaymentMethodChangeEvent.html
│ │ ├── _internal_.PaymentRequestUpdateEvent.html
│ │ ├── _internal_.Performance.html
│ │ ├── _internal_.PerformanceEntry.html
│ │ ├── _internal_.PerformanceEventMap.html
│ │ ├── _internal_.PerformanceMark.html
│ │ ├── _internal_.PerformanceMarkOptions.html
│ │ ├── _internal_.PerformanceMeasure.html
│ │ ├── _internal_.PerformanceMeasureOptions.html
│ │ ├── _internal_.PerformanceNavigation.html
│ │ ├── _internal_.PerformanceTiming.html
│ │ ├── _internal_.PictureInPictureWindow.html
│ │ ├── _internal_.PictureInPictureWindowEventMap.html
│ │ ├── _internal_.PointerEvent.html
│ │ ├── _internal_.PopStateEvent.html
│ │ ├── _internal_.ProcessingInstruction.html
│ │ ├── _internal_.ProgressEvent.html
│ │ ├── _internal_.PromiseLike.html
│ │ ├── _internal_.PromiseRejectionEvent.html
│ │ ├── _internal_.PropertyIndexedKeyframes.html
│ │ ├── _internal_.RTCDTMFToneChangeEvent.html
│ │ ├── _internal_.RTCDataChannel.html
│ │ ├── _internal_.RTCDataChannelEvent.html
│ │ ├── _internal_.RTCDataChannelEventMap.html
│ │ ├── _internal_.RTCDtlsTransport.html
│ │ ├── _internal_.RTCDtlsTransportEventMap.html
│ │ ├── _internal_.RTCError.html
│ │ ├── _internal_.RTCErrorEvent.html
│ │ ├── _internal_.RTCIceCandidate.html
│ │ ├── _internal_.RTCIceCandidateInit.html
│ │ ├── _internal_.RTCIceTransport.html
│ │ ├── _internal_.RTCIceTransportEventMap.html
│ │ ├── _internal_.RTCPeerConnectionIceErrorEvent.html
│ │ ├── _internal_.RTCPeerConnectionIceEvent.html
│ │ ├── _internal_.RTCRtcpParameters.html
│ │ ├── _internal_.RTCRtpCapabilities.html
│ │ ├── _internal_.RTCRtpCodecCapability.html
│ │ ├── _internal_.RTCRtpCodecParameters.html
│ │ ├── _internal_.RTCRtpContributingSource.html
│ │ ├── _internal_.RTCRtpHeaderExtensionCapability.html
│ │ ├── _internal_.RTCRtpHeaderExtensionParameters.html
│ │ ├── _internal_.RTCRtpParameters.html
│ │ ├── _internal_.RTCRtpReceiveParameters.html
│ │ ├── _internal_.RTCRtpReceiver.html
│ │ ├── _internal_.RTCRtpSynchronizationSource.html
│ │ ├── _internal_.RTCTrackEvent.html
│ │ ├── _internal_.Range.html
│ │ ├── _internal_.ReadableStream-1.html
│ │ ├── _internal_.ReadableStream.html
│ │ ├── _internal_.ReadableStreamDefaultReadDoneResult.html
│ │ ├── _internal_.ReadableStreamDefaultReadValueResult.html
│ │ ├── _internal_.ReadableStreamDefaultReader.html
│ │ ├── _internal_.ReadableStreamGenericReader.html
│ │ ├── _internal_.ReadableWritablePair.html
│ │ ├── _internal_.RemotePlayback.html
│ │ ├── _internal_.RemotePlaybackAvailabilityCallback.html
│ │ ├── _internal_.RemotePlaybackEventMap.html
│ │ ├── _internal_.Request.html
│ │ ├── _internal_.RequestInit.html
│ │ ├── _internal_.Response.html
│ │ ├── _internal_.SVGAElement.html
│ │ ├── _internal_.SVGAngle.html
│ │ ├── _internal_.SVGAnimateElement.html
│ │ ├── _internal_.SVGAnimateMotionElement.html
│ │ ├── _internal_.SVGAnimateTransformElement.html
│ │ ├── _internal_.SVGAnimatedAngle.html
│ │ ├── _internal_.SVGAnimatedBoolean.html
│ │ ├── _internal_.SVGAnimatedEnumeration.html
│ │ ├── _internal_.SVGAnimatedInteger.html
│ │ ├── _internal_.SVGAnimatedLength.html
│ │ ├── _internal_.SVGAnimatedLengthList.html
│ │ ├── _internal_.SVGAnimatedNumber.html
│ │ ├── _internal_.SVGAnimatedNumberList.html
│ │ ├── _internal_.SVGAnimatedPoints.html
│ │ ├── _internal_.SVGAnimatedPreserveAspectRatio.html
│ │ ├── _internal_.SVGAnimatedRect.html
│ │ ├── _internal_.SVGAnimatedString.html
│ │ ├── _internal_.SVGAnimatedTransformList.html
│ │ ├── _internal_.SVGAnimationElement.html
│ │ ├── _internal_.SVGBoundingBoxOptions.html
│ │ ├── _internal_.SVGCircleElement.html
│ │ ├── _internal_.SVGClipPathElement.html
│ │ ├── _internal_.SVGComponentTransferFunctionElement.html
│ │ ├── _internal_.SVGDefsElement.html
│ │ ├── _internal_.SVGDescElement.html
│ │ ├── _internal_.SVGElement.html
│ │ ├── _internal_.SVGElementEventMap.html
│ │ ├── _internal_.SVGElementTagNameMap.html
│ │ ├── _internal_.SVGEllipseElement.html
│ │ ├── _internal_.SVGFEBlendElement.html
│ │ ├── _internal_.SVGFEColorMatrixElement.html
│ │ ├── _internal_.SVGFEComponentTransferElement.html
│ │ ├── _internal_.SVGFECompositeElement.html
│ │ ├── _internal_.SVGFEConvolveMatrixElement.html
│ │ ├── _internal_.SVGFEDiffuseLightingElement.html
│ │ ├── _internal_.SVGFEDisplacementMapElement.html
│ │ ├── _internal_.SVGFEDistantLightElement.html
│ │ ├── _internal_.SVGFEDropShadowElement.html
│ │ ├── _internal_.SVGFEFloodElement.html
│ │ ├── _internal_.SVGFEFuncAElement.html
│ │ ├── _internal_.SVGFEFuncBElement.html
│ │ ├── _internal_.SVGFEFuncGElement.html
│ │ ├── _internal_.SVGFEFuncRElement.html
│ │ ├── _internal_.SVGFEGaussianBlurElement.html
│ │ ├── _internal_.SVGFEImageElement.html
│ │ ├── _internal_.SVGFEMergeElement.html
│ │ ├── _internal_.SVGFEMergeNodeElement.html
│ │ ├── _internal_.SVGFEMorphologyElement.html
│ │ ├── _internal_.SVGFEOffsetElement.html
│ │ ├── _internal_.SVGFEPointLightElement.html
│ │ ├── _internal_.SVGFESpecularLightingElement.html
│ │ ├── _internal_.SVGFESpotLightElement.html
│ │ ├── _internal_.SVGFETileElement.html
│ │ ├── _internal_.SVGFETurbulenceElement.html
│ │ ├── _internal_.SVGFilterElement.html
│ │ ├── _internal_.SVGFilterPrimitiveStandardAttributes.html
│ │ ├── _internal_.SVGFitToViewBox.html
│ │ ├── _internal_.SVGForeignObjectElement.html
│ │ ├── _internal_.SVGGElement.html
│ │ ├── _internal_.SVGGeometryElement.html
│ │ ├── _internal_.SVGGradientElement.html
│ │ ├── _internal_.SVGGraphicsElement.html
│ │ ├── _internal_.SVGImageElement.html
│ │ ├── _internal_.SVGLength.html
│ │ ├── _internal_.SVGLineElement.html
│ │ ├── _internal_.SVGLinearGradientElement.html
│ │ ├── _internal_.SVGMPathElement.html
│ │ ├── _internal_.SVGMarkerElement.html
│ │ ├── _internal_.SVGMaskElement.html
│ │ ├── _internal_.SVGMetadataElement.html
│ │ ├── _internal_.SVGNumber.html
│ │ ├── _internal_.SVGPathElement.html
│ │ ├── _internal_.SVGPatternElement.html
│ │ ├── _internal_.SVGPolygonElement.html
│ │ ├── _internal_.SVGPolylineElement.html
│ │ ├── _internal_.SVGPreserveAspectRatio.html
│ │ ├── _internal_.SVGRadialGradientElement.html
│ │ ├── _internal_.SVGRectElement.html
│ │ ├── _internal_.SVGSVGElement.html
│ │ ├── _internal_.SVGSVGElementEventMap.html
│ │ ├── _internal_.SVGScriptElement.html
│ │ ├── _internal_.SVGSetElement.html
│ │ ├── _internal_.SVGStopElement.html
│ │ ├── _internal_.SVGStyleElement.html
│ │ ├── _internal_.SVGSwitchElement.html
│ │ ├── _internal_.SVGSymbolElement.html
│ │ ├── _internal_.SVGTSpanElement.html
│ │ ├── _internal_.SVGTests.html
│ │ ├── _internal_.SVGTextContentElement.html
│ │ ├── _internal_.SVGTextElement.html
│ │ ├── _internal_.SVGTextPathElement.html
│ │ ├── _internal_.SVGTextPositioningElement.html
│ │ ├── _internal_.SVGTitleElement.html
│ │ ├── _internal_.SVGTransform.html
│ │ ├── _internal_.SVGURIReference.html
│ │ ├── _internal_.SVGUseElement.html
│ │ ├── _internal_.SVGViewElement.html
│ │ ├── _internal_.Screen.html
│ │ ├── _internal_.ScreenOrientation.html
│ │ ├── _internal_.ScreenOrientationEventMap.html
│ │ ├── _internal_.ScrollIntoViewOptions.html
│ │ ├── _internal_.ScrollOptions.html
│ │ ├── _internal_.ScrollToOptions.html
│ │ ├── _internal_.SecurityPolicyViolationEvent.html
│ │ ├── _internal_.Selection.html
│ │ ├── _internal_.ShadowRoot.html
│ │ ├── _internal_.ShadowRootEventMap.html
│ │ ├── _internal_.ShadowRootInit.html
│ │ ├── _internal_.SharedArrayBuffer.html
│ │ ├── _internal_.SharedArrayBufferConstructor.html
│ │ ├── _internal_.Slottable.html
│ │ ├── _internal_.SourceBuffer.html
│ │ ├── _internal_.SourceBufferEventMap.html
│ │ ├── _internal_.SpeechSynthesis.html
│ │ ├── _internal_.SpeechSynthesisErrorEvent.html
│ │ ├── _internal_.SpeechSynthesisEvent.html
│ │ ├── _internal_.SpeechSynthesisEventMap.html
│ │ ├── _internal_.SpeechSynthesisUtterance.html
│ │ ├── _internal_.SpeechSynthesisUtteranceEventMap.html
│ │ ├── _internal_.SpeechSynthesisVoice.html
│ │ ├── _internal_.StaticRange.html
│ │ ├── _internal_.Storage.html
│ │ ├── _internal_.StorageEvent.html
│ │ ├── _internal_.StreamPipeOptions.html
│ │ ├── _internal_.StructuredSerializeOptions.html
│ │ ├── _internal_.StyleSheet.html
│ │ ├── _internal_.SubmitEvent.html
│ │ ├── _internal_.Text.html
│ │ ├── _internal_.TextMetrics.html
│ │ ├── _internal_.TextTrack.html
│ │ ├── _internal_.TextTrackCue.html
│ │ ├── _internal_.TextTrackCueEventMap.html
│ │ ├── _internal_.TextTrackEventMap.html
│ │ ├── _internal_.TimeRanges.html
│ │ ├── _internal_.TouchEvent.html
│ │ ├── _internal_.TrackEvent.html
│ │ ├── _internal_.TransitionEvent.html
│ │ ├── _internal_.TreeWalker.html
│ │ ├── _internal_.UIEvent.html
│ │ ├── _internal_.ULongRange.html
│ │ ├── _internal_.ValidityState.html
│ │ ├── _internal_.VideoFrameMetadata.html
│ │ ├── _internal_.VideoFrameRequestCallback.html
│ │ ├── _internal_.VideoPlaybackQuality.html
│ │ ├── _internal_.VisualViewport.html
│ │ ├── _internal_.VisualViewportEventMap.html
│ │ ├── _internal_.VoidFunction.html
│ │ ├── _internal_.WEBGL_color_buffer_float.html
│ │ ├── _internal_.WEBGL_compressed_texture_astc.html
│ │ ├── _internal_.WEBGL_compressed_texture_etc.html
│ │ ├── _internal_.WEBGL_compressed_texture_etc1.html
│ │ ├── _internal_.WEBGL_compressed_texture_s3tc.html
│ │ ├── _internal_.WEBGL_compressed_texture_s3tc_srgb.html
│ │ ├── _internal_.WEBGL_debug_renderer_info.html
│ │ ├── _internal_.WEBGL_debug_shaders.html
│ │ ├── _internal_.WEBGL_depth_texture.html
│ │ ├── _internal_.WEBGL_lose_context.html
│ │ ├── _internal_.WebGL2RenderingContext.html
│ │ ├── _internal_.WebGLActiveInfo.html
│ │ ├── _internal_.WebGLBuffer.html
│ │ ├── _internal_.WebGLContextAttributes.html
│ │ ├── _internal_.WebGLContextEvent.html
│ │ ├── _internal_.WebGLFramebuffer.html
│ │ ├── _internal_.WebGLProgram.html
│ │ ├── _internal_.WebGLQuery.html
│ │ ├── _internal_.WebGLRenderbuffer.html
│ │ ├── _internal_.WebGLRenderingContext.html
│ │ ├── _internal_.WebGLSampler.html
│ │ ├── _internal_.WebGLShader.html
│ │ ├── _internal_.WebGLShaderPrecisionFormat.html
│ │ ├── _internal_.WebGLSync.html
│ │ ├── _internal_.WebGLTexture.html
│ │ ├── _internal_.WebGLTransformFeedback.html
│ │ ├── _internal_.WebGLUniformLocation.html
│ │ ├── _internal_.WebGLVertexArrayObject.html
│ │ ├── _internal_.WebGLVertexArrayObjectOES.html
│ │ ├── _internal_.WheelEvent.html
│ │ ├── _internal_.Window.html
│ │ ├── _internal_.WindowEventHandlers.html
│ │ ├── _internal_.WindowEventHandlersEventMap.html
│ │ ├── _internal_.WindowEventMap.html
│ │ ├── _internal_.WindowLocalStorage.html
│ │ ├── _internal_.WindowOrWorkerGlobalScope.html
│ │ ├── _internal_.WindowPostMessageOptions.html
│ │ ├── _internal_.WindowSessionStorage.html
│ │ ├── _internal_.WritableStream-1.html
│ │ ├── _internal_.WritableStream.html
│ │ ├── _internal_.WritableStreamDefaultWriter.html
│ │ ├── _internal_.XMLDocument.html
│ │ ├── _internal_.XPathEvaluatorBase.html
│ │ ├── _internal_.XPathExpression.html
│ │ └── _internal_.XPathResult.html
│ ├── modules.html
│ └── modules
│ │ └── _internal_.html
├── common.97dc6094.css
├── dom-multiple.364abb33.css
├── dom-multiple.f1f90186.js
├── dom.c2350d4c.js
├── dom.f83825bb.css
├── examples.b3b81731.js
├── examples.fa10a2f1.css
├── godray.58904440.js
├── godray.a8d3693c.css
├── godray.c294baa0.js
├── group.2d1ce79b.css
├── group.9da781f2.js
├── image.2d1ce79b.css
├── image.3a2bf2f6.js
├── index.html
├── instancing.00f8c81f.js
├── instancing.167e377c.js
├── instancing.a8d3693c.css
├── kgl-auto
│ ├── godray
│ │ └── index.html
│ ├── instancing
│ │ └── index.html
│ └── simple
│ │ └── index.html
├── kgl
│ ├── 3d
│ │ └── index.html
│ ├── dom-multiple
│ │ └── index.html
│ ├── dom
│ │ └── index.html
│ ├── godray
│ │ └── index.html
│ ├── group
│ │ └── index.html
│ ├── image
│ │ └── index.html
│ ├── instancing
│ │ └── index.html
│ ├── point
│ │ └── index.html
│ ├── simple
│ │ └── index.html
│ └── transparent-images
│ │ └── index.html
├── point.2d1ce79b.css
├── point.c0a8c1fa.js
├── simple.24c3f6a9.js
├── simple.26db8ec6.js
├── simple.2d1ce79b.css
├── transparent-images.2d1ce79b.css
└── transparent-images.7d1a2fcd.js
├── examples
├── .babelrc
├── .gitignore
├── common.styl
├── index.html
├── index.js
├── index.styl
├── kgl-auto
│ ├── godray
│ │ ├── index.css
│ │ ├── index.html
│ │ └── index.js
│ ├── instancing
│ │ ├── index.css
│ │ ├── index.html
│ │ └── index.js
│ └── simple
│ │ ├── index.css
│ │ ├── index.html
│ │ └── index.js
├── kgl
│ ├── 3d
│ │ ├── index.css
│ │ ├── index.frag
│ │ ├── index.html
│ │ └── index.js
│ ├── dom-multiple
│ │ ├── index.css
│ │ ├── index.frag
│ │ ├── index.html
│ │ └── index.js
│ ├── dom
│ │ ├── index.css
│ │ ├── index.frag
│ │ ├── index.html
│ │ └── index.js
│ ├── godray
│ │ ├── index.css
│ │ ├── index.html
│ │ ├── index.js
│ │ └── mask.frag
│ ├── group
│ │ ├── cross.frag
│ │ ├── full.frag
│ │ ├── index.css
│ │ ├── index.frag
│ │ ├── index.html
│ │ └── index.js
│ ├── image
│ │ ├── index.css
│ │ ├── index.frag
│ │ ├── index.html
│ │ └── index.js
│ ├── instancing
│ │ ├── index.css
│ │ ├── index.html
│ │ ├── index.js
│ │ └── shaders
│ │ │ ├── main.frag
│ │ │ ├── main.vert
│ │ │ ├── position.frag
│ │ │ ├── reset-position.frag
│ │ │ ├── reset-velocity.frag
│ │ │ └── velocity.frag
│ ├── point
│ │ ├── index.css
│ │ ├── index.frag
│ │ ├── index.html
│ │ ├── index.js
│ │ └── index.vert
│ ├── simple
│ │ ├── index.css
│ │ ├── index.frag
│ │ ├── index.html
│ │ └── index.js
│ └── transparent-images
│ │ ├── 1-white-clouds-png-image_400x400.png
│ │ ├── index.css
│ │ ├── index.frag
│ │ ├── index.html
│ │ └── index.js
├── package-lock.json
├── package.json
├── shaders
│ ├── PI.glsl
│ ├── discardOutOfRangeUv.glsl
│ ├── fitContain.glsl
│ ├── fitCover.glsl
│ ├── getZoomedUv.glsl
│ └── hsv.glsl
├── utils.js
└── variables.styl
├── package-lock.json
├── package.json
├── src
├── effects
│ ├── bloom.ts
│ ├── blur.ts
│ ├── godray.ts
│ ├── godrayLight.ts
│ ├── index.ts
│ ├── specular.ts
│ └── zoomblur.ts
├── index.ts
├── kgl.ts
├── kglAuto.ts
├── kglEffect.ts
├── minMatrix.ts
├── object.ts
├── program.ts
├── shaders
│ ├── glsl.d.ts
│ ├── postprocessing
│ │ ├── bloom.frag
│ │ ├── blur.frag
│ │ ├── godray.frag
│ │ ├── specular.frag
│ │ └── zoomblur.frag
│ └── template
│ │ └── texture.frag
├── shape.ts
├── type.ts
└── vector.ts
├── tsconfig.json
└── tsconfig.types.json
/.editorconfig:
--------------------------------------------------------------------------------
1 | # editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
12 | [*.md]
13 | trim_trailing_whitespace = false
14 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | dist/
3 | docs/
4 | .cache
5 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | browser: true,
4 | es2021: true,
5 | },
6 | extends: ['standard', 'prettier', 'plugin:prettier/recommended'],
7 | plugins: ['prettier'],
8 | parserOptions: {
9 | ecmaVersion: 12,
10 | sourceType: 'module',
11 | },
12 | rules: {
13 | 'no-new': 'off',
14 | },
15 | }
16 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | /node_modules
3 | /dist
4 | /lib
5 | /types
6 | # /docs
7 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | dist
2 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "semi": false,
3 | "singleQuote": true
4 | }
5 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.formatOnSave": true
3 | }
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Ko.Yelie
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # KGL
2 |
3 | Minimal WebGL library
4 |
5 | ## Pros and Cons
6 |
7 | ### Pros
8 |
9 | - Lightweight
10 | - Can write with less code.
11 | - Automates calculations to fit WebGL and DOM sizes.
12 | - Support TypeScript.
13 |
14 | ### Cons
15 |
16 | - Fragment shaders must always be written by you.
17 | - Cannot use complex 3D models.
18 | - Cannot use lighting.
19 | - Not support WebGL2 yet.
20 |
21 | ## Documentation
22 |
23 | - [API](https://ko-yelie.github.io/kgl/api/)
24 |
25 | ## Usage
26 |
27 | ### Installation
28 |
29 | #### ES Modules
30 |
31 | [npm](https://www.npmjs.com/package/@ko-yelie/kgl)
32 |
33 | ```sh
34 | npm i @ko-yelie/kgl
35 | ```
36 |
37 | ```js
38 | // Kgl
39 | import Kgl from '@ko-yelie/kgl'
40 |
41 | // KglAuto
42 | import { KglAuto } from '@ko-yelie/kgl'
43 |
44 | // Import only KGL (ignore KglAuto and effects)
45 | import Kgl from '@ko-yelie/kgl/dist/kgl.es.js'
46 | ```
47 |
48 | #### CDN
49 |
50 | [unpkg](https://unpkg.com/@ko-yelie/kgl)
51 |
52 | ```html
53 |
54 | ```
55 |
56 | ```js
57 | // Kgl
58 | Kgl.default
59 |
60 | // KglAuto
61 | const { KglAuto } = Kgl
62 | ```
63 |
64 | ### `Kgl`
65 |
66 | #### HTML
67 |
68 | ```html
69 |
80 | ```
81 |
82 | #### JS
83 |
84 | ```js
85 | import Kgl from '@ko-yelie/kgl'
86 |
87 | const kgl = new Kgl()
88 |
89 | /**
90 | * program
91 | */
92 | const program = kgl.createProgram({
93 | fragmentShaderId: 'fs',
94 | uniforms: {
95 | uTime: 0,
96 | },
97 | isAutoAdd: true,
98 | })
99 |
100 | /**
101 | * resize
102 | */
103 | function resize() {
104 | kgl.resize()
105 | }
106 | resize()
107 | window.addEventListener('resize', resize)
108 |
109 | /**
110 | * tick
111 | */
112 | function tick(time) {
113 | program.uniforms.uTime = time * 0.001
114 |
115 | kgl.draw()
116 |
117 | requestAnimationFrame(tick)
118 | }
119 | requestAnimationFrame(tick)
120 | ```
121 |
122 | ### `KglAuto`
123 |
124 | #### JS
125 |
126 | ```js
127 | import { KglAuto } from '@ko-yelie/kgl'
128 |
129 | new KglAuto({
130 | programs: {
131 | main: {
132 | fragmentShaderId: 'fs',
133 | uniforms: {
134 | uTime: 0,
135 | },
136 | },
137 | },
138 | tick: (kgl, time) => {
139 | kgl.programs.main.uniforms.uTime = time
140 | kgl.draw()
141 | },
142 | })
143 | ```
144 |
145 | ## Examples
146 |
147 | https://ko-yelie.github.io/kgl/
148 |
--------------------------------------------------------------------------------
/bili.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | const pkg = require(path.resolve(process.cwd(), 'package.json'))
3 |
4 | const NAME = 'KGL'
5 | const banner = `/*!
6 | * ${NAME || pkg.name} v${pkg.version}
7 | * ${pkg.homepage}
8 | * @license ${pkg.license}
9 | * Copyright ${pkg.author}
10 | */`
11 |
12 | module.exports = {
13 | babel: {
14 | minimal: true,
15 | },
16 | banner,
17 | input: ['src/index.ts', 'src/kgl.ts'],
18 | output: {
19 | moduleName: 'Kgl',
20 | format: ['es', 'iife', 'iife-min'],
21 | sourceMap: false,
22 | target: 'browser',
23 | },
24 | plugins: {
25 | replace: { preventAssignment: true },
26 | glslify: true,
27 | },
28 | }
29 |
--------------------------------------------------------------------------------
/docs/1-white-clouds-png-image_400x400.2471b47f.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ko-yelie/kgl/746f039b018192e5e78574ff933ce0ded15805cc/docs/1-white-clouds-png-image_400x400.2471b47f.png
--------------------------------------------------------------------------------
/docs/3d.2d1ce79b.css:
--------------------------------------------------------------------------------
1 | body,html{height:100%}body{margin:0;background-color:#494e57}
--------------------------------------------------------------------------------
/docs/api/.nojekyll:
--------------------------------------------------------------------------------
1 | TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false.
--------------------------------------------------------------------------------
/docs/api/assets/highlight.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --light-hl-0: #000000;
3 | --dark-hl-0: #D4D4D4;
4 | --light-hl-1: #008000;
5 | --dark-hl-1: #6A9955;
6 | --light-hl-2: #AF00DB;
7 | --dark-hl-2: #C586C0;
8 | --light-hl-3: #001080;
9 | --dark-hl-3: #9CDCFE;
10 | --light-hl-4: #A31515;
11 | --dark-hl-4: #CE9178;
12 | --light-hl-5: #800000;
13 | --dark-hl-5: #808080;
14 | --light-hl-6: #800000;
15 | --dark-hl-6: #569CD6;
16 | --light-hl-7: #000000FF;
17 | --dark-hl-7: #D4D4D4;
18 | --light-hl-8: #FF0000;
19 | --dark-hl-8: #9CDCFE;
20 | --light-hl-9: #0000FF;
21 | --dark-hl-9: #CE9178;
22 | --light-hl-10: #0000FF;
23 | --dark-hl-10: #569CD6;
24 | --light-hl-11: #0070C1;
25 | --dark-hl-11: #4FC1FF;
26 | --light-hl-12: #795E26;
27 | --dark-hl-12: #DCDCAA;
28 | --light-hl-13: #098658;
29 | --dark-hl-13: #B5CEA8;
30 | --light-hl-14: #EE0000;
31 | --dark-hl-14: #D7BA7D;
32 | --light-hl-15: #267F99;
33 | --dark-hl-15: #4EC9B0;
34 | --light-code-background: #F5F5F5;
35 | --dark-code-background: #1E1E1E;
36 | }
37 |
38 | @media (prefers-color-scheme: light) { :root {
39 | --hl-0: var(--light-hl-0);
40 | --hl-1: var(--light-hl-1);
41 | --hl-2: var(--light-hl-2);
42 | --hl-3: var(--light-hl-3);
43 | --hl-4: var(--light-hl-4);
44 | --hl-5: var(--light-hl-5);
45 | --hl-6: var(--light-hl-6);
46 | --hl-7: var(--light-hl-7);
47 | --hl-8: var(--light-hl-8);
48 | --hl-9: var(--light-hl-9);
49 | --hl-10: var(--light-hl-10);
50 | --hl-11: var(--light-hl-11);
51 | --hl-12: var(--light-hl-12);
52 | --hl-13: var(--light-hl-13);
53 | --hl-14: var(--light-hl-14);
54 | --hl-15: var(--light-hl-15);
55 | --code-background: var(--light-code-background);
56 | } }
57 |
58 | @media (prefers-color-scheme: dark) { :root {
59 | --hl-0: var(--dark-hl-0);
60 | --hl-1: var(--dark-hl-1);
61 | --hl-2: var(--dark-hl-2);
62 | --hl-3: var(--dark-hl-3);
63 | --hl-4: var(--dark-hl-4);
64 | --hl-5: var(--dark-hl-5);
65 | --hl-6: var(--dark-hl-6);
66 | --hl-7: var(--dark-hl-7);
67 | --hl-8: var(--dark-hl-8);
68 | --hl-9: var(--dark-hl-9);
69 | --hl-10: var(--dark-hl-10);
70 | --hl-11: var(--dark-hl-11);
71 | --hl-12: var(--dark-hl-12);
72 | --hl-13: var(--dark-hl-13);
73 | --hl-14: var(--dark-hl-14);
74 | --hl-15: var(--dark-hl-15);
75 | --code-background: var(--dark-code-background);
76 | } }
77 |
78 | body.light {
79 | --hl-0: var(--light-hl-0);
80 | --hl-1: var(--light-hl-1);
81 | --hl-2: var(--light-hl-2);
82 | --hl-3: var(--light-hl-3);
83 | --hl-4: var(--light-hl-4);
84 | --hl-5: var(--light-hl-5);
85 | --hl-6: var(--light-hl-6);
86 | --hl-7: var(--light-hl-7);
87 | --hl-8: var(--light-hl-8);
88 | --hl-9: var(--light-hl-9);
89 | --hl-10: var(--light-hl-10);
90 | --hl-11: var(--light-hl-11);
91 | --hl-12: var(--light-hl-12);
92 | --hl-13: var(--light-hl-13);
93 | --hl-14: var(--light-hl-14);
94 | --hl-15: var(--light-hl-15);
95 | --code-background: var(--light-code-background);
96 | }
97 |
98 | body.dark {
99 | --hl-0: var(--dark-hl-0);
100 | --hl-1: var(--dark-hl-1);
101 | --hl-2: var(--dark-hl-2);
102 | --hl-3: var(--dark-hl-3);
103 | --hl-4: var(--dark-hl-4);
104 | --hl-5: var(--dark-hl-5);
105 | --hl-6: var(--dark-hl-6);
106 | --hl-7: var(--dark-hl-7);
107 | --hl-8: var(--dark-hl-8);
108 | --hl-9: var(--dark-hl-9);
109 | --hl-10: var(--dark-hl-10);
110 | --hl-11: var(--dark-hl-11);
111 | --hl-12: var(--dark-hl-12);
112 | --hl-13: var(--dark-hl-13);
113 | --hl-14: var(--dark-hl-14);
114 | --hl-15: var(--dark-hl-15);
115 | --code-background: var(--dark-code-background);
116 | }
117 |
118 | .hl-0 { color: var(--hl-0); }
119 | .hl-1 { color: var(--hl-1); }
120 | .hl-2 { color: var(--hl-2); }
121 | .hl-3 { color: var(--hl-3); }
122 | .hl-4 { color: var(--hl-4); }
123 | .hl-5 { color: var(--hl-5); }
124 | .hl-6 { color: var(--hl-6); }
125 | .hl-7 { color: var(--hl-7); }
126 | .hl-8 { color: var(--hl-8); }
127 | .hl-9 { color: var(--hl-9); }
128 | .hl-10 { color: var(--hl-10); }
129 | .hl-11 { color: var(--hl-11); }
130 | .hl-12 { color: var(--hl-12); }
131 | .hl-13 { color: var(--hl-13); }
132 | .hl-14 { color: var(--hl-14); }
133 | .hl-15 { color: var(--hl-15); }
134 | pre, code { background: var(--code-background); }
135 |
--------------------------------------------------------------------------------
/docs/api/assets/icons.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ko-yelie/kgl/746f039b018192e5e78574ff933ce0ded15805cc/docs/api/assets/icons.png
--------------------------------------------------------------------------------
/docs/api/assets/icons@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ko-yelie/kgl/746f039b018192e5e78574ff933ce0ded15805cc/docs/api/assets/icons@2x.png
--------------------------------------------------------------------------------
/docs/api/assets/widgets.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ko-yelie/kgl/746f039b018192e5e78574ff933ce0ded15805cc/docs/api/assets/widgets.png
--------------------------------------------------------------------------------
/docs/api/assets/widgets@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ko-yelie/kgl/746f039b018192e5e78574ff933ce0ded15805cc/docs/api/assets/widgets@2x.png
--------------------------------------------------------------------------------
/docs/api/interfaces/_internal_.DOMStringMap.html:
--------------------------------------------------------------------------------
1 |
DOMStringMap | @ko-yelie/kgl Indexable [ name: string ]: string | undefined
Legend Constructor Property Method Accessor Inherited constructor Inherited property Inherited method Inherited accessor Settings Theme OS Light Dark
--------------------------------------------------------------------------------
/docs/api/interfaces/_internal_.EXT_color_buffer_float.html:
--------------------------------------------------------------------------------
1 | EXT_color_buffer_float | @ko-yelie/kgl Interface EXT_color_buffer_float Legend Constructor Property Method Accessor Inherited constructor Inherited property Inherited method Inherited accessor Settings Theme OS Light Dark
--------------------------------------------------------------------------------
/docs/api/interfaces/_internal_.EXT_float_blend.html:
--------------------------------------------------------------------------------
1 | EXT_float_blend | @ko-yelie/kgl Interface EXT_float_blend Legend Constructor Property Method Accessor Inherited constructor Inherited property Inherited method Inherited accessor Settings Theme OS Light Dark
--------------------------------------------------------------------------------
/docs/api/interfaces/_internal_.EXT_frag_depth.html:
--------------------------------------------------------------------------------
1 | EXT_frag_depth | @ko-yelie/kgl Legend Constructor Property Method Accessor Inherited constructor Inherited property Inherited method Inherited accessor Settings Theme OS Light Dark
--------------------------------------------------------------------------------
/docs/api/interfaces/_internal_.EXT_shader_texture_lod.html:
--------------------------------------------------------------------------------
1 | EXT_shader_texture_lod | @ko-yelie/kgl Interface EXT_shader_texture_lod Legend Constructor Property Method Accessor Inherited constructor Inherited property Inherited method Inherited accessor Settings Theme OS Light Dark
--------------------------------------------------------------------------------
/docs/api/interfaces/_internal_.OES_element_index_uint.html:
--------------------------------------------------------------------------------
1 | OES_element_index_uint | @ko-yelie/kgl Interface OES_element_index_uint Legend Constructor Property Method Accessor Inherited constructor Inherited property Inherited method Inherited accessor Settings Theme OS Light Dark
--------------------------------------------------------------------------------
/docs/api/interfaces/_internal_.OES_texture_float.html:
--------------------------------------------------------------------------------
1 | OES_texture_float | @ko-yelie/kgl Interface OES_texture_float Legend Constructor Property Method Accessor Inherited constructor Inherited property Inherited method Inherited accessor Settings Theme OS Light Dark
--------------------------------------------------------------------------------
/docs/api/interfaces/_internal_.OES_texture_float_linear.html:
--------------------------------------------------------------------------------
1 | OES_texture_float_linear | @ko-yelie/kgl Interface OES_texture_float_linear Legend Constructor Property Method Accessor Inherited constructor Inherited property Inherited method Inherited accessor Settings Theme OS Light Dark
--------------------------------------------------------------------------------
/docs/api/interfaces/_internal_.OES_texture_half_float_linear.html:
--------------------------------------------------------------------------------
1 | OES_texture_half_float_linear | @ko-yelie/kgl Interface OES_texture_half_float_linear Hierarchy OES_texture_half_float_linear Legend Constructor Property Method Accessor Inherited constructor Inherited property Inherited method Inherited accessor Settings Theme OS Light Dark
--------------------------------------------------------------------------------
/docs/api/interfaces/_internal_.VoidFunction.html:
--------------------------------------------------------------------------------
1 | VoidFunction | @ko-yelie/kgl Callable Defined in node_modules/typescript/lib/lib.dom.d.ts:17464 Returns void Legend Constructor Property Method Accessor Inherited constructor Inherited property Inherited method Inherited accessor Settings Theme OS Light Dark
--------------------------------------------------------------------------------
/docs/api/interfaces/_internal_.WebGLBuffer.html:
--------------------------------------------------------------------------------
1 | WebGLBuffer | @ko-yelie/kgl Legend Constructor Property Method Accessor Inherited constructor Inherited property Inherited method Inherited accessor Settings Theme OS Light Dark
--------------------------------------------------------------------------------
/docs/api/interfaces/_internal_.WebGLFramebuffer.html:
--------------------------------------------------------------------------------
1 | WebGLFramebuffer | @ko-yelie/kgl Interface WebGLFramebuffer Legend Constructor Property Method Accessor Inherited constructor Inherited property Inherited method Inherited accessor Settings Theme OS Light Dark
--------------------------------------------------------------------------------
/docs/api/interfaces/_internal_.WebGLProgram.html:
--------------------------------------------------------------------------------
1 | WebGLProgram | @ko-yelie/kgl Legend Constructor Property Method Accessor Inherited constructor Inherited property Inherited method Inherited accessor Settings Theme OS Light Dark
--------------------------------------------------------------------------------
/docs/api/interfaces/_internal_.WebGLQuery.html:
--------------------------------------------------------------------------------
1 | WebGLQuery | @ko-yelie/kgl Legend Constructor Property Method Accessor Inherited constructor Inherited property Inherited method Inherited accessor Settings Theme OS Light Dark
--------------------------------------------------------------------------------
/docs/api/interfaces/_internal_.WebGLRenderbuffer.html:
--------------------------------------------------------------------------------
1 | WebGLRenderbuffer | @ko-yelie/kgl Interface WebGLRenderbuffer Legend Constructor Property Method Accessor Inherited constructor Inherited property Inherited method Inherited accessor Settings Theme OS Light Dark
--------------------------------------------------------------------------------
/docs/api/interfaces/_internal_.WebGLSampler.html:
--------------------------------------------------------------------------------
1 | WebGLSampler | @ko-yelie/kgl Legend Constructor Property Method Accessor Inherited constructor Inherited property Inherited method Inherited accessor Settings Theme OS Light Dark
--------------------------------------------------------------------------------
/docs/api/interfaces/_internal_.WebGLShader.html:
--------------------------------------------------------------------------------
1 | WebGLShader | @ko-yelie/kgl Legend Constructor Property Method Accessor Inherited constructor Inherited property Inherited method Inherited accessor Settings Theme OS Light Dark
--------------------------------------------------------------------------------
/docs/api/interfaces/_internal_.WebGLSync.html:
--------------------------------------------------------------------------------
1 | WebGLSync | @ko-yelie/kgl Legend Constructor Property Method Accessor Inherited constructor Inherited property Inherited method Inherited accessor Settings Theme OS Light Dark
--------------------------------------------------------------------------------
/docs/api/interfaces/_internal_.WebGLTexture.html:
--------------------------------------------------------------------------------
1 | WebGLTexture | @ko-yelie/kgl Legend Constructor Property Method Accessor Inherited constructor Inherited property Inherited method Inherited accessor Settings Theme OS Light Dark
--------------------------------------------------------------------------------
/docs/api/interfaces/_internal_.WebGLTransformFeedback.html:
--------------------------------------------------------------------------------
1 | WebGLTransformFeedback | @ko-yelie/kgl Interface WebGLTransformFeedback Legend Constructor Property Method Accessor Inherited constructor Inherited property Inherited method Inherited accessor Settings Theme OS Light Dark
--------------------------------------------------------------------------------
/docs/api/interfaces/_internal_.WebGLUniformLocation.html:
--------------------------------------------------------------------------------
1 | WebGLUniformLocation | @ko-yelie/kgl Interface WebGLUniformLocation Legend Constructor Property Method Accessor Inherited constructor Inherited property Inherited method Inherited accessor Settings Theme OS Light Dark
--------------------------------------------------------------------------------
/docs/api/interfaces/_internal_.WebGLVertexArrayObject.html:
--------------------------------------------------------------------------------
1 | WebGLVertexArrayObject | @ko-yelie/kgl Interface WebGLVertexArrayObject Legend Constructor Property Method Accessor Inherited constructor Inherited property Inherited method Inherited accessor Settings Theme OS Light Dark
--------------------------------------------------------------------------------
/docs/api/interfaces/_internal_.WebGLVertexArrayObjectOES.html:
--------------------------------------------------------------------------------
1 | WebGLVertexArrayObjectOES | @ko-yelie/kgl Interface WebGLVertexArrayObjectOES Hierarchy WebGLVertexArrayObjectOES Legend Constructor Property Method Accessor Inherited constructor Inherited property Inherited method Inherited accessor Settings Theme OS Light Dark
--------------------------------------------------------------------------------
/docs/common.97dc6094.css:
--------------------------------------------------------------------------------
1 | body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif}.attribution{position:absolute;top:.5rem;right:.5rem;background-color:rgba(0,0,0,.3);color:hsla(0,0%,100%,.5);font-size:.8rem;padding:0 .3em;text-decoration:none}.attribution:hover{color:hsla(0,0%,100%,.7);text-decoration:underline}
--------------------------------------------------------------------------------
/docs/dom-multiple.364abb33.css:
--------------------------------------------------------------------------------
1 | body,html{height:100%}body{margin:0;background-color:#494e57}.wapper{position:relative;z-index:2;padding:20% 0}.scroll{position:absolute;top:2%;left:0;right:0;margin:auto;text-align:center;color:hsla(0,0%,100%,.7)}.list{display:flex;flex-direction:column;justify-content:space-between;width:50%;min-height:150vh;margin:0 auto;list-style:none}.item{align-self:flex-start}.item:nth-child(2n){align-self:flex-end}.item:nth-child(n+2){margin-top:20%}.link{display:block;color:hsla(0,0%,100%,.5);text-decoration:none;text-align:center}.image{width:30vw;height:auto;opacity:0}.title{background-color:rgba(0,0,0,.3);font-size:.8rem;padding:0 .3em}.link:hover{color:hsla(0,0%,100%,.7);text-decoration:underline}canvas{position:fixed;top:0;left:0;z-index:1;width:100%;height:100%}
--------------------------------------------------------------------------------
/docs/dom.f83825bb.css:
--------------------------------------------------------------------------------
1 | body,html{height:100%}body{margin:0;background-color:#494e57}.wapper{position:relative;z-index:2;height:100%;display:flex;justify-content:center;align-items:center}.link{display:block;color:hsla(0,0%,100%,.5);text-decoration:none;text-align:center}.image{width:50vw;height:auto;opacity:0}.title{background-color:rgba(0,0,0,.3);font-size:.8rem;padding:0 .3em}.link:hover{color:hsla(0,0%,100%,.7);text-decoration:underline}canvas{position:fixed;top:0;left:0;z-index:1;width:100%;height:100%}
--------------------------------------------------------------------------------
/docs/examples.fa10a2f1.css:
--------------------------------------------------------------------------------
1 | body{display:flex;align-items:flex-start;margin:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif}a{text-decoration:none;color:hsla(0,0%,100%,.5)}a:hover{text-decoration:underline}a:hover,header{color:hsla(0,0%,100%,.7)}header{overflow:auto;box-sizing:border-box;position:fixed;top:.5rem;left:.5rem;z-index:1;max-height:calc(100% - 1rem);margin:auto;padding:.5rem;background-color:rgba(0,0,0,.3)}nav ul{margin:0}nav a{padding:.1em .2em;line-height:1.5}nav a.-current{pointer-events:none;text-decoration:none;outline:1px solid hsla(0,0%,100%,.7);background-color:hsla(0,0%,100%,.7);color:#000}h1,h2{margin:0;font-size:1rem;font-weight:400}h1{margin-bottom:.5em}h2{margin-top:.5em}#example{top:0;left:0;width:100%;height:100%}#code,#example{position:absolute}#code{bottom:.5rem;right:.5rem;z-index:2;padding:0 .3em;background-color:rgba(0,0,0,.3)}
--------------------------------------------------------------------------------
/docs/godray.a8d3693c.css:
--------------------------------------------------------------------------------
1 | body,html{height:100%}body{margin:0}
--------------------------------------------------------------------------------
/docs/group.2d1ce79b.css:
--------------------------------------------------------------------------------
1 | body,html{height:100%}body{margin:0;background-color:#494e57}
--------------------------------------------------------------------------------
/docs/image.2d1ce79b.css:
--------------------------------------------------------------------------------
1 | body,html{height:100%}body{margin:0;background-color:#494e57}
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 | KGL Library Examples <code>
--------------------------------------------------------------------------------
/docs/instancing.a8d3693c.css:
--------------------------------------------------------------------------------
1 | body,html{height:100%}body{margin:0}
--------------------------------------------------------------------------------
/docs/kgl-auto/godray/index.html:
--------------------------------------------------------------------------------
1 | KGL Library Examples - God Ray (KglAuto) Photo by Sasha Freemind on Unsplash
--------------------------------------------------------------------------------
/docs/kgl-auto/instancing/index.html:
--------------------------------------------------------------------------------
1 | KGL Library Examples - Instancing (KglAuto)
--------------------------------------------------------------------------------
/docs/kgl-auto/simple/index.html:
--------------------------------------------------------------------------------
1 | KGL Library Examples - Simple (KglAuto)
--------------------------------------------------------------------------------
/docs/kgl/3d/index.html:
--------------------------------------------------------------------------------
1 | KGL Library Examples - 3D
--------------------------------------------------------------------------------
/docs/kgl/dom-multiple/index.html:
--------------------------------------------------------------------------------
1 | KGL Library Examples - Fit Multiple DOM
--------------------------------------------------------------------------------
/docs/kgl/dom/index.html:
--------------------------------------------------------------------------------
1 | KGL Library Examples - Fit DOM
--------------------------------------------------------------------------------
/docs/kgl/godray/index.html:
--------------------------------------------------------------------------------
1 | KGL Library Examples - God Ray Photo by Sasha Freemind on Unsplash
--------------------------------------------------------------------------------
/docs/kgl/group/index.html:
--------------------------------------------------------------------------------
1 | KGL Library Examples - Group
--------------------------------------------------------------------------------
/docs/kgl/image/index.html:
--------------------------------------------------------------------------------
1 | KGL Library Examples - Image Photo by FLY:D on Unsplash
--------------------------------------------------------------------------------
/docs/kgl/instancing/index.html:
--------------------------------------------------------------------------------
1 | KGL Library Examples - Instancing
--------------------------------------------------------------------------------
/docs/kgl/point/index.html:
--------------------------------------------------------------------------------
1 | KGL Library Examples - Point
--------------------------------------------------------------------------------
/docs/kgl/simple/index.html:
--------------------------------------------------------------------------------
1 | KGL Library Examples - Simple
--------------------------------------------------------------------------------
/docs/kgl/transparent-images/index.html:
--------------------------------------------------------------------------------
1 | KGL Library Examples - Transparent Images White Clouds Png Image FreePNGImg.com
--------------------------------------------------------------------------------
/docs/point.2d1ce79b.css:
--------------------------------------------------------------------------------
1 | body,html{height:100%}body{margin:0;background-color:#494e57}
--------------------------------------------------------------------------------
/docs/simple.2d1ce79b.css:
--------------------------------------------------------------------------------
1 | body,html{height:100%}body{margin:0;background-color:#494e57}
--------------------------------------------------------------------------------
/docs/transparent-images.2d1ce79b.css:
--------------------------------------------------------------------------------
1 | body,html{height:100%}body{margin:0;background-color:#494e57}
--------------------------------------------------------------------------------
/examples/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | "@babel/plugin-transform-runtime"
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/examples/.gitignore:
--------------------------------------------------------------------------------
1 | .cache
2 | /dist
3 | /node_modules
4 |
--------------------------------------------------------------------------------
/examples/common.styl:
--------------------------------------------------------------------------------
1 | @import 'variables'
2 |
3 | body
4 | font-family font-family
5 |
6 | .attribution
7 | position absolute
8 | top margin-window
9 | right margin-window
10 | background-color background-color
11 | color color-link
12 | font-size 0.8rem
13 | padding 0 0.3em
14 | text-decoration none
15 |
16 | .attribution:hover
17 | color color-text
18 | text-decoration underline
19 |
--------------------------------------------------------------------------------
/examples/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | KGL Library Examples
7 |
8 |
9 |
10 |
11 |
12 |
13 | KGL Library Examples
14 |
15 |
16 | Document
17 |
18 |
19 | Kgl
20 |
32 |
33 | KglAuto
34 |
39 |
40 |
41 |
42 |
43 |
44 | <code>
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/examples/index.js:
--------------------------------------------------------------------------------
1 | const CLASS_NAME_INITIAL = 'kgl'
2 | const PAGE_INITIAL = 'simple'
3 | const CLASS_NAME_CURRENT = '-current'
4 |
5 | const elExample = document.getElementById('example')
6 | const elCode = document.getElementById('code')
7 | let urlIndex
8 | let classNameCurrent
9 | let pageCurrent
10 | let elLinkCurrent
11 |
12 | const mapLink = [...document.querySelectorAll('nav a')].map((el) => {
13 | const { pathname } = new URL(el.href)
14 | const [, className, page] = pathname.match(
15 | /^\/?(?:kgl\/)?(.+?)\/(.+?)\/index\.html/
16 | )
17 |
18 | el.addEventListener('click', (e) => {
19 | e.preventDefault()
20 |
21 | urlIndex.searchParams.set('class', className)
22 | urlIndex.searchParams.set('page', page)
23 | history.pushState(null, '', urlIndex)
24 |
25 | detectExample()
26 | })
27 |
28 | return {
29 | el,
30 | className,
31 | page,
32 | }
33 | })
34 |
35 | detectExample()
36 |
37 | window.addEventListener('popstate', detectExample)
38 |
39 | function detectExample() {
40 | urlIndex = new URL(location.href)
41 | const className = urlIndex.searchParams.get('class') || CLASS_NAME_INITIAL
42 | const page = urlIndex.searchParams.get('page') || PAGE_INITIAL
43 |
44 | if (className === classNameCurrent && page === pageCurrent) return
45 |
46 | const directory = `${className}/${page}`
47 | const pathname = `${directory}/index.html`
48 | elExample.contentWindow.location.replace(pathname)
49 | elCode.href = `https://github.com/ko-yelie/kgl/blob/main/examples/${directory}`
50 |
51 | classNameCurrent = className
52 | pageCurrent = page
53 |
54 | detectLink()
55 | }
56 |
57 | function detectLink() {
58 | mapLink.some(({ el, className, page }) => {
59 | if (!(className === classNameCurrent && page === pageCurrent)) return false
60 |
61 | if (elLinkCurrent) {
62 | elLinkCurrent.classList.remove(CLASS_NAME_CURRENT)
63 | }
64 |
65 | el.classList.add(CLASS_NAME_CURRENT)
66 | elLinkCurrent = el
67 |
68 | return true
69 | })
70 | }
71 |
--------------------------------------------------------------------------------
/examples/index.styl:
--------------------------------------------------------------------------------
1 | @import 'variables'
2 |
3 | body
4 | display flex
5 | align-items flex-start
6 | margin 0
7 | font-family font-family
8 |
9 | a
10 | text-decoration none
11 | color color-link
12 |
13 | &:hover
14 | text-decoration underline
15 | color color-text
16 |
17 | header
18 | overflow auto
19 | box-sizing border-box
20 | position fixed
21 | top margin-window
22 | left margin-window
23 | z-index 1
24 | max-height 'calc(100% - %s)' % (margin-window * 2)
25 | margin auto
26 | padding 0.5rem
27 | background-color background-color
28 | color color-text
29 |
30 | nav
31 | ul
32 | margin 0
33 |
34 | a
35 | padding 0.1em 0.2em
36 | line-height 1.5
37 |
38 | &.-current
39 | pointer-events none
40 | text-decoration none
41 | outline solid 1px color-text
42 | background-color color-text
43 | color #000
44 |
45 | h1,
46 | h2
47 | margin 0
48 | font-size 1rem
49 | font-weight normal
50 |
51 | h1
52 | margin-bottom 0.5em
53 |
54 | h2
55 | margin-top 0.5em
56 |
57 | #example
58 | position absolute
59 | top 0
60 | left 0
61 | width 100%
62 | height 100%
63 |
64 | #code
65 | position absolute
66 | bottom margin-window
67 | right margin-window
68 | z-index 2
69 | padding 0 0.3em
70 | background-color background-color
71 |
--------------------------------------------------------------------------------
/examples/kgl-auto/godray/index.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | height: 100%;
4 | }
5 |
6 | body {
7 | margin: 0;
8 | }
9 |
--------------------------------------------------------------------------------
/examples/kgl-auto/godray/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | KGL Library Examples - God Ray (KglAuto)
7 |
8 |
9 |
10 |
11 |
12 |
13 |
36 |
37 | Photo
38 | by Sasha Freemind on Unsplash
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/examples/kgl-auto/godray/index.js:
--------------------------------------------------------------------------------
1 | import { KglAuto } from '../../../src/index'
2 | import { loadImage, mix } from '../../utils.js'
3 |
4 | const image =
5 | 'https://images.unsplash.com/photo-1534330207526-8e81f10ec6fc?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=800&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' // https://unsplash.com/photos/Pv5WeEyxMWU
6 | const speed = 0.5
7 | const strength = 12
8 | const maxRadius = window.innerWidth < 768 ? 0.4 : 0.8
9 | const minRadius = 0.1
10 |
11 | async function main() {
12 | const img = await loadImage(image, true)
13 |
14 | new KglAuto({
15 | programs: {
16 | mask: {
17 | fragmentShaderId: 'mask',
18 | uniforms: {
19 | uImage: img,
20 | uImageResolution: [img.width, img.height],
21 | },
22 | },
23 | },
24 | effects: ['godray'],
25 | framebuffers: ['mask', 'cache', 'output'],
26 | tick: (kgl, time) => {
27 | const cTime = Math.sin(time * speed) * 0.5 + 0.5
28 | const halfTime = -Math.abs(cTime * 2 - 1) + 1
29 |
30 | kgl.bindFramebuffer('mask')
31 | kgl.programs.mask.draw()
32 |
33 | kgl.effects.godray.drawEffect(
34 | 'mask',
35 | 'cache',
36 | 'output',
37 | strength,
38 | [mix(kgl.canvas.width, 0, cTime), kgl.canvas.height * 0.5],
39 | mix(maxRadius, minRadius, halfTime),
40 | true
41 | )
42 | },
43 | })
44 | }
45 | main()
46 |
--------------------------------------------------------------------------------
/examples/kgl-auto/instancing/index.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | height: 100%;
4 | }
5 |
6 | body {
7 | margin: 0;
8 | }
9 |
--------------------------------------------------------------------------------
/examples/kgl-auto/instancing/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | KGL Library Examples - Instancing (KglAuto)
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/examples/kgl-auto/instancing/index.js:
--------------------------------------------------------------------------------
1 | import { KglAuto } from '../../../src/index'
2 | import resetVelocityFrag from '../../kgl/instancing/shaders/reset-velocity.frag'
3 | import resetPositionFrag from '../../kgl/instancing/shaders/reset-position.frag'
4 | import velocityFrag from '../../kgl/instancing/shaders/velocity.frag'
5 | import positionFrag from '../../kgl/instancing/shaders/position.frag'
6 | import mainVert from '../../kgl/instancing/shaders/main.vert'
7 | import mainFrag from '../../kgl/instancing/shaders/main.frag'
8 |
9 | const width = 100
10 | const height = 100
11 |
12 | const sizeUniform = [width, height]
13 | const particleUv = []
14 |
15 | for (let i = 0; i < width; i++) {
16 | for (let j = 0; j < height; j++) {
17 | particleUv.push(i / (width - 1), 1 - j / (height - 1))
18 | }
19 | }
20 |
21 | let loopCount = 0
22 | let targetBufferIndex = loopCount++ % 2
23 | let prevBufferIndex
24 |
25 | new KglAuto({
26 | clearedColor: [0, 0, 0, 1],
27 | hasCamera: true,
28 | hasLight: true,
29 | cameraPosition: [0, 0, 480],
30 | fov: 50,
31 | programs: {
32 | resetVelocity: {
33 | fragmentShader: resetVelocityFrag,
34 | isFloats: true,
35 | },
36 | resetPosition: {
37 | fragmentShader: resetPositionFrag,
38 | uniforms: {
39 | uSize: sizeUniform,
40 | },
41 | isFloats: true,
42 | },
43 | velocity: {
44 | fragmentShader: velocityFrag,
45 | uniforms: {
46 | uSize: sizeUniform,
47 | uPrevVelocityTexture: 'framebuffer',
48 | uPrevPositionTexture: 'framebuffer',
49 | },
50 | isFloats: true,
51 | },
52 | position: {
53 | fragmentShader: positionFrag,
54 | uniforms: {
55 | uSize: sizeUniform,
56 | uPrevPositionTexture: 'framebuffer',
57 | uVelocityTexture: 'framebuffer',
58 | },
59 | isFloats: true,
60 | },
61 | main: {
62 | shape: 'cube',
63 | vertexShader: mainVert,
64 | fragmentShader: mainFrag,
65 | instancedAttributes: {
66 | aInstancedUv: {
67 | value: particleUv,
68 | size: 2,
69 | },
70 | },
71 | uniforms: {
72 | uPositionTexture: 'framebuffer',
73 | uVelocityTexture: 'framebuffer',
74 | uTime: 0,
75 | },
76 | isDepth: true,
77 | isTransparent: true,
78 | },
79 | },
80 | framebufferFloats: {
81 | velocity0: {
82 | width,
83 | height,
84 | },
85 | velocity1: {
86 | width,
87 | height,
88 | },
89 | position0: {
90 | width,
91 | height,
92 | },
93 | position1: {
94 | width,
95 | height,
96 | },
97 | },
98 | onBefore: (kgl) => {
99 | kgl.bindFramebuffer('velocity' + targetBufferIndex)
100 | kgl.programs.resetVelocity.draw()
101 |
102 | kgl.bindFramebuffer('position' + targetBufferIndex)
103 | kgl.programs.resetPosition.draw()
104 | },
105 | tick: (kgl, time) => {
106 | prevBufferIndex = targetBufferIndex
107 | targetBufferIndex = loopCount++ % 2
108 |
109 | const prevVelocityTexture = `velocity${prevBufferIndex}`
110 | const prevPositionTexture = `position${prevBufferIndex}`
111 | const velocityTexture = `velocity${targetBufferIndex}`
112 | const positionTexture = `position${targetBufferIndex}`
113 |
114 | kgl.bindFramebuffer(velocityTexture)
115 |
116 | kgl.programs.velocity.updateUniforms({
117 | uPrevVelocityTexture: prevVelocityTexture,
118 | uPrevPositionTexture: prevPositionTexture,
119 | })
120 | kgl.programs.velocity.draw()
121 |
122 | kgl.bindFramebuffer(positionTexture)
123 |
124 | kgl.programs.position.updateUniforms({
125 | uPrevPositionTexture: prevPositionTexture,
126 | uVelocityTexture: velocityTexture,
127 | })
128 | kgl.programs.position.draw()
129 |
130 | kgl.unbindFramebuffer()
131 | kgl.clear()
132 |
133 | kgl.programs.main.updateUniforms({
134 | uPositionTexture: positionTexture,
135 | uVelocityTexture: velocityTexture,
136 | uTime: time,
137 | })
138 | kgl.programs.main.draw()
139 | },
140 | })
141 |
--------------------------------------------------------------------------------
/examples/kgl-auto/simple/index.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | height: 100%;
4 | }
5 |
6 | body {
7 | margin: 0;
8 | background-color: #494e57;
9 | }
10 |
--------------------------------------------------------------------------------
/examples/kgl-auto/simple/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | KGL Library Examples - Simple (KglAuto)
7 |
8 |
9 |
10 |
11 |
12 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/examples/kgl-auto/simple/index.js:
--------------------------------------------------------------------------------
1 | import { KglAuto } from '../../../src/index'
2 |
3 | new KglAuto({
4 | programs: {
5 | main: {
6 | fragmentShaderId: 'fs',
7 | uniforms: {
8 | uTime: 0,
9 | },
10 | },
11 | },
12 | tick: (kgl, time) => {
13 | kgl.programs.main.uniforms.uTime = time
14 | kgl.draw()
15 | },
16 | })
17 |
--------------------------------------------------------------------------------
/examples/kgl/3d/index.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | height: 100%;
4 | }
5 |
6 | body {
7 | margin: 0;
8 | background-color: #494e57;
9 | }
10 |
--------------------------------------------------------------------------------
/examples/kgl/3d/index.frag:
--------------------------------------------------------------------------------
1 | precision highp float;
2 |
3 | uniform float uTime;
4 |
5 | varying vec2 vUv;
6 |
7 | void main() {
8 | gl_FragColor = vec4(vec3(1. / length(vUv * 2. - 1.) * (sin(uTime) * 0.5 + 0.5)), 1.);
9 | }
10 |
--------------------------------------------------------------------------------
/examples/kgl/3d/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | KGL Library Examples - 3D
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/examples/kgl/3d/index.js:
--------------------------------------------------------------------------------
1 | import Kgl from '../../../src/index'
2 | import fragmentShader from './index.frag'
3 |
4 | const kgl = new Kgl({
5 | hasCamera: true,
6 | })
7 |
8 | /**
9 | * program
10 | */
11 | const plane = kgl.createProgram({
12 | shape: 'plane',
13 | fragmentShader,
14 | uniforms: {
15 | uTime: 0,
16 | },
17 | isAutoAdd: true,
18 | })
19 |
20 | /**
21 | * resize
22 | */
23 | function resize() {
24 | const size = window.innerHeight
25 |
26 | kgl.extraFar = size / 2
27 | kgl.resize()
28 |
29 | plane.scale = size
30 | }
31 | resize()
32 | window.addEventListener('resize', resize)
33 |
34 | /**
35 | * tick
36 | */
37 | function tick(time) {
38 | time *= 0.001
39 |
40 | plane.x = Math.sin(time * 1) * 300
41 | plane.rotateY = Math.sin(time * 1) * 1
42 | plane.uniforms.uTime = time
43 |
44 | kgl.draw()
45 |
46 | requestAnimationFrame(tick)
47 | }
48 | requestAnimationFrame(tick)
49 |
--------------------------------------------------------------------------------
/examples/kgl/dom-multiple/index.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | height: 100%;
4 | }
5 |
6 | body {
7 | margin: 0;
8 | background-color: #494e57;
9 | }
10 |
11 | .wapper {
12 | position: relative;
13 | z-index: 2;
14 | padding: 20% 0;
15 | }
16 |
17 | .scroll {
18 | position: absolute;
19 | top: 2%;
20 | left: 0;
21 | right: 0;
22 | margin: auto;
23 | text-align: center;
24 | color: rgba(255, 255, 255, 0.7);
25 | }
26 |
27 | .list {
28 | display: flex;
29 | flex-direction: column;
30 | justify-content: space-between;
31 | width: 50%;
32 | min-height: 150vh;
33 | margin: 0 auto;
34 | list-style: none;
35 | }
36 |
37 | .item {
38 | align-self: flex-start;
39 | }
40 |
41 | .item:nth-child(even) {
42 | align-self: flex-end;
43 | }
44 |
45 | .item:nth-child(n + 2) {
46 | margin-top: 20%;
47 | }
48 |
49 | .link {
50 | display: block;
51 | color: rgba(255, 255, 255, 0.5);
52 | text-decoration: none;
53 | text-align: center;
54 | }
55 |
56 | .image {
57 | width: 30vw;
58 | height: auto;
59 | opacity: 0;
60 | }
61 |
62 | .title {
63 | background-color: rgba(0, 0, 0, 0.3);
64 | font-size: 0.8rem;
65 | padding: 0 0.3em;
66 | }
67 |
68 | .link:hover {
69 | color: rgba(255, 255, 255, 0.7);
70 | text-decoration: underline;
71 | }
72 |
73 | canvas {
74 | position: fixed;
75 | top: 0;
76 | left: 0;
77 | z-index: 1;
78 | width: 100%;
79 | height: 100%;
80 | }
81 |
--------------------------------------------------------------------------------
/examples/kgl/dom-multiple/index.frag:
--------------------------------------------------------------------------------
1 | precision highp float;
2 |
3 | uniform vec2 uResolutionShape;
4 | uniform sampler2D uImage;
5 | uniform vec2 uImageResolution;
6 | uniform float uScrollDiff;
7 |
8 | varying vec2 vUv;
9 |
10 | #pragma glslify: PI = require(../../shaders/PI.glsl)
11 | #pragma glslify: fitContain = require(../../shaders/fitContain.glsl)
12 | #pragma glslify: discardOutOfRangeUv = require(../../shaders/discardOutOfRangeUv.glsl)
13 |
14 | void main() {
15 | vec2 uv = vUv;
16 | uv.y = 1. - uv.y;
17 | uv = fitContain(uv, uImageResolution, uResolutionShape);
18 | uv.y += sin(uv.x * PI) * uScrollDiff;
19 | discardOutOfRangeUv(uv);
20 |
21 | gl_FragColor = texture2D(uImage, uv);
22 | }
23 |
--------------------------------------------------------------------------------
/examples/kgl/dom-multiple/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | KGL Library Examples - Fit Multiple DOM
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
Scroll Down ↓
15 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/examples/kgl/dom-multiple/index.js:
--------------------------------------------------------------------------------
1 | import Kgl from '../../../src/index'
2 | import fragmentShader from './index.frag'
3 | import { onLoadImage } from '../../utils.js'
4 |
5 | const kgl = new Kgl({
6 | canvas: '.canvas',
7 | hasCamera: true,
8 | isFullSize: true,
9 | })
10 |
11 | function createImage(img) {
12 | const { width, height } = img.getBoundingClientRect()
13 |
14 | const program = kgl.createProgram({
15 | shape: 'plane',
16 | fragmentShader,
17 | uniforms: {
18 | uImage: img,
19 | uImageResolution: [width, height],
20 | uScrollDiff: 0,
21 | },
22 | isTransparent: true,
23 | isAutoAdd: true,
24 | data: {
25 | img,
26 | },
27 | })
28 |
29 | return program
30 | }
31 |
32 | /**
33 | * program
34 | */
35 | const groupCloud = kgl.createGroup({
36 | isAutoAdd: true,
37 | })
38 |
39 | document.querySelectorAll('.image').forEach(async (img) => {
40 | await onLoadImage(img)
41 | const program = createImage(img)
42 | groupCloud.add(program)
43 | resizeProgram(program)
44 | })
45 |
46 | /**
47 | * scroll
48 | */
49 | let scrollPrev = 0
50 | let scrollDiff = 0
51 | let scrollDiffSmooth = 0
52 | let timerId
53 | function scroll() {
54 | groupCloud.y = window.scrollY
55 |
56 | scrollDiff = window.scrollY - scrollPrev
57 | scrollPrev = window.scrollY
58 |
59 | if (timerId) {
60 | clearTimeout(timerId)
61 | }
62 | timerId = setTimeout(() => {
63 | scrollDiff = 0
64 | }, 300)
65 | }
66 | scroll()
67 | window.addEventListener('scroll', scroll)
68 |
69 | /**
70 | * resize
71 | */
72 | function resizeProgram(program) {
73 | const { width, height, top, left } = program.data.img.getBoundingClientRect()
74 |
75 | program.scale = width
76 | program.x = left - (window.innerWidth * 0.5 - width * 0.5)
77 | program.y = -(
78 | top +
79 | window.scrollY -
80 | (window.innerHeight * 0.5 - height * 0.5)
81 | )
82 | }
83 | function resize() {
84 | kgl.resize()
85 |
86 | groupCloud.forEachProgram((program) => {
87 | resizeProgram(program)
88 | })
89 | }
90 | resize()
91 | window.addEventListener('resize', resize)
92 |
93 | /**
94 | * tick
95 | */
96 | function tick(time) {
97 | scrollDiffSmooth += (scrollDiff - scrollDiffSmooth) * 0.05
98 | if (Math.abs(scrollDiff - scrollDiffSmooth) < 0.01) {
99 | scrollDiffSmooth = scrollDiff
100 | }
101 |
102 | groupCloud.forEachProgram((program) => {
103 | program.uniforms.uScrollDiff = scrollDiffSmooth * 0.003
104 | })
105 |
106 | kgl.draw()
107 |
108 | requestAnimationFrame(tick)
109 | }
110 | requestAnimationFrame(tick)
111 |
--------------------------------------------------------------------------------
/examples/kgl/dom/index.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | height: 100%;
4 | }
5 |
6 | body {
7 | margin: 0;
8 | background-color: #494e57;
9 | }
10 |
11 | .wapper {
12 | position: relative;
13 | z-index: 2;
14 | height: 100%;
15 | display: flex;
16 | justify-content: center;
17 | align-items: center;
18 | }
19 |
20 | .link {
21 | display: block;
22 | color: rgba(255, 255, 255, 0.5);
23 | text-decoration: none;
24 | text-align: center;
25 | }
26 |
27 | .image {
28 | width: 50vw;
29 | height: auto;
30 | opacity: 0;
31 | }
32 |
33 | .title {
34 | background-color: rgba(0, 0, 0, 0.3);
35 | font-size: 0.8rem;
36 | padding: 0 0.3em;
37 | }
38 |
39 | .link:hover {
40 | color: rgba(255, 255, 255, 0.7);
41 | text-decoration: underline;
42 | }
43 |
44 | canvas {
45 | position: fixed;
46 | top: 0;
47 | left: 0;
48 | z-index: 1;
49 | width: 100%;
50 | height: 100%;
51 | }
52 |
--------------------------------------------------------------------------------
/examples/kgl/dom/index.frag:
--------------------------------------------------------------------------------
1 | precision highp float;
2 |
3 | uniform sampler2D uImage;
4 | uniform float uTime;
5 |
6 | varying vec2 vUv;
7 |
8 | void main() {
9 | vec2 uv = vUv;
10 | uv.y = 1. - uv.y;
11 | vec4 color = texture2D(uImage, uv);
12 | color.rgb *= mix(0.2, 2.5, sin(uTime) * 0.5 + 0.5);
13 | gl_FragColor = color;
14 | }
15 |
--------------------------------------------------------------------------------
/examples/kgl/dom/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | KGL Library Examples - Fit DOM
7 |
8 |
9 |
10 |
11 |
12 |
13 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/examples/kgl/dom/index.js:
--------------------------------------------------------------------------------
1 | import Kgl from '../../../src/index'
2 | import fragmentShader from './index.frag'
3 | import { onLoadImage } from '../../utils.js'
4 |
5 | const kgl = new Kgl({
6 | canvas: '.canvas',
7 | hasCamera: true,
8 | isFullSize: true,
9 | })
10 |
11 | async function main() {
12 | /**
13 | * program
14 | */
15 | const img = await onLoadImage(document.querySelector('.image'))
16 |
17 | const program = kgl.createProgram({
18 | shape: 'plane',
19 | fragmentShader,
20 | uniforms: {
21 | uImage: img,
22 | uTime: 0,
23 | },
24 | isTransparent: true,
25 | isAutoAdd: true,
26 | })
27 |
28 | /**
29 | * resize
30 | */
31 | function resize() {
32 | kgl.resize()
33 |
34 | const { width, height, top, left } = img.getBoundingClientRect()
35 |
36 | program.scale2d = [width, height]
37 | program.x = left - (window.innerWidth * 0.5 - width * 0.5)
38 | program.y = -(
39 | top +
40 | window.scrollY -
41 | (window.innerHeight * 0.5 - height * 0.5)
42 | )
43 | }
44 | resize()
45 | window.addEventListener('resize', resize)
46 |
47 | /**
48 | * tick
49 | */
50 | function tick(time) {
51 | time *= 0.001
52 |
53 | program.uniforms.uTime = time
54 |
55 | kgl.draw()
56 |
57 | requestAnimationFrame(tick)
58 | }
59 | requestAnimationFrame(tick)
60 | }
61 | main()
62 |
--------------------------------------------------------------------------------
/examples/kgl/godray/index.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | height: 100%;
4 | }
5 |
6 | body {
7 | margin: 0;
8 | }
9 |
--------------------------------------------------------------------------------
/examples/kgl/godray/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | KGL Library Examples - God Ray
7 |
8 |
9 |
10 |
11 |
12 |
13 | Photo
14 | by Sasha Freemind on Unsplash
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/examples/kgl/godray/index.js:
--------------------------------------------------------------------------------
1 | import { KglEffect, Godray } from '../../../src/index'
2 | import fragmentShader from './mask.frag'
3 | import { loadImage, mix } from '../../utils.js'
4 |
5 | const image =
6 | 'https://images.unsplash.com/photo-1534330207526-8e81f10ec6fc?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=800&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' // https://unsplash.com/photos/Pv5WeEyxMWU
7 | const speed = 0.5
8 | const strength = 12
9 | const maxRadius = window.innerWidth < 768 ? 0.4 : 0.8
10 | const minRadius = 0.1
11 |
12 | const kgl = new KglEffect()
13 |
14 | async function main() {
15 | const img = await loadImage(image, true)
16 |
17 | const mask = kgl.createProgram({
18 | fragmentShader,
19 | uniforms: {
20 | uImage: img,
21 | uImageResolution: [img.width, img.height],
22 | },
23 | isAutoAdd: true,
24 | })
25 |
26 | ;['mask', 'cache', 'output'].forEach((name) => {
27 | kgl.createFramebuffer(name)
28 | })
29 |
30 | const godray = kgl.createEffect(Godray)
31 |
32 | /**
33 | * resize
34 | */
35 | function resize() {
36 | kgl.resize()
37 | }
38 | resize()
39 | window.addEventListener('resize', resize)
40 |
41 | /**
42 | * tick
43 | */
44 | function tick(time) {
45 | const cTime = Math.sin(time * 0.001 * speed) * 0.5 + 0.5
46 | const halfTime = -Math.abs(cTime * 2 - 1) + 1
47 |
48 | kgl.bindFramebuffer('mask')
49 | mask.draw()
50 |
51 | godray.drawEffect(
52 | 'mask',
53 | 'cache',
54 | 'output',
55 | strength,
56 | [mix(kgl.canvas.width, 0, cTime), kgl.canvas.height * 0.5],
57 | mix(maxRadius, minRadius, halfTime),
58 | true
59 | )
60 |
61 | requestAnimationFrame(tick)
62 | }
63 | requestAnimationFrame(tick)
64 | }
65 | main()
66 |
--------------------------------------------------------------------------------
/examples/kgl/godray/mask.frag:
--------------------------------------------------------------------------------
1 | precision highp float;
2 |
3 | uniform vec2 uResolution;
4 | uniform sampler2D uImage;
5 | uniform vec2 uImageResolution;
6 |
7 | #pragma glslify: fitCover = require(../../shaders/fitCover.glsl)
8 |
9 | void main() {
10 | vec2 uv = gl_FragCoord.st / uResolution;
11 | uv.y = 1. - uv.y;
12 | uv = fitCover(uv, uImageResolution, uResolution);
13 |
14 | gl_FragColor = texture2D(uImage, uv);
15 | }
16 |
--------------------------------------------------------------------------------
/examples/kgl/group/cross.frag:
--------------------------------------------------------------------------------
1 | precision highp float;
2 |
3 | const vec3 color = vec3(181. / 255., 174. / 255., 161. / 255.);
4 |
5 | void main() {
6 | gl_FragColor = vec4(color, 1.);
7 | }
8 |
--------------------------------------------------------------------------------
/examples/kgl/group/full.frag:
--------------------------------------------------------------------------------
1 | precision highp float;
2 |
3 | uniform float uTime;
4 |
5 | const vec3 color = vec3(181. / 255., 174. / 255., 161. / 255.);
6 |
7 | void main() {
8 | gl_FragColor = vec4(color * mix(1.1, 1.5, sin(uTime) * 0.5 + 0.5), 1.);
9 | }
10 |
--------------------------------------------------------------------------------
/examples/kgl/group/index.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | height: 100%;
4 | }
5 |
6 | body {
7 | margin: 0;
8 | background-color: #494e57;
9 | }
10 |
--------------------------------------------------------------------------------
/examples/kgl/group/index.frag:
--------------------------------------------------------------------------------
1 | precision highp float;
2 |
3 | uniform float uTime;
4 |
5 | varying vec2 vUv;
6 |
7 | void main() {
8 | float alpha = 1. - min(max(1. / length(vUv * 2. - 1.) * (sin(uTime) * 0.5 + 0.5), 0.), 1.);
9 | gl_FragColor = vec4(vec3(0.), alpha);
10 | }
11 |
--------------------------------------------------------------------------------
/examples/kgl/group/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | KGL Library Examples - Group
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/examples/kgl/group/index.js:
--------------------------------------------------------------------------------
1 | import Kgl from '../../../src/index'
2 | import fragmentShader from './index.frag'
3 | import fragmentShaderCross from './cross.frag'
4 | import fragmentShaderFull from './full.frag'
5 |
6 | const kgl = new Kgl({
7 | hasCamera: true,
8 | isFullSize: true,
9 | })
10 | const { root } = kgl // root group
11 |
12 | /**
13 | * program
14 | */
15 |
16 | const full = kgl.createProgram({
17 | fragmentShader: fragmentShaderFull,
18 | uniforms: {
19 | uTime: 0,
20 | },
21 | isAutoAdd: true,
22 | })
23 |
24 | /* group cross */
25 | const groupCross = kgl.createGroup({
26 | isAutoAdd: true, // add to kgl.root
27 | })
28 |
29 | /* cross1 */
30 | const cross1 = kgl.createProgram({
31 | shape: 'plane',
32 | width: 200,
33 | height: 50,
34 | fragmentShader: fragmentShaderCross,
35 | })
36 | groupCross.add(cross1)
37 |
38 | /* cross2 */
39 | const cross2 = kgl.createProgram({
40 | shape: 'plane',
41 | width: 50,
42 | height: 200,
43 | fragmentShader: fragmentShaderCross,
44 | })
45 | groupCross.add(cross2)
46 |
47 | /* plane1 */
48 | const size = 500
49 | const plane1 = kgl.createProgram({
50 | shape: 'plane',
51 | width: size,
52 | height: size,
53 | fragmentShader,
54 | uniforms: {
55 | uTime: 0,
56 | },
57 | isTransparent: true,
58 | })
59 | kgl.add(plane1) // add to kgl.root
60 |
61 | /* plane2 */
62 | const size2 = 100
63 | const plane2 = kgl.createProgram({
64 | shape: 'plane',
65 | width: size2,
66 | height: size2,
67 | fragmentShader,
68 | uniforms: {
69 | uTime: 0,
70 | },
71 | isTransparent: true,
72 | })
73 | kgl.add(plane2) // add to kgl.root
74 |
75 | kgl.extraFar = size / 2
76 |
77 | /**
78 | * resize
79 | */
80 | function resize() {
81 | kgl.resize()
82 | }
83 | resize()
84 | window.addEventListener('resize', resize)
85 |
86 | /**
87 | * tick
88 | */
89 | function tick(time) {
90 | time *= 0.001
91 |
92 | // kgl.cameraPosition[1] = Math.sin(time * 0.5) * 300
93 | // kgl.cameraRotation[1] = Math.sin(time * 0.1)
94 | // kgl.updateCamera()
95 |
96 | full.uniforms.uTime = time
97 |
98 | root.x = -Math.sin(time * 0.5) * 500
99 |
100 | plane1.x = Math.sin(time * 1) * 300
101 | plane1.scale = 1 - ((Math.sin(time * 2) + 1) / 2) * 0.5
102 | plane1.rotateY = Math.sin(time * 1) * 1
103 | plane1.uniforms.uTime = time
104 |
105 | plane2.y = Math.sin(time * 1) * 300
106 | plane2.rotateX = Math.sin(time * 1) * 1
107 | plane2.uniforms.uTime = time
108 |
109 | groupCross.rotate = time * 3
110 | cross2.x = -Math.sin(time * 5) * 100
111 |
112 | kgl.draw()
113 |
114 | requestAnimationFrame(tick)
115 | }
116 | requestAnimationFrame(tick)
117 |
118 | /**
119 | * add, remove
120 | */
121 | // let isExistPlane1 = true
122 | // setInterval(() => {
123 | // if (isExistPlane1) {
124 | // kgl.remove(plane1)
125 | // isExistPlane1 = false
126 | // } else {
127 | // kgl.add(plane1)
128 | // isExistPlane1 = true
129 | // }
130 | // }, 1000)
131 |
--------------------------------------------------------------------------------
/examples/kgl/image/index.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | height: 100%;
4 | }
5 |
6 | body {
7 | margin: 0;
8 | background-color: #494e57;
9 | }
10 |
--------------------------------------------------------------------------------
/examples/kgl/image/index.frag:
--------------------------------------------------------------------------------
1 | precision highp float;
2 |
3 | uniform vec2 uResolution;
4 | uniform sampler2D uImage;
5 | uniform vec2 uImageResolution;
6 | uniform float uTime;
7 |
8 | const float pSpeed = 1.5;
9 |
10 | #pragma glslify: PI = require(../../shaders/PI.glsl)
11 | #pragma glslify: fitCover = require(../../shaders/fitCover.glsl)
12 | #pragma glslify: getZoomedUv = require(../../shaders/getZoomedUv.glsl)
13 |
14 | void main() {
15 | vec2 uv = gl_FragCoord.st / uResolution;
16 | uv.y = 1. - uv.y;
17 | uv = fitCover(uv, uImageResolution, uResolution);
18 |
19 | vec2 uvCenter = uv * 2. - 1.;
20 | float distortion = min(max(1. / length(uvCenter) * (sin(uTime * pSpeed - PI * 0.5) * 0.5 + 0.5), 0.), 1.);
21 | distortion = smoothstep(0.6, 0.8, distortion) * smoothstep(1., 0.8, distortion);
22 |
23 | vec2 zoomedUv = getZoomedUv(uv, 0.8, vec2(0.));
24 |
25 | gl_FragColor = texture2D(uImage, mix(uv, zoomedUv, distortion));
26 | // gl_FragColor = vec4(vec3(distortion), 1.);
27 | }
28 |
--------------------------------------------------------------------------------
/examples/kgl/image/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | KGL Library Examples - Image
7 |
8 |
9 |
10 |
11 |
12 |
13 | Photo
14 | by FLY:D on Unsplash
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/examples/kgl/image/index.js:
--------------------------------------------------------------------------------
1 | import Kgl from '../../../src/index'
2 | import fragmentShader from './index.frag'
3 | import { loadImage } from '../../utils.js'
4 |
5 | const image =
6 | 'https://images.unsplash.com/photo-1631372126726-edb028823784?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=800&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ' // https://unsplash.com/photos/TfntmeQaK6Q
7 |
8 | const kgl = new Kgl()
9 |
10 | async function main() {
11 | /**
12 | * program
13 | */
14 | const img = await loadImage(image, true)
15 |
16 | const program = kgl.createProgram({
17 | fragmentShader,
18 | uniforms: {
19 | uImage: img,
20 | uImageResolution: [img.width, img.height],
21 | uTime: 0,
22 | },
23 | isAutoAdd: true,
24 | })
25 |
26 | /**
27 | * resize
28 | */
29 | function resize() {
30 | kgl.resize()
31 | }
32 | resize()
33 | window.addEventListener('resize', resize)
34 |
35 | /**
36 | * tick
37 | */
38 | function tick(time) {
39 | time *= 0.001
40 |
41 | program.uniforms.uTime = time
42 |
43 | kgl.draw()
44 |
45 | requestAnimationFrame(tick)
46 | }
47 | requestAnimationFrame(tick)
48 | }
49 | main()
50 |
--------------------------------------------------------------------------------
/examples/kgl/instancing/index.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | height: 100%;
4 | }
5 |
6 | body {
7 | margin: 0;
8 | }
9 |
--------------------------------------------------------------------------------
/examples/kgl/instancing/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | KGL Library Examples - Instancing
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/examples/kgl/instancing/index.js:
--------------------------------------------------------------------------------
1 | import Kgl from '../../../src/index'
2 | import resetVelocityFrag from './shaders/reset-velocity.frag'
3 | import resetPositionFrag from './shaders/reset-position.frag'
4 | import velocityFrag from './shaders/velocity.frag'
5 | import positionFrag from './shaders/position.frag'
6 | import mainVert from './shaders/main.vert'
7 | import mainFrag from './shaders/main.frag'
8 |
9 | const width = 100
10 | const height = 100
11 |
12 | const sizeUniform = [width, height]
13 | const particleUv = []
14 |
15 | for (let i = 0; i < width; i++) {
16 | for (let j = 0; j < height; j++) {
17 | particleUv.push(i / (width - 1), 1 - j / (height - 1))
18 | }
19 | }
20 |
21 | /**
22 | * generate KGL
23 | */
24 | const kgl = new Kgl({
25 | clearedColor: [0, 0, 0, 1],
26 | hasCamera: true,
27 | hasLight: true,
28 | cameraPosition: [0, 0, 480],
29 | fov: 50,
30 | })
31 |
32 | /**
33 | * program
34 | */
35 | const programResetVelocity = kgl.createProgram({
36 | fragmentShader: resetVelocityFrag,
37 | isFloats: true,
38 | })
39 |
40 | const programResetPosition = kgl.createProgram({
41 | fragmentShader: resetPositionFrag,
42 | uniforms: {
43 | uSize: sizeUniform,
44 | },
45 | isFloats: true,
46 | })
47 |
48 | const programVelocity = kgl.createProgram({
49 | fragmentShader: velocityFrag,
50 | uniforms: {
51 | uSize: sizeUniform,
52 | uPrevVelocityTexture: 'framebuffer',
53 | uPrevPositionTexture: 'framebuffer',
54 | },
55 | isFloats: true,
56 | })
57 |
58 | const programPosition = kgl.createProgram({
59 | fragmentShader: positionFrag,
60 | uniforms: {
61 | uSize: sizeUniform,
62 | uPrevPositionTexture: 'framebuffer',
63 | uVelocityTexture: 'framebuffer',
64 | },
65 | isFloats: true,
66 | })
67 |
68 | const programMain = kgl.createProgram({
69 | shape: 'cube',
70 | // shape: 'plane',
71 | vertexShader: mainVert,
72 | fragmentShader: mainFrag,
73 | instancedAttributes: {
74 | aInstancedUv: {
75 | value: particleUv,
76 | size: 2,
77 | },
78 | },
79 | uniforms: {
80 | uPositionTexture: 'framebuffer',
81 | uVelocityTexture: 'framebuffer',
82 | uTime: 0,
83 | },
84 | isDepth: true,
85 | isTransparent: true,
86 | isAutoAdd: true,
87 | })
88 |
89 | /**
90 | * framebuffer (float)
91 | */
92 | ;['velocity0', 'velocity1', 'position0', 'position1'].forEach((key) => {
93 | kgl.createFramebufferFloat(key, width, height)
94 | })
95 |
96 | /**
97 | * resize
98 | */
99 | function resize() {
100 | kgl.resize()
101 | }
102 | resize()
103 | window.addEventListener('resize', resize)
104 |
105 | /**
106 | * reset framebuffer
107 | */
108 | let loopCount = 0
109 | let targetBufferIndex = loopCount++ % 2
110 | let prevBufferIndex
111 |
112 | kgl.bindFramebuffer(`velocity${targetBufferIndex}`)
113 | programResetVelocity.draw()
114 |
115 | kgl.bindFramebuffer(`position${targetBufferIndex}`)
116 | programResetPosition.draw()
117 |
118 | /**
119 | * tick
120 | */
121 | function tick(time) {
122 | time *= 0.001
123 |
124 | prevBufferIndex = targetBufferIndex
125 | targetBufferIndex = loopCount++ % 2
126 |
127 | const prevVelocityTexture = `velocity${prevBufferIndex}`
128 | const prevPositionTexture = `position${prevBufferIndex}`
129 | const velocityTexture = `velocity${targetBufferIndex}`
130 | const positionTexture = `position${targetBufferIndex}`
131 |
132 | kgl.bindFramebuffer(velocityTexture)
133 |
134 | programVelocity.updateUniforms({
135 | uPrevVelocityTexture: prevVelocityTexture,
136 | uPrevPositionTexture: prevPositionTexture,
137 | })
138 | programVelocity.draw()
139 |
140 | kgl.bindFramebuffer(positionTexture)
141 |
142 | programPosition.updateUniforms({
143 | uPrevPositionTexture: prevPositionTexture,
144 | uVelocityTexture: velocityTexture,
145 | })
146 | programPosition.draw()
147 |
148 | kgl.unbindFramebuffer()
149 | kgl.clear()
150 |
151 | programMain.updateUniforms({
152 | uPositionTexture: positionTexture,
153 | uVelocityTexture: velocityTexture,
154 | uTime: time,
155 | })
156 | programMain.draw()
157 |
158 | requestAnimationFrame(tick)
159 | }
160 | requestAnimationFrame(tick)
161 |
--------------------------------------------------------------------------------
/examples/kgl/instancing/shaders/main.frag:
--------------------------------------------------------------------------------
1 | precision highp float;
2 |
3 | varying vec2 vUv;
4 | varying vec4 vColor;
5 |
6 | void main () {
7 | gl_FragColor = vColor;
8 | }
9 |
--------------------------------------------------------------------------------
/examples/kgl/instancing/shaders/main.vert:
--------------------------------------------------------------------------------
1 | attribute vec3 aPosition;
2 | attribute vec2 aUv;
3 | attribute vec3 aNormal;
4 | attribute vec2 aInstancedUv;
5 |
6 | uniform sampler2D uPositionTexture;
7 | uniform sampler2D uVelocityTexture;
8 | uniform mat4 uMvpMatrix;
9 | uniform mat4 uInvMatrix;
10 | uniform vec3 uLightDirection;
11 | uniform vec3 uAmbientColor;
12 | uniform vec3 uEyeDirection;
13 | uniform float uTime;
14 |
15 | varying vec2 vUv;
16 | varying vec4 vColor;
17 |
18 | #pragma glslify: rotateQ = require(glsl-y-rotate/rotateQ)
19 | #pragma glslify: random = require(glsl-random)
20 | #pragma glslify: hsv = require(../../../shaders/hsv.glsl)
21 | #pragma glslify: PI = require(../../../shaders/PI.glsl)
22 |
23 | const float PI2 = PI * 2.;
24 | const float colorInterval = PI2 * 10.;
25 | const float scale = 2.;
26 | const float maxScaleRate = 1.4;
27 | const float rotationSpeed = 100.;
28 | const float minRotationSpeed = 0.1;
29 |
30 | void main () {
31 | vec3 modelPosition = aPosition;
32 | vec4 instancedPosition = texture2D(uPositionTexture, aInstancedUv);
33 | float randomValue = instancedPosition.w;
34 |
35 | float velocity = texture2D(uVelocityTexture, aInstancedUv).w;
36 | float life = smoothstep(0.01, 0.04, velocity);
37 |
38 | float cScale = scale;
39 | cScale *= life;
40 | cScale *= mix(1., maxScaleRate, (instancedPosition.z - 1.) * 0.01);
41 | modelPosition *= cScale;
42 |
43 | vec3 axis = normalize(vec3(
44 | random(vec2(randomValue, 0.)),
45 | random(vec2(0., randomValue)),
46 | random(vec2(randomValue, 1.))
47 | ));
48 | float radian = PI2 * random(vec2(randomValue));
49 | radian += velocity * mix(minRotationSpeed, rotationSpeed, randomValue);
50 | mat3 rotate = rotateQ(axis, radian);
51 | modelPosition *= rotate;
52 |
53 | vec3 cNormal = normalize(aNormal);
54 | cNormal *= rotate;
55 | vec3 invLight = normalize(uInvMatrix * vec4(uLightDirection, 0.)).rgb;
56 | vec3 invEye = normalize(uInvMatrix * vec4(uEyeDirection, 0.)).rgb;
57 | vec3 halfLE = normalize(invLight + invEye);
58 | float diffuse = clamp(dot(cNormal, invLight), 0.1, 1.);
59 | float specular = pow(clamp(dot(cNormal, halfLE), 0., 1.), 50.);
60 |
61 | vUv = aUv;
62 |
63 | float colorNTime = mod(uTime, colorInterval) / colorInterval;
64 | float alpha = 1.;
65 | vColor = vec4(hsv(colorNTime * PI2, 0.25 + 0.7 * colorNTime, 0.85 + 0.1 * colorNTime), alpha);
66 | vColor.rgb *= vec3(diffuse + specular);
67 | vColor.rgb += uAmbientColor;
68 | vColor.rgb *= mix(0.2, 1., clamp(((instancedPosition + 100.) / 200.).z, 0., 1.));
69 | vColor.rgb *= life;
70 |
71 | gl_Position = uMvpMatrix * (vec4(modelPosition + instancedPosition.xyz, 1.));
72 | }
73 |
--------------------------------------------------------------------------------
/examples/kgl/instancing/shaders/position.frag:
--------------------------------------------------------------------------------
1 | precision highp float;
2 |
3 | uniform vec2 uSize;
4 | uniform sampler2D uPrevPositionTexture;
5 | uniform sampler2D uVelocityTexture;
6 |
7 | void main () {
8 | vec2 uv = gl_FragCoord.st / uSize;
9 | vec4 prevPosition = texture2D(uPrevPositionTexture, uv);
10 | vec4 velocity = texture2D(uVelocityTexture, uv);
11 |
12 | vec3 position;
13 | if (velocity.w == 1.) {
14 | vec2 nPosition = uv * 2. - 1.;
15 | position = vec3(nPosition * uSize, 0.);
16 | } else {
17 | position = prevPosition.xyz + velocity.xyz;
18 | }
19 |
20 | gl_FragColor = vec4(position, prevPosition.w);
21 | }
22 |
--------------------------------------------------------------------------------
/examples/kgl/instancing/shaders/reset-position.frag:
--------------------------------------------------------------------------------
1 | precision highp float;
2 |
3 | uniform vec2 uSize;
4 |
5 | #pragma glslify: random = require(glsl-random)
6 |
7 | void main () {
8 | vec2 nPosition = gl_FragCoord.st / uSize * 2. - 1.;
9 | vec4 position = vec4(
10 | nPosition * uSize,
11 | 0.,
12 | random(nPosition)
13 | );
14 | gl_FragColor = position;
15 | }
16 |
--------------------------------------------------------------------------------
/examples/kgl/instancing/shaders/reset-velocity.frag:
--------------------------------------------------------------------------------
1 | precision highp float;
2 |
3 | void main () {
4 | gl_FragColor = vec4(vec3(0.), 1.);
5 | }
6 |
--------------------------------------------------------------------------------
/examples/kgl/instancing/shaders/velocity.frag:
--------------------------------------------------------------------------------
1 | precision highp float;
2 |
3 | uniform vec2 uSize;
4 | uniform sampler2D uPrevVelocityTexture;
5 | uniform sampler2D uPrevPositionTexture;
6 |
7 | #pragma glslify: curlNoise = require(glsl-curl-noise)
8 |
9 | const float speed = 2.;
10 | const float density = 0.007;
11 | const float ease = 0.02;
12 |
13 | void main () {
14 | vec2 uv = gl_FragCoord.st / uSize;
15 | vec4 velocity = texture2D(uPrevVelocityTexture, uv);
16 | vec3 prevPosition = texture2D(uPrevPositionTexture, uv).xyz;
17 | velocity.xyz += curlNoise(prevPosition * density) * speed;
18 | velocity.xyz *= velocity.w;
19 | if (velocity.w > 0.01) {
20 | velocity.w -= velocity.w * ease;
21 | } else {
22 | velocity.w = 1.;
23 | }
24 | gl_FragColor = velocity;
25 | }
26 |
--------------------------------------------------------------------------------
/examples/kgl/point/index.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | height: 100%;
4 | }
5 |
6 | body {
7 | margin: 0;
8 | background-color: #494e57;
9 | }
10 |
--------------------------------------------------------------------------------
/examples/kgl/point/index.frag:
--------------------------------------------------------------------------------
1 | precision highp float;
2 |
3 | uniform float uTime;
4 |
5 | varying float vRandom;
6 |
7 | void main() {
8 | vec2 uv = gl_PointCoord;
9 | gl_FragColor = vec4(
10 | smoothstep(0.97, 1., 1. / length(uv * 2. - 1.) * mix(0.1, 1., sin(uTime * vRandom) * 0.5 + 0.5))
11 | );
12 | }
13 |
--------------------------------------------------------------------------------
/examples/kgl/point/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | KGL Library Examples - Point
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/examples/kgl/point/index.js:
--------------------------------------------------------------------------------
1 | import Kgl from '../../../src/index'
2 | import vertexShader from './index.vert'
3 | import fragmentShader from './index.frag'
4 |
5 | const kgl = new Kgl({
6 | hasCamera: true,
7 | })
8 |
9 | /**
10 | * program
11 | */
12 | const halfSize = 100
13 | const points = kgl.createProgram({
14 | shape: 'point',
15 | attributes: {
16 | aPosition: {
17 | value: [
18 | -halfSize,
19 | halfSize,
20 | 0,
21 | -halfSize,
22 | -halfSize,
23 | 0,
24 | halfSize,
25 | halfSize,
26 | 0,
27 | halfSize,
28 | -halfSize,
29 | 0,
30 | ],
31 | size: 3,
32 | },
33 | aRandom: {
34 | value: [Math.random(), Math.random(), Math.random(), Math.random()],
35 | size: 1,
36 | },
37 | },
38 | vertexShader,
39 | fragmentShader,
40 | uniforms: {
41 | uTime: 0,
42 | },
43 | isAutoAdd: true,
44 | })
45 |
46 | /**
47 | * resize
48 | */
49 | function resize() {
50 | kgl.resize()
51 | }
52 | resize()
53 | window.addEventListener('resize', resize)
54 |
55 | /**
56 | * tick
57 | */
58 | function tick(time) {
59 | time *= 0.001
60 |
61 | // points.x = Math.sin(time * 1) * 100
62 | points.uniforms.uTime = time * 2
63 |
64 | kgl.draw()
65 |
66 | requestAnimationFrame(tick)
67 | }
68 | requestAnimationFrame(tick)
69 |
--------------------------------------------------------------------------------
/examples/kgl/point/index.vert:
--------------------------------------------------------------------------------
1 | precision highp float;
2 |
3 | attribute vec3 aPosition;
4 | attribute float aRandom;
5 |
6 | uniform mat4 uMvpMatrix;
7 | uniform float uPixelRatio;
8 | uniform float uTime;
9 |
10 | varying float vRandom;
11 |
12 | void main () {
13 | vRandom = aRandom;
14 |
15 | vec3 position = aPosition;
16 | float time = uTime * aRandom;
17 | position.xy += vec2(cos(time), sin(time)) * 30.;
18 |
19 | gl_Position = uMvpMatrix * vec4(position, 1.);
20 | gl_PointSize = uPixelRatio * mix(16., 32., aRandom);
21 | }
22 |
--------------------------------------------------------------------------------
/examples/kgl/simple/index.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | height: 100%;
4 | }
5 |
6 | body {
7 | margin: 0;
8 | background-color: #494e57;
9 | }
10 |
--------------------------------------------------------------------------------
/examples/kgl/simple/index.frag:
--------------------------------------------------------------------------------
1 | precision highp float;
2 |
3 | uniform vec2 uResolution; // window size (auto added)
4 | uniform float uTime;
5 |
6 | void main() {
7 | float color = max(1. - length(gl_FragCoord.xy / uResolution) * (sin(uTime) * 0.5 + 0.5), 0.);
8 | gl_FragColor = vec4(vec3(color), 1.);
9 | }
10 |
--------------------------------------------------------------------------------
/examples/kgl/simple/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | KGL Library Examples - Simple
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/examples/kgl/simple/index.js:
--------------------------------------------------------------------------------
1 | import Kgl from '../../../src/index'
2 | import fragmentShader from './index.frag'
3 |
4 | const kgl = new Kgl()
5 |
6 | /**
7 | * program
8 | */
9 | const program = kgl.createProgram({
10 | fragmentShader,
11 | uniforms: {
12 | uTime: 0,
13 | },
14 | isAutoAdd: true,
15 | })
16 |
17 | /**
18 | * resize
19 | */
20 | function resize() {
21 | kgl.resize()
22 | }
23 | resize()
24 | window.addEventListener('resize', resize)
25 |
26 | /**
27 | * tick
28 | */
29 | function tick(time) {
30 | program.uniforms.uTime = time * 0.001
31 |
32 | kgl.draw()
33 |
34 | requestAnimationFrame(tick)
35 | }
36 | requestAnimationFrame(tick)
37 |
--------------------------------------------------------------------------------
/examples/kgl/transparent-images/1-white-clouds-png-image_400x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ko-yelie/kgl/746f039b018192e5e78574ff933ce0ded15805cc/examples/kgl/transparent-images/1-white-clouds-png-image_400x400.png
--------------------------------------------------------------------------------
/examples/kgl/transparent-images/index.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | height: 100%;
4 | }
5 |
6 | body {
7 | margin: 0;
8 | background-color: #494e57;
9 | }
10 |
--------------------------------------------------------------------------------
/examples/kgl/transparent-images/index.frag:
--------------------------------------------------------------------------------
1 | precision highp float;
2 |
3 | uniform sampler2D uImage;
4 |
5 | varying vec2 vUv;
6 |
7 | void main() {
8 | vec2 uv = vUv;
9 | uv.y = 1. - uv.y;
10 |
11 | gl_FragColor = texture2D(uImage, uv);
12 | }
13 |
--------------------------------------------------------------------------------
/examples/kgl/transparent-images/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | KGL Library Examples - Transparent Images
7 |
8 |
9 |
10 |
11 |
12 |
13 | White Clouds Png Image FreePNGImg.com
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/examples/kgl/transparent-images/index.js:
--------------------------------------------------------------------------------
1 | import Kgl from '../../../src/index'
2 | import fragmentShader from './index.frag'
3 | import { loadImage } from '../../utils.js'
4 | import image from './1-white-clouds-png-image_400x400.png'
5 |
6 | const kgl = new Kgl({
7 | hasCamera: true,
8 | isFullSize: true,
9 | })
10 |
11 | function createCloud(img) {
12 | const randomScale = Math.random() * 2
13 |
14 | const program = kgl.createProgram({
15 | shape: 'plane',
16 | fragmentShader,
17 | uniforms: {
18 | uImage: img,
19 | },
20 | isTransparent: true,
21 | isAutoAdd: true,
22 | width: img.width,
23 | height: img.height,
24 | x: (Math.random() * 2 - 1) * window.innerWidth * 0.5,
25 | y: (Math.random() * 2 - 1) * window.innerHeight * 0.5,
26 | // z: randomScale * kgl.cameraPosition[2] * 0.3,
27 | scale: 1 + randomScale,
28 | })
29 |
30 | return program
31 | }
32 |
33 | async function main() {
34 | /**
35 | * program
36 | */
37 | const groupCloud = kgl.createGroup({
38 | isAutoAdd: true,
39 | })
40 |
41 | const img = await loadImage(image)
42 |
43 | for (let i = 0; i < 10; i++) {
44 | const program = createCloud(img)
45 | groupCloud.add(program)
46 | }
47 |
48 | /**
49 | * resize
50 | */
51 | function resize() {
52 | kgl.resize()
53 | }
54 | resize()
55 | window.addEventListener('resize', resize)
56 |
57 | /**
58 | * tick
59 | */
60 | function tick(time) {
61 | groupCloud.forEachProgram((program) => {
62 | program.x += 1 * program.scale
63 |
64 | const xMax = window.innerWidth * 0.5 + program.width * program.scale * 0.5
65 | if (program.x > xMax) {
66 | program.x = -xMax
67 | }
68 | })
69 |
70 | kgl.draw()
71 |
72 | requestAnimationFrame(tick)
73 | }
74 | requestAnimationFrame(tick)
75 | }
76 | main()
77 |
--------------------------------------------------------------------------------
/examples/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@ko-yelie/kgl-example",
3 | "private": true,
4 | "scripts": {
5 | "dev": "parcel index.html",
6 | "build": "parcel build index.html --no-source-maps --out-dir ../docs --public-url /kgl/",
7 | "pages": "rm -rf ../docs && npm run build"
8 | },
9 | "devDependencies": {
10 | "@babel/core": "^7.17.10",
11 | "@babel/plugin-transform-runtime": "^7.17.10",
12 | "parcel-bundler": "^1.12.5",
13 | "stylus": "^0.57.0"
14 | },
15 | "dependencies": {
16 | "glsl-curl-noise": "0.0.4",
17 | "glsl-random": "0.0.5",
18 | "glsl-y-rotate": "^3.0.0"
19 | },
20 | "volta": {
21 | "node": "14.21.3"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/examples/shaders/PI.glsl:
--------------------------------------------------------------------------------
1 | const float PI = 3.1415926;
2 |
3 | #pragma glslify: export(PI)
4 |
--------------------------------------------------------------------------------
/examples/shaders/discardOutOfRangeUv.glsl:
--------------------------------------------------------------------------------
1 | void discardOutOfRangeUv(vec2 uv) {
2 | if (uv.x < 0. || uv.x > 1. || uv.y < 0. || uv.y > 1.) discard;
3 | }
4 |
5 | #pragma glslify: export(discardOutOfRangeUv)
6 |
--------------------------------------------------------------------------------
/examples/shaders/fitContain.glsl:
--------------------------------------------------------------------------------
1 | vec2 fitContain(vec2 coord, vec2 inputResolution, vec2 outputResolution) {
2 | vec2 ratio = vec2(
3 | max((outputResolution.x / outputResolution.y) / (inputResolution.x / inputResolution.y), 1.0),
4 | max((outputResolution.y / outputResolution.x) / (inputResolution.y / inputResolution.x), 1.0)
5 | );
6 | return coord * ratio + (1. - ratio) * 0.5;
7 | }
8 |
9 | #pragma glslify: export(fitContain)
10 |
--------------------------------------------------------------------------------
/examples/shaders/fitCover.glsl:
--------------------------------------------------------------------------------
1 | vec2 fitCover(vec2 uv, vec2 inputResolution, vec2 outputResolution) {
2 | vec2 ratio = vec2(
3 | min((outputResolution.x / outputResolution.y) / (inputResolution.x / inputResolution.y), 1.),
4 | min((outputResolution.y / outputResolution.x) / (inputResolution.y / inputResolution.x), 1.)
5 | );
6 | return uv * ratio + (1. - ratio) * 0.5;
7 | }
8 |
9 | #pragma glslify: export(fitCover)
10 |
--------------------------------------------------------------------------------
/examples/shaders/getZoomedUv.glsl:
--------------------------------------------------------------------------------
1 | vec2 getZoomedUv(vec2 uv, float zoom, vec2 origin) {
2 | origin.x = -origin.x;
3 | uv += origin;
4 | float scale = 1. / zoom;
5 | return uv * scale - 0.5 * (scale - 1.);
6 | }
7 |
8 | #pragma glslify: export(getZoomedUv)
9 |
--------------------------------------------------------------------------------
/examples/shaders/hsv.glsl:
--------------------------------------------------------------------------------
1 | vec3 hsv(float h, float s, float v) {
2 | vec4 t = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
3 | vec3 p = abs(fract(vec3(h) + t.xyz) * 6.0 - vec3(t.w));
4 | return v * mix(vec3(t.x), clamp(p - vec3(t.x), 0.0, 1.0), s);
5 | }
6 |
7 | #pragma glslify: export(hsv)
8 |
--------------------------------------------------------------------------------
/examples/utils.js:
--------------------------------------------------------------------------------
1 | export function onLoadImage(el) {
2 | return new Promise((resolve) => {
3 | if (el.complete) {
4 | resolve(el)
5 | } else {
6 | el.addEventListener('load', () => {
7 | resolve(el)
8 | })
9 | }
10 | })
11 | }
12 |
13 | const cacheLoadImage = {}
14 |
15 | export function loadImage(src, isCrossOrigin) {
16 | const isArray = typeof src === 'object' && src.constructor.name === 'Array'
17 | const promises = []
18 | ;(isArray ? src : [src]).forEach((srcString) => {
19 | const cache = cacheLoadImage[srcString]
20 | if (cache) {
21 | promises.push(Promise.resolve(cache))
22 | return
23 | }
24 | const img = document.createElement('img')
25 | if (isCrossOrigin) img.crossOrigin = 'anonymous'
26 | img.src = srcString
27 | const promiseLoad = onLoadImage(img)
28 | promiseLoad.then(() => {
29 | cacheLoadImage[srcString] = img
30 | })
31 | promises.push(promiseLoad)
32 | })
33 | return isArray ? Promise.all(promises) : promises[0]
34 | }
35 |
36 | export function mix(x, y, a) {
37 | return x * (1 - a) + y * a
38 | }
39 |
--------------------------------------------------------------------------------
/examples/variables.styl:
--------------------------------------------------------------------------------
1 | margin-window = 0.5rem
2 | font-family = -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif
3 | color-text = rgba(#fff, 0.7)
4 | color-link = rgba(#fff, 0.5)
5 | background-color = rgba(#000, 0.3)
6 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@ko-yelie/kgl",
3 | "moduleName": "kgl",
4 | "version": "0.6.2",
5 | "description": "Minimal WebGL library",
6 | "main": "dist/index.es.js",
7 | "types": "types/index.d.ts",
8 | "unpkg": "dist/index.iife.min.js",
9 | "files": [
10 | "dist",
11 | "types"
12 | ],
13 | "scripts": {
14 | "build": "rm -rf dist && bili",
15 | "types": "tsc --build tsconfig.types.json",
16 | "publish": "npm run build && npm run types && npm publish",
17 | "docs": "typedoc ./src/index.ts --out docs/api",
18 | "dev": "npm run dev --prefix examples",
19 | "pages": "npm run pages --prefix examples && npm run docs"
20 | },
21 | "repository": {
22 | "type": "git",
23 | "url": "git+https://github.com/ko-yelie/kgl.git"
24 | },
25 | "keywords": [],
26 | "author": "Ko.Yelie",
27 | "license": "MIT",
28 | "bugs": {
29 | "url": "https://github.com/ko-yelie/kgl/issues"
30 | },
31 | "homepage": "https://ko-yelie.github.io/kgl/",
32 | "devDependencies": {
33 | "bili": "^5.0.5",
34 | "eslint": "^8.15.0",
35 | "eslint-config-prettier": "^8.5.0",
36 | "eslint-config-standard": "^17.0.0",
37 | "eslint-plugin-import": "^2.26.0",
38 | "eslint-plugin-node": "^11.1.0",
39 | "eslint-plugin-prettier": "^4.0.0",
40 | "eslint-plugin-promise": "^6.0.0",
41 | "prettier": "^2.6.2",
42 | "rollup-plugin-glslify": "^1.2.1",
43 | "rollup-plugin-typescript2": "^0.31.1",
44 | "typedoc": "^0.22.17",
45 | "typedoc-plugin-missing-exports": "^0.22.6",
46 | "typescript": "^4.5.3"
47 | },
48 | "dependencies": {
49 | "glsl-fast-gaussian-blur": "^1.0.2",
50 | "glsl-random": "^0.0.5"
51 | },
52 | "volta": {
53 | "node": "14.21.3"
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/effects/bloom.ts:
--------------------------------------------------------------------------------
1 | import KglEffect from '../kglEffect'
2 | import Program from '../program'
3 | import Specular from './specular'
4 | import Blur from './blur'
5 | import bloomFrag from '../shaders/postprocessing/bloom.frag'
6 |
7 | export default class Bloom extends Program {
8 | bloomSpecular: Specular
9 | bloomBlur: Blur
10 | radius = 0.4
11 |
12 | constructor(kgl: KglEffect) {
13 | const option = {
14 | fragmentShader: bloomFrag,
15 | uniforms: {
16 | uSpecular: 'framebuffer',
17 | uTextureRead: 'framebuffer',
18 | },
19 | isAdditive: true,
20 | hasCamera: false,
21 | hasLight: false,
22 | }
23 | super(kgl, option)
24 |
25 | this.bloomSpecular = kgl.createEffect(Specular, {
26 | threshold: 0.3,
27 | })
28 |
29 | this.bloomBlur = kgl.createEffect(Blur)
30 | }
31 |
32 | drawEffect(
33 | readFramebufferKey: string,
34 | cacheFramebufferKey: string,
35 | outFramebufferKey: string,
36 | radius?: number,
37 | isOnscreen?: boolean
38 | ) {
39 | this.bloomSpecular.drawEffect(readFramebufferKey, cacheFramebufferKey)
40 |
41 | this.bloomBlur.drawEffect(
42 | cacheFramebufferKey,
43 | outFramebufferKey,
44 | typeof radius !== 'undefined' ? radius : this.radius
45 | )
46 |
47 | this.kgl.bindFramebuffer(isOnscreen ? null : outFramebufferKey)
48 |
49 | this.uniforms.uTextureRead = readFramebufferKey
50 | this.uniforms.uSpecular = cacheFramebufferKey
51 | super.draw()
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/effects/blur.ts:
--------------------------------------------------------------------------------
1 | import KglEffect from '../kglEffect'
2 | import Program from '../program'
3 | import blurFrag from '../shaders/postprocessing/blur.frag'
4 |
5 | export default class Blur extends Program {
6 | radius = 0.5
7 |
8 | constructor(kgl: KglEffect) {
9 | const option = {
10 | fragmentShader: blurFrag,
11 | uniforms: {
12 | uTexture: 'framebuffer',
13 | uRadius: 0,
14 | uIsHorizontal: false,
15 | },
16 | hasCamera: false,
17 | hasLight: false,
18 | }
19 |
20 | super(kgl, option)
21 | }
22 |
23 | drawEffect(
24 | readFramebufferKey: string,
25 | cacheFramebufferKey: string,
26 | radius?: number,
27 | isOnscreen?: boolean
28 | ) {
29 | const iterations = 8
30 | for (let i = 0; i < iterations; i++) {
31 | this.kgl.bindFramebuffer(
32 | isOnscreen && i >= iterations - 1 ? null : cacheFramebufferKey
33 | )
34 | this.uniforms.uTexture = readFramebufferKey
35 | this.uniforms.uRadius =
36 | (iterations - 1 - i) *
37 | (typeof radius !== 'undefined' ? radius : this.radius)
38 | this.uniforms.uIsHorizontal = i % 2 === 0
39 | this.kgl.clear()
40 | super.draw()
41 |
42 | const t = cacheFramebufferKey
43 | cacheFramebufferKey = readFramebufferKey
44 | readFramebufferKey = t
45 | }
46 | // output: readFramebufferKey
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/effects/godray.ts:
--------------------------------------------------------------------------------
1 | import KglEffect from '../kglEffect'
2 | import Program from '../program'
3 | import Blur from './blur'
4 | import Specular from './specular'
5 | import Zoomblur from './zoomblur'
6 | import textureFrag from '../shaders/postprocessing/godray.frag'
7 | import { Array2 } from '../type'
8 |
9 | export default class Godray extends Program {
10 | godraySpecular: Specular
11 | godrayZoomblur: Zoomblur
12 | godrayBlur: Blur
13 | radius = 0.02
14 |
15 | constructor(kgl: KglEffect) {
16 | const option = {
17 | fragmentShader: textureFrag,
18 | uniforms: {
19 | uTexture: 'framebuffer',
20 | uTextureCache: 'framebuffer',
21 | },
22 | isAdditive: true,
23 | }
24 | super(kgl, option)
25 |
26 | this.godraySpecular = kgl.createEffect(Specular, {
27 | threshold: 0.75,
28 | })
29 |
30 | this.godrayZoomblur = kgl.createEffect(Zoomblur)
31 |
32 | this.godrayBlur = kgl.createEffect(Blur)
33 | }
34 |
35 | drawEffect(
36 | readFramebufferKey: string,
37 | cacheFramebufferKey: string,
38 | outFramebufferKey: string,
39 | strength?: number,
40 | center?: Array2,
41 | radius?: number,
42 | isOnscreen?: boolean
43 | ) {
44 | this.godraySpecular.drawEffect(readFramebufferKey, outFramebufferKey)
45 |
46 | this.godrayZoomblur.drawEffect(
47 | outFramebufferKey,
48 | cacheFramebufferKey,
49 | strength,
50 | center
51 | )
52 |
53 | this.godrayBlur.drawEffect(
54 | cacheFramebufferKey,
55 | outFramebufferKey,
56 | typeof radius !== 'undefined' ? radius : this.radius
57 | )
58 |
59 | this.kgl.bindFramebuffer(isOnscreen ? null : outFramebufferKey)
60 |
61 | this.uniforms.uTexture = readFramebufferKey
62 | this.uniforms.uTextureCache = cacheFramebufferKey
63 | super.draw()
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/effects/godrayLight.ts:
--------------------------------------------------------------------------------
1 | import KglEffect from '../kglEffect'
2 | import Program from '../program'
3 | import Blur from './blur'
4 | import Specular from './specular'
5 | import Zoomblur from './zoomblur'
6 | import textureFrag from '../shaders/template/texture.frag'
7 | import { Array2 } from '../type'
8 |
9 | export default class GodrayLight extends Program {
10 | godraySpecular: Specular
11 | godrayZoomblur: Zoomblur
12 | godrayBlur: Blur
13 | radius = 0.02
14 |
15 | constructor(kgl: KglEffect) {
16 | const option = {
17 | fragmentShader: textureFrag,
18 | uniforms: {
19 | uTexture: 'framebuffer',
20 | },
21 | isAdditive: true,
22 | }
23 | super(kgl, option)
24 |
25 | this.godraySpecular = kgl.createEffect(Specular, {
26 | threshold: 0.75,
27 | })
28 |
29 | this.godrayZoomblur = kgl.createEffect(Zoomblur)
30 |
31 | this.godrayBlur = kgl.createEffect(Blur)
32 | }
33 |
34 | drawEffect(
35 | readFramebufferKey: string,
36 | cacheFramebufferKey: string,
37 | outFramebufferKey: string,
38 | strength?: number,
39 | center?: Array2,
40 | radius?: number,
41 | isOnscreen?: boolean
42 | ) {
43 | this.godraySpecular.drawEffect(readFramebufferKey, outFramebufferKey)
44 |
45 | this.godrayZoomblur.drawEffect(
46 | outFramebufferKey,
47 | cacheFramebufferKey,
48 | strength,
49 | center
50 | )
51 |
52 | this.godrayBlur.drawEffect(
53 | cacheFramebufferKey,
54 | outFramebufferKey,
55 | typeof radius !== 'undefined' ? radius : this.radius
56 | )
57 |
58 | this.kgl.bindFramebuffer(isOnscreen ? null : outFramebufferKey)
59 |
60 | this.uniforms.uTexture = cacheFramebufferKey
61 | super.draw()
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/effects/index.ts:
--------------------------------------------------------------------------------
1 | import { default as Blur } from './blur'
2 | import { default as Specular } from './specular'
3 | import { default as Bloom } from './bloom'
4 | import { default as Zoomblur } from './zoomblur'
5 | import { default as Godray } from './godray'
6 | import { default as GodrayLight } from './godrayLight'
7 |
8 | export type EffectInstance =
9 | | Blur
10 | | Specular
11 | | Bloom
12 | | Zoomblur
13 | | Godray
14 | | GodrayLight
15 |
16 | export type KeyofEffect =
17 | | 'blur'
18 | | 'specular'
19 | | 'bloom'
20 | | 'zoomblur'
21 | | 'godray'
22 | | 'godrayLight'
23 |
24 | export { default as Blur } from './blur'
25 | export { default as Specular } from './specular'
26 | export { default as Bloom } from './bloom'
27 | export { default as Zoomblur } from './zoomblur'
28 | export { default as Godray } from './godray'
29 | export { default as GodrayLight } from './godrayLight'
30 |
--------------------------------------------------------------------------------
/src/effects/specular.ts:
--------------------------------------------------------------------------------
1 | import KglEffect from '../kglEffect'
2 | import Program from '../program'
3 | import specularFrag from '../shaders/postprocessing/specular.frag'
4 |
5 | export type Option = {
6 | threshold?: number
7 | }
8 |
9 | export default class Specular extends Program {
10 | constructor(kgl: KglEffect, option: Option = {}) {
11 | const { threshold = 0.5 } = option
12 |
13 | const programOption = {
14 | fragmentShader: specularFrag,
15 | uniforms: {
16 | uTexture: 'framebuffer',
17 | uThreshold: threshold,
18 | },
19 | hasCamera: false,
20 | hasLight: false,
21 | }
22 |
23 | super(kgl, programOption)
24 | }
25 |
26 | drawEffect(
27 | readFramebufferKey: string,
28 | outFramebufferKey: string,
29 | threshold?: number
30 | ) {
31 | this.kgl.bindFramebuffer(outFramebufferKey)
32 | this.uniforms.uTexture = readFramebufferKey
33 | if (typeof threshold !== 'undefined') this.uniforms.uThreshold = threshold
34 | this.kgl.clear()
35 | super.draw()
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/effects/zoomblur.ts:
--------------------------------------------------------------------------------
1 | import KglEffect from '../kglEffect'
2 | import Program from '../program'
3 | import zoomblurFrag from '../shaders/postprocessing/zoomblur.frag'
4 | import { Array2 } from '../type'
5 |
6 | export default class Zoomblur extends Program {
7 | constructor(kgl: KglEffect) {
8 | const option = {
9 | fragmentShader: zoomblurFrag,
10 | uniforms: {
11 | uTexture: 'framebuffer',
12 | uStrength: 5,
13 | uCenter: [kgl.canvas.width / 2, kgl.canvas.height / 2],
14 | },
15 | }
16 | super(kgl, option)
17 | }
18 |
19 | drawEffect(
20 | readFramebufferKey: string,
21 | outFramebufferKey: string,
22 | strength?: number,
23 | center?: Array2,
24 | isOnscreen?: boolean
25 | ) {
26 | this.kgl.bindFramebuffer(isOnscreen ? null : outFramebufferKey)
27 | this.uniforms.uTexture = readFramebufferKey
28 | if (typeof strength !== 'undefined') this.uniforms.uStrength = strength
29 | if (typeof center !== 'undefined') this.uniforms.uCenter = center
30 | this.kgl.clear()
31 | super.draw()
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './kgl'
2 | export { default } from './kgl'
3 |
4 | export { default as KglEffect } from './kglEffect'
5 | export { default as KglAuto } from './kglAuto'
6 |
7 | export * from './effects/index'
8 |
--------------------------------------------------------------------------------
/src/kglAuto.ts:
--------------------------------------------------------------------------------
1 | import { Option as OptionKgl, Framebuffer, OptionCreateProgram } from './kgl'
2 | import KglEffect from './kglEffect'
3 | import Program from './program'
4 | import { EffectInstance, KeyofEffect } from './effects/index'
5 | import * as Effects from './effects/index'
6 |
7 | type framebufferOptions = { [K: string]: { width: number; height: number } }
8 |
9 | type Option = {
10 | programs?: { [K: string]: OptionCreateProgram }
11 | effects?: KeyofEffect[]
12 | framebuffers?: string[] | framebufferOptions
13 | framebufferFloats?: framebufferOptions
14 | tick?: Function
15 | onBefore?: Function
16 | onResize?: Function
17 | isAutoResize?: boolean
18 | isAutoStart?: boolean
19 | } & OptionKgl
20 |
21 | export default class KglAuto extends KglEffect {
22 | programs: { [K: string]: Program } = {}
23 | effects: {
24 | [K: string]: EffectInstance
25 | } = {}
26 | framebuffers: { [K: string]: Framebuffer } = {}
27 | ticks: Function[] = []
28 |
29 | onResize?: Function
30 |
31 | _resize?: EventListener | Function
32 | requestID: number = 0
33 |
34 | constructor(option: Option = {}) {
35 | super(option)
36 |
37 | const {
38 | programs = {},
39 | effects = [],
40 | framebuffers = [],
41 | framebufferFloats = {},
42 | tick,
43 | onBefore,
44 | onResize,
45 | isAutoResize = true,
46 | isAutoStart = true,
47 | } = option
48 |
49 | if (typeof tick === 'function') {
50 | this.addTick(tick)
51 | }
52 | if (typeof onResize === 'function') {
53 | this.onResize = onResize
54 | }
55 |
56 | Object.keys(programs).forEach((key) => {
57 | const data = programs[key]
58 | const program = (this.programs[key] = this.createProgram(data))
59 | if (!data.isFloats) {
60 | this.add(program)
61 | }
62 | })
63 |
64 | effects.forEach((key) => {
65 | const classKey = (key.charAt(0).toUpperCase() +
66 | key.slice(1)) as keyof typeof Effects
67 | this.effects[key] = this.createEffect(Effects[classKey])
68 | })
69 |
70 | if (isAutoResize) {
71 | this._initResize()
72 | }
73 |
74 | switch (framebuffers.constructor.name) {
75 | case 'Array':
76 | ;(framebuffers as string[]).forEach((key) => {
77 | this.createFramebuffer(key)
78 | })
79 | break
80 | case 'Object':
81 | Object.keys(framebuffers).forEach((key) => {
82 | const { width, height } = (framebuffers as framebufferOptions)[key]
83 | this.createFramebuffer(key, width, height)
84 | })
85 | break
86 | }
87 |
88 | Object.keys(framebufferFloats).forEach((key) => {
89 | const { width, height } = framebufferFloats[key]
90 | this.createFramebufferFloat(key, width, height)
91 | })
92 |
93 | if (typeof onBefore === 'function') onBefore(this)
94 |
95 | if (isAutoStart) this.start()
96 | }
97 |
98 | _initResize() {
99 | this._resize = () => {
100 | this.resize()
101 | if (this.onResize) {
102 | this.onResize()
103 | }
104 | }
105 | ;(this._resize as Function)()
106 | window.addEventListener('resize', this._resize as EventListener)
107 | }
108 |
109 | addTick(tick: Function) {
110 | this.ticks.push(tick)
111 | }
112 |
113 | start() {
114 | let initialTimestamp: number
115 |
116 | requestAnimationFrame((timestamp) => {
117 | initialTimestamp = timestamp
118 | })
119 |
120 | const render: FrameRequestCallback = (timestamp) => {
121 | const time = (timestamp - initialTimestamp) * 0.001
122 |
123 | for (let i = 0; i < this.ticks.length; i++) {
124 | this.ticks[i](this, time)
125 | }
126 |
127 | this.requestID = requestAnimationFrame(render)
128 | }
129 | this.requestID = requestAnimationFrame(render)
130 | }
131 |
132 | stop() {
133 | if (!this.requestID) return
134 |
135 | cancelAnimationFrame(this.requestID)
136 | this.requestID = 0
137 | }
138 |
139 | destroy() {
140 | this.stop()
141 |
142 | if (this._resize) {
143 | window.removeEventListener('resize', this._resize as EventListener)
144 | }
145 |
146 | super.destroy()
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/src/kglEffect.ts:
--------------------------------------------------------------------------------
1 | import Kgl from './kgl'
2 | import { EffectInstance } from './effects/index'
3 | import { Option as OptionSpecular } from './effects/specular'
4 |
5 | export default class KglEffect extends Kgl {
6 | effectList: EffectInstance[] = []
7 |
8 | createEffect(
9 | EffectClass: { new (kgl: KglEffect, option?: OptionSpecular): T },
10 | option?: OptionSpecular
11 | ) {
12 | const effect = new EffectClass(this, option)
13 | this.effectList.push(effect)
14 | return effect
15 | }
16 |
17 | resize() {
18 | super.resize()
19 |
20 | this.effectList.forEach((program) => {
21 | if (program.isAutoResolution) {
22 | program.uniforms.uResolution = [this.canvas.width, this.canvas.height]
23 | }
24 | })
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/shaders/glsl.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.vert' {
2 | const src: string
3 | export default src
4 | }
5 |
6 | declare module '*.frag' {
7 | const src: string
8 | export default src
9 | }
10 |
11 | declare module '*.glsl' {
12 | const src: string
13 | export default src
14 | }
15 |
--------------------------------------------------------------------------------
/src/shaders/postprocessing/bloom.frag:
--------------------------------------------------------------------------------
1 | precision highp float;
2 |
3 | uniform vec2 uResolution;
4 | uniform sampler2D uSpecular;
5 | uniform sampler2D uTextureRead;
6 |
7 | const float brightness = 0.7;
8 | const float spread = 0.3;
9 |
10 | void main() {
11 | vec2 uv = gl_FragCoord.st / uResolution;
12 | vec4 specularColor = texture2D(uSpecular, uv);
13 | specularColor.rgb = pow(specularColor.rgb, vec3(1. - brightness));
14 | specularColor.a = pow(specularColor.a, 1. - spread);
15 | gl_FragColor = texture2D(uTextureRead, uv) + specularColor;
16 | // gl_FragColor = vec4(vec3(specularColor.a), 1.); // * debug
17 | // gl_FragColor = vec4(texture2D(uSpecular, uv).rgb, 1.); // * debug
18 | }
19 |
--------------------------------------------------------------------------------
/src/shaders/postprocessing/blur.frag:
--------------------------------------------------------------------------------
1 | precision highp float;
2 |
3 | uniform sampler2D uTexture;
4 | uniform vec2 uResolution;
5 | uniform float uRadius;
6 | uniform bool uIsHorizontal;
7 |
8 | #pragma glslify: blur = require(glsl-fast-gaussian-blur)
9 |
10 | void main () {
11 | vec2 uv = gl_FragCoord.xy / uResolution;
12 | vec2 direction = uIsHorizontal ? vec2(1., 0.) : vec2(0., 1.);
13 | direction *= uRadius;
14 | gl_FragColor = blur(uTexture, uv, uResolution, direction);
15 | }
16 |
--------------------------------------------------------------------------------
/src/shaders/postprocessing/godray.frag:
--------------------------------------------------------------------------------
1 | precision highp float;
2 |
3 | uniform vec2 uResolution;
4 | uniform sampler2D uTexture;
5 | uniform sampler2D uTextureCache;
6 |
7 | void main() {
8 | vec2 uv = gl_FragCoord.st / uResolution;
9 | gl_FragColor = texture2D(uTexture, uv) + texture2D(uTextureCache, uv);
10 | }
11 |
--------------------------------------------------------------------------------
/src/shaders/postprocessing/specular.frag:
--------------------------------------------------------------------------------
1 | precision highp float;
2 |
3 | uniform vec2 uResolution;
4 | uniform sampler2D uTexture;
5 | uniform float uThreshold;
6 |
7 | void main() {
8 | vec2 uv = gl_FragCoord.st / uResolution;
9 | vec4 color = texture2D(uTexture, uv);
10 | if (color.a == 0. || length(color.rgb) < uThreshold * 1.732) discard;
11 | gl_FragColor = color;
12 | }
13 |
--------------------------------------------------------------------------------
/src/shaders/postprocessing/zoomblur.frag:
--------------------------------------------------------------------------------
1 | precision highp float;
2 |
3 | uniform sampler2D uTexture;
4 | uniform vec2 uResolution;
5 | uniform float uStrength;
6 | uniform vec2 uCenter;
7 |
8 | #pragma glslify: random = require(glsl-random)
9 |
10 | const float nFrag = 1. / 30.;
11 |
12 | void main () {
13 | vec2 tFrag = 1. / uResolution;
14 | vec3 destColor = vec3(0.);
15 | float randomValue = random(vec2(12.9898, 78.233));
16 | vec2 fc = gl_FragCoord.st;
17 | vec2 fcc = fc - uCenter;
18 | float totalWeight = 0.;
19 |
20 | for (float i = 0.; i <= 30.; i++) {
21 | float percent = (i + randomValue) * nFrag;
22 | float weight = percent - percent * percent;
23 | vec2 t = fc - fcc * percent * uStrength * nFrag;
24 | destColor += texture2D(uTexture, t * tFrag).rgb * weight;
25 | totalWeight += weight;
26 | }
27 | gl_FragColor = vec4(destColor / totalWeight, 1.);
28 | }
29 |
--------------------------------------------------------------------------------
/src/shaders/template/texture.frag:
--------------------------------------------------------------------------------
1 | precision highp float;
2 |
3 | uniform vec2 uResolution;
4 | uniform sampler2D uTexture;
5 |
6 | void main() {
7 | gl_FragColor = texture2D(uTexture, gl_FragCoord.st / uResolution);
8 | }
9 |
--------------------------------------------------------------------------------
/src/type.ts:
--------------------------------------------------------------------------------
1 | export type Array2 = [number, number]
2 | export type Array3 = [number, number, number]
3 | export type Array4 = [number, number, number, number]
4 |
--------------------------------------------------------------------------------
/src/vector.ts:
--------------------------------------------------------------------------------
1 | export class Vec2 extends Array {
2 | constructor(initialValues?: [number, number]) {
3 | if (initialValues) {
4 | return initialValues
5 | } else {
6 | super(2)
7 | }
8 | }
9 | }
10 |
11 | export class Vec3 extends Array {
12 | constructor(initialValues?: [number, number, number]) {
13 | if (initialValues) {
14 | return initialValues
15 | } else {
16 | super(3)
17 | }
18 | }
19 | }
20 |
21 | export class Vec4 extends Array {
22 | constructor(initialValues?: [number, number, number, number]) {
23 | if (initialValues) {
24 | return initialValues
25 | } else {
26 | super(4)
27 | }
28 | }
29 | }
30 |
31 | export type Matrix = Float32Array
32 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "strict": true,
4 | "sourceMap": true,
5 | "target": "ES2015",
6 | "module": "ESNext",
7 | "moduleResolution": "node",
8 | },
9 | "exclude": [
10 | "node_modules"
11 | ]
12 | }
13 |
--------------------------------------------------------------------------------
Used by the dataset HTML attribute to represent data for custom attributes added to elements.
3 |