// 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); }
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++; } }
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); }
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]); }
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; }
ResponceCollection::ResponceCollection(void) { colour = RGBColour(); band = ResponceBand(); level = 1.0f; leftIntensity = 0.0f; rightIntensity = 0.0f; }
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); }
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); }
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); }
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 }
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 ); } } }
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; }
RGBColour DifferentialSurface::Le(const Vector3& p_w) const { const AreaLight *area = primitive->GetAreaLight(); return area ? area->L(point, normal, p_w) : RGBColour(0.); }
static RGBColour White() { return RGBColour(255, 255, 255); }
// Colour constants static RGBColour Black() { return RGBColour(0, 0, 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()); } }