スクリプト RenderEffect プラグイン

スクリプト可能な RenderEffect のプラグインを宣言するには、<superclass>RenderEffect として指定し、apply イベント ハンドラを宣言します。宣言されると、このレンダリング効果が[レンダリング効果](Render Effects)/[追加] (Add)ダイアログ ボックスに表示されます。

イベント ハンドラ:

on apply <bitmap> do <expr>

スクリプト化された効果をレンダリング効果の 1 つとして追加し、[シーンを更新](Update Scene)または[効果を更新](Update Effect)ボタンを押すと、apply イベント ハンドラが呼び出され、あらゆるレンダリング効果で修正できるビットマップが渡されます。与えられるビットマップは、ビットマップに適用された以前のレンダリング効果リストにあるすべての効果が適用されている、現在のレンダリングされたイメージです。通常、getPixel() および setPixel() 関数を使用してこのビットマップを適切に修正します。修正したビットマップはリストの次のレンダリング効果に渡されるか、最後の効果の場合はレンダリング出力に渡されます。

スクリプト化された効果が G-バッファ チャネル アクセスを利用できるようにするには、次のハンドラが必要です。

on channelsRequired do <expr>

ハンドラの式では、必要な G バッファ チャネル名の配列が評価される必要があります。G バッファ チャネル名を次に示します。

#zDepth #matID #objectID #UVCoords #normal #unClamped #coverage #mask #node #shaderColor #shaderTransparency #velocity #weight
on preApply <bitmap> do <expr>

preApply ハンドラは、代理の効果処理をあらかじめ調整するために、スクリプト化された効果による、入ってくるレンダリング ビットマップおよびチャネルの分析ができるようにします。

そのため、on channelsRequired do を追加して #node および #coverage チャネルをレンダラーのビットマップに追加し、on preApply bm do を追加して #node チャネルをマスクとして取り出してから代理のマスク パラメータに設定し、与えられたオブジェクトへの効果を制限します。

render() 関数の再入可能な呼び出しを、スクリプト化された renderEffect 内でできるようになりました。3ds Max 4 以前のリリースでは、この関数の再入可能な呼び出しを行うと、レンダリングの進行中にレンダリングを呼び出すことができないことを示すランタイム エラーが発生していました。

次に、ブラー効果を拡張して、ノード選択ボタンのある他のロールアウトを追加する簡単な例を示します。ノードを選択した場合、ノードによってチャネル マスクが生成され、これによりブラーがそのオブジェクトに限定されます。

スクリプト:

    plugin RenderEffect myBlurFX
    name:"Super Blur FX"
    classID:#(6545,456581)
    extends:Blur
    version:1
    (
      local tx, cm, g_channels
      local tx = bitmaptexture ()
      local g_channels = #(#node, #coverage)
      rollout params "SupaFX Parameters"
      (
        label nn align:#center
        pickbutton nodepick "Pick Node"
      )
      parameters main rollout:params
      (
        thenode type:#node ui:nodepick
        on thenode set nd do
          params.nn.text = if nd == undefined then "" else nd.name
      )
      on channelsRequired do g_channels
      on preApply map do if theNode != undefined then
      (
        if cm == undefined then
        (
          cm = getChannelAsMask map #node node:theNode \
          fileName:(scriptsPath + "__fxtmp.bmp")
          save cm
          tx.bitmap = cm
        )
        else
          getChannelAsMask map #node node:theNode to:cm
      )
      on create do
      (
        delegate.selMaskActive = true
        delegate.selImageActive = false
        delegate.selMaskMap = tx
      )
    )

スクリプト:

    plugin renderEffect myColorBalanceFx
    name:"Super Color Balance FX"
    classID:#(64425,45761)
    extends:Color_Balance version:1
    (
      parameters main rollout:params
      (
        redness type:#integer animatable:true ui:redness default:0.0
        on redness set val do delegate.red = val
      )
      rollout params "Super Color Balance Parameters"
      (
        spinner redness "Redness: " type:#integer range:[-100,100,0]
      )
    )

スクリプト:

    plugin renderEffect myNegative
    name:"myNegative"
    classID:#(0xb7aa794c, 0xc3bd78ab)
    (
      parameters main rollout:params
      (
        Color type:#color default:blue ui:Color
      )
      rollout params "Negative Parameters"
      (
        colorpicker Color "Base color: " align:#center
      )
      on apply bmp do
      (
        for h=0 to (bmp.height-1) do
        (
          local sline = getPixels bmp [0,h] bmp.width
          for i=1 to sline.count do sline[i] = Color - sline[i]
          setPixels bmp [0,h] sline
        )
      )
    )