BlackSheep-LSL@Wiki

高度なカメラ制御

最終更新:

mizcremorne

- view
メンバー限定 登録/ログイン

はじめに


「初級スクリプト」でカメラ制御について簡単な方法は紹介したのですが、さらに踏み込んだカメラ制御について書いておこうと思います。
高度なカメラ制御を使うと、一定の場所にカメラを固定するだけではなく、例えばアバターの周囲をぐるぐると回転させたり、俯瞰視点にしてみたり、はたまたカメラを固定してアバターが自由に歩き回れるようなものなど、面白い見せ方がいろいろとできます。
こうしたスクリプトは動画作成や乗り物、ライドなどに応用することができます。

カメラ制御とは


まず最初に、カメラを制御する上での用語について簡単に説明しながら、一体どんなことが出来るのか概要をお話しておきます。
ここで言う「カメラ」と言うのは、SLの画面(視界)のことです。
SLという仮想世界をテレビカメラで撮影して、PC画面でモニタしているイメージです。
「カメラ制御」とは、このテレビカメラを動かして、例えばズームしてみたり、横に動かしてみたり、撮影している対象の周りを回ってみたりすることを言います。
カメラを固定して定点撮影のような視界にするのもカメラ制御の一つです。

ポジション


カメラの位置(ポジション)は、テレビカメラが置かれている位置のことです。
通常、カメラの位置はアバターの背後になっています。
アバターが回転するとそれに合わせてカメラも移動し、常にアバターの背中からの映像を映しますよね。
LSLのカメラ制御ではカメラのポジションをアバターの背後以外の場所に設定することができます。
例えばアバターの背後ではなく、右側から見た視点にしたりすることが可能です。

フォーカス


カメラが見ている対象(の位置)のことを「フォーカス」と言います。
通常は「フォーカス」は自分のアバターになっていますが、ALTを押しながらオブジェクト等をクリックすると「フォーカス」がそのオブジェクトに合います。
誰か他のアバターに「フォーカス」を合わせると、カメラはその人を映し続けます。
俗に「ALTズーム」と言われますが、残念ながらフォーカス対象を追尾する機能はLSLではサポートされていません。
ですが「フォーカス」位置を設定することはできます。
例えばアバターの足元を映し続けるようなことが可能です。

ロック


ポジション及びフォーカスは「ロック」することが出来ます。
ロックとは固定することです。
通常ではアバターが動くとカメラもそれにつれて動き、ポジションやフォーカスは変化していきますが、「ロック」を使うとカメラポジションやフォーカスを固定することが可能です。
例えばポジションをロックすると、カメラは定点に設置されますが、アバターが動くとその動きを追うように向きを変えます。
フォーカスをロックすると、カメラはアバターの動きと共に移動しますが、フォーカス位置を常に映し続けます。
ポジションとフォーカスの双方をロックすると、完全な定点撮影になります。
アバターが画面外にスタスタ歩いて行ったとしても、カメラはひたすらに固定された位置を映し続けます。

ディスタンス


カメラをズームインしたりズームアウトする動きは「ディスタンス」で表現されます。
つまりカメラの距離です。
ディスタンスが近くなれば視界はズームインし、遠くなればズームアウトします。

ピッチ


「ピッチ」はカメラの上下角度のことを指します。
通常は地面(水平線)と平行の角度になっており、上から見下ろす場合はプラスの角度、下から見上げる場合はマイナスの角度を設定します。
例えばピッチを最大まで上げると、俯瞰図のような視界になります。

ビハインドネス


「ビハインドネス」という聞きなれない設定項目もあります。
これはカメラがアバターの背後にどれくらい着いて回るかを設定する項目です。
通常ですと、アバターが向きを変えると、カメラはすぐにその背後へと回り込みますが、ビハインドネスを調整することで、例えばアバターが真横を向くまではカメラが回り込まないような設定をすることができます。
さらにはカメラの回りこみを完全に無効にもできます。
回り込みを無効にすると、普段は背中しか見れない自分のアバターを正面から見ることができるようになったりもします。

ラグ


「ラグ」と聞くと我々の天敵のように思えますが、カメラ制御における「ラグ」はカメラの反応速度のことを指します。
アバターの動きに合わせてカメラが動くとき、通常ではカメラは即座に反応してアバターを追いかけます。
「ラグ」を大きく設定すると、カメラの動きは鈍くなります。
アバターが動いてから、ワンテンポ遅れてカメラが追いかけるような動きが可能です。
あるいは言い換えるなら、「ラグ」を大きく設定したときにはカメラの動きがソフトになると言ってもいいでしょう。
「ラグ」が小さいときには、カメラはシャープに動きます。

スレッショルド


最後に「スレッショルド」ですが、直訳すると「敷居」です。
「スレッショルド」はカメラが移動したりフォーカスを追うときの「あそび」を設定します。
例えばフォーカスの「スレッショルド」が半径1mで設定されていた場合、カメラはフォーカス対象が1m以内で動く分には追尾しません。
フォーカス対象が1m以上移動して初めて、カメラは追尾します。

カメラ制御の関数


ではカメラ制御を行うための関数について見てみましょう。
できることは多岐に渡りますが、関数自体は多くありません。

llSetCameraParams関数


 llSetCameraParams(list rules)

カメラ制御を行うための関数はこれ一つだけと言ってもいいでしょう。
ただしカメラ制御を行うためにはパーミッションが必要です。
アニメーションなどのスクリプトにおいて何度か説明しているのでパーミッションについては改めて説明はしません。
llSetCameraParams関数の実行に必要なパーミッションはPERMISSION_CONTROL_CAMERAです。

例えば以下のようにしてパーミッションを取得します(アタッチメントにカメラ制御を組み込む場合の例です)。

default {
  attach(key agent){
    if (agent != NULL_KEY){
      llRequestPermissions(agent, PERMISSION_CONTROL_CAMERA);
    }
  }
  run_time_permissions(integer perm) {
    if (!(perm & PERMISSION_CONTROL_CAMERA)) {
      llRequestPermissions(agent, PERMISSION_CONTROL_CAMERA);
    }
  }
}

llSetCameraParams関数の引数rulesはリスト型になっており、様々なカメラ制御用のパラメータをまとめて渡します。
引数rulesには以下の形式でパラメータを羅列します。

 [パラメータ定数1, 設定値1, パラメータ定数2, 設定値2,....]

パラメータ定数及び設定可能な値は以下の通りです。

パラメータ定数 定数値 設定値の型 初期設定値 設定値の範囲 説明
CAMERA_ACTIVE 12 integer(有効/無効) FALSE TRUE か FALSE カメラ制御のON/OFF
CAMERA_BEHINDNESS_ANGLE 8 float(角度) 10.0 0.0 から 180.0 ビハインドネス角度
CAMERA_BEHINDNESS_LAG 9 float(秒) 0.0 0.0 から 3.0 ビハインドネスのラグ
CAMERA_DISTANCE 7 float(m) 3.0 0.5 から 10.0 カメラの距離(ズーム)
CAMERA_FOCUS 17 vector(位置) なし フォーカス位置(デフォルトはアバター)
CAMERA_FOCUS_LAG 6 float(秒) 0.1 0.0 から 3.0 フォーカスのラグ
CAMERA_FOCUS_LOCKED 22 integer(固定/非固定) FALSE TRUE か FALSE フォーカスロック/アンロック
CAMERA_FOCUS_OFFSET 1 vector(m) <0.0, 0.0, 0.0> <-10,-10,-10>から<10,10,10> フォーカス位置(アバターからの相対位置)
CAMERA_FOCUS_THRESHOLD 11 float(m) 1.0 0.0 から 4.0 フォーカススレッショルド
CAMERA_PITCH 0 float(角度) 0.0 -45.0 から 80.0 ピッチ角度
CAMERA_POSITION 13 vector(位置) なし n/a カメラポジション
CAMERA_POSITION_LAG 5 float(秒) 0.1 0.0 から 3.0 カメラポジションのラグ
CAMERA_POSITION_LOCKED 21 integer(固定/非固定) FALSE TRUE か FALSE ポジションのロック/アンロック
CAMERA_POSITION_THRESHOLD 10 float(m) 1.0 0.0 から 4.0 ポジションスレッショルド

例えば、カメラ制御を有効にしてズーム距離を10mにするには以下のようなリストを引数として渡します。

llSetCameraParams([
  CAMERA_ACTIVE, 1, 
  CAMERA_DISTANCE, 10.0
]);

カメラ制御を有効にしてデフォルトの設定を遣うときには以下のようにします。

llSetCameraParams([
  CAMERA_ACTIVE, 1,
  CAMERA_BEHINDNESS_ANGLE, 10.0,
  CAMERA_BEHINDNESS_LAG, 0.0,
  CAMERA_DISTANCE, 3.0,
  CAMERA_FOCUS_LAG, 0.1 ,
  CAMERA_FOCUS_LOCKED, FALSE,
  CAMERA_FOCUS_THRESHOLD, 1.0,
  CAMERA_PITCH, 0.0,
  CAMERA_POSITION_LAG, 0.1,
  CAMERA_POSITION_LOCKED, FALSE,
  CAMERA_POSITION_THRESHOLD, 1.0,
  CAMERA_FOCUS_OFFSET, ZERO_VECTOR
]);

こうしてみると、関数の使い方よりも各パラメータの意味を理解することが重要になってくるのがお分かりいただけるかと思います。

ついでにもう一つ二つ、カメラ制御に関わる関数を紹介しておきましょう。

llClearCameraParams関数


 llClearCameraParams()

カメラのパラメータをデフォルトに戻し、制御をOFFにする関数です。
引数はありません。

llReleaseCamera関数


 llReleaseCamera(key agent)

カメラ制御を引数agentに指定したUUIDのアバターに戻します。
つまりカメラ制御を終了するときに使う関数です。

以上、llSetCameraParams関数の引数がややこしい以外は難しい関数はありません。

カメラ制御スクリプト


具体的にカメラ制御を行うLSLを作ってみましょう。
実際に動かしてみるのが一番です。

俯瞰カメラ


簡単なものということで、俯瞰カメラを作ってみます。
上空から見下ろす視点のカメラです。

制御するのはピッチのパラメータになります。
それから高いところから見下ろしている感じを出すために、ディスタンスを最大にします。
また、アバターの回転に合わせてカメラがグルグル回ると酔うと思うので、ビハインドネスを最大にしてカメラが回らないようにしておきます。

default{
  state_entry(){
    if (llGetAttached() != 0){
      llRequestPermissions(llGetOwner(), PERMISSION_CONTROL_CAMERA);
    }
  }

  attach(key agent){
    if (agent != NULL_KEY){
      llRequestPermissions(agent, PERMISSION_CONTROL_CAMERA);
    }else{
      integer perm = llGetPermissions();
      if (perm & PERMISSION_CONTROL_CAMERA){
        llClearCameraParams();
        llReleaseCamera(llGetPermissionsKey());
      }
    }
  } 

  run_time_permissions(integer perm) {
    if (perm & PERMISSION_CONTROL_CAMERA) {
      llSetCameraParams([
        CAMERA_ACTIVE, 1,
        CAMERA_BEHINDNESS_ANGLE, 180.0, 
        CAMERA_DISTANCE, 10.0,
        CAMERA_PITCH, 80.0
      ]);    
    }
  }
}

このサンプルはアタッチメント用です。
何でもいいので適当なオブジェクトを作り、スクリプトを組み込んでアタッチして下さい。

アタッチされたとき、あるいはスクリプト開始時点でアタッチされていた場合にカメラ制御のパーミッションを取得しに行きます。
パーミッションが取得されたら、llSetCameraParams関数を使ってカメラ制御をONにし、ビハインドネスを180度、ディスタンスを10m、ピッチを80度に設定します。
デタッチされたときにはカメラ制御を開放します。

これでカメラは上空からアバターを映すようになります。
回転に応じてカメラは動きませんので、アバターを動かすときには奇異な動作に感じるかもしれません。
アバターの回転に応じてカメラを回したい場合は、CAMERA_BEHINDNESS_ANGLEの設定値を小さくしてやります。

普段とは違う視点を体感できたでしょうか。
カメラ制御を遣うと、このように面白い視界を得ることが可能になります。

固定追尾カメラ


他にも試してみましょう。
ポジションのロックを使用し、カメラの位置を固定しつつアバターの動きを追いかけるカメラを実現してみます。

カメラのポジションはアバターの現在位置から3mほどずらした位置にしてみます。

default{
  state_entry(){
    if (llGetAttached() != 0){
      llRequestPermissions(llGetOwner(), PERMISSION_CONTROL_CAMERA);
    }
  }

  attach(key agent){
    if (agent != NULL_KEY){
      llRequestPermissions(agent, PERMISSION_CONTROL_CAMERA);
    }else{
      integer perm = llGetPermissions();
      if (perm & PERMISSION_CONTROL_CAMERA){
        llClearCameraParams();
        llReleaseCamera(llGetPermissionsKey());
      }
    }
  }

  run_time_permissions(integer perm) {
    if (perm & PERMISSION_CONTROL_CAMERA) {
      llSetCameraParams([
        CAMERA_ACTIVE, 1,
        CAMERA_POSITION, llGetPos() + <-3.0,0,0>, 
        CAMERA_POSITION_LOCKED, TRUE,
        CAMERA_FOCUS_LAG, 0.0
      ]);    
    }
  }
}

変えているのはllSetCameraParams関数の設定パラメータだけです。
CAMERA_POSITIONパラメータでカメラポジションを指定し、CAMERA_POSITION_LOCKEDパラメータをTRUEにしてカメラを固定します。

アバターを動かすと、カメラの位置は固定のまま、アバターの動きに合わせてカメラが向きを変えます。
ALT+クリックによる追尾ともまた違う面白い効果です。

せっかくですのでもう少しパラメータをいじってみましょう。
CAMERA_FOCUS_LAGパラメータの値を3.0にしてみて下さい。

(略)
llSetCameraParams([
  CAMERA_ACTIVE, 1,
  CAMERA_POSITION, llGetPos() + <-3.0,0,0>, 
  CAMERA_POSITION_LOCKED, TRUE,
  CAMERA_FOCUS_LAG, 3.0
]);
(略)

カメラがフォーカスを合わせるときに遅延するようになり、追尾がソフトな動きになります。
すばやく動かすとアバターが画面外に出てしまったりもします(^^;

完全固定カメラ


ポジションのロックと同時にフォーカスにもロックをかけると、完全な固定カメラになります。

default{
  state_entry(){
    if (llGetAttached() != 0){
      llRequestPermissions(llGetOwner(), PERMISSION_CONTROL_CAMERA);
    }
  } 

  attach(key agent){
    if (agent != NULL_KEY){
      llRequestPermissions(agent, PERMISSION_CONTROL_CAMERA);
    }else{
      integer perm = llGetPermissions();
      if (perm & PERMISSION_CONTROL_CAMERA){
        llClearCameraParams();
        llReleaseCamera(llGetPermissionsKey());
      }
    }
  } 

  run_time_permissions(integer perm) {
    if (perm & PERMISSION_CONTROL_CAMERA) {
      llSetCameraParams([
        CAMERA_ACTIVE, 1,
        CAMERA_POSITION, llGetPos() + <-3.0,0,0>, 
        CAMERA_POSITION_LOCKED, TRUE,
        CAMERA_FOCUS, llGetPos(),
        CAMERA_FOCUS_LOCKED, TRUE
      ]);    
    }
  }
}

アバターが画面外に出て行こうが何をしようが、カメラはひらすら定点を映し続けます。
動画の撮影などをする際には便利なカメラ制御です。

カメラの動的制御


パラメータを連続的に変化させることで、動的にカメラを制御することも可能です。
動画などでは左右にぐるぐる回すカメラワークはよく見かけますが、せっかくですのでスクリプトならではの動きを実現してみましょう。
左右ではなく、縦方向に回転するカメラです。
・・・・・・いや、何に使うのか知りませんが(^^;

default{
  state_entry(){
    if (llGetAttached() != 0){
      llRequestPermissions(llGetOwner(), PERMISSION_CONTROL_CAMERA);
    }
  } 

  attach(key agent){
    if (agent != NULL_KEY){
      llRequestPermissions(agent, PERMISSION_CONTROL_CAMERA);
    }else{
      integer perm = llGetPermissions();
      if (perm & PERMISSION_CONTROL_CAMERA){
        llClearCameraParams();
        llReleaseCamera(llGetPermissionsKey());
      }
    }
  }

  run_time_permissions(integer perm) {
    if (perm & PERMISSION_CONTROL_CAMERA) {
      llSetTimerEvent(0.5);
    }
  }

  timer(){
      llSetTimerEvent(10.0);
      float i;
      vector camera_position;
      for (i=0; i< TWO_PI; i+=.05){
        camera_position = llGetPos() + <5, 0, 0> * llEuler2Rot(<i, 0, 0>);
        llSetCameraParams([
          CAMERA_ACTIVE, 1,
          CAMERA_BEHINDNESS_ANGLE, 180.0,
          CAMERA_FOCUS_LAG, 0.1 ,
          CAMERA_POSITION_LAG, 3.0,
          CAMERA_BEHINDNESS_LAG, 0.0,
          CAMERA_POSITION, camera_position
        ]);
      }
  }
}

このスクリプトは10秒ごとに“縦方向”にカメラを回転させます。
カメラが自由に回転できるよう、ビハインドネスを180度にし、ポジションの移動がスムーズになるよう、ポジションラグを大きく設定しています。
しかし・・・酔いそうです・・・。

というわけでいくつかサンプルをのっけてみましたが、他にも面白い視点を設定することができますので試してみて下さい。

名前:
コメント:
記事メニュー
目安箱バナー