POV-Ray : Newsgroups : povray.binaries.images : Stochastic render rig focal blur FIXED : Re: Stochastic render rig focal blur FIXED Server Time
1 Aug 2024 10:16:40 EDT (-0400)
  Re: Stochastic render rig focal blur FIXED  
From: Edouard Poor
Date: 22 Aug 2008 19:50:00
Message: <web.48af4f8e90c1c695dbf7248f0@news.povray.org>
stbenge <THI### [at] hotmailcom> wrote:
> Edouard Poor wrote:
> > I wrote a simple command-line program to merge the HDR images - I'll try and
> > post the source somewhere soonish, but if you were on Mac OS X, I could just
> > post that executable straight away.
>
> I'm running WinXP here. If your code uses SDL, then I might be able to
> compile it myself.

The source is very simple - if you've got a C++ compiler of some sort (e.g.
gcc/g++ or the free vidual studio) you should be able to get something going
from this. Linux and Mac OS X will handle very long command lines (e.g. 1000
image names), I'm not sure about Windows though.

You'll need the rgbe files from
http://www.graphics.cornell.edu/online/formats/rgbe/ as well.

The output is "x.hdr".

/*
 *  join.cc
 *
 *    g++ -g -o join join.cc rgbe.o
 *
 */


// -- Include Files -----------------------------------------------------------

#include <cstdio>
    // For: fopen(), FILE etc

extern "C"
{
#include "rgbe.h"
    // For: Radience File Format Reading/Writing
}

#include <iostream>
    // For: cout, etc


// -- Namespace Directives ----------------------------------------------------

using namespace std;


// -- Classes -----------------------------------------------------------------

class image
  {
  public:

  double *pixel;
  int     width;
  int     height;

  image( int width, int height )
    : width( width ), height( height ),
      pixel( new double[ width * height * 3 ] )
    {
    for( int i = 0; i < width * height * 3; i++ )
      pixel[ i ] = 0.0;
    }

  ~image()
    {
    delete [] pixel;
    }

  double& operator()( int x, int y, int p )
    {
    return pixel[ y * width * 3 + x * 3 + p ];
    }

  image& operator/=( const double d )
    {
    for( int i = 0; i < width * height * 3; i++ )
      pixel[ i ] /= d;

    return *this;
    }

  image& operator+=( const image& other )
    {
    for( int i = 0; i < width * height * 3; i++ )
      pixel[ i ] += other.pixel[ i ];

    return *this;
    }

  image( const image& other )
    : width( other.width ), height( other.height ),
      pixel( new double[ other.width * other.height * 3 ] )
    {
    for( int i = 0; i < width * height * 3; i++ )
      pixel[ i ] = other.pixel[ i ];
    }

  image& operator=( const image& other )
    {
    if( this == &other ) return *this;

    delete [] pixel;

    width = other.width;
    height = other.height;
    pixel = new double[ width * height * 3 ];

    for( int i = 0; i < width * height * 3; i++ )
      pixel[ i ] = other.pixel[ i ];

    return *this;
    }
  };


// -- Utility Functions -------------------------------------------------------

image loadHDR( string filename )
  {
  int width, height;

  FILE *f = fopen( filename.c_str(), "rb" );
  RGBE_ReadHeader( f, &width, &height, NULL );
  float *fim = new float[ width * height * 3 ];
  RGBE_ReadPixels_RLE( f, fim, width, height );
  fclose( f );

  image tmpImage( width, height );

  for( int y = 0; y < height; y++ )
    for( int x = 0; x < width; x++ )
      for( int p = 0; p < 3; p++ )
        tmpImage( x, y, p ) = fim[ y * width * 3 + x * 3 + p ];

  delete [] fim;

  return tmpImage;
  }

void saveHDR( image& im, string filename )
  {
  float *fim = new float[ im.width * im.height * 3 ];
  for( int y = 0; y < im.height; y++ )
    for( int x = 0; x < im.width; x++ )
      for( int p = 0; p < 3; p++ )
        fim[ y * im.width * 3 + x * 3 + p ] = im( x, y, p );

  FILE *f = fopen( filename.c_str(), "wb" );
  RGBE_WriteHeader( f, im.width, im.height, NULL );
  RGBE_WritePixels( f, fim, im.width * im.height );
  fclose( f );

  delete [] fim;
  }


// -- Program Entry Point -----------------------------------------------------

int main( int argc, char *argv[] )
  {
  cout << "Joining " << argc-1 << " images" << endl;

  cout << "  " << argv[ 1 ] << endl;
  image base = loadHDR( argv[ 1 ] );

  for( int i = 2; i < argc; i++ )
    {
    cout << "  " << argv[ i ] << endl;
    image im = loadHDR( argv[ i ] );
    base += im;
    }

  base /= argc-1;

  saveHDR( base, "x.hdr" );

  cout << "Done." << endl;
  }



> > Usually a random distribution seems to work well, and different scenes require a
> > different number of frames to look good.
> >
> > Actually one issue I've noticed is that I think that the random number generator
> > in POV-Ray isn't quite as randomly distributed as I would like - esp with
> > averaging deep DoF and specular highlights (or HDR reflections of point light
> > sources) I notice a discernible pattern appearing in the bokeh. I guess I could
> > test it by loading a random array produced externally (with some high quality
> > RNG)  and comparing the results.
>
> What's RNG? Is that some sort of even distribution routine? I've been
> able to make evenly-distributed random point arrays in the past by
> testing each spot with a circle routine. It can be slow to compute
> sometimes, but it's always nice to have such a point array handy.

Random Number Generator - POV-Ray's "rand()" (and "seed()"). POV's one is fast,
but, I'm suspecting, may show patterns when you use it in particular ways. An
interesting example of another RNG that was used in the past, but had problems
when used for 3D data, is at
http://www.cs.pitt.edu/~kirk/cs1501/animations/Random.html - POVs RNG is better
than that one I think, but might still show some non-randomness.

> Sam

Cheers,
Edouard.


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.