2018/01/15(月) [n年前の日記]
#1 [love2d] love2dのShaderでパレット書き換えっぽい処理
love2d の Shader を使ってパレット書き換えっぽい処理を書いているけど、高速化・最適化できないか試したり。
環境は以下。
5種類の書き方を試したけど、結果はこんな感じで。
せいぜい、1FPS程度変わるか変わらないか、ぐらいの違いしか出てこなかった。
- GLSLはif文が重いという話があるらしいので、if文を無くしたり、三項演算子を無くしたり。
- A * (1.0 - f) + B * f を mix()関数で置き換えてみたり。
- A * (1.0 - f) + B * f を、A - A * f + B * f に置き換えてみたり。
- (A.r == C.r && A.g = C.g && A.b == C.b) を (A.rgb == C.rgb) に置き換えてみたり。
環境は以下。
- Raspberry Pi Zero W
- raspbian jessie
- love2d 0.10.2
- SDL2 2.0.5(OpenGL ES有効化)
5種類の書き方を試したけど、結果はこんな感じで。
Shader kind | FPS |
---|---|
1 | 7 |
2 | 7 - 8 |
3 | 7 |
4 | 6 - 7 |
5 | 7 - 8 |
◎ ソースと画像。 :
使用画像は以下。
_colorblock.png
ソースは以下。
_conf.lua
_main.lua
_colorblock.png
ソースは以下。
_conf.lua
function love.conf(t) t.window.title = "Shader test 04 palette change modoki" t.window.vsync = true t.window.resizable = true t.window.width = 1280 t.window.height = 720 -- t.window.fullscreen = true -- t.window.fullscreentype = "exclusive" end
_main.lua
-- Shader test 04 -- palette change modoki loop_count = 32 function love.load() love.graphics.setDefaultFilter("nearest", "nearest") scr_w, scr_h = 1280, 720 canvas = love.graphics.newCanvas(scr_w, scr_h) -- load image img = love.graphics.newImage("colorblock.png") local shadercode1 = [[ extern number factor; extern vec3 checkcolor; extern vec3 replacecolor; vec4 effect( vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords ){ vec4 pixel = Texel(texture, texture_coords); if (pixel.r == checkcolor.r && pixel.g == checkcolor.g && pixel.b == checkcolor.b) { pixel.r = pixel.r * (1.0 - factor) + replacecolor.r * factor; pixel.g = pixel.g * (1.0 - factor) + replacecolor.g * factor; pixel.b = pixel.b * (1.0 - factor) + replacecolor.b * factor; } return pixel * color; } ]] myshader1 = love.graphics.newShader(shadercode1) myshader1:send("checkcolor", {1.0, 0.0, 0.0}) -- R,G,B myshader1:send("replacecolor", {0.0, 0.0, 0.0}) -- R,G,B local shadercode2 = [[ extern number factor; extern number checkcolor; extern vec4 replacecolor; vec4 effect( vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords ){ vec4 pixel = Texel(texture, texture_coords); float nowcol = pixel.r * 16711680.0 + pixel.g * 65280.0 + pixel.b * 255.0; float fac = (checkcolor == nowcol)? factor : 0.0; return mix(pixel, replacecolor, fac) * color; } ]] myshader2 = love.graphics.newShader(shadercode2) -- checkcolor : 0xRRGGBB = (R << 16) + (G << 8) + B local checkcolor = ((1.0 * 65536) + (0.0 * 256) + 0.0) * 255.0 myshader2:send("checkcolor", checkcolor) myshader2:send("replacecolor", {0.0, 0.0, 0.0, 1.0}) -- R,G,B,A local shadercode3 = [[ extern number factor; extern number checkcolor; extern vec4 replacecolor; vec4 effect( vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords ){ vec4 pixel = Texel(texture, texture_coords); float nowcol = pixel.r * 16711680.0 + pixel.g * 65280.0 + pixel.b * 255.0; float fac = (1.0 - sign(abs(nowcol - checkcolor))) * factor; return mix(pixel, replacecolor, fac) * color; } ]] myshader3 = love.graphics.newShader(shadercode3) local checkcolor = ((1.0 * 65536) + (0.0 * 256) + 0.0) * 255.0 myshader3:send("checkcolor", checkcolor) myshader3:send("replacecolor", {0.0, 0.0, 0.0, 1.0}) -- R,G,B,A local shadercode4 = [[ extern number factor; extern vec4 checkcolor; extern vec4 replacecolor; vec4 effect( vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords ){ vec4 pixel = Texel(texture, texture_coords); return mix(pixel, replacecolor, ((pixel == checkcolor)? factor : 0.0)) * color; } ]] myshader4 = love.graphics.newShader(shadercode4) myshader4:send("checkcolor", {1.0, 0.0, 0.0, 1.0}) -- R,G,B myshader4:send("replacecolor", {0.0, 0.0, 0.0, 1.0}) -- R,G,B local shadercode5 = [[ extern number factor; extern vec3 checkcolor; extern vec3 replacecolor; vec4 effect( vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords ){ vec4 pixel = Texel(texture, texture_coords); if (pixel.rgb == checkcolor.rgb) { pixel.r = pixel.r - pixel.r * factor + replacecolor.r * factor; pixel.g = pixel.g - pixel.g * factor + replacecolor.g * factor; pixel.b = pixel.b - pixel.b * factor + replacecolor.b * factor; } return pixel * color; } ]] myshader5 = love.graphics.newShader(shadercode5) myshader5:send("checkcolor", {1.0, 0.0, 0.0}) -- R,G,B myshader5:send("replacecolor", {0.0, 0.0, 0.0}) -- R,G,B myshaders = { myshader1, myshader2, myshader3, myshader4, myshader5 } myshader_kind = 1 angle = 0 end function love.update(dt) angle = (angle + 90 * dt) % 360.0 local v = 1.0 - math.abs(math.sin(math.rad(angle))) myshaders[myshader_kind]:send("factor", v) -- set 0.0 - 1.0 px = (scr_w - img:getWidth()) / 2 py = (scr_h - img:getHeight()) / 2 end function love.draw() love.graphics.setCanvas(canvas) love.graphics.clear(0, 0, 0, 255) love.graphics.setShader(myshaders[myshader_kind]) love.graphics.setColor(255, 255, 255, 255) for i=1,loop_count do love.graphics.draw(img, px, py, 0, 1.0, 1.0, 0, 0) end love.graphics.setShader() love.graphics.setCanvas() -- draw canvas to window wdw_w, wdw_h = love.graphics.getDimensions() scr_scale = math.min((wdw_w / scr_w), (wdw_h / scr_h)) scr_ofsx = (wdw_w - (scr_w * scr_scale)) / 2 scr_ofsy = (wdw_h - (scr_h * scr_scale)) / 2 love.graphics.setColor(255, 255, 255) love.graphics.draw(canvas, scr_ofsx, scr_ofsy, 0, scr_scale, scr_scale) love.graphics.print("FPS: "..tostring(love.timer.getFPS()), 10, 10) love.graphics.print("Shader Kind: "..tostring(myshader_kind), 10, 30) end function love.keypressed(key, isrepeat) if key == "escape" then -- ESC to exit love.event.quit() elseif key == "f11" then -- toggle fullscreen mode if love.window.getFullscreen() then love.window.setFullscreen(false) else love.window.setFullscreen(true) end elseif key == "down" then myshader_kind = myshader_kind - 1 if myshader_kind <= 0 then myshader_kind = #myshaders end elseif key == "up" then myshader_kind = myshader_kind + 1 if myshader_kind > #myshaders then myshader_kind = 1 end end end
[ ツッコむ ]
#2 [windows] BRTSvcってなんだろう
oCamというデスクトップキャプチャソフトを起動したら、「更新版があるよ!」と言ってきて、問答無用で何かのアプリのインストーラが起動された。が、ダイアログの左下のほうに、「BRTSvc」なる項目があって、チェックが入ってる。何だコレ…。
ググってみたら、以下の記事が。韓国語、中国語の記事だけど。
_http://www.hankookilbo.com/v/0adaa6614b7f4c8689d8e8df07199505
_http://dapente.com/1795.html
どうやら、ユーザに無断でビットコインの採掘とやらを行うプログラムらしい…。CPUを100%で回してPCの寿命を短くするとかなんとか書いてある、ような。
感染(?)してるかどうかを調べる方法は、前述の記事によると…。
解決策として、oCam をアンインストールしてから古い版をインストールして自動更新を無効に、と書いてあるけど…。
手元に残してた古い版 (v3xx) をインストールしてみたものの、それでも必ず「最新版に更新します!」と言ってくる。しかも「OK」ボタンしか無いので、必ず謎インストーラが起動するし、oCam も終了してしまう。
隙を狙って oCam のオプションを開いて確認してみるも、どこで自動更新を無効にできるのか分からない。そんな項目はどこにも無さそうだが…。
お金を払って購入する以外にないのかな、と思って登録だの購入だのの項目を選んでみるも、その感にも「最新版に更新します!」と言ってきて登録も購入もできそうにない。ダメだろコレ…。
手の打ちようがないなと。アンインストールするしかない…。これでは試用すらできないのではなかろうか…。
ググってみたら、以下の記事が。韓国語、中国語の記事だけど。
_http://www.hankookilbo.com/v/0adaa6614b7f4c8689d8e8df07199505
_http://dapente.com/1795.html
どうやら、ユーザに無断でビットコインの採掘とやらを行うプログラムらしい…。CPUを100%で回してPCの寿命を短くするとかなんとか書いてある、ような。
感染(?)してるかどうかを調べる方法は、前述の記事によると…。
- C:\Program Files (x86)\BRTSvc\ というフォルダがあったら感染してる。
- BRT.exe というサービスが動いてたら感染してる。
解決策として、oCam をアンインストールしてから古い版をインストールして自動更新を無効に、と書いてあるけど…。
手元に残してた古い版 (v3xx) をインストールしてみたものの、それでも必ず「最新版に更新します!」と言ってくる。しかも「OK」ボタンしか無いので、必ず謎インストーラが起動するし、oCam も終了してしまう。
隙を狙って oCam のオプションを開いて確認してみるも、どこで自動更新を無効にできるのか分からない。そんな項目はどこにも無さそうだが…。
お金を払って購入する以外にないのかな、と思って登録だの購入だのの項目を選んでみるも、その感にも「最新版に更新します!」と言ってきて登録も購入もできそうにない。ダメだろコレ…。
手の打ちようがないなと。アンインストールするしかない…。これでは試用すらできないのではなかろうか…。
◎ 代わりに OBS Studio を試用。 :
NVIDIA製GPUが載ったビデオカード(GeForce GTX 750 Ti)を使っているので、NVENC で圧縮・キャプチャできるツールが使いたいなと。ググってみたら、OBS Studio なる配信向けのソフトなら、NVENC を使ってキャプチャ・録画できると知った。
_OBS Studioの詳しい使い方(1/2) - VIPで初心者がゲーム実況するには
_Open Broadcaster Software | ホーム
インストールして試用してみたけど、一応デスクトップ全画面をNVENCを使いながらキャプチャすることができた。
デスクトップ画面のキャプチャや、ウインドウ内容だけキャプチャはできるようだけど…。現行版では特定領域を指定してキャプチャできるようには見えず。一旦全画面でキャプチャしてから、後で AviUtl等を使いつつ、必要な部分だけクリッピングして書き出し、かな…。
_OBS Studioの詳しい使い方(1/2) - VIPで初心者がゲーム実況するには
_Open Broadcaster Software | ホーム
インストールして試用してみたけど、一応デスクトップ全画面をNVENCを使いながらキャプチャすることができた。
デスクトップ画面のキャプチャや、ウインドウ内容だけキャプチャはできるようだけど…。現行版では特定領域を指定してキャプチャできるようには見えず。一旦全画面でキャプチャしてから、後で AviUtl等を使いつつ、必要な部分だけクリッピングして書き出し、かな…。
[ ツッコむ ]
以上、1 日分です。