diff --git a/renin/package.json b/renin/package.json index 6bf35a9..0639895 100644 --- a/renin/package.json +++ b/renin/package.json @@ -1,6 +1,6 @@ { "name": "renin", - "version": "1.4.0", + "version": "2.0.0", "bin": "cli", "module": "lib/renin.js", "files": [ diff --git a/renin/src/ReninNode.ts b/renin/src/ReninNode.ts index c816d17..bea2de8 100644 --- a/renin/src/ReninNode.ts +++ b/renin/src/ReninNode.ts @@ -15,6 +15,7 @@ export class ReninNode { /* The unique node id of this node. */ id: string; + renin: Renin; /* Subclasses can implement this if they need code to happen in the * update stage. Update is guaranteed to be called exactly 60 times @@ -33,8 +34,9 @@ export class ReninNode { // @ts-ignore resize(width: number, height: number): void {} - constructor() { + constructor(renin: Renin) { this.id = this.constructor.name + '-' + ((1000000 * Math.random()) | 0); + this.renin = renin; console.log('new', this.id); } diff --git a/renin/src/renin.ts b/renin/src/renin.ts index f315273..ad1950a 100644 --- a/renin/src/renin.ts +++ b/renin/src/renin.ts @@ -1,10 +1,14 @@ import { CanvasTexture, Color, + FloatType, + LinearEncoding, + MeshBasicMaterial, NoToneMapping, OrthographicCamera, Scene, ShaderMaterial, + sRGBEncoding, WebGLRenderer, WebGLRendererParameters, WebGLRenderTarget, @@ -24,6 +28,7 @@ import screenShader from './ui/screenShader.glsl'; import performancePanelShader from './ui/performancePanel.glsl'; import { thirdsOverlayTexture } from './ui/thirdsOverlay'; import { performancePanelTexture } from './ui/performancePanelTexture'; +import { ColorManagement } from 'three/src/math/ColorManagement'; /* otherwise it won't be added to the build */ export * as vite from './ui/vite'; @@ -43,7 +48,7 @@ export interface Options { subdivision: number; beatOffset: number; }; - root: ReninNode; + root: typeof ReninNode; productionMode: boolean; rendererOptions?: WebGLRendererParameters; toneMapping: WebGLRenderer['toneMapping']; @@ -69,7 +74,6 @@ export class Renin { renderTimesGPUIndex: number = 0; renderer: WebGLRenderer; - demoRenderTarget = new WebGLRenderTarget(640, 360); screen = new UIBox({ shadowSize: 16, customMaterial: new ShaderMaterial({ @@ -108,7 +112,9 @@ export class Renin { scene = new Scene(); camera = new OrthographicCamera(-1, 1, 1, -1); root: ReninNode; - screenRenderTarget: WebGLRenderTarget = new WebGLRenderTarget(640, 360); + screenRenderTarget: WebGLRenderTarget = new WebGLRenderTarget(640, 360, { + type: FloatType, + }); isFullscreen: boolean = false; fullscreenAnimation = new UIAnimation(); uiOldTime: number = Date.now() / 1000; @@ -128,10 +134,13 @@ export class Renin { constructor(options: Options) { Renin.instance = this; + //@ts-ignore + ColorManagement.legacyMode = false; this.options = options; - this.root = options.root; this.renderer = new WebGLRenderer(options.rendererOptions); this.renderer.physicallyCorrectLights = true; + this.renderer.outputEncoding = LinearEncoding; + this.root = new options.root(this); this.audioBar = new AudioBar(this); const body = document.getElementsByTagName('body')[0]; @@ -373,7 +382,8 @@ export class Renin { } /* for hmr */ - register(newNode: ReninNode) { + register(newNodeClass: typeof ReninNode) { + const newNode = new newNodeClass(this); function recurse(node: ReninNode): ReninNode | null { if ('children' in node && node.children) { for (const [id, child] of Object.entries(node.children)) { @@ -582,15 +592,22 @@ export class Renin { this.performancePanel.getMaterial().uniforms.jsHeapSizeLimit.value = performance.memory.jsHeapSizeLimit; this.performancePanel.getMaterial().uniforms.overlay.value = performancePanelTexture; this.performancePanel.getMaterial().uniformsNeedUpdate = true; + const oldEncoding = this.renderer.outputEncoding; + this.renderer.outputEncoding = sRGBEncoding; this.renderer.render(this.scene, this.camera); + this.renderer.outputEncoding = oldEncoding; } render() { if (this.options.productionMode) { this.renderer.setRenderTarget(null); + const oldEncoding = this.renderer.outputEncoding; + const oldToneMapping = this.renderer.toneMapping; this.renderer.toneMapping = this.options.toneMapping; + this.renderer.outputEncoding = sRGBEncoding; this.root._render(this.frame, this.renderer, this); - this.renderer.toneMapping = NoToneMapping; + this.renderer.outputEncoding = oldEncoding; + this.renderer.toneMapping = oldToneMapping; return; } const time = performance.now(); @@ -624,9 +641,10 @@ export class Renin { } this.renderer.setRenderTarget(this.screenRenderTarget); + const oldToneMapping = this.renderer.toneMapping; this.renderer.toneMapping = this.options.toneMapping; this.root._render(this.frame, this.renderer, this); - this.renderer.toneMapping = NoToneMapping; + this.renderer.toneMapping = oldToneMapping; const dt = performance.now() - time; if (!this.music.paused) { this.renderTimesCPU[this.renderTimesCPUIndex] = dt; diff --git a/renin/src/ui/screenShader.glsl b/renin/src/ui/screenShader.glsl index fd69f17..083b3bb 100644 --- a/renin/src/ui/screenShader.glsl +++ b/renin/src/ui/screenShader.glsl @@ -4,7 +4,7 @@ uniform sampler2D thirdsOverlay; uniform float thirdsOverlayOpacity; void main() { - vec3 color = texture2D(screen, vUv.xy).rgb; + vec3 color = LinearTosRGB(texture2D(screen, vUv.xy)).rgb; float a = texture2D(thirdsOverlay, vUv.xy).a; vec3 inverted = 1. - color; color = mix(color, inverted, a * thirdsOverlayOpacity); diff --git a/renin/src/ui/vite.ts b/renin/src/ui/vite.ts index 69e9643..7801de6 100644 --- a/renin/src/ui/vite.ts +++ b/renin/src/ui/vite.ts @@ -10,7 +10,7 @@ export default function reninPlugin() { src += ` if (import.meta.hot) { import.meta.hot.accept((module) => { - Renin.instance.register(new module.${match[1]}()); + Renin.instance.register(module.${match[1]}); }); } `; diff --git a/renin/src/utils.ts b/renin/src/utils.ts index 82cc8b6..bfc13ff 100644 --- a/renin/src/utils.ts +++ b/renin/src/utils.ts @@ -12,7 +12,7 @@ export function children<T>(spec: any): T { if (store[prop]) { return store[prop]; } else { - store[prop] = new spec[prop](); + store[prop] = spec[prop]; return store[prop]; } },