From 76981445be73868dec8d2c69fb93782e8415ce0e Mon Sep 17 00:00:00 2001 From: FMS-Cat Date: Fri, 26 Mar 2021 02:47:05 +0900 Subject: [PATCH] dev: better RTInspector --- src/entities/RTInspector.ts | 40 +++++++++--- src/shaders/inspector.frag | 122 ++++++++++++++++++++++++++++++++++++ 2 files changed, 154 insertions(+), 8 deletions(-) create mode 100644 src/shaders/inspector.frag diff --git a/src/entities/RTInspector.ts b/src/entities/RTInspector.ts index ba5a5da..fa078b0 100644 --- a/src/entities/RTInspector.ts +++ b/src/entities/RTInspector.ts @@ -2,8 +2,14 @@ import { Entity } from '../heck/Entity'; import { RenderTarget } from '../heck/RenderTarget'; import { BufferRenderTarget } from '../heck/BufferRenderTarget'; import { RTINSPECTOR_CAPTURE_INDEX, RTINSPECTOR_CAPTURE_NAME, RTINSPECTOR_MULTIPLE } from '../config-hot'; -import { gl } from '../globals/canvas'; +import quadVert from '../shaders/quad.vert'; +import inspectorFrag from '../shaders/inspector.frag'; +import { canvas, gl } from '../globals/canvas'; import { Blit } from '../heck/components/Blit'; +import { Material } from '../heck/Material'; +import { dummyRenderTarget } from '../globals/dummyRenderTarget'; +import { quadGeometry } from '../globals/quadGeometry'; +import { Quad } from '../heck/components/Quad'; export interface RTInspectorOptions { target: RenderTarget; @@ -12,7 +18,8 @@ export interface RTInspectorOptions { export class RTInspector extends Entity { public entitySingle: Entity; public entityMultiple: Entity; - public blitSingle: Blit; + public materialSingle: Material; + public quadSingle: Quad; public blitsMultiple: Blit[]; public constructor( options: RTInspectorOptions ) { @@ -22,12 +29,28 @@ export class RTInspector extends Entity { this.entitySingle = new Entity(); this.children.push( this.entitySingle ); - this.blitSingle = new Blit( { - dst: options.target, - name: process.env.DEV && 'RTInspector/blitSingle', + this.materialSingle = new Material( + quadVert, + inspectorFrag, + { initOptions: { target: dummyRenderTarget, geometry: quadGeometry } }, + ); + + this.quadSingle = new Quad( { + target: options.target, + material: this.materialSingle, + name: `RTInspector/quadSingle`, ignoreBreakpoints: true, } ); - this.entitySingle.components.push( this.blitSingle ); + this.entitySingle.components.push( this.quadSingle ); + + // -- mouse listener --------------------------------------------------------------------------- + canvas.addEventListener( 'mousemove', ( { offsetX, offsetY } ) => { + const rect = canvas.getBoundingClientRect(); + const x = offsetX / rect.width; + const y = 1.0 - offsetY / rect.height; + + this.materialSingle.addUniform( 'mouse', '2f', x, y ); + } ); // -- multiple --------------------------------------------------------------------------------- this.entityMultiple = new Entity(); @@ -106,8 +129,9 @@ export class RTInspector extends Entity { return; } - this.blitSingle.src = target; - this.blitSingle.attachment = attachment; + const texture = target.getTexture( attachment ); + this.materialSingle.addUniformTexture( 'sampler0', texture ); + this.entitySingle.active = true; } else { // fallback to not render it diff --git a/src/shaders/inspector.frag b/src/shaders/inspector.frag new file mode 100644 index 0000000..2d410f7 --- /dev/null +++ b/src/shaders/inspector.frag @@ -0,0 +1,122 @@ +#version 300 es + +precision highp float; + +const float RADIUS = 40.0; +const vec3 CIRCLE_COLOR = vec3( 1.0, 1.0, 1.0 ); + +in vec2 vUv; + +out vec4 fragColor; + +uniform vec2 resolution; +uniform vec2 mouse; +uniform sampler2D sampler0; + +bool print( in vec2 _coord, float _in ) { + vec2 coord = _coord; + + // vertical restriction + if ( coord.y <= 0.0 || 5.0 <= coord.y ) { return false; } + + // dot + if ( 0.0 < coord.x && coord.x < 2.0 ) { + return coord.x < 1.0 && coord.y < 1.0; + } + + // padded by dot + if ( 2.0 < coord.x ) { coord.x -= 2.0; } + + // determine digit + float ci = floor( coord.x / 5.0 ) + 1.0; + + // too low / too high + if ( 4.0 < ci ) { return false; } + if ( ci < -4.0 ) { return false; } + + // x of char + float cfx = floor( mod( coord.x, 5.0 ) ); + + // width is 4 + if ( 4.0 == cfx ) { return false; } + + // y of char + float cfy = floor( coord.y ); + + // bit of char + float cf = cfx + 4.0 * cfy; + + // determine char + float num = 0.0; + if ( 0.0 < ci ) { + float n = abs( _in ); + for ( int i = 0; i < 6; i ++ ) { + if ( ci < float( i ) ) { break; } + + num = mod( floor( n ), 10.0 ); + n -= num; + n *= 10.0; + } + } else { + float n = abs( _in ); + for ( int i = 0; i < 6; i ++ ) { + if ( -ci < float( i ) ) { break; } + + if ( ci != 0.0 && n < 1.0 ) { + // minus + return float( i ) == -ci && _in < 0.0 && cfy == 2.0 && 0.0 < cfx; + } + num = mod( floor( n ), 10.0 ); + n -= num; + n /= 10.0; + } + } + + bool a; + a = 1.0 == mod( floor( ( + num == 0.0 ? 432534.0 : + num == 1.0 ? 410692.0 : + num == 2.0 ? 493087.0 : + num == 3.0 ? 493191.0 : + num == 4.0 ? 630408.0 : + num == 5.0 ? 989063.0 : + num == 6.0 ? 399254.0 : + num == 7.0 ? 1016898.0 : + num == 8.0 ? 431766.0 : + 433798.0 + ) / pow( 2.0, cf ) ), 2.0 ); + + return a ? true : false; +} + +void main() { + vec2 uv = vUv; + vec2 coord = vUv * resolution; + + vec2 center = floor( mouse * resolution + vec2( 1.0, 0.7 ) * RADIUS ); + float circle = length( coord.xy - center ) - RADIUS; + + vec4 col = texture( sampler0, uv ); + vec4 mcol = texture( sampler0, mouse ); + float mcolb = dot( mcol.rgb, vec3( 0.299, 0.587, 0.114 ) ); + vec4 bcol = vec4( vec3( step( mcolb, 0.5 ) ), 1.0 ); + + col = mix( + col, + mix( + bcol, + mcol, + smoothstep( 1.0, 0.0, circle + 5.0 ) + ), + smoothstep( 1.0, 0.0, circle ) + ); + + if ( circle < 0.0 ) { + col = print( coord.xy - center - vec2( 0.0, 8.0 ), mcol.x ) ? bcol : col; + col = print( coord.xy - center - vec2( 0.0, 0.0 ), mcol.y ) ? bcol : col; + col = print( coord.xy - center - vec2( 0.0, -8.0 ), mcol.z ) ? bcol : col; + col = print( coord.xy - center - vec2( 0.0, -16.0 ), mcol.w ) ? bcol : col; + } + + fragColor = col; +}