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 日分です。