View Categories

Uçuş Animasyonları

2 dakika okuma

giriiş #


Bu bölümde, V-Ray tarafından desteklenen bir başka animasyon türünü ele alacağız: uçuş animasyonları. Bu, kameranın sahne içinde “uçtuğu”, örneğin konumunun animasyonla gösterildiği sahneler anlamına gelir. Kullanılan diğer isim ise “yürüyüş” animasyonlarıdır.

Parametreler #


Hafif önbellek #

Işık önbelleği kullanıyorsak, bunu yalnızca tek bir kare için değil, tüm animasyon boyunca hesaplamak en iyisidir. Bunun kesinlikle gerekli olmadığını belirtmekte fayda var – ışık önbelleği her karede hesaplanarak animasyonu işleyebiliriz; ancak, özellikle uzun animasyonlar için, yalnızca bir kez işlemek işleme süresinden tasarruf sağlayacaktır.

Bunun çalışması için, ışık önbelleği ayarları parametre  modunu  Fly-through  ( SettingsLightCache::mode = 1 ) olarak  ayarlamamız gerekiyor. Zaman çizelgesi animasyon aralığının ( SettingsOutput’ta ayarlanan) oluşturmak istediğiniz aralıkla eşleştiğinden emin olun  . Bu önemlidir çünkü ışık önbelleği, fly-through önbelleğini hesaplarken mevcut zaman çizelgesi animasyon aralığına bakacaktır.

Tüm ışık önbelleği örnekleri tüm animasyon karelerine dağıtılacağından, ışık önbelleği  Subdivs  değerini artırmamız gerekecek (örneğin  SettingsLightCache::subdivs = 2000 , varsayılan değer 1000’dir). Tam değer, elde etmek istediğiniz kaliteye ve özel animasyonunuza bağlıdır. Kamera yavaş hareket ediyorsa veya yol nispeten kısa ise (örneğin bir evin sadece bir odası), örneklerin çoğu zaten aynı yere düşeceğinden daha düşük bir Subdivs değeri kullanabilirsiniz. Kamera hızlı hareket ediyorsa veya sahnenin daha büyük bölümlerini kapsıyorsa, her yerde yeterli kapsama alanı elde etmek için daha fazla örneğe ihtiyacınız olacaktır.

İşte dokümanlardan alınan Uçuş Modu açıklaması: “Uçuş Modu – Kameranın konumu/yönü dışında hiçbir şeyin değişmediğini varsayarak, tüm uçuş animasyonu için bir ışık önbelleği hesaplar. Yalnızca aktif zaman dilimindeki kamera hareketi dikkate alınır.  Uçuş animasyonları için Ölçeği Dünya  Çapına   ( SettingsLightCache::world_scale = true ) ayarlamanın daha iyi olabileceğini unutmayın. Tüm animasyonlu sekans için ışık önbelleği yalnızca ilk oluşturulan karede hesaplanır ve sonraki kareler için değişiklik yapılmadan yeniden kullanılır.”

GI ile ilgili daha sonraki bir bölümde hafif önbellek parametrelerini ayrıntılı olarak ele alacağız.

Animasyon oluşturmada tercih edilen yöntem, birincil/ikincil motor olarak Brute force/Light cache veya Brute force/Brute force kullanmaktır.

Örnek #

Yukarıdaki animasyon, sahne paketindeki “Animated_Camera.vrscene” dosyasının işlenmesiyle oluşturulmuştur  . Animasyonda GI’nin nasıl daha verimli kullanılabileceğini görmek için dosya içindeki ve dahil edilen yorumları inceleyin.

Kod Örneği #


Bu örnek, önceki bölümdeki örneğe benzer, ancak bir nesneyi canlandırmak yerine, renderView’ın konumunu canlandıracağız. Burada, AppSDK 6 ve üzeri sürümlerde bulunan Animation2 API’si kullanılmaktadır.

Animation2 API, özellikle animasyonlu parametre değerlerinde render işlemi sırasında değişiklikler uygulanırken oldukça kullanışlıdır. Bu durumda, renderer.setCurrentTime(t) ile geçerli zamanı/kareyi değiştirmeye gerek yoktur .

# Compatibility with Python 2.7.
from __future__ import print_function
 
# The directory containing the vray shared object should be present in the PYTHONPATH environment variable.
# Try to import the vray module from VRAY_SDK/python, if it is not in PYTHONPATH
import sys, os
VRAY_SDK = os.environ.get('VRAY_SDK')
if VRAY_SDK:
    sys.path.append(os.path.join(VRAY_SDK, 'python'))
import vray
 
startFrame = 1
endFrame = 20
SCENE_PATH = os.path.join(os.environ.get('VRAY_SDK'), 'scenes')
# Change process working directory to SCENE_PATH in order to be able to load relative scene resources.
os.chdir(SCENE_PATH)
 
def updateNextFrameRenderView(renderer, startFrame):
    # Next frame to be updated
    frameToUpdate = renderer.frame + 1 if renderer.frame > 0 else startFrame + 1
    # t corresponds to the time of the next frame to be rendered
    t = frameToUpdate / renderer.classes.SettingsOutput.getInstanceOrCreate().frames_per_second
    # Obtain a reference to the 'RenderView' plugin.
    renderView = renderer.classes.RenderView.getInstanceOrCreate()
    # Obtain a copy of the renderView transform at time t.
    updatedTransform = renderView.getValue('transform', t)
    # Modify the copy of the renderView transform.
    # The changes do not affect the scene directly since updatedTransform is a copy of the actual transform.
    updatedTransform = updatedTransform.replaceOffset(updatedTransform.offset + vray.Vector(0, 0, 3 * t))
    # Update the transform value in renderView at time t (applying the changes above).
    # NOTE: Animation2 API is particularly useful, in the case when 
    # applying changes to animated parameter values during rendering.
    # In this case, there's no need to change the current time/frame with renderer.time = t
    renderView.setValue('transform', updatedTransform, t)
 
def onStateChanged(renderer, oldState, newState, instant):
    if newState == vray.RENDERER_STATE_IDLE_FRAME_DONE or newState == vray.RENDERER_STATE_IDLE_DONE:
        print('Image Ready, frame ' + str(renderer.frame) + ' (sequenceEnd = ' + str(renderer.sequenceEnded) + ')')
        if newState == vray.RENDERER_STATE_IDLE_FRAME_DONE:
            # Prepare the renderView of the next frame to be rendered
            updateNextFrameRenderView(renderer, startFrame)
            # If the sequence has NOT finished - continue with next frame.
            renderer.continueSequence()
 
# Create an instance of VRayRenderer with default options.
# The renderer is automatically closed after the `with` block.
with vray.VRayRenderer() as renderer:
    # Register a simple log callback. Always useful for debugging.
    def dumpMsg(renderer, message, level, instant):
        if level == vray.LOGLEVEL_ERROR:
            print("[ERROR]", message)
        elif level == vray.LOGLEVEL_WARNING:
            print("[Warning]", message)
        elif level == vray.LOGLEVEL_INFO:
            print("[info]", message)
        # Uncomment for testing, but you might want to ignore these in real code
        #else: print("[debug]", message)
    renderer.setOnLogMessage(dumpMsg)
    # Add a listener for the renderer state change event.
    # We will use it to detect when a frame is completed and allow the next one to start.
    renderer.setOnStateChanged(onStateChanged)
    # Load scene from a file.
    renderer.load(os.path.join(SCENE_PATH, 'animation.vrscene'))
    # Maximum paths per pixel for interactive mode. Set a low sample level to complete rendering faster.
    # The default value is unlimited. We have to call this *after* loading the scene.
    renderer.setInteractiveSampleLevel(1)
    # NOTE: 'useAnimatedValues' is not necessary to be set, in case only Animation2 API is used
    # renderer.useAnimatedValues = True
    # Prepare the renderView of the next frame to be rendered
    updateNextFrameRenderView(renderer, startFrame)
    # Set 'start' and 'end' of the sequence. 'step' is omitted and defaults to 1.
    # For all possible use cases of 'renderSequence' check the documentation for VRayRenderer.renderSequence.
    renderer.renderSequence({'start': startFrame, 'end': endFrame})
    # Wait until the entire sequence has finished rendering.
    renderer.waitForSequenceEnd()
#define VRAY_RUNTIME_LOAD_PRIMARY
#include "vraysdk.hpp"
#include "vrayplugins.hpp"
#include "utils.h"
 
using namespace VRay;
using namespace VRay::Plugins;
using namespace std;
 
const char *BASE_PATH = getenv("VRAY_SDK");
string SCENE_PATH = (BASE_PATH ? string(BASE_PATH) : string(".")) + PATH_DELIMITER + "scenes";
const int startFrame = 1;
const int endFrame = 20;
 
void updateNextFrameRenderView(VRayRenderer &renderer, const int startFrame) {
const int currentFrame = renderer.getCurrentFrame();
// Next frame to be updated
const int frameToUpdate = (currentFrame > 0) ? (currentFrame + 1) : (startFrame + 1);
// t corresponds to the time of the next frame to be rendered
const double t = frameToUpdate / renderer.getInstanceOrCreate<SettingsOutput>().get_frames_per_second();
// Obtain a reference to the 'RenderView' plugin.
RenderView renderView = renderer.getInstanceOrCreate<RenderView>();
// Obtain a copy of the renderView transform at time t.
Transform updatedTransform = renderView.get_transform(t);
// Modify the copy of the renderView transform.
// The changes do not affect the scene directly since updatedTransform is a copy of the actual transform.
updatedTransform.offset += Vector(0.0, 0.0, 3 * t);
// Update the transform value in renderView at time t (applying the changes above).
// NOTE: Animation2 API is particularly useful, in the case when 
// applying changes to animated parameter values during rendering.
// In this case, there's no need to change the current time/frame with renderer.setCurrentTime(t)
renderView.set_transform(updatedTransform, t);
}
 
void onStateChanged(VRayRenderer &renderer, RendererState oldState, RendererState newState, double instant, void* userData) {
if (newState == IDLE_FRAME_DONE || newState == IDLE_DONE) {
printf("Image Ready, frame %d (sequenceEnded = %d)\
", renderer.getCurrentFrame(), renderer.isSequenceEnded());
if (newState == IDLE_FRAME_DONE) {
// Prepare the renderView of the next frame to be rendered
updateNextFrameRenderView(renderer, startFrame);
// If the sequence has NOT finished - continue with next frame.
renderer.continueSequence();
}
}
}
 
int main() {
// Change process working directory to SCENE_PATH in order to be able to load relative scene resources.
changeCurrentDir(SCENE_PATH.c_str());
// Load V-Ray SDK library.
VRayInit init(NULL, true);
// Create an instance of VRayRenderer with default options.
// The renderer is automatically closed at the end of the current scope.
VRayRenderer renderer;
// It's recommended to always have a console log
renderer.setOnLogMessage(logMessage);
// Add a listener for the renderer state change event.
// We will use it to detect when a frame is completed and allow the next one to start.
renderer.setOnStateChanged(onStateChanged);
// Load scene from a file.
renderer.load("animation.vrscene");
// Maximum paths per pixel for interactive mode. Set a low sample level to complete rendering faster.
// The default value is unlimited. We have to call this *after* loading the scene.
renderer.setInteractiveSampleLevel(1);
// NOTE: 'useAnimatedValues' is not necessary to be set, in case only Animation2 API is used
// renderer.useAnimatedValues(true);
// Prepare the renderView of the next frame to be rendered
updateNextFrameRenderView(renderer, startFrame);
// Set 'start' and 'end' of the sequence.
// For all possible use cases of 'renderSequence' check the documentation for VRayRenderer.renderSequence.
SubSequenceDesc subSequenceDescriptions[1];
subSequenceDescriptions[0].start = startFrame;
subSequenceDescriptions[0].end = endFrame;
subSequenceDescriptions[0].step = 1;
renderer.renderSequence(subSequenceDescriptions, 1);
// Wait until the entire sequence has finished rendering.
renderer.waitForSequenceEnd();
return 0;
}
using System;
using System.IO;
using VRay;
using VRay.Plugins;
 
namespace _03_animation2_api
{
class Program
{
const int startFrame = 1;
const int endFrame = 20;
static void UpdateNextFrameRenderView(VRayRenderer renderer, int startFrame)
{
// Next frame to be updated
int frameToUpdate = (renderer.Frame > 0) ? (renderer.Frame + 1) : (startFrame + 1);
// t corresponds to the time of the next frame to be rendered
double t = frameToUpdate / renderer.GetInstanceOrCreate<SettingsOutput>().FramesPerSecond;
// Obtain a reference to the 'RenderView' plugin.
RenderView renderView = renderer.GetInstanceOrCreate<RenderView>();
// Obtain a copy of the renderView transform at time t.
Transform updatedTransform = renderView.Get_Transform(t);
// Modify the copy of the renderView transform.
// The changes do not affect the scene directly since updatedTransform is a copy of the actual transform.
updatedTransform = updatedTransform.ReplaceOffset(updatedTransform.Offset + new Vector(0, 0, 3 * t));
// Update the transform value in renderView at time t (applying the changes above).
// NOTE: Animation2 API is particularly useful, in the case when 
// applying changes to animated parameter values during rendering.
// In this case, there's no need to change the current time/frame with renderer.Time = t
renderView.Set_Transform(updatedTransform, t);
}
 
static void Main(string[] args)
{
string SCENE_PATH = Path.Combine(Environment.GetEnvironmentVariable("VRAY_SDK"), "scenes");
// Change process working directory to SCENE_PATH in order to be able to load relative scene resources.
Directory.SetCurrentDirectory(SCENE_PATH);
// Create an instance of VRayRenderer with default options. The renderer is automatically closed after the `using` block.
using (VRayRenderer renderer = new VRayRenderer())
{
// Add a listener for any type of log message.
renderer.LogMessage += new EventHandler<MessageEventArgs>((source, e) =>
{
// You can remove the if for testing, but you might want to ignore Debug in real code
if (e.LogLevel != LogLevelType.Debug)
{
Console.WriteLine(String.Format("[{0}] {1}", e.LogLevel.ToString(), e.Message));
}
});
// Add a listener for state changes.
// It is invoked when the renderer prepares for rendering, renders, finishes or fails.
renderer.StateChanged += new EventHandler<StateChangedEventArgs>((source, e) =>
{
if (e.NewState == VRayRenderer.RendererState.IDLE_FRAME_DONE || e.NewState == VRayRenderer.RendererState.IDLE_DONE)
{
Console.WriteLine("Image Ready, frame " + renderer.Frame + " (sequenceEnded = " + renderer.IsSequenceEnded + ")");
 
// Prepare the renderView of the next frame to be rendered
UpdateNextFrameRenderView(renderer, startFrame);
// If the sequence has NOT finished - continue with next frame.
renderer.ContinueSequence();
}
});
// Load scene from a file.
renderer.Load("animation.vrscene");
// Maximum paths per pixel for interactive mode. Set a low sample level to complete rendering faster.
// The default value is unlimited. We have to call this *after* loading the scene.
renderer.SetInteractiveSampleLevel(1);
// NOTE: 'UseAnimatedValues' is not necessary to be set, in case only Animation2 API is used
// renderer.UseAnimatedValues = true;
// Prepare the renderView of the next frame to be rendered
UpdateNextFrameRenderView(renderer, startFrame);
// Set 'start' and 'end' of the sequence. 'step' is omitted and defaults to 1.
// For all possible use cases of 'renderSequence' check the documentation for VRayRenderer.renderSequence.
renderer.RenderSequence(new SubSequenceDesc[] { new SubSequenceDesc(startFrame, endFrame) });
// Wait until the entire sequence has finished rendering.
renderer.WaitForSequenceEnd();
}
}
}
}
var path = require('path');
var vray = require(path.join(process.env.VRAY_SDK, 'node', 'vray'));
var SCENE_PATH = path.join(process.env.VRAY_SDK, 'scenes');
const startFrame = 1;
const endFrame = 20;
 
function updateNextFrameRenderView(renderer, startFrame) {
// Next frame to be updated
var frameToUpdate = (renderer.frame > 0) ? (renderer.frame + 1) : (startFrame + 1);
// t corresponds to the time of the next frame to be rendered
var t = frameToUpdate / renderer.classes.SettingsOutput.getInstanceOrCreate().frames_per_second;
// Obtain a reference to the 'RenderView' plugin.
var renderView = renderer.classes.RenderView.getInstanceOrCreate()
// Obtain a copy of the renderView transform at time t.
var updatedTransform = renderView.getValue("transform", t);
// Modify the copy of the renderView transform.
// The changes do not affect the scene directly since updatedTransform is a copy of the actual transform.
updatedTransform = updatedTransform.replaceOffset(updatedTransform.offset.add(vray.Vector(0, 0, 3 * t)));
// Update the transform value in renderView at time t (applying the changes above).
// NOTE: Animation2 API is particularly useful, in the case when 
// applying changes to animated parameter values during rendering.
// In this case, there's no need to change the current time/frame with renderer.time = t
renderView.setValue("transform", updatedTransform, t);
}
 
// Change process working directory to SCENE_PATH in order to be able to load relative scene resources.
process.chdir(SCENE_PATH);
// Create an instance of VRayRenderer with default options.
var renderer = vray.VRayRenderer();
// It's recommended to always have a console log callback
renderer.on("logMessage", function (message, level, instant) {
if (level == vray.LOGLEVEL_ERROR)
console.log("[ERROR] ", message);
else if (level == vray.LOGLEVEL_WARNING)
console.log("[Warning] ", message);
else if (level == vray.LOGLEVEL_INFO)
console.log("[info] ", message);
// Uncomment for testing, but you might want to ignore these in real code
//else console.log("[debug] ", message);
});
// Add a listener for the renderer state change event.
// We will use it to detect when a frame is completed and allow the next one to start.
renderer.on("stateChanged", function (oldState, newState, instant) {
if (newState == "idleFrameDone" || newState == "idleDone") {
console.log("Image Ready, frame " + renderer.frame + " (sequenceEnd = " + renderer.sequenceEnded + ")");
// Check if the sequence has finished rendering.
if (newState == "idleDone") {
// Closes the renderer.
renderer.close();
} else {
// Prepare the renderView of the next frame to be rendered
updateNextFrameRenderView(renderer, startFrame);
// If the sequence has NOT finished - continue with next frame.
renderer.continueSequence();
}
} else if (newState.startsWith("idle")) {
console.log("Unexpected end of render sequence: ", newState);
renderer.close();
}
});
 
// Load scene from a file asynchronously.
renderer.load("animation.vrscene", function (err) {
if (err) throw err;
// Maximum paths per pixel for interactive mode. Set a low sample level to complete rendering faster.
// The default value is unlimited. We have to call this *after* loading the scene.
renderer.setInteractiveSampleLevel(1);
// NOTE: "useAnimatedValues" is not necessary to be set, in case only Animation2 API is used
// renderer.useAnimatedValues = true;
// Prepare the renderView of the next frame to be rendered
updateNextFrameRenderView(renderer, startFrame);
// Set "start" and "end" of the sequence.
// "step" is omitted and defaults to 1.
// For all possible use cases of "renderSequence" check the documentation
renderer.renderSequence({ "start": startFrame, "end": endFrame });
// Prevent garbage collection and exiting nodejs until the renderer is closed.
renderer.keepAlive();
});

 

Tarafından desteklenmektedir BetterDocs

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir