예제 #1
0
// TODO: implement adaptive supersampling
RGBColour World::colourForPixelAt(int i, int j) {
	double d = viewport.getViewingDistance();

	if (ss_level == 1) {
		// no super-sampling
		double uValue = viewport.uAmount(i, 1, 0, false);
		double vValue = viewport.vAmount(j, 1, 0, false);
		vec3 direction = wAxis.scaled(-d) + uAxis.scaled(uValue) + vAxis.scaled(vValue);
		Ray theRay(cameraPosition, direction);

		return RGBColour(traceRay(theRay, 0.0, 0));
	}

	// 0.01 => x16, 1.2 => x64
	double thresholds[2] = {0.01, 1.2}; 


	double var = 0.0;
	int lvl_log = 2;

	RGBVec pixelColour;

	while (lvl_log <= ss_level) {
		pixelColour = RGBVec(0.0,0.0,0.0);

		int lvl = int_pow(2, lvl_log - 1); 

		double scale_factor = 1.0 / static_cast<double>(lvl*lvl);

		vec3 sum_x_sq(0.0,0.0,0.0);

		for (int a = 0; a < lvl; a++) {
			for (int b = 0; b < lvl; b++) {
				double uValue = viewport.uAmount(i, ss_level, a, lvl_log > 2);
				double vValue = viewport.vAmount(j, ss_level, b, lvl_log > 2);
				vec3 direction = wAxis.scaled(-d) + uAxis.scaled(uValue) + vAxis.scaled(vValue);	
				Ray theRay(cameraPosition, direction);
				RGBVec sample = traceRay(theRay, 0.0, 0).scaled(scale_factor);
				pixelColour += sample;
				if (ss_level > 2) sum_x_sq += sample.getVector().pointwise(sample.getVector());
			}
		}		

		if (lvl_log == 2 && ss_level > 2) {
			vec3 varvec = sum_x_sq.scaled(scale_factor) - pixelColour.getVector().pointwise(pixelColour.getVector());
			var = varvec.magnitude();
			if (i % 100 == 0 && j % 100 == 0) std::cout << "var: " << var << std::endl;
		}

		if (var < thresholds[lvl_log - 2] || lvl_log == ss_level) break;
		lvl_log++;
	}

	if (lvl_log == 2) renderStats.ss_x4++;
       	else if (lvl_log == 3) renderStats.ss_x16++;
	else if (lvl_log == 4) renderStats.ss_x64++;

	return RGBColour(pixelColour);
}	
예제 #2
0
void Spectrum::acquireColourPulses(list<RGBColour> &colours, list<PositionAngle> &angles)
{
	list<ResponceCollection>::iterator collectionIter = bandResponceCollections_->begin();
	while(collectionIter != bandResponceCollections_->end())
	{
		float leftDifference = 0.0f;
		float rightDifference = 0.0f;

		float minHertz = ENTRY_HZ * (MIN_ENTRY);
		float maxHertz = ENTRY_HZ * (MIN_ENTRY + 1);

		for(int entry = MIN_ENTRY; entry < SPECTRUM_WIDTH; entry++)
		{
			float contribution = CLAMP(((*collectionIter).band.maxFreq - minHertz) / (maxHertz - minHertz), 0.0f, 1.0f) *
								 CLAMP(1.0f - (((*collectionIter).band.minFreq - minHertz) / (maxHertz - minHertz)), 0.0f, 1.0f);

			leftDifference = max(leftInstantSpectrum_[entry] * (*collectionIter).level * contribution, leftDifference);
			rightDifference = max(rightInstantSpectrum_[entry] * (*collectionIter).level * contribution, rightDifference);

			minHertz = maxHertz;
			maxHertz += ENTRY_HZ;
		}

		leftDifference = ((leftDifference * spectrumVolume_) - pulseThreshold_) / (1.0f - pulseThreshold_);
		rightDifference = ((rightDifference * spectrumVolume_) - pulseThreshold_) / (1.0f - pulseThreshold_);

		if((leftDifference > 0.0f) && (rightDifference > 0.0f))
		{
			colours.push_back(RGBColour(LOGSCALE((*collectionIter).colour.r * ((leftDifference + rightDifference) / 2)),
										LOGSCALE((*collectionIter).colour.g * ((leftDifference + rightDifference) / 2)),
										LOGSCALE((*collectionIter).colour.b * ((leftDifference + rightDifference) / 2))));

			angles.push_back(NORTH_ANGLE);
		}

		//Removed this as the effect became confusing to watch

		else if((leftDifference > 0.0f) && (rightDifference <= 0.0f))
		{
			colours.push_back(RGBColour(LOGSCALE((*collectionIter).colour.r * leftDifference),
										LOGSCALE((*collectionIter).colour.g * leftDifference),
										LOGSCALE((*collectionIter).colour.b * leftDifference)));

			angles.push_back(WEST_ANGLE);
		}
		else if((leftDifference <= 0.0f) && (rightDifference > 0.0f))
		{
			colours.push_back(RGBColour(LOGSCALE((*collectionIter).colour.r * rightDifference),
										LOGSCALE((*collectionIter).colour.g * rightDifference),
										LOGSCALE((*collectionIter).colour.b * rightDifference)));

			angles.push_back(EAST_ANGLE);
		}

		collectionIter++;
	}
}
예제 #3
0
파일: encoding.cpp 프로젝트: Nyoho/povray
void GetEncodedRGBAValue(const Image* img, unsigned int x, unsigned int y, const GammaCurvePtr& g, unsigned int max, unsigned int& red, unsigned int& green, unsigned int& blue, unsigned int& alpha, DitherHandler& dh, bool premul)
{
	bool doPremultiply   = premul && !img->IsPremultiplied() && img->HasTransparency(); // need to apply premultiplication if encoded data should be premul'ed but container content isn't
	bool doUnPremultiply = !premul && img->IsPremultiplied() && img->HasTransparency(); // need to undo premultiplication if other way round
	float fRed, fGreen, fBlue, fAlpha;
	img->GetRGBAValue(x, y, fRed, fGreen, fBlue, fAlpha);
	if (doPremultiply)
	{
		// Data has been stored premultiplied, but should be encoded non-premultiplied.
		// No need for special handling of color components greater than alpha.
		// Need to convert from premultiplied to non-premultiplied encoding.
		AlphaPremultiply(fRed, fGreen, fBlue, fAlpha);
	}
	else if (doUnPremultiply)
	{
		// Data has been stored premultiplied, but should be encoded non-premultiplied.
		// Clipping will happen /before/ re-multiplying with alpha (because the latter is done in the viewer), which is equivalent to clipping
		// pre-multiplied components to be no greater than alpha, thereby "killing" highlights on transparent objects;
		// compensate for this by boosting opacity of any exceptionally bright pixels.
		float fBright = RGBColour(fRed, fGreen, fBlue).greyscale();
		if (fBright > fAlpha)
			fAlpha = min(1.0f, fBright);
		// Need to convert from premultiplied to non-premultiplied encoding.
		AlphaUnPremultiply(fRed, fGreen, fBlue, fAlpha);
	}
	else if (!premul)
	{
		// Data has been stored un-premultiplied and should be encoded that way.
		// Clipping will happen /before/ multiplying with alpha (because the latter is done in the viewer), which is equivalent to clipping
		// pre-multiplied components to be no greater than alpha, thereby "killing" highlights on transparent objects;
		// compensate for this by boosting opacity of any exceptionally bright pixels.
		float fBright = RGBColour(fRed, fGreen, fBlue).greyscale();
		if (fBright > 1.0)
		{
			float fFactor = fBright;
			if (fFactor * fAlpha > 1.0)
				fFactor = 1.0/fAlpha;
			// this keeps the product of alpha*color constant
			fAlpha *= fFactor;
			fRed   /= fFactor;
			fGreen /= fFactor;
			fBlue  /= fFactor;
		}
		// No need for converting between premultiplied and un-premultiplied encoding.
	}
	// else no need to worry about premultiplication
	DitherHandler::OffsetInfo linOff, encOff;
	dh.getOffset(x,y,linOff,encOff);
	red   = IntEncode(g,fRed   + linOff.red,   max, encOff.red,   linOff.red);
	green = IntEncode(g,fGreen + linOff.green, max, encOff.green, linOff.green);
	blue  = IntEncode(g,fBlue  + linOff.blue,  max, encOff.blue,  linOff.blue);
	alpha = IntEncode(fAlpha   + linOff.alpha, max, encOff.alpha, linOff.alpha);
	dh.setError(x,y,linOff);
}
예제 #4
0
RGBColour SpectralBand::GetHueIntegral(double wavelength)
{
	double tableOffset = clip((wavelength-SPECTRAL_HUE_TABLE_BASE)/SPECTRAL_HUE_TABLE_STEP, 0.0, SPECTRAL_HUE_TABLE_SIZE-1.0);
	int tableIndex = min((int)tableOffset, SPECTRAL_HUE_TABLE_SIZE-2);
	tableOffset -= tableIndex;
	return (1.0-tableOffset) * RGBColour(SpectralHueIntegral[tableIndex]) + tableOffset * RGBColour(SpectralHueIntegral[tableIndex+1]);
}
예제 #5
0
auto_ptr<MathmlNode> Manager::GenerateMathml(
    const MathmlOptions& options
) const
{
    if (mHasDelayedMathmlError)
        throw mDelayedMathmlError;
    
    if (!mLayoutTree.get())
        throw logic_error(
            "Layout tree not yet built in Manager::GenerateMathml"
        );

    MathmlOptions optionsCopy = options;
    if (mStrictSpacingRequested)
        // Override the spacing control setting if the "\strictspacing"
        // command appeared somewhere in the input.
        optionsCopy.mSpacingControl = MathmlOptions::cSpacingControlStrict;

    // Build the MathML tree. The nodeCount variables counts the number
    // of nodes being generated; if too many appear, an exception is thrown.
    unsigned nodeCount = 0;
    auto_ptr<MathmlNode> root = mLayoutTree->BuildMathmlTree(
        optionsCopy,
        MathmlEnvironment(LayoutTree::Node::cStyleText, RGBColour(0)),
        nodeCount
    );

    return root;
}
예제 #6
0
ResponceCollection::ResponceCollection(void)
{
	colour = RGBColour();
	band = ResponceBand();

	level = 1.0f;
	
	leftIntensity = 0.0f;
	rightIntensity = 0.0f;
}
예제 #7
0
void Spectrum::includeColourBand(HSVColour &colour, ResponceBand &band, float level)
{
	ResponceCollection collection;
	collection.colour = RGBColour(colour.computeRed(), colour.computeGreen(), colour.computeBlue());
	collection.band = band;
	collection.level = level;
	collection.leftIntensity = 0.0f;
	collection.rightIntensity = 0.0f;

	bandResponceCollections_->push_back(collection);
}
예제 #8
0
파일: atmosph.cpp 프로젝트: Degot/povray
SKYSPHERE *Create_Skysphere()
{
	SKYSPHERE *New;

	New = new SKYSPHERE;

	New->Count = 0;
	New->Emission = RGBColour(1.0);

	New->Pigments = NULL;

	New->Trans = Create_Transform();

	return (New);
}
예제 #9
0
파일: atmosph.cpp 프로젝트: Nyoho/povray
SKYSPHERE *Create_Skysphere()
{
	SKYSPHERE *New;

	New = (SKYSPHERE *)POV_MALLOC(sizeof(SKYSPHERE), "fog");

	New->Count = 0;
	New->Emission = RGBColour(1.0);

	New->Pigments = NULL;

	New->Trans = Create_Transform();

	return (New);
}
예제 #10
0
파일: colour.cpp 프로젝트: SteveShaw/povray
namespace pov_base
{

#if (NUM_COLOUR_CHANNELS == 3)

    // Approximate dominant wavelengths of primary hues.
    // Source: 3D Computer Graphics by John Vince (Addison Wesely)
    // These are user-adjustable with the irid_wavelength keyword.
    // Red = 700 nm  Grn = 520 nm Blu = 480 nm
    // Divided by 1000 gives: rwl = 0.70;  gwl = 0.52;  bwl = 0.48;
    template<> const MathColour MathColour::mkDefaultWavelengths = MathColour(RGBColour(0.70, 0.52, 0.48));
    template<> const PreciseMathColour PreciseMathColour::mkDefaultWavelengths = PreciseMathColour(PreciseRGBColour(0.70, 0.52, 0.48));

#else

    #error TODO!

#endif

}
예제 #11
0
void wxMoColourPanel::UpdatePattern() {

    ///Get control size
    wxSize sz = GetSize();
    wxMemoryDC mdc;
    int i,j;
    int pat = 8;
    wxImage* pPatternImage;

    ///intialize memory dc to the bitmap
    mdc.SelectObject( m_Pattern );
    mdc.SetPen( wxPen( wxColour(255,255,255), 1, wxTRANSPARENT ) );

    pat = std::min( m_Pattern.GetHeight() / 4, m_Pattern.GetWidth() / 4);
    if (pat==0) pat = 4;

    for( i=0; i<sz.GetWidth(); i+=pat) {
      for( j=0; j<sz.GetHeight(); j+=pat) {
        if ( ( ( i/pat + j/pat ) % 2 ) == 0 ) {
          mdc.SetBrush( wxBrush( wxColour(  0,
                                            0,
                                            0), wxSOLID) );
        }
        else {
          mdc.SetBrush( wxBrush( wxColour(  255,
                                           255,
                                            255), wxSOLID) );
        }
        mdc.DrawRectangle( i, j, pat, pat );
      }
    }


    if ( m_Bitmap.IsOk() && m_Bitmap.GetHeight()>0 && m_Bitmap.GetWidth()>0 )
    {
      pPatternImage = new wxImage( m_Bitmap.ConvertToImage() );

      ///We draw the bitmap as a transparent coloured and filtered by the actual colour value wxImage

      if ( !pPatternImage ) {
        wxMessageBox(wxString("wxMoColourPanel error creating m_ImagePattern."));
      } else {

              ///wxMessageBox("draw bitmap");

              pPatternImage->InitAlpha();
              for( i=0; i<pPatternImage->GetWidth(); i+=1) {
                for( j=0; j<pPatternImage->GetHeight(); j+=1) {
                  ///rgb colour bitmap colour multiply actual colour value
                  wxColour RGBColour(
                      ( pPatternImage->GetRed(i,j)   * m_ColourValue.Red() )    / 255.0,
                      ( pPatternImage->GetGreen(i,j) * m_ColourValue.Green() )  / 255.0,
                      ( pPatternImage->GetBlue(i,j)  * m_ColourValue.Blue() )    / 255.0
                       );

                  pPatternImage->SetRGB( i, j, RGBColour.Red(), RGBColour.Green(), RGBColour.Blue() );
                  pPatternImage->SetAlpha( i, j, ( pPatternImage->GetAlpha(i,j)  * m_ColourValue.Alpha() )    / 255.0);

                }

              }

              int leftx = GetSize().GetWidth() / 2 - m_Bitmap.GetWidth() / 2;
              int topx = GetSize().GetHeight() / 2 - m_Bitmap.GetHeight() / 2;

              mdc.DrawBitmap( wxBitmap(*pPatternImage), leftx, topx, true );

              delete pPatternImage;
      }

    } else {

      pPatternImage = new wxImage( GetSize().GetWidth(), GetSize().GetHeight(), true );

      ///We draw the colour value as a transparent image over the pattern
      ///wxMessageBox("draw color");
      if (pPatternImage) {

              pPatternImage->InitAlpha();
              for( i=0; i<pPatternImage->GetWidth(); i+=1) {
                for( j=0; j<pPatternImage->GetHeight(); j+=1) {
                  pPatternImage->SetRGB( i, j, m_ColourValue.Red(), m_ColourValue.Green(), m_ColourValue.Blue() );
                  pPatternImage->SetAlpha( i, j, m_ColourValue.Alpha() );
                }
              }

              mdc.DrawBitmap( wxBitmap( *pPatternImage ), 0, 0, true );

      }

    }

}
예제 #12
0
void 												
World::render_scene(const Pixel& pixel, RenderedPixel & rendered) const {

	RGBColour	pixel_color = black;
	Vector3D u(1, 0, 0);
	Vector3D v(0, 1, 0);
	Vector3D w(0, 0, 1);
	
	float exposure_time = 1.0f;
	
	Ray			ray;					
	int 		hres 	= vp.hres;
	int 		vres 	= vp.vres;
	float		s		= vp.s;
    if(camera_ptr)
      s 		/= (static_cast<Pinhole*>(camera_ptr)->zoom);
	s = -0.333;
	float		zw		= 1000.0;
	
	Point2D 	pp;			// sample point on a pixel
	int n = (int)sqrt((float)vp.num_samples);
    n = 1;

    rendered.color = RGBColour();
	int count = 0;
	int jump  = 0;
	int depth = 0;

	ray.d = Vector3D(0, 0, -1);

	ray.o = Point3D(s * (pixel.x - hres / 2.0 + 0.5), s * (pixel.y - vres / 2.0 + 0.5), zw);
	
	int sp_count = 0;
	int sp_jump = 0;
	for (int p = 0; p < n; p++)	{		// up pixel
		for (int q = 0; q < n; q++) {	// across pixel
			pp.x = vp.s * (pixel.x - 0.5 * vp.hres + (q + 0.5) / n);
			pp.y = vp.s * (pixel.y - 0.5 * vp.vres + (p + 0.5) / n);
			
			Vector3D dir = pp.x * u + pp.y * v - zw * w;
			dir.normalize();
			ray.d = dir;
			
			pixel_color += tracer_ptr->trace_ray(ray, depth, count, jump);
		}
	}
	
	//pixel_color = tracer_ptr->trace_ray(ray, depth, count, jump);
	
	
	pixel_color /= vp.num_samples;
	pixel_color *= exposure_time;
	
	rendered.color = pixel_color;			// for send every row
	rendered.xy = Point2D(pixel.x,pixel.y);	

            
	return;
	
	
	
}  
예제 #13
0
	RGBColour DifferentialSurface::Le(const Vector3& p_w) const {
		const AreaLight *area = primitive->GetAreaLight();
		return area ? area->L(point, normal, p_w) : RGBColour(0.);
	}
예제 #14
0
파일: Colour.hpp 프로젝트: weimingtom/rlvm
 static RGBColour White() { return RGBColour(255, 255, 255); }
예제 #15
0
파일: Colour.hpp 프로젝트: weimingtom/rlvm
 // Colour constants
 static RGBColour Black() { return RGBColour(0, 0, 0); }
예제 #16
0
void Spectrum::acquireColourResponces(RGBColour &leftColour, RGBColour &rightColour)
{
	leftColour = RGBColour();
	rightColour = RGBColour();

	list<ResponceCollection>::iterator collectionIter = bandResponceCollections_->begin();
	while(collectionIter != bandResponceCollections_->end())
	{
		float leftIntensity = 0.0f;
		float rightIntensity = 0.0f;

		float minHertz = ENTRY_HZ * (MIN_ENTRY);
		float maxHertz = ENTRY_HZ * (MIN_ENTRY + 1);

		for(int entry = MIN_ENTRY; entry < SPECTRUM_WIDTH; entry++)
		{
			float contribution = CLAMP(((*collectionIter).band.maxFreq - minHertz) / (maxHertz - minHertz), 0.0f, 1.0f) *
								 CLAMP(1.0f - (((*collectionIter).band.minFreq - minHertz) / (maxHertz - minHertz)), 0.0f, 1.0f);

			leftIntensity = max(leftSpectrum_[entry] * (*collectionIter).level * contribution, leftIntensity);
			rightIntensity = max(rightSpectrum_[entry] * (*collectionIter).level * contribution, rightIntensity);

			minHertz = maxHertz;
			maxHertz += ENTRY_HZ;
		}

		//Apply a degree of smoothing to the changing colour responces
		leftIntensity = (((leftIntensity * spectrumVolume_) - (*collectionIter).leftIntensity) / smoothingFactor_) + (*collectionIter).leftIntensity;
		rightIntensity = (((rightIntensity * spectrumVolume_) - (*collectionIter).rightIntensity) / smoothingFactor_) + (*collectionIter).rightIntensity;
		
		//Record newly calculated intensity values
		(*collectionIter).leftIntensity = leftIntensity;
		(*collectionIter).rightIntensity = rightIntensity;


		//Introduce the responce bands colour for the left channel, proportional to the calculated intensity
		leftColour.r += leftIntensity * (*collectionIter).colour.r;
		leftColour.g += leftIntensity * (*collectionIter).colour.g;
		leftColour.b += leftIntensity * (*collectionIter).colour.b;

		//Introduce the responce bands colour for the right channel, proportional to the calculated intensity
		rightColour.r += rightIntensity * (*collectionIter).colour.r;
		rightColour.g += rightIntensity * (*collectionIter).colour.g;
		rightColour.b += rightIntensity * (*collectionIter).colour.b;
		

		collectionIter++;
	}

	if(!bandResponceCollections_->empty())
	{
		leftColour.r = LOGSCALE(leftColour.r / bandResponceCollections_->size());
		leftColour.g = LOGSCALE(leftColour.g / bandResponceCollections_->size());
		leftColour.b = LOGSCALE(leftColour.b / bandResponceCollections_->size());

		rightColour.r = LOGSCALE(rightColour.r / bandResponceCollections_->size());
		rightColour.g = LOGSCALE(rightColour.g / bandResponceCollections_->size());
		rightColour.b = LOGSCALE(rightColour.b / bandResponceCollections_->size());
	}


}