Rendering学習日記

日々3DCGの世界は進歩しているけど、勉強して理解したことをまとめていきたい。RenderMan互換レンダラーやグローバル・イルミネーション。いろんなことに好奇心を持ち面白くなってくる。目指せShader書き!!

Lightflow C API sample cornell box

main8.cpp
#includeの両側に半角スペースが入っています。


#include < Lightflow/LfLocalSceneProxy.h >

int main()
{
LfLocalSceneProxy* s = new LfLocalSceneProxy();
LfArgList list;
LfTransform trs;

list.Reset();
list << "trace-depth" << LfInt( 6 );
list << "radiosity-samples" << LfInt( 400 );
list << "radiosity-threshold" << 0.1;
list << "radiosity-reuse-distance" << 0.25, 0.4, 0.01;
list << "photon-count" << LfInt( 300000 );
list << "photon-clustering-count" << LfInt( 2000 ) << LfInt( 100 );
s->NewInterface( "default", list );

// the "trace-depth" attribute controls the maximal number of ray-traced
// light bounces.
// the "radiosity-depth" attribute controls the maximal number of
// radiosity iterations, that is to say the number of bounces of the indirect
// illumination.
// the "radiosity-samples" attribute sets the amount of rays that are
// used to sample the light space at every surface location. Normally
// values between 200 and 500 produce good results. Note that this parameter
// is very influent on the rendering time, since light sampling is one
// of the most time consuming tasks.
// "radiosity-threshold" sets the maximal error bound in the radiosity
// estimation. A value of 0.1 means that the error is allowed to be 10%
// of the real value.
// "radiosity-reuse-distance" sets the screen, maximum and minimum distance
// from different sampling locations. This parameter is the only one that
// must be set accordingly to the scene size. The smaller these values are,
// the better the result will be, but usually a good value for the
// screen distance is from 0.2 to 0.5, while a good value for the
// maximum distance is everything greater than one fifth of the length
// of the visible surfaces.
// In this case we are modeling a room with sides 2 unities long, hence
// a value of 0.4 will prove to be good enough. The minimum distance
// should be an order of magnitude less.
// should be an order of magnitude less.
// The "photon-count" parameter controls the amount of photons that are
// spread into the scene to compute the global illumination. Obviously
// more photons means better approximations and longer times.


list.Reset();
list << "position" << LfPoint( 0, 0, 0.98 );
list << "direction" << LfVector3( 0, 0, -1 );
list << "angle" << 0.0 << PI / 2.0;
list << "radius" << 0.05;
list << "samples" << LfInt( 7 );
list << "color" << LfColor( 8, 8, 8 );
s->LightOn( s->NewLight( "soft-conic", list ) );

// We simulate an area light with a conic light that produces soft
// shadows. The spreading angle of the light is set to 90 degrees
// (PI / 2 in radians) to obtain the same light distribution of a patch
// light source. We could also put a real "patch" light, with a well
// defined surface, but the computation times would have been longer.
// Check the class documentation to see how area lights work, and how
// fake soft shadows may be obtained with the "soft" and "soft-conic" types.


list.Reset();
list << "kc" << LfColor( 3, 3, 3 );
list << "shadowing" << 0.0;
LfInt neon = s->NewMaterial( "matte", list );

list.Reset();
list << "kdr" << LfColor( 0.9, 0.9, 0.9 );
list << "ksr" << LfColor( 0.5, 0.5, 0.5 );
list << "km" << 0.07;
list << "shinyness" << 1.0;
list << "radiosity" << LfInt( 1 );
list << "caustics" << LfInt( 0 ) << LfInt( 0 );
LfInt whitewash = s->NewMaterial( "generic", list );

list.Reset();
list << "kdr" << LfColor( 0.8, 0.1, 0.1 );
list << "ksr" << LfColor( 0.5, 0.5, 0.5 );
list << "km" << 0.07;
list << "shinyness" << 1.0;
list << "radiosity" << LfInt( 1 );
list << "caustics" << LfInt( 0 ) << LfInt( 0 );
LfInt redwash = s->NewMaterial( "generic", list );

list.Reset();
list << "kdr" << LfColor( 0.2, 0.3, 0.8 );
list << "ksr" << LfColor( 0.5, 0.5, 0.5 );
list << "km" << 0.07;
list << "shinyness" << 1.0;
list << "radiosity" << LfInt( 1 );
list << "caustics" << LfInt( 0 ) << LfInt( 0 );
LfInt bluewash = s->NewMaterial( "generic", list );

list.Reset();
list << "kdr" << LfColor( 0.9, 0.9, 0.9 );
list << "ksr" << LfColor( 0.5, 0.5, 0.5 );
list << "km" << 0.07;
list << "shinyness" << 1.0;
list << "radiosity" << LfInt( 1 );
list << "caustics" << LfInt( 0 ) << LfInt( 0 );
list << "visibility" << LfInt( 1 );
LfInt trnswash = s->NewMaterial( "generic", list );

list.Reset();
list << "fresnel" << LfInt( 1 );
list << "IOR" << 9.0;
list << "kr" << LfColor( 1, 1, 1 );
list << "kt" << LfColor( 1, 1, 1 );
list << "kd" << 0.0;
list << "km" << 0.02;
list << "shinyness" << 1.0;
list << "radiosity" << LfInt( 0 );
list << "caustics" << LfInt( 2 ) << LfInt( 2 );
LfInt metal = s->NewMaterial( "physical", list );

list.Reset();
list << "fresnel" << LfInt( 1 );
list << "IOR" << 1.57;
list << "kdr" << LfColor( 0, 0, 0 );
list << "kdt" << LfColor( 0, 0, 0 );
list << "ksr" << LfColor( 1, 1, 1 ) << LfColor( 0.5, 0.8, 1 );
list << "kst" << LfColor( 1, 1, 1 ) << LfColor( 1, 0.6, 0.2 );
list << "kr" << LfColor( 1, 1, 1 );
list << "kt" << LfColor( 1, 1, 1 );
list << "km" << 0.02;
list << "shinyness" << 1.0;
list << "radiosity" << LfInt( 0 );
list << "caustics" << LfInt( 2 ) << LfInt( 2 );
LfInt glass = s->NewMaterial( "generic", list );


s->MaterialBegin( whitewash );

list.Reset();
list << "points"
<< LfVector3( -0.25, -0.25, 0.995 ) << LfVector3( 0.25, -0.25, 0.995 )
<< LfVector3( -0.25, 0.25, 0.995 ) << LfVector3( 0.25, 0.25, 0.995 );
s->AddObject( s->NewObject( "patch", list ));

list.Reset();
list << "points"
<< LfVector3( -0.25, 0.25, 0.99 ) << LfVector3( 0.25, 0.25, 0.99 )
<< LfVector3( -0.25, 0.25, 1.00 ) << LfVector3( 0.25, 0.25, 1.00 );
s->AddObject( s->NewObject( "patch", list ));

list.Reset();
list << "points"
<< LfVector3( -0.25, -0.25, 0.99 ) << LfVector3( -0.25, -0.25, 1.00 )
<< LfVector3( 0.25, -0.25, 0.99 ) << LfVector3( 0.25, -0.25, 1.00 );
s->AddObject( s->NewObject( "patch", list ));

list.Reset();
list << "points"
<< LfVector3( 0.25, -0.25, 0.99 ) << LfVector3( 0.25, -0.25, 1.00 )
<< LfVector3( 0.25, 0.25, 0.99 ) << LfVector3( 0.25, 0.25, 1.00 );
s->AddObject( s->NewObject( "patch", list ));

list.Reset();
list << "points"
<< LfVector3( -0.25, -0.25, 0.99 ) << LfVector3( -0.25, 0.25,
0.99 )
<< LfVector3( -0.25, -0.25, 1.00 ) << LfVector3( -0.25, 0.25, 1.00 );
s->AddObject( s->NewObject( "patch", list ));

s->MaterialEnd();

s->MaterialBegin( neon );

list.Reset();
list << "points"
<< LfVector3( -0.25, -0.25, 0.99 ) << LfVector3( 0.25, -0.25, 0.99 )
<< LfVector3( -0.25, 0.25, 0.99 ) << LfVector3( 0.25, 0.25, 0.99 );
s->AddObject( s->NewObject( "patch", list ));

s->MaterialEnd();

s->MaterialBegin( trnswash );

list.Reset();
list << "points"
<< LfVector3( -1, -1, -1 ) << LfVector3( 1, -1, -1 )
<< LfVector3( -1, -1, 1 ) << LfVector3( 1, -1, 1 );
s->AddObject( s->NewObject( "patch", list ));

s->MaterialEnd();

s->MaterialBegin( whitewash );

list.Reset();
list << "points"
<< LfVector3( -1, -1, -1 ) << LfVector3( -1, 1, -1 )
<< LfVector3( 1, -1, -1 ) << LfVector3( 1, 1, -1 );
s->AddObject( s->NewObject( "patch", list ));

list.Reset();
list << "points"
<< LfVector3( -1, -1, 1 ) << LfVector3( 1, -1, 1 )
<< LfVector3( -1, 1, 1 ) << LfVector3( 1, 1, 1 );
s->AddObject( s->NewObject( "patch", list ));

list.Reset();
list << "points"
<< LfVector3( -1, 1, -1 ) << LfVector3( -1, 1, 1 )
<< LfVector3( 1, 1, -1 ) << LfVector3( 1, 1, 1 );
s->AddObject( s->NewObject( "patch", list ));

s->MaterialEnd();

s->MaterialBegin( redwash );

list.Reset();
list << "points"
<< LfVector3( -1, -1, -1 ) << LfVector3( -1, -1, 1 )
<< LfVector3( -1, 1, -1 ) << LfVector3( -1, 1, 1 );
s->AddObject( s->NewObject( "patch", list ));

s->MaterialEnd();

s->MaterialBegin( bluewash );

list.Reset();
list << "points"
<< LfVector3( 1, -1, -1 ) << LfVector3( 1, 1, -1 )
<< LfVector3( 1, -1, 1 ) << LfVector3( 1, 1, 1 );
s->AddObject( s->NewObject( "patch", list ));

s->MaterialEnd();


s->MaterialBegin( glass );

s->TransformBegin( trs.Translation( LfVector3( -0.45, 0, -0.1 ) ) );

list.Reset();
list << "radius" << 0.35;
s->AddObject( s->NewObject( "sphere", list ) );

s->TransformEnd();

s->MaterialEnd();


s->MaterialBegin( metal );

s->TransformBegin( trs.Translation( LfVector3( 0.45, 0.4, -0.65 ) )
);

list.Reset();
list << "radius" << 0.35;
s->AddObject( s->NewObject( "sphere", list ) );

s->TransformEnd();

s->MaterialEnd();


list.Reset();
list << "file" << "cornell.tga";
LfInt saver = s->NewImager( "tga-saver", list );

s->ImagerBegin( saver );

list.Reset();
list << "eye" << LfPoint( 0, -2.99, 0 );
list << "aim" << LfPoint( 0, 0, 0 );
LfInt camera = s->NewCamera( "pinhole", list );

s->ImagerEnd();

s->Render( camera, 300, 300 );

delete s;
}


$ /usr/local/gcc-2.95/bin/g++ -I ./include -lLightflow main8.cpp -o simplescene8
$ ./simplescene8
$ convert cornell.tga cornell.jpg
$ eog cornell.jpg
cornell.jpg
Lightflow | - | -

Lightflow C API sample ocean

main6.cpp
#includeの両側に半角スペースが入っています。


#include < Lightflow/LfLocalSceneProxy.h >
int main()
{
LfLocalSceneProxy* s = new LfLocalSceneProxy();
LfArgList list;
LfTransform trs;

// Specify some rendering settings. These values are used by
// all the built-in types, so they are grouped under a unique
// interface, named "default".
list.Reset();
list << "trace-depth" << LfInt( 5 );
list << "lighting-depth" << LfInt( 3 );
s->NewInterface( "default", list );

// Make a bright, bright light to model the sun.
list.Reset();
list << "position" << LfPoint( 0, 900, 100 );
list << "color" << LfColor( 60000.0, 60000.0, 60000.0 );
s->LightOn( s->NewLight( "point", list ) );


// Model the water waves with a fractal pattern.
s->TransformBegin( trs.Scaling( LfVector3( 10, 5, 5 ) ) );

list.Reset();
list << "basis" << "sin";
list << "scale" << 2.0;
list << "depth" << 0.1;
list << "turbulence.distortion" << 1.0;
list << "turbulence.omega" << 0.1 << 0.3;
list << "turbulence.lambda" << 2.0;
list << "turbulence.octaves" << LfInt( 5 );
LfInt waterbumps = s->NewPattern( "multifractal", list );

// the "basis" value describes the fractal basis, that here is set to
// "sin", as waves have a sinusoidal origin.
// "scale" represents the width of the waves. This factor is then
// multiplied by the scaling transform we put before.
// "depth" represents the depth of the waves, when used to displace a
// surface.
// the "turbulence." keywords are turbulence parameters, that are
// explained in the "multifractal" documentation.

s->TransformEnd();

// Model water with a material.
list.Reset();
list << "fresnel" << LfInt( 1 ) << LfFloat(0.3) << LfFloat(0.0);
list << "IOR" << 1.33;
list << "kr" << LfColor( 1, 1, 1 );
list << "kt" << LfColor( 1, 1, 1 );
list << "kd" << 0.0;
list << "km" << 0.03;
list << "shinyness" << 0.5;
list << "displacement" << waterbumps;
LfInt water = s->NewMaterial( "physical", list );

// the choosed type is "physical", because this provides physical
// parameters, very good to model liquids, glasses and metals.
// note the use of the waterbumps pattern as a displacement.


// Model the ocean fundals in a similar way.
list.Reset();
list << "basis" << "sin";
list << "scale" << 10.0;
list << "depth" << 0.5;
list << "turbulence.distortion" << 1.0;
list << "turbulence.omega" << 0.1 << 0.3;
list << "turbulence.lambda" << 2.0;
list << "turbulence.octaves" << LfInt( 5 );
LfInt earthbumps = s->NewPattern( "multifractal", list );

list.Reset();
list << "kr" << LfColor( 0.8, 0.75, 0.7 );
list << "displacement" << earthbumps;
LfInt earth = s->NewMaterial( "diffuse", list );


// Here starts the sky.
// It contains a lot of volumetric clouds, especially at the horizon,
// so it is a bit complex.

// Volumetric clouds are modeled with an interior and a pattern that modulates its density.
s->TransformBegin( trs.Scaling( LfVector3( 100, 100, 100 ) ) );
s->TransformBegin( trs.Translation( LfVector3( 0, 0, -0.5 ) ) );

list.Reset();
list << "value"
<< 0.0 << 1.0 << 1.0
<< 0.3 << 0.0 << 0.0;
list << "scale" << 1.0;
list << "turbulence.distortion" << 1.0;
list << "turbulence.omega" << 0.5 << 0.8;
list << "turbulence.lambda" << 2.0;
list << "turbulence.octaves" << LfInt( 3 );
LfInt cloudpattern = s->NewPattern( "multifractal", list );

// Make the output distribution go from 1 to 0.1 to model clouds.

s->TransformEnd();
s->TransformEnd();

list.Reset();
list << "kr" << LfColor( 2.0, 0.8, 0.4 );
list << "kaf" << LfColor( 0.6, 0.8, 0.4 ) * 0.035;
list << "density" << 1.0;
list << "density" << cloudpattern;
list << "sampling" << 0.07;
list << "shadow-caching" << LfPoint( -1000, -1000, -1 ) << LfPoint(1000, 1000, 100 );
list << "density-caching" << LfInt( 2048 ) << LfPoint( -1000, -1000, -1 ) << LfPoint( 1000, 1000, 100 );
list << "density-caching" << LfInt( 2048 ) << LfPoint( -1.2, -1.2, -1.2 ) << LfPoint( 1.2, 1.2, 1.2 );
LfInt cloudinterior = s->NewInterior( "cloud", list );

// Note that our scene will have a radius of 1000 unities, and our
// camera would be at its center, so with a sampling factor of 0.07 we
// allow 70 samples per ray: an enormous quantity! This will make our
// scene render slowly, but the caches will give a help. Obviously if
// you remove these volumetric clouds the rendering will be much faster.
// Here we don't care about speed however, since we want only to
// produce a single, astonishing image...


// Now model the fundal, a blue sky made of flat clouds that will be
// wrapped on a sphere.

list.Reset();
list << "color"
<< 0.2 << LfColor( 0.8, 0.9, 1.0 ) << LfColor( 0.8, 0.9, 1.0 )
<< 1.0 << LfColor( 0.2, 0.4, 0.9 ) << LfColor( 0.2, 0.4, 0.9 );
LfInt skypattern1 = s->NewPattern( "linear-v", list );

s->TransformBegin( trs.Scaling( LfVector3(80, 80, 10) ) );

list.Reset();
list << "color"
<< 0.2 << LfColor( 0.2, 0.4, 0.9 ) << LfColor( 0.2, 0.4, 0.9 )
<< 1.0 << LfColor( 0.2, 0.3, 0.7 ) << LfColor( 0.2, 0.3, 0.7 );
list << "scale" << 1.1;
list << "turbulence.distortion" << 1.0;
list << "turbulence.omega" << 0.5 << 0.8;
LfInt skypattern2 = s->NewPattern( "multifractal", list );

s->TransformEnd();

list.Reset();
list << "pattern" << skypattern1;
list << "gradient"
<< 0.3 << skypattern1 << skypattern1
<< 1.0 << skypattern2 << skypattern2;
LfInt skypattern = s->NewPattern( "blend", list );

// Note that we actually created two patterns, and we merged them
// together with a "blend".
// The first pattern is a linear gradient that will span the V
// direction of the parametric surface we will attach it to.
// In this case we will use it on a sphere, where the V direction is
// the one which connects the north and south poles (that is to say a
// line of constant U and varying V is a meridian).
// This gradient associates a color to each parallel of the sphere,
// going from bright blue near the horizon to dark blue near the
// azimuth.
// The second pattern is again a "multifractal", which we use to model
// very distant clouds. Note that we stretch it with a scaling, so that
// the clouds will look wide and thin.
// The "blend" pattern finally blends the two. It uses the pattern
// specified with "pattern" to mix more patterns. In particular it
// defines a pattern-gradient that smoothly interpolates between
// different patterns. In this case we use the linear pattern both to
// model the distribution of the gradient and to model the gradient
// itself.
// The numeric value of the linear pattern has not been specified
// (with a value-gradient), and so it goes from 0 to 1, as default.
// Thus the "blend" will make a transition that goes from a clear
// and bright sky near the horizon (at the V value of 0.3) to a cloudy
// sky near the azimuth (at the V value of 1.0).

// Create the sky material.
s->InteriorBegin( cloudinterior );

list.Reset();
list << "kc" << LfColor(1.0, 1.0, 1.0);
list << "kc" << skypattern;
list << "shadowing" << LfFloat(0.0);
LfInt sky = s->NewMaterial( "matte", list );

s->InteriorEnd();

// "matte" is a material made to create matte objects, that are not
// shaded by light, but that emit a uniform color. In this case this
// color is first set to white (1, 1, 1) and then scaled by the skypattern.
// The result will be the skypattern itself.


// Create a water disc.
s->MaterialBegin( water );

list.Reset();
list << "radius" << 1000.0;
s->AddObject( s->NewObject( "disc", list ));

s->MaterialEnd();


// Create an under-water disc made of earth.
s->TransformBegin( trs.Translation( LfVector3( 0, 0, -10 ) ) );

s->MaterialBegin( earth );

list.Reset();
list << "radius" << 1000.0;
s->AddObject( s->NewObject( "disc", list ));

s->MaterialEnd();

s->TransformEnd();


// Create the sky sphere.
s->TransformBegin( trs.Scaling( LfVector3( 1, 1, 0.1 ) ) );

s->MaterialBegin( sky );

list.Reset();
list << "radius" << 1000.0;
s->AddObject( s->NewObject( "sphere", list ));

s->MaterialEnd();

s->TransformEnd();


list.Reset();
list << "file" << "ocean.tga";
LfInt saver = s->NewImager( "tga-saver", list );

s->ImagerBegin( saver );

list.Reset();
list << "eye" << LfPoint( 0, -8, 4 );
list << "aim" << LfPoint( 0, 0, 4 );
list << "aa-samples" << LfInt( 2 ) << LfInt( 5 );
LfInt camera = s->NewCamera( "pinhole", list );

s->ImagerEnd();

s->Render( camera, 400, 300 );

delete s;
}


$ /usr/local/gcc-2.95/bin/g++ -I ./include -lLightflow main6.cpp -o simplescene6
$ ./simplescene6
$ convert ocean.tga ocean.jpg
$ eog ocean.jpg
ocean.jpg
Lightflow | - | -

Lightflow C API sample cloud

main5.cpp
#includeの両側に半角スペースが入っています。


#include < Lightflow/LfLocalSceneProxy.h >

void main()
{
LfLocalSceneProxy* s = new LfLocalSceneProxy();
LfArgList list;

list.Reset();
list << "direction" << LfVector3( 8.0, 5.0, -6.0 );
list << "color" << LfColor( 1.0, 1.0, 1.0 );
s->LightOn( s->NewLight( "directional", list ) );


list.Reset();
list << "value"
<< 0.3 << 1.0 << 1.0
<< 0.5 << 0.0 << 0.0;
list << "scale" << 1.0;
list << "turbulence.omega" << 0.55;
list << "turbulence.lambda" << 1.8;
list << "turbulence.octaves" << LfInt( 6 );
LfInt cloudpattern1 = s->NewPattern( "granite", list );

// Make a granite-like volumetric pattern.
// Note the keyword "value", followed by two rows of three parameters
// each.
// This is an example of value-gradient. A gradient is a function which
// interpolates many values, which may be numbers, colors, or entire
// patterns and materials.
// By convention numeric gradients are called value-gradients, color ones
// are named color-gradients and so on.
// As a function a gradient associates a value to a real variable.
// You can imagine it in cartesian coordinates, putting the variable on
// the abscissas and the associated value on the ordinates.
// Here the first expected argument is the abscissa at which the value
// of the function is specified, then the value follows. The value is
// specified both at the right and at the left of the abscissa in order
// to model discontinuities, so it is composed by two numbers.
// You can specify how many abscissas (and values) you want.
// This gradient is used to model the output of our fractal pattern,
// that we will use to describe the spatial density of the cloud.
// Here the gradient smoothly blends from the value of 1 at the point 0.3,
// to the value of 0 at the point 0.5.
// Normally the output would be a value between 0 and 1, but we
// make it droppoff rapidly from 1 to 0 to model masses of clouds that
// are denser at their center and that disappear at their boundaries.

list.Reset();
list << "value"
<< 0.8 << 1.0 << 1.0
<< 1.0 << 0.0 << 0.0;
list << "scale" << 1.2;
LfInt cloudpattern2 = s->NewPattern( "radial", list );

// Make a radial pattern, that is to say a spherical figure that is
// dense at its center and that has zero density at its border.
// This sphere has a radius of 1.2.

list.Reset();
list << "patterns" << cloudpattern1 << cloudpattern2;
LfInt cloudpattern = s->NewPattern( "compose", list );

// Compose the two patterns. Here the output of cloudpattern1 is used
// as the input of cloudpattern2. Since the radial pattern uses its
// input to scale its output, the result will be a sphere containing a
// granitic texture which diminishes its intensity near the border.

list.Reset();
list << "kr" << LfColor( 0.7, 0.85, 1.0 );
list << "kaf" << LfColor( 0.2, 0.35, 0.5 );
list << "density" << 1.0;
list << "density" << cloudpattern;
list << "sampling" << 20.0;
list << "shadow-caching" << LfPoint( -1.2, -1.2, -1.2 ) << LfPoint( 1.2, 1.2, 1.2 );
list << "density-caching" << LfInt( 2048 ) << LfPoint( -1.2, -1.2, -1.2 ) << LfPoint( 1.2, 1.2, 1.2 );
LfInt cloudinterior = s->NewInterior( "cloud", list );

// Here you should note how we described density.
// It has been specified with a single value of 1 and then with the
// pattern we modeled before. The value of 1 will be used as a input to
// cloudpattern1, which will scale its output by this factor. In
// this case there will be no scaling, and the output will go from 1 to
// 0, as we stated above.
// The "shadow-caching" and "density-caching" attributes specify the use of
// two different caching mechanisms that will be used to speed-up
// computations. They both require a bounding box where to work, and
// the density cache also requires the maximum allowed memory
// occupancy, which is expressed in Kb (here 2048, i.e. 2 Mb).
// The "sampling" value specifies how many samples will be taken into a
// segment long one.

s->InteriorBegin( cloudinterior );

list.Reset();
LfInt cloud = s->NewMaterial( "transparent", list );

s->InteriorEnd();


s->MaterialBegin( cloud );

list.Reset();
list << "radius" << 1.2;
s->AddObject( s->NewObject( "sphere", list ) );

s->MaterialEnd();


list.Reset();
list << "file" << "cloud.tga";
LfInt saver = s->NewImager( "tga-saver", list );

s->ImagerBegin( saver );

list.Reset();
list << "eye" << LfPoint( 0, -4, 0 );
list << "aim" << LfPoint( 0, 0, 0 );
LfInt camera = s->NewCamera( "pinhole", list );

s->ImagerEnd();

s->Render( camera, 300, 300 );

delete s;
}


$ /usr/local/gcc-2.95/bin/g++ -I ./include -lLightflow main5.cpp -o simplescene5
$ ./simplescene5
$ convert cloud.tga cloud.jpg
$ eog cloud.jpg
cloud.jpg
Lightflow | - | -

Lightflow C API sample lights

main4.cpp
#includeの両側に半角スペースが入っています。


#include < Lightflow/LfLocalSceneProxy.h >

int main()
{
LfLocalSceneProxy* s = new LfLocalSceneProxy();
LfArgList list;
LfTransform trs;

list.Reset();
list << "position" << LfPoint( 4.0, -6.0, -5.0 );
list << "color" << LfColor( 200.0, 200.0, 200.0 );
s->LightOn( s->NewLight( "point", list ) );

list.Reset();
list << "position" << LfPoint( -7.5, -6.0, 2.0 );
list << "color" << LfColor( 300.0, 150.0, 150.0 );
LfInt light1 = s->NewLight( "point", list );

list.Reset();
list << "position" << LfPoint( -2.0, 0.0, 8.0 );
list << "color" << LfColor( 150.0, 300.0, 150.0 );
LfInt light2 = s->NewLight( "point", list );

list.Reset();
list << "position" << LfPoint( 8.0, -6.0, 5.0 );
list << "color" << LfColor( 150.0, 150.0, 300.0 );
LfInt light3 = s->NewLight( "point", list );


s->LightBegin();
s->LightOn( light1 );

list.Reset();
list << "ka" << LfColor( 0.1, 0.1, 0.1 );
list << "kc" << LfColor( 1, 1, 1 );
list << "kd" << 0.5;
list << "km" << 0.1;
LfInt plastic1 = s->NewMaterial( "standard", list );

s->LightEnd();

s->LightBegin();
s->LightOn( light2 );

list.Reset();
list << "ka" << LfColor( 0.1, 0.1, 0.1 );
list << "kc" << LfColor( 1, 1, 1 );
list << "kd" << 0.5;
list << "km" << 0.1;
LfInt plastic2 = s->NewMaterial( "standard", list );

s->LightEnd();

s->LightBegin();
s->LightOn( light3 );

list.Reset();
list << "ka" << LfColor( 0.1, 0.1, 0.1 );
list << "kc" << LfColor( 1, 1, 1 );
list << "kd" << 0.5;
list << "km" << 0.1;
LfInt plastic3 = s->NewMaterial( "standard", list );

s->LightEnd();


s->TransformBegin( trs.Translation( LfVector3( -2.0, 0, 0 ) ) );

s->MaterialBegin( plastic1 );

list.Reset();
list << "radius" << 1.0;
s->AddObject( s->NewObject( "sphere", list ) );

s->MaterialEnd();

s->TransformEnd();


s->MaterialBegin( plastic2 );

list.Reset();
list << "radius" << 1.0;
s->AddObject( s->NewObject( "sphere", list ) );

s->MaterialEnd();


s->TransformBegin( trs.Translation( LfVector3( 2.0, 0, 0 ) ) );

s->MaterialBegin( plastic3 );

list.Reset();
list << "radius" << 1.0;
s->AddObject( s->NewObject( "sphere", list ) );

s->MaterialEnd();

s->TransformEnd();


list.Reset();
list << "file" << "lights.tga";
LfInt saver = s->NewImager( "tga-saver", list );

s->ImagerBegin( saver );

list.Reset();
list << "eye" << LfPoint( 0, -4, 0 );
list << "aim" << LfPoint( 0, 0, 0 );
list << "fov" << atan( 0.5 / 0.75 )*2.0;
LfInt camera = s->NewCamera( "pinhole", list );

s->ImagerEnd();

s->Render( camera, 300, 300 );

delete s;
}


$ /usr/local/gcc-2.95/bin/g++ -I ./include -lLightflow main4.cpp -o simplescene4
$ ./simplescene4
$ convert lights.tga lights.jpg
$ eog lights.jpg
lights.jpg
Lightflow | - | -

Lightflow C API sample ball3

main3.cpp
#includeの両側に半角スペースが入っています。


#include < Lightflow/LfLocalSceneProxy.h >

int main()
{
LfLocalSceneProxy* s = new LfLocalSceneProxy();
LfArgList list;

list.Reset();
list << "position" << LfPoint( 5.0, -5.0, 4.0 );
list << "color" << LfColor( 300.0, 300.0, 300.0 );
s->LightOn( s->NewLight( "point", list ) );


list.Reset();
list << "kr" << LfColor( 1.0, 0.9, 0.8 );
list << "kaf" << 0.3;
list << "density" << 0.3;
list << "sampling" << 40.0;
list << "shadow-caching" << LfPoint( -1.2, -1.2, -1.2 ) << LfPoint(
1.2, 1.2, 1.2 );
LfInt gas = s->NewInterior( "dust", list );

s->InteriorBegin( gas );

list.Reset();
LfInt cloud = s->NewMaterial( "transparent", list );

s->InteriorEnd();


s->MaterialBegin( cloud );

list.Reset();
list << "radius" << 1.2;
s->AddObject( s->NewObject( "sphere", list ) );

s->MaterialEnd();


list.Reset();
list << "ka" << LfColor( 0, 0, 0.5 );
list << "kc" << LfColor( 1, 0.5, 0.5 );
list << "kd" << 0.5;
list << "km" << 0.1;
LfInt plastic = s->NewMaterial( "standard", list );

s->MaterialBegin( plastic );

list.Reset();
list << "radius" << 0.5;
s->AddObject( s->NewObject( "sphere", list ) );

s->MaterialEnd();


list.Reset();
list << "file" << "ball3.tga";
LfInt saver = s->NewImager( "tga-saver", list );

s->ImagerBegin( saver );

list.Reset();
list << "eye" << LfPoint( 0, -4, 0 );
list << "aim" << LfPoint( 0, 0, 0 );
LfInt camera = s->NewCamera( "pinhole", list );

s->ImagerEnd();

s->Render( camera, 300, 300 );

delete s;
}


$ /usr/local/gcc-2.95/bin/g++ -I ./include -lLightflow main3.cpp -o simplescene3
$ ./simplescene3
$ convert ball3.tga ball3.jpg
$ eog ball3.jpg
ball3.jpg
Lightflow | - | -

Lightflow C API sample ball2

2018/10/22
sample ball2
main2.cpp
#includeの両側に半角スペースが入っています。


#include < Lightflow/LfLocalSceneProxy.h >

int main()
{
LfLocalSceneProxy* s = new LfLocalSceneProxy();
LfArgList list;

list.Reset();
list << "position" << LfPoint( 5.0, -5.0, 4.0 );
list << "color" << LfColor( 300.0, 300.0, 300.0 );
s->LightOn( s->NewLight( "point", list ) );

list.Reset();
list << "basis" << "sin";
list << "scale" << 0.6;
list << "depth" << 0.2;
list << "turbulence.omega" << 0.5 << 0.7;
list << "turbulence.octaves" << LfInt( 6 );
LfInt bump = s->NewPattern( "multifractal", list );

list.Reset();
list << "ka" << LfColor( 0, 0, 0.05 );
list << "kc" << LfColor( 1, 1, 1 );
list << "kd" << 0.5;
list << "km" << 0.1;
list << "displacement" << bump;
LfInt plastic = s->NewMaterial( "standard", list );


s->MaterialBegin( plastic );

list.Reset();
list << "radius" << 1.0;
LfInt sphere = s->NewObject( "sphere", list );

list.Reset();
list << "surfaces" << sphere;
list << "tolerance" << 0.02 << 0.1 << 0.05;
s->AddObject( s->NewObject( "surface-engine", list ) );

s->MaterialEnd();


list.Reset();
list << "file" << "ball2.tga";
LfInt saver = s->NewImager( "tga-saver", list );

s->ImagerBegin( saver );

list.Reset();
list << "eye" << LfPoint( 0, -4, 0 );
list << "aim" << LfPoint( 0, 0, 0 );
LfInt camera = s->NewCamera( "pinhole", list );

s->ImagerEnd();

s->Render( camera, 300, 300 );

delete s;
}


$ /usr/local/gcc-2.95/bin/g++ -I ./include -lLightflow main2.cpp -o simplescene2
$ ./simplescene2
$ convert ball2.tga ball2.jpg
$ eog ball2.jpg
ball2.jpg
main22.cpp
#includeの両側に半角スペースが入っています。


#include < Lightflow/LfLocalSceneProxy.h >

int main()
{
LfLocalSceneProxy* s = new LfLocalSceneProxy();
LfArgList list;

list.Reset();
list << "position" << LfPoint( 5.0, -5.0, 4.0 );
list << "color" << LfColor( 300.0, 300.0, 300.0 );
s->LightOn( s->NewLight( "point", list ) );

list.Reset();
list << "basis" << "sin";
list << "scale" << 0.6;
list << "depth" << 0.2;
list << "turbulence.omega" << 0.5 << 0.7;
list << "turbulence.octaves" << LfInt( 6 );
LfInt bump = s->NewPattern( "multifractal", list );

list.Reset();
list << "kr" << LfVector3(0.3,0.3,0.5);
list << "kd" << 0.3;
list << "km" << 0.3;
list << "shinyness" << 0.8;
list << "fresnel" << LfInt(1) << LfFloat(0.5) << LfFloat(0.5);
list << "caustics" << LfInt(1) << LfInt(1);
list << "displacement" << bump;
LfInt bumpmetal = s->NewMaterial( "physical", list );


s->MaterialBegin( bumpmetal );

list.Reset();
list << "radius" << 1.0;
LfInt sphere = s->NewObject( "sphere", list );

list.Reset();
list << "surfaces" << sphere;
list << "tolerance" << 0.02 << 0.1 << 0.05;
s->AddObject( s->NewObject( "surface-engine", list ) );

s->MaterialEnd();


list.Reset();
list << "file" << "ball2.tga";
LfInt saver = s->NewImager( "tga-saver", list );

s->ImagerBegin( saver );

list.Reset();
list << "eye" << LfPoint( 0, -4, 0 );
list << "aim" << LfPoint( 0, 0, 0 );
LfInt camera = s->NewCamera( "pinhole", list );

s->ImagerEnd();

s->Render( camera, 300, 300 );

delete s;
}


$ /usr/local/gcc-2.95/bin/g++ -I ./include -lLightflow main22.cpp -o simplescene22
$ ./simplescene22
$ convert ball2.tga ball2.jpg
$ eog ball2.jpg
ball2.jpg
Lightflow | - | -

Lightflow Rendering Tool C API for Linux 2018/10

2018/10/22

LightflowのC APIについて、動いたLinux distributionを調べました。

Fedora28(64bit)をインストールしたノートパソコン(2012年 W255HPW)にVirtualBox5.2.20をインストール。

32bitのLinuxをいくつかインストールしました。
Lightflow C APIが動いたのは、
VineLinux2.6(include python1.5, gcc2.95)
VineLinux3.2
VineLinux4.0
VineLinux4.2
VineLinux5.2
CentOS5.11

動かなかったのは、
Scientific Linux6 i386
Fedora28 32bit

//** インストール方法
http://www.python.org/download/releases/1.5/
Python 1.5.2 sources (2.5 MB)をダウンロード
■python1.5.2をインストール。
$ ./configure
$ make
# make altinstall

■さらに次のファイルをダウンロードします。
compat-libstdc++-6.2-2.9.0.14.i386.rpm
http://rpm.pbone.net/index.php3/stat/4/idpl/14760/com/compat-libstdc++-6.2-2.9.0.14.i386.rpm.html

■gcc-2.95.3をインストール。
インストール先のディレクトリを作成しておく。
# mkdir /usr/local/gcc-2.95
$ ./configure --prefix=/usr/local/gcc-2.95 --enable-languages=c,c++
$ make
# make install
確認
$ /usr/local/gcc-2.95/bin/g++ --version
2.95.3

■Lightflowのダウンロード
Lightflowのサイトから
http://www.lightflowtech.com/

Linux RedHat 6.1 Version (1608 Kb)
lf_redhat.tgzをダウンロードします。
/home/ユーザ/Lightflow
で解凍します。

.bash_profileまたは.bashrcに記入
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/Lightflow
PYTHONPATH=$PYTHONPATH:$HOME/Lightflow
LIGHTFLOWPATH=$HOME/Lightflow
LIGHTFLOW_SE_MEMORY=32000
LIGHTFLOW_VE_MEMORY=32000

export LD_LIBRARY_PATH PYTHONPATH LIGHTFLOWPATH LIGHTFLOW_SE_MEMORY LIGHTFLOW_VE_MEMORY

以下を実行するとpython1.5でレンダリングできました。
Examples]$ python1.5 ball1.py


■C APIの設定。
http://www.knoerig.de/lightflow_en.html
「Rudi's Homepage - Lightflow」を参考にincludeファイルをダウンロードします。

$ mkdir simplescene
includeファイルを置きます。

C++-libraryをシンボリックリンクします。
# ln -s /home/ユーザ/Lightflow/libLightflow.so /usr/lib

以下Makefile


CC = /usr/local/gcc-2.95/bin/g++
INCLUDE=-I ./include
LNK = -lLightflow
CNV = convert

all: ball.jpg

ball.jpg: ball.tga
$(CNV) ball.tga ball.jpg

ball.tga: simplescene
simplescene

simplescene: main.cpp
$(CC) $(INCLUDE) $(LNK) main.cpp -o simplescene





main.cpp


#include
#include

int main()
{
// create a new proxy
LfLocalSceneProxy *s = new LfLocalSceneProxy();
// this is a container object for storing the arguments passed to
// the renderer via the proxy
LfArgList list;

// define a light
list.Reset();
list << "position" << LfVector3(-4,-7,6);
list << "color" << LfVector3(450*1.0,450*1.0,450*0.8);
LfInt light = s->NewLight("soft",list);
s->LightOn(light);

// define a material (standard material, there are others)
list.Reset();
// ambient color
list << "ka" << LfColor(0,0,0.5);
// reflection color
list << "kc" << LfColor(1,0.5,0.5);
// diffuse reflection factor
list << "kd" << 0.5;
// specular reflection smoothness (0-polished,1-plastic)
list << "km" << 0.1;
// surface displacement
// LfInt is a long int representing a handle
LfInt plastic = s->NewMaterial("standard",list);

// define a sphere object
s->MaterialBegin(plastic);
list.Reset();
list << "radius" << 1.0;
LfInt ball = s->NewObject("sphere",list);
s->AddObject(ball);
s->MaterialEnd();

// specify the output object
list.Reset();
list << "file" << "ball.tga";
LfInt saver = s->NewImager("tga-saver",list);

// specify the rendering context
s->ImagerBegin(saver);
list.Reset();
// camera position
list << "eye" << LfPoint(0,-4,0);
// point to aim at
list << "aim" << LfPoint(0,0,0);
LfInt camera = s->NewCamera("pinhole",list);
s->ImagerEnd();

// start rendering
s->Render(camera,300,300);

delete s;
return 0;
}


一時的にPATHを通しても良いです。
$ export PATH=/usr/local/gcc-2.95/bin:$PATH

makeします。
$ make simplescene
$ ./simplescene
Lightflow Rendering Tools
Copyright (c) 1995-2000 by Jacopo Pantaleoni. All rights reserved

Pinhole Camera On
Objects : 1
LfSoftLight::Init()
00:00:00 - cell 418176 / 418176

Rendering 300 x 300 pixels
00:00:00 - 87.1%

$ convert ball.tga ball.jpg
$ eog ball.jpg
ball.jpg

Lightflowを設定していくことで、Linuxの勉強になりました。
ありがとうございます。
Lightflow | - | -

Lightflow C++-Tutorial for beginners

C++でのやり方。参考になりました。
ありがとうございます。
http://www.knoerig.de/lightflow_en.html
Rudi's Homepage - Lightflow
Lightflow | - | -

LightFlow for linux 64bit その2

前回64bitでうまくいかなかった。やっとできたのでメモする。
CentOS 64bit環境でpython1.5を32bitビルド試みたが、64bitになってしまう。結局Virtualboxに入れたCentOS i686(32bit)版でビルドしたpython1.5をコピーして、LightFlowが起動した。

以下試みる。CentOS 64bitでビルドしても64bit.
export CFLAGS=-m32
export CXXFLAGS=-m32
echo $CFLAGS
echo $CXXFLAGS
yum install glibc-2.12-1.80.el6_3.5.i686
yum install libstdc++*
yum install libstdc++*.i686
./configure --enable-32bit
make ARCH="-m32"

32bit環境の以下をコピー
/usr/local/bin python1.5
/usr/local/lib python1.5/
/usr/local/include python1.5/
64bit環境にインストールする。
sudo cp python1.5 /usr/local/bin

さらに次のファイルをダウンロードします。
compat-libstdc++-6.2-2.9.0.14.i386.rpm
http://rpm.pbone.net/index.php3/stat/4/idpl/14760/com/compat-libstdc++-6.2-2.9.0.14.i386.rpm.html

インストールします。
[root@localhost]# rpm -ivh compat-libstdc++-6.2-2.9.0.14.i386.rpm
Preparing... ########################################### [100%]
1:compat-libstdc++ ########################################### [100%]

その他、.bashrcに記入
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/Lightflow
PYTHONPATH=$PYTHONPATH:$HOME/Lightflow
LIGHTFLOWPATH=$HOME/Lightflow
LIGHTFLOW_SE_MEMORY=32000
LIGHTFLOW_VE_MEMORY=32000

export LD_LIBRARY_PATH PYTHONPATH LIGHTFLOWPATH LIGHTFLOW_SE_MEMORY LIGHTFLOW_VE_MEMORY

以下を実行するとレンダリングできました。
Examples]$ python1.5 ball1.py

Lightflow Rendering Tools
Copyright (c) 1995-2000 by Jacopo Pantaleoni. All rights reserved


Pinhole Camera On
Objects : 1

Rendering 300 x 300 pixels
00:00:00 - 87.1%
Windowsより速いです。
Lightflow | - | -

LFexportGUI

Lightflowをblenderで使うプラグイン
LFexportGUI

ダウンロード先

http://www.zoo-logique.org/3D.Blender/index.php3?page=php/python.php3

blender2.28cあたりで動くだろうか。試してみる。
Lightflow | - | -
1/8 >>