mieki256's diary



2018/01/15(月) [n年前の日記]

#1 [love2d] love2dのShaderでパレット書き換えっぽい処理

love2d の Shader を使ってパレット書き換えっぽい処理を書いているけど、高速化・最適化できないか試したり。



色々な書き方を試してみたけど…。今回のような処理では、あまり劇的な変化は無いなと。

環境は以下。 処理内容は、1280x720 の画像を、Shaderを通して32回繰り返して描画。

5種類の書き方を試したけど、結果はこんな感じで。
Shader kindFPS
17
27 - 8
37
46 - 7
57 - 8
せいぜい、1FPS程度変わるか変わらないか、ぐらいの違いしか出てこなかった。

ソースと画像。 :

使用画像は以下。

_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

以上です。

過去ログ表示

Prev - 2018/01 - Next
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project