음악, 삶, 개발

Pixi 에서 필요할때만 랜더링 하기 (PIXI.Renderer) 본문

개발 Web/PixiJS

Pixi 에서 필요할때만 랜더링 하기 (PIXI.Renderer)

Lee_____ 2021. 8. 2. 05:14

아래 포스팅에서 60fps 로 계속 랜더링이 되는것이 많은 자원을 소모한다고 글을 썼었는데,

직접 manual 하게 랜더링할수있는 방법이 있다.

먼저 이야기하면 "필요한 부분만" 랜더링은 불가능하다.

무조건 전체를 다시 랜더링해야한다. (아래서 자세히 설명)

 

PIXI.Application 클래스를 사용하는 대신 직접

PIXI.Renderer 인스턴스를 생성하는것이다.

 

간단히 버튼을 클릭했을때 색이 바뀌는 코드를 작성해보자.

 

import { Renderer, Sprite, Texture } from 'pixi.js'

const renderer = new Renderer({

    width : window.innerWidth,
    height : window.innerHeight,
    backgroundColor : 0x000000 // black

})

document.body.appendChild(renderer.view) // 이거없으면 dom 에 canvas 추가 안되서 아무것도 안보임!

const sprite = new Sprite(Texture.WHITE)

sprite.position.set(100, 100)
sprite.width = sprite.height = 200
sprite.tint = 0xff0000 // red

sprite.interactive = true
sprite.buttonMode = true

sprite.on('mousedown', () => {

    sprite.tint = 0xffffff * Math.random()
    renderer.render(sprite)

})

renderer.render(sprite)

위와 같이 sprite 에 mousedown 이 발생했을때,

render(sprite) 을 호출해줘야한다.

안타깝게도 DOM 과 다른점은, 일부만 랜더링되게 할수없고 전체를 다시 랜더링해야한다.

검색해보니 webGL 에서는 Dirty rect 같은 메카니즘이 존재하지않는다고 한다.

한마디로 변화된 부분만 리액트처럼 랜더링할수없다.

아래의 pixi js issue 에서 이와 관련된것을 이야기하고있는데, 

결과적으로 변화된 구간을 확인하는 cpu 사용량이 더 클거라고 pixi 팀이 이야기한다.

게임같은 경우는 변화되는곳이 매 프레임마다 발생하기때문에 그냥 전체를 하는것이 효율적이라고.

https://github.com/pixijs/pixijs/issues/3503

 

이 전체 랜더링이 내 발목을 잡게될지는 지켜봐야할것같다.

어쨋든 랜더링되는 속도가 매우 빠르기때문에, mousedown 의 경우 전체가 랜더링한다고 cpu 가 막 spike 튀거나 하지는않지만,

mousemove 나 mousedrag 일 경우 이야기가 좀 달라진다. (10만개 일경우 100프로로 cpu 튐)

따라서 드래그 이벤트일때는 dom 요소를 작게 layer 한다거나 머리를 꽤나 써야할거같다.

cacheAsBitmap 을 true 로 함으로써 snapshot 을 뜰수는있다고 한다.

const sprite = new Sprite(Texture.WHITE)

sprite.cacheAsBitmap = true

이처럼 pixi 에서 성능향상을 위해서는 리액트와 다른 두통들이 존재한다.

여러가지 기술들이 자질구레하게 조합이 되어야한다.

그래도 이렇게 랜더러로 조금이나마 이벤트 발생이 없을때 자원을 절약할수있다.

 

부분 랜더링은 안되더라도 stage 별로 다른 랜더러를 쓸수없을까.. 해서 검색해보았다.

아래는 이와 관련된 글들이다.

읽어보니, 한 canvas 당 하나의 랜더러만을 사용해야하고, 브라우저 에서 다중 context 를 허용하지않는것,

또 모바일 디바이스에서 성능 저하등이 나타날수있다고한다.

 

https://www.html5gamedevs.com/topic/37097-multiple-webgl-pixirenderer-instances-on-the-same-screen/

https://github.com/pixijs/pixijs/issues/5216