extern int raymixture( /* mix modifiers */ RAY *r, OBJECT fore, OBJECT back, double coef ) { RAY fr, br; int foremat, backmat; int i; /* bound coefficient */ if (coef > 1.0) coef = 1.0; else if (coef < 0.0) coef = 0.0; /* compute foreground and background */ foremat = backmat = 0; /* foreground */ fr = *r; if (coef > FTINY) { fr.rweight *= coef; scalecolor(fr.rcoef, coef); foremat = rayshade(&fr, fore); } /* background */ br = *r; if (coef < 1.0-FTINY) { br.rweight *= 1.0-coef; scalecolor(br.rcoef, 1.0-coef); backmat = rayshade(&br, back); } /* check for transparency */ if (backmat ^ foremat) { if (backmat && coef > FTINY) raytrans(&fr); else if (foremat && coef < 1.0-FTINY) raytrans(&br); } /* mix perturbations */ for (i = 0; i < 3; i++) r->pert[i] = coef*fr.pert[i] + (1.0-coef)*br.pert[i]; /* mix pattern colors */ scalecolor(fr.pcol, coef); scalecolor(br.pcol, 1.0-coef); copycolor(r->pcol, fr.pcol); addcolor(r->pcol, br.pcol); /* return value tells if material */ if (!foremat & !backmat) return(0); /* mix returned ray values */ scalecolor(fr.rcol, coef); scalecolor(br.rcol, 1.0-coef); copycolor(r->rcol, fr.rcol); addcolor(r->rcol, br.rcol); r->rt = bright(fr.rcol) > bright(br.rcol) ? fr.rt : br.rt; return(1); }
/* Estimate variance based on ambient division differences */ static float * getambdiffs(AMBHEMI *hp) { const double normf = 1./bright(hp->acoef); float *earr = (float *)calloc(hp->ns*hp->ns, sizeof(float)); float *ep; AMBSAMP *ap; double b, b1, d2; int i, j; if (earr == NULL) /* out of memory? */ return(NULL); /* sum squared neighbor diffs */ for (ap = hp->sa, ep = earr, i = 0; i < hp->ns; i++) for (j = 0; j < hp->ns; j++, ap++, ep++) { b = bright(ap[0].v); if (i) { /* from above */ b1 = bright(ap[-hp->ns].v); d2 = b - b1; d2 *= d2*normf/(b + b1); ep[0] += d2; ep[-hp->ns] += d2; } if (!j) continue; /* from behind */ b1 = bright(ap[-1].v); d2 = b - b1; d2 *= d2*normf/(b + b1); ep[0] += d2; ep[-1] += d2; if (!i) continue; /* diagonal */ b1 = bright(ap[-hp->ns-1].v); d2 = b - b1; d2 *= d2*normf/(b + b1); ep[0] += d2; ep[-hp->ns-1] += d2; } /* correct for number of neighbors */ earr[0] *= 8./3.; earr[hp->ns-1] *= 8./3.; earr[(hp->ns-1)*hp->ns] *= 8./3.; earr[(hp->ns-1)*hp->ns + hp->ns-1] *= 8./3.; for (i = 1; i < hp->ns-1; i++) { earr[i*hp->ns] *= 8./5.; earr[i*hp->ns + hp->ns-1] *= 8./5.; } for (j = 1; j < hp->ns-1; j++) { earr[j] *= 8./5.; earr[(hp->ns-1)*hp->ns + j] *= 8./5.; } return(earr); }
void LocationEditor::RenderModeCameraMount() { RGBAColour bright(255,255,0); RGBAColour dim(90,90,0); LList <CameraAnimation*> *list = &g_app->m_location->m_levelFile->m_cameraAnimations; for (int i = 0; i < list->Size(); ++i) { CameraAnimation *anim = list->GetData(i); CamAnimNode *lastNode = anim->m_nodes.GetData(0); for (int j = 1; j < anim->m_nodes.Size(); ++j) { CamAnimNode *node = anim->m_nodes.GetData(j); if (stricmp(node->m_mountName, MAGIC_MOUNT_NAME_START_POS) == 0 || stricmp(lastNode->m_mountName, MAGIC_MOUNT_NAME_START_POS) == 0) { continue; } CameraMount *mount1 = g_app->m_location->m_levelFile->GetCameraMount(lastNode->m_mountName); CameraMount *mount2 = g_app->m_location->m_levelFile->GetCameraMount(node->m_mountName); if (i == m_selectionId) { RenderArrow(mount1->m_pos, mount2->m_pos, 1.0, bright); } else { RenderArrow(mount1->m_pos, mount2->m_pos, 1.0, dim); } lastNode = node; } } }
void Canvas::DrawButton(PixelRect rc, bool down) { const Pen old_pen = pen; Color gray = COLOR_LIGHT_GRAY; DrawFilledRectangle(rc, gray); Pen bright(1, LightColor(gray)); Pen dark(1, DarkColor(gray)); Select(down ? dark : bright); DrawTwoLines(rc.left, rc.bottom - 2, rc.left, rc.top, rc.right - 2, rc.top); DrawTwoLines(rc.left + 1, rc.bottom - 3, rc.left + 1, rc.top + 1, rc.right - 3, rc.top + 1); Select(down ? bright : dark); DrawTwoLines(rc.left + 1, rc.bottom - 1, rc.right - 1, rc.bottom - 1, rc.right - 1, rc.top + 1); DrawTwoLines(rc.left + 2, rc.bottom - 2, rc.right - 2, rc.bottom - 2, rc.right - 2, rc.top + 2); pen = old_pen; }
static double rgb_bright( COLOR clr ) { return(bright(clr)); }
//------------------------------------------------------------------------------ void Canvas::DrawRaisedEdge(PixelRect &rc) { Pen bright(1, Color(240, 240, 240)); this->Select(bright); this->DrawTwoLinesExact(rc.left, rc.bottom - 2, rc.left, rc.top, rc.right - 2, rc.top); Pen dark(1, Color(128, 128, 128)); this->Select(dark); this->DrawTwoLinesExact(rc.left + 1, rc.bottom - 1, rc.right - 1, rc.bottom - 1, rc.right - 1, rc.top + 1); ++rc.left; ++rc.top; --rc.right; --rc.bottom; }
static AMBHEMI * samp_hemi( /* sample indirect hemisphere */ COLOR rcol, RAY *r, double wt ) { AMBHEMI *hp; double d; int n, i, j; /* insignificance check */ if (bright(rcol) <= FTINY) return(NULL); /* set number of divisions */ if (ambacc <= FTINY && wt > (d = 0.8*intens(rcol)*r->rweight/(ambdiv*minweight))) wt = d; /* avoid ray termination */ n = sqrt(ambdiv * wt) + 0.5; i = 1 + 5*(ambacc > FTINY); /* minimum number of samples */ if (n < i) n = i; /* allocate sampling array */ hp = (AMBHEMI *)malloc(sizeof(AMBHEMI) + sizeof(AMBSAMP)*(n*n - 1)); if (hp == NULL) error(SYSTEM, "out of memory in samp_hemi"); hp->rp = r; hp->ns = n; hp->acol[RED] = hp->acol[GRN] = hp->acol[BLU] = 0.0; memset(hp->sa, 0, sizeof(AMBSAMP)*n*n); hp->sampOK = 0; /* assign coefficient */ copycolor(hp->acoef, rcol); d = 1.0/(n*n); scalecolor(hp->acoef, d); /* make tangent plane axes */ if (!getperpendicular(hp->ux, r->ron, 1)) error(CONSISTENCY, "bad ray direction in samp_hemi"); VCROSS(hp->uy, r->ron, hp->ux); /* sample divisions */ for (i = hp->ns; i--; ) for (j = hp->ns; j--; ) hp->sampOK += ambsample(hp, i, j, 0); copycolor(rcol, hp->acol); if (!hp->sampOK) { /* utter failure? */ free(hp); return(NULL); } if (hp->sampOK < hp->ns*hp->ns) { hp->sampOK *= -1; /* soft failure */ return(hp); } if (hp->sampOK < 64) return(hp); /* insufficient for super-sampling */ n = ambssamp*wt + 0.5; if (n > 8) { /* perform super-sampling? */ ambsupersamp(hp, n); copycolor(rcol, hp->acol); } return(hp); /* all is well */ }
virtual void onDraw(SkCanvas* canvas) { SkRect r = SkRect::MakeWH(FILTER_WIDTH, FILTER_HEIGHT); SkPaint paint; paint.setColor(SK_ColorRED); canvas->save(); for (float brightness = -1.0f; brightness <= 1.0f; brightness += 0.2f) { SkAutoTUnref<SkImageFilter> dim(make_brightness(-brightness)); SkAutoTUnref<SkImageFilter> bright(make_brightness(brightness, dim)); paint.setImageFilter(bright); drawClippedRect(canvas, r, paint); canvas->translate(FILTER_WIDTH + MARGIN, 0); } canvas->restore(); canvas->translate(0, FILTER_HEIGHT + MARGIN); { SkAutoTUnref<SkImageFilter> brightness(make_brightness(0.9f)); SkAutoTUnref<SkImageFilter> grayscale(make_grayscale(brightness)); paint.setImageFilter(grayscale); drawClippedRect(canvas, r, paint); canvas->translate(FILTER_WIDTH + MARGIN, 0); } { SkAutoTUnref<SkImageFilter> grayscale(make_grayscale()); SkAutoTUnref<SkImageFilter> brightness(make_brightness(0.9f, grayscale)); paint.setImageFilter(brightness); drawClippedRect(canvas, r, paint); canvas->translate(FILTER_WIDTH + MARGIN, 0); } { SkAutoTUnref<SkImageFilter> blue(make_mode_blue()); SkAutoTUnref<SkImageFilter> brightness(make_brightness(1.0f, blue)); paint.setImageFilter(brightness); drawClippedRect(canvas, r, paint); canvas->translate(FILTER_WIDTH + MARGIN, 0); } { SkAutoTUnref<SkImageFilter> brightness(make_brightness(1.0f)); SkAutoTUnref<SkImageFilter> blue(make_mode_blue(brightness)); paint.setImageFilter(blue); drawClippedRect(canvas, r, paint); canvas->translate(FILTER_WIDTH + MARGIN, 0); } { SkAutoTUnref<SkImageFilter> blur(make_blur(3.0f)); SkAutoTUnref<SkImageFilter> brightness(make_brightness(0.5f, blur)); paint.setImageFilter(brightness); drawClippedRect(canvas, r, paint, 3); canvas->translate(FILTER_WIDTH + MARGIN, 0); } { SkAutoTUnref<SkImageFilter> blue(make_mode_blue()); paint.setImageFilter(blue.get()); drawClippedRect(canvas, r, paint, 5); canvas->translate(FILTER_WIDTH + MARGIN, 0); } }
static int cresp( /* transform color according to matrix */ COLOR cout, COLOR cin ) { colortrans(cout, solmat, cin); return(clipgamut(cout, bright(cout), CGAMUT, colmin, colmax)); }
void lightinit() /* initialize lighting */ { GLfloat ambv[4]; if (!dolights) return; glPushAttrib(GL_LIGHTING_BIT); if (expval <= FTINY && bright(ambval) > FTINY) expval = 0.2/bright(ambval); ambv[0] = expval*colval(ambval,RED); ambv[1] = expval*colval(ambval,GRN); ambv[2] = expval*colval(ambval,BLU); ambv[3] = 1.; glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambv); glCallList(lightlist = newglist()); rgl_checkerr("in lightinit"); nlights = 0; }
static void picdebug(void) /* put out debugging picture */ { static COLOR blkcol = BLKCOLOR; COLOR *scan; int y, i; register int x, rg; if (fseek(stdin, 0L, 0) == EOF) { fprintf(stderr, "%s: cannot seek on input picture\n", progname); exit(1); } getheader(stdin, NULL, NULL); /* skip input header */ fgetresolu(&xmax, &ymax, stdin); /* allocate scanline */ scan = (COLOR *)malloc(xmax*sizeof(COLOR)); if (scan == NULL) { perror(progname); exit(1); } /* finish debug header */ fputformat(COLRFMT, debugfp); putc('\n', debugfp); fprtresolu(xmax, ymax, debugfp); /* write debug picture */ for (y = ymax-1; y >= 0; y--) { if (freadscan(scan, xmax, stdin) < 0) { fprintf(stderr, "%s: error rereading input picture\n", progname); exit(1); } for (x = 0; x < xmax; x++) { rg = chartndx(x, y, &i); if (rg == RG_CENT) { if (!(1L<<i & gmtflags) || (x+y)&07) { copycolor(scan[x], mbRGB[i]); clipgamut(scan[x], bright(scan[x]), CGAMUT, colmin, colmax); } else copycolor(scan[x], blkcol); } else if (rg == RG_CORR) cvtcolor(scan[x], scan[x]); else if (rg != RG_ORIG) copycolor(scan[x], blkcol); } if (fwritescan(scan, xmax, debugfp) < 0) { fprintf(stderr, "%s: error writing debugging picture\n", progname); exit(1); } } /* clean up */ fclose(debugfp); free((void *)scan); }
float drawerWidget::getBright() { int x, y; int temp = 0; for(x = 0; x < buffer.width(); x++) for(y = 0; y < buffer.height(); y++) { temp += bright(buffer.pixel(x,y)); } return (float)temp/(float)(buffer.height()*buffer.width()*255); }
float * /* keep consistent with COLOR typedef */ greyof( /* convert color to greyscale */ COLOR col ) { static COLOR gcol; double b; b = bright(col); setcolor(gcol, b, b, b); return(gcol); }
void onDraw(const int loops, SkCanvas* canvas) override { SkRect r = getFilterRect(); SkPaint paint; paint.setColor(SK_ColorRED); for (int i = 0; i < loops; i++) { for (float brightness = -1.0f; brightness <= 1.0f; brightness += 0.4f) { SkAutoTUnref<SkImageFilter> dim(make_brightness(-brightness)); SkAutoTUnref<SkImageFilter> bright(make_brightness(brightness, dim)); paint.setImageFilter(bright); canvas->drawRect(r, paint); } } }
QImage convertImage(const QImage& image, int hue, int saturation, int brightness, int gamma) { float mat[3][3] = {{1.0,0.0,0.0},{0.0,1.0,0.0},{0.0,0.0,1.0}}; int lut[3][3][256]; QRgb c; int r,g,b,v,r2,g2,b2; float gam = 1.0/(float(gamma)/1000.0); QImage img(image); saturate(mat,saturation*0.01); huerotate(mat,(float)hue); bright(mat,brightness*0.01); for (int i = 0; i < 3; i ++) for (int j = 0; j < 3; j ++) for (int k = 0; k < 256; k ++) lut[i][j][k] = (int)(mat[i][j] * k + 0.5); img.detach(); for (int i=0;i<image.width();i++) for (int j=0;j<image.height();j++) { c = image.pixel(i,j); r = qRed(c); g = qGreen(c); b = qBlue(c); v = lut[0][0][r] + lut[1][0][g] + lut[2][0][b]; if (gamma != 1000) v = (int)rint(pow(v,gam)); if (v < 0) r2 = 0; else if (v > 255) r2 = 255; else r2 = v; v = lut[0][1][r] + lut[1][1][g] + lut[2][1][b]; if (gamma != 1000) v = (int)rint(pow(v,gam)); if (v < 0) g2 = 0; else if (v > 255) g2 = 255; else g2 = v; v = lut[0][2][r] + lut[1][2][g] + lut[2][2][b]; if (gamma != 1000) v = (int)rint(pow(v,gam)); if (v < 0) b2 = 0; else if (v > 255) b2 = 255; else b2 = v; img.setPixel(i,j,qRgb(r2,g2,b2)); } return img; }
static double greypoint( /* compute gamut mapping grey target */ COLOR col ) { COLOR gryc; int i; /* improves saturated color rendering */ copycolor(gryc, col); for (i = 3; i--; ) if (gryc[i] > 1) gryc[i] = 1; else if (gryc[i] < 0) gryc[i] = 0; return(bright(gryc)); }
void raised_edge(PixelRect &rc) { Pen bright(1, Color(240, 240, 240)); select(bright); two_lines(rc.left, rc.bottom - 2, rc.left, rc.top, rc.right - 2, rc.top); Pen dark(1, Color(128, 128, 128)); select(dark); two_lines(rc.left + 1, rc.bottom - 1, rc.right - 1, rc.bottom - 1, rc.right - 1, rc.top + 1); ++rc.left; ++rc.top; --rc.right; --rc.bottom; }
static int cvtcolor( /* convert color according to our mapping */ COLOR cout, COLOR cin ) { COLOR ctmp; int clipped; if (wcor != NULL) { clipped = warp3d(cout, cin, wcor); clipped |= clipgamut(cout,bright(cout),CGAMUT,colmin,colmax); } else if (scanning) { bresp(ctmp, cin); clipped = cresp(cout, ctmp); } else { clipped = cresp(ctmp, cin); bresp(cout, ctmp); } return(clipped); }
static AMBVAL * avstore( /* allocate memory and store aval */ AMBVAL *aval ) { AMBVAL *av; double d; if ((av = newambval()) == NULL) error(SYSTEM, "out of memory in avstore"); *av = *aval; av->latick = ambclock; av->next = NULL; nambvals++; d = bright(av->val); if (d > FTINY) { /* add to log sum for averaging */ avsum += log(d); navsum++; } return(av); }
void Canvas::draw_button(RECT rc, bool down) { Brush gray(Color(192, 192, 192)); fill_rectangle(rc, gray); Pen bright(1, Color(240, 240, 240)); Pen dark(1, Color(128, 128, 128)); select(down ? dark : bright); two_lines(rc.left, rc.bottom - 2, rc.left, rc.top, rc.right - 2, rc.top); two_lines(rc.left + 1, rc.bottom - 3, rc.left + 1, rc.top + 1, rc.right - 3, rc.top + 1); select(down ? bright : dark); two_lines(rc.left + 1, rc.bottom - 1, rc.right - 1, rc.bottom - 1, rc.right - 1, rc.top + 1); two_lines(rc.left + 2, rc.bottom - 2, rc.right - 2, rc.bottom - 2, rc.right - 2, rc.top + 2); white_pen(); }
Blob::Blob(PG_Widget* parent, PG_Rect r): PG_ThemeWidget(parent, r, true){ starttimer = 0; vmem1=NULL; vmem2= (unsigned char *)malloc(XSIZE*YSIZE); if(!vmem2) nomem(); mul640= (unsigned char **)malloc(YSIZE*sizeof(char *)); if(!mul640) nomem(); remap= (char *)malloc(16384); if(!remap) nomem(); remap2=(char *)malloc(16384); if(!remap2) nomem(); blobs= (explosion *)malloc(MAXBLOBS*sizeof(struct explosion)); if(!blobs) nomem(); freeblobs=activeblobs=0; for(int i=0;i<MAXBLOBS;i++) { blobs[i].blobnext=freeblobs; freeblobs=blobs+i; } normal(remap); bright(remap2); explosion_surface = SDL_CreateRGBSurface(SDL_SWSURFACE, my_width, my_height, 8, 0,0,0,0); flash=0; whichmap=0; loadcolors(whichmap); //addblob(); now=0; }
extern void direct( /* add direct component */ RAY *r, /* ray that hit surface */ srcdirf_t *f, /* direct component coefficient function */ void *p /* data for f */ ) { register int sn; register CONTRIB *scp; SRCINDEX si; int nshadcheck, ncnts; int nhits; double prob, ourthresh, hwt; RAY sr; /* NOTE: srccnt and cntord global so no recursion */ if (nsources <= 0) return; /* no sources?! */ /* potential contributions */ initsrcindex(&si); for (sn = 0; srcray(&sr, r, &si); sn++) { if (sn >= maxcntr) { maxcntr = sn + MAXSPART; srccnt = (CONTRIB *)realloc((void *)srccnt, maxcntr*sizeof(CONTRIB)); cntord = (CNTPTR *)realloc((void *)cntord, maxcntr*sizeof(CNTPTR)); if ((srccnt == NULL) | (cntord == NULL)) error(SYSTEM, "out of memory in direct"); } cntord[sn].sndx = sn; scp = srccnt + sn; scp->sno = sr.rsrc; /* compute coefficient */ (*f)(scp->coef, p, sr.rdir, si.dom); cntord[sn].brt = intens(scp->coef); if (cntord[sn].brt <= 0.0) continue; #if SHADCACHE /* check shadow cache */ if (si.np == 1 && srcblocked(&sr)) { cntord[sn].brt = 0.0; continue; } #endif VCOPY(scp->dir, sr.rdir); copycolor(sr.rcoef, scp->coef); /* compute potential */ sr.revf = srcvalue; rayvalue(&sr); multcolor(sr.rcol, sr.rcoef); copycolor(scp->val, sr.rcol); cntord[sn].brt = bright(sr.rcol); } /* sort contributions */ qsort(cntord, sn, sizeof(CNTPTR), cntcmp); { /* find last */ register int l, m; ncnts = l = sn; sn = 0; while ((m = (sn + ncnts) >> 1) != l) { if (cntord[m].brt > 0.0) sn = m; else ncnts = m; l = m; } } if (ncnts == 0) return; /* no contributions! */ /* accumulate tail */ for (sn = ncnts-1; sn > 0; sn--) cntord[sn-1].brt += cntord[sn].brt; /* compute number to check */ nshadcheck = pow((double)ncnts, shadcert) + .5; /* modify threshold */ ourthresh = shadthresh / r->rweight; /* test for shadows */ for (nhits = 0, hwt = 0.0, sn = 0; sn < ncnts; hwt += (double)source[scp->sno].nhits / (double)source[scp->sno].ntests, sn++) { /* check threshold */ if ((sn+nshadcheck>=ncnts ? cntord[sn].brt : cntord[sn].brt-cntord[sn+nshadcheck].brt) < ourthresh*bright(r->rcol)) break; scp = srccnt + cntord[sn].sndx; /* test for hit */ rayorigin(&sr, SHADOW, r, NULL); copycolor(sr.rcoef, scp->coef); VCOPY(sr.rdir, scp->dir); sr.rsrc = scp->sno; /* keep statistics */ if (source[scp->sno].ntests++ > 0xfffffff0) { source[scp->sno].ntests >>= 1; source[scp->sno].nhits >>= 1; } if (localhit(&sr, &thescene) && ( sr.ro != source[scp->sno].so || source[scp->sno].sflags & SFOLLOW )) { /* follow entire path */ raycont(&sr); if (trace != NULL) (*trace)(&sr); /* trace execution */ if (bright(sr.rcol) <= FTINY) { #if SHADCACHE if ((scp <= srccnt || scp[-1].sno != scp->sno) && (scp >= srccnt+ncnts-1 || scp[1].sno != scp->sno)) srcblocker(&sr); #endif continue; /* missed! */ } rayparticipate(&sr); multcolor(sr.rcol, sr.rcoef); copycolor(scp->val, sr.rcol); } else if (trace != NULL && (source[scp->sno].sflags & (SDISTANT|SVIRTUAL|SFOLLOW)) == (SDISTANT|SFOLLOW) && sourcehit(&sr) && rayshade(&sr, sr.ro->omod)) { (*trace)(&sr); /* trace execution */ /* skip call to rayparticipate() & scp->val update */ } /* add contribution if hit */ addcolor(r->rcol, scp->val); nhits++; source[scp->sno].nhits++; }
static int disperse( /* check light sources for dispersion */ OBJREC *m, RAY *r, FVECT vt, double tr, COLOR cet, COLOR abt ) { RAY sray; const RAY *entray; FVECT v1, v2, n1, n2; FVECT dv, v2Xdv; double v2Xdvv2Xdv; int success = 0; SRCINDEX si; FVECT vtmp1, vtmp2; double dtmp1, dtmp2; int l1, l2; COLOR ctmp; int i; /* * This routine computes dispersion to the first order using * the following assumptions: * * 1) The dependency of the index of refraction on wavelength * is approximated by Hartmann's equation with lambda0 * equal to zero. * 2) The entry and exit locations are constant with respect * to dispersion. * * The second assumption permits us to model dispersion without * having to sample refracted directions. We assume that the * geometry inside the material is constant, and concern ourselves * only with the relationship between the entering and exiting ray. * We compute the first derivatives of the entering and exiting * refraction with respect to the index of refraction. This * is then used in a first order Taylor series to determine the * index of refraction necessary to send the exiting ray to each * light source. * If an exiting ray hits a light source within the refraction * boundaries, we sum all the frequencies over the disc of the * light source to determine the resulting color. A smaller light * source will therefore exhibit a sharper spectrum. */ if (!(r->crtype & REFRACTED)) { /* ray started in material */ VCOPY(v1, r->rdir); n1[0] = -r->rdir[0]; n1[1] = -r->rdir[1]; n1[2] = -r->rdir[2]; } else { /* find entry point */ for (entray = r; entray->rtype != REFRACTED; entray = entray->parent) ; entray = entray->parent; if (entray->crtype & REFRACTED) /* too difficult */ return(0); VCOPY(v1, entray->rdir); VCOPY(n1, entray->ron); } VCOPY(v2, vt); /* exiting ray */ VCOPY(n2, r->ron); /* first order dispersion approx. */ dtmp1 = 1./DOT(n1, v1); dtmp2 = 1./DOT(n2, v2); for (i = 0; i < 3; i++) dv[i] = v1[i] + v2[i] - n1[i]*dtmp1 - n2[i]*dtmp2; if (DOT(dv, dv) <= FTINY) /* null effect */ return(0); /* compute plane normal */ fcross(v2Xdv, v2, dv); v2Xdvv2Xdv = DOT(v2Xdv, v2Xdv); /* check sources */ initsrcindex(&si); while (srcray(&sray, r, &si)) { if (DOT(sray.rdir, v2) < MINCOS) continue; /* bad source */ /* adjust source ray */ dtmp1 = DOT(v2Xdv, sray.rdir) / v2Xdvv2Xdv; sray.rdir[0] -= dtmp1 * v2Xdv[0]; sray.rdir[1] -= dtmp1 * v2Xdv[1]; sray.rdir[2] -= dtmp1 * v2Xdv[2]; l1 = lambda(m, v2, dv, sray.rdir); /* mean lambda */ if (l1 > MAXLAMBDA || l1 < MINLAMBDA) /* not visible */ continue; /* trace source ray */ copycolor(sray.cext, cet); copycolor(sray.albedo, abt); normalize(sray.rdir); rayvalue(&sray); if (bright(sray.rcol) <= FTINY) /* missed it */ continue; /* * Compute spectral sum over diameter of source. * First find directions for rays going to opposite * sides of source, then compute wavelengths for each. */ fcross(vtmp1, v2Xdv, sray.rdir); dtmp1 = sqrt(si.dom / v2Xdvv2Xdv / PI); /* compute first ray */ VSUM(vtmp2, sray.rdir, vtmp1, dtmp1); l1 = lambda(m, v2, dv, vtmp2); /* first lambda */ if (l1 < 0) continue; /* compute second ray */ VSUM(vtmp2, sray.rdir, vtmp1, -dtmp1); l2 = lambda(m, v2, dv, vtmp2); /* second lambda */ if (l2 < 0) continue; /* compute color from spectrum */ if (l1 < l2) spec_rgb(ctmp, l1, l2); else spec_rgb(ctmp, l2, l1); multcolor(ctmp, sray.rcol); scalecolor(ctmp, tr); addcolor(r->rcol, ctmp); success++; } return(success); }
void Compressor::Compress(unsigned int *out) { /* Create the matrix with the original data */ Eigen::MatrixXi orig(height_, width_); for (int y = 0; y < height_; ++y) { for (int x = 0; x < width_; ++x) { orig(y, x) = data_[y*width_ + x]; } } /* Get the internal data format */ util::DATA_FORMAT df = util::ImageToData(format_); /* Convert to YUV if necessary */ Eigen::MatrixXi bits; if (format_ == PVRTC_4BPP || format_ == PVRTC_2BPP) { bits = orig; } else { bits = util::RGBtoYUV(orig); } /* Wavelet filter */ Eigen::MatrixXi result = util::Downscale(bits); /* Initial dark and bright prototypes */ Eigen::Vector3i offset(32, 32, 32); Eigen::MatrixXi dark(result.rows(), result.cols()); Eigen::MatrixXi bright(result.rows(), result.cols()); #ifdef USE_OPENMP #pragma omp parallel for #endif for(int y = 0; y < result.rows(); ++y) { for(int x = 0; x < result.cols(); ++x) { Eigen::Vector3i color = util::MakeColorVector(result(y, x), util::PVR888); dark(y, x) = util::MakeRGB(color - offset, df); bright(y, x) = util::MakeRGB(color + offset, df); } } // Eigen::MatrixXi dark = result - offset; // Eigen::MatrixXi bright = result + offset; /* Iterative optimization */ Optimizer opt(bits, dark, bright, Optimizer::SVD, df); float prev_err = std::numeric_limits<float>::max(); float curr_err = std::numeric_limits<float>::max(); for (int k = 0; (k < 4 || (prev_err - curr_err) > 1e-10) && (k < 20); ++k) { /* Least squares optimization */ opt.Optimize(ComputeModulation(bits, util::Upscale4x4(opt.dark(), df), util::Upscale4x4(opt.bright(), df))); /* Get the current error */ result = util::ModulateImage(util::Upscale4x4(opt.dark(), df), util::Upscale4x4(opt.bright(), df), opt.mod()); prev_err = curr_err; curr_err = util::ComputeError(orig, result); } /* Write the final output */ result = util::ModulateImage(util::Upscale4x4(opt.dark(), df), util::Upscale4x4(opt.bright(), df), opt.mod()); /* Convert back to RGB if necessary */ if (!(format_ == PVRTC_4BPP || format_ == PVRTC_2BPP)) { result = util::YUVtoRGB(result); } for (int y = 0; y < result.rows(); ++y) { for (int x = 0; x < result.cols(); ++x) { out[y*width_ + x] = result(y, x); } } /* Get the error */ std::cout << "RMS Error: " << util::ComputeError(orig, result) << std::endl; }
extern void multambient( /* compute ambient component & multiply by coef. */ COLOR aval, RAY *r, FVECT nrm ) { static int rdepth = 0; /* ambient recursion */ COLOR acol; double d, l; if (ambdiv <= 0) /* no ambient calculation */ goto dumbamb; /* check number of bounces */ if (rdepth >= ambounce) goto dumbamb; /* check ambient list */ if (ambincl != -1 && r->ro != NULL && ambincl != inset(ambset, r->ro->omod)) goto dumbamb; if (ambacc <= FTINY) { /* no ambient storage */ copycolor(acol, aval); rdepth++; d = doambient(acol, r, r->rweight, NULL, NULL); rdepth--; if (d <= FTINY) goto dumbamb; copycolor(aval, acol); return; } if (tracktime) /* sort to minimize thrashing */ sortambvals(0); /* interpolate ambient value */ setcolor(acol, 0.0, 0.0, 0.0); d = sumambient(acol, r, nrm, rdepth, &atrunk, thescene.cuorg, thescene.cusize); if (d > FTINY) { d = 1.0/d; scalecolor(acol, d); multcolor(aval, acol); return; } rdepth++; /* need to cache new value */ d = makeambient(acol, r, nrm, rdepth-1); rdepth--; if (d > FTINY) { multcolor(aval, acol); /* got new value */ return; } dumbamb: /* return global value */ if ((ambvwt <= 0) | (navsum == 0)) { multcolor(aval, ambval); return; } l = bright(ambval); /* average in computations */ if (l > FTINY) { d = (log(l)*(double)ambvwt + avsum) / (double)(ambvwt + navsum); d = exp(d) / l; scalecolor(aval, d); multcolor(aval, ambval); /* apply color of ambval */ } else { d = exp( avsum / (double)navsum ); scalecolor(aval, d); /* neutral color */ } }
void getexposure( /* get new exposure */ char *s ) { char buf[128]; char *cp; int x, y; PNODE *p = &ptrunk; int adapt = 0; double e = 1.0; for (cp = s; isspace(*cp); cp++) ; if (*cp == '@') { adapt++; while (isspace(*++cp)) ; } if (*cp == '\0') { /* normalize to point */ if (dev->getcur == NULL) return; (*dev->comout)("Pick point for exposure\n"); if ((*dev->getcur)(&x, &y) == ABORT) return; p = findrect(x, y, &ptrunk, -1); } else { if (*cp == '=') { /* absolute setting */ p = NULL; e = 1.0/exposure; for (cp++; isspace(*cp); cp++) ; if (*cp == '\0') { /* interactive */ sprintf(buf, "exposure (%f): ", exposure); (*dev->comout)(buf); (*dev->comin)(buf, NULL); for (cp = buf; isspace(*cp); cp++) ; if (*cp == '\0') return; } } if (*cp == '+' || *cp == '-') /* f-stops */ e *= pow(2.0, atof(cp)); else /* multiplier */ e *= atof(cp); } if (p != NULL) { /* relative setting */ compavg(p); if (bright(p->v) < 1e-15) { error(COMMAND, "cannot normalize to zero"); return; } if (adapt) e *= 106./pow(1.219+pow(luminance(p->v)/exposure,.4),2.5)/exposure; else e *= 0.5 / bright(p->v); } if (e <= FTINY || fabs(1.0 - e) <= FTINY) return; scalepict(&ptrunk, e); exposure *= e; redraw(); }
void exportBy(const QImage& bg, const QImage& smap) { if (bg.size() != smap.size()) //assert size match return; Vec3 lp = Session::get()->canvas()->lightPos3D(); int W = bg.width(), H = bg.height(); RGBA histogram[BUCKETS][SAT_BUCKETS][BUCKETS]; for(int i_h = 0; i_h < H; i_h++) { for(int i_w = 0; i_w < W; i_w++) { //QColor col = QColor(_img.pixel( x - (ww/2) + i, y - (hh/2) + j )); QColor col(bg.pixel(i_w, i_h)); float h = col.hueF(), s = col.saturationF(), v = col.valueF(); if (h < 0) continue; int bi_h = CLAMP((h * BUCKETS), 0 , BUCKETS-1), bi_s = CLAMP((s * SAT_BUCKETS), 0 , SAT_BUCKETS-1), bi_v = CLAMP((v * BUCKETS), 0 , BUCKETS-1); histogram[bi_h][bi_s][bi_v] = histogram[bi_h][bi_s][bi_v] + RGBA(col.redF(), col.greenF(), col.blueF(),1); } } int size = W*H; //QImage darkI(W, H, QImage::Format_ARGB32); //QImage brightI(W, H, QImage::Format_ARGB32); uchar* darkbits = new uchar[size*4]; uchar* brightbits = new uchar[size*4]; uchar* final2bits = new uchar[size*4]; for(int i_h = 0; i_h < H; i_h++) { for(int i_w = 0; i_w < W; i_w++) { //QColor col = QColor(_img.pixel( x - (ww/2) + i, y - (hh/2) + j )); QRgb nrgb = smap.pixel(i_w, i_h); QColor coln(nrgb); if (qAlpha(nrgb) == 0) continue; //Vec3 n(coln.redF(), coln.greenF(), coln.blueF()); Vec3 n(coln.redF()*2.0-1.0, coln.greenF()*2.0-1.0,0); n.z = sqrt(n.x*n.x + n.y*n.y); //if (n.norm()>1.0) continue; double px = i_w *2.0 / (W-1) - 1.0; double py = (H - i_h - 1)*2.0 / (H-1) - 1.0; Vec3 lvn = (lp - Vec3(px, py, 0)).normalize(); float cosa = n * lvn; float t = (cosa+1)/2.0; t = CLAMP(t, 0.0, 1.0); QColor col(bg.pixel(i_w, i_h)); RGB dark(0, 0, 0); RGB bright(1,1,1); RGB final(col.redF(), col.greenF(), col.blueF()); if (col.hueF()>=0) { int bi_h = col.hueF()*BUCKETS, bi_s = col.saturationF()*SAT_BUCKETS, iD, iB; findDandB(histogram[bi_h][bi_s], iD, iB); dark.set(histogram[bi_h][bi_s][iD]); bright.set(histogram[bi_h][bi_s][iB]); } //bright = (final-dark*(1.0-t))*(1.0/t); RGB final2 = bright*t + dark*(1-t); int off = (i_w + i_h*W)*4; for(int i=0; i<3; i++) { float k = final[i]/(final2[i]<0.0001?0.0001:final2[i]); darkbits[off+2-i] = CLAMP(dark[i]*k, 0.0, 1.0)*255; brightbits[off+2-i] =CLAMP(bright[i]*k, 0.0, 1.0)*255; final2bits[off+2-i] = final2[i]*255; } darkbits[off+3] = 255; brightbits[off+3] = 255; final2bits[off+3] = 255; } } QImage darkI(darkbits, W, H, QImage::Format_ARGB32); QImage brightI(brightbits, W, H, QImage::Format_ARGB32); QImage final2I(final2bits, W, H, QImage::Format_ARGB32); darkI.save("c:/temp/D.png"); brightI.save("c:/temp/B.png"); smap.save("c:/temp/smap.png"); final2I.save("c:/temp/final2.png"); }
static void dirbrdf( /* compute source contribution */ COLOR cval, /* returned coefficient */ void *nnp, /* material data */ FVECT ldir, /* light source direction */ double omega /* light source size */ ) { BRDFDAT *np = nnp; double ldot; double dtmp; COLOR ctmp; FVECT ldx; static double vldx[5], pt[MAXDIM]; char **sa; int i; #define lddx (vldx+1) setcolor(cval, 0.0, 0.0, 0.0); ldot = DOT(np->pnorm, ldir); if (ldot <= FTINY && ldot >= -FTINY) return; /* too close to grazing */ if (ldot < 0.0 ? np->trans <= FTINY : np->trans >= 1.0-FTINY) return; /* wrong side */ if (ldot > 0.0) { /* * Compute and add diffuse reflected component to returned * color. The diffuse reflected component will always be * modified by the color of the material. */ copycolor(ctmp, np->rdiff); dtmp = ldot * omega / PI; scalecolor(ctmp, dtmp); addcolor(cval, ctmp); } else { /* * Diffuse transmitted component. */ copycolor(ctmp, np->tdiff); dtmp = -ldot * omega / PI; scalecolor(ctmp, dtmp); addcolor(cval, ctmp); } if (ldot > 0.0 ? np->rspec <= FTINY : np->tspec <= FTINY) return; /* diffuse only */ /* set up function */ setbrdfunc(np); sa = np->mp->oargs.sarg; errno = 0; /* transform light vector */ multv3(ldx, ldir, funcxf.xfm); for (i = 0; i < 3; i++) lddx[i] = ldx[i]/funcxf.sca; lddx[3] = omega; /* compute BRTDF */ if (np->mp->otype == MAT_BRTDF) { if (sa[6][0] == '0') /* special case */ colval(ctmp,RED) = 0.0; else colval(ctmp,RED) = funvalue(sa[6], 4, lddx); if (sa[7][0] == '0') colval(ctmp,GRN) = 0.0; else if (!strcmp(sa[7],sa[6])) colval(ctmp,GRN) = colval(ctmp,RED); else colval(ctmp,GRN) = funvalue(sa[7], 4, lddx); if (!strcmp(sa[8],sa[6])) colval(ctmp,BLU) = colval(ctmp,RED); else if (!strcmp(sa[8],sa[7])) colval(ctmp,BLU) = colval(ctmp,GRN); else colval(ctmp,BLU) = funvalue(sa[8], 4, lddx); dtmp = bright(ctmp); } else if (np->dp == NULL) { dtmp = funvalue(sa[0], 4, lddx); setcolor(ctmp, dtmp, dtmp, dtmp); } else { for (i = 0; i < np->dp->nd; i++) pt[i] = funvalue(sa[3+i], 4, lddx); vldx[0] = datavalue(np->dp, pt); dtmp = funvalue(sa[0], 5, vldx); setcolor(ctmp, dtmp, dtmp, dtmp); } if ((errno == EDOM) | (errno == ERANGE)) { objerror(np->mp, WARNING, "compute error"); return; } if (dtmp <= FTINY) return; if (ldot > 0.0) { /* * Compute reflected non-diffuse component. */ if ((np->mp->otype == MAT_MFUNC) | (np->mp->otype == MAT_MDATA)) multcolor(ctmp, np->mcolor); dtmp = ldot * omega * np->rspec; scalecolor(ctmp, dtmp); addcolor(cval, ctmp); } else { /* * Compute transmitted non-diffuse component. */ if ((np->mp->otype == MAT_TFUNC) | (np->mp->otype == MAT_TDATA)) multcolor(ctmp, np->mcolor); dtmp = -ldot * omega * np->tspec; scalecolor(ctmp, dtmp); addcolor(cval, ctmp); } #undef lddx }
int m_brdf( /* color a ray that hit a BRDTfunc material */ OBJREC *m, RAY *r ) { int hitfront = 1; BRDFDAT nd; RAY sr; double mirtest=0, mirdist=0; double transtest=0, transdist=0; int hasrefl, hastrans; int hastexture; COLOR ctmp; FVECT vtmp; double d; MFUNC *mf; int i; /* check arguments */ if ((m->oargs.nsargs < 10) | (m->oargs.nfargs < 9)) objerror(m, USER, "bad # arguments"); nd.mp = m; nd.pr = r; /* dummy values */ nd.rspec = nd.tspec = 1.0; nd.trans = 0.5; /* diffuse reflectance */ if (r->rod > 0.0) setcolor(nd.rdiff, m->oargs.farg[0], m->oargs.farg[1], m->oargs.farg[2]); else setcolor(nd.rdiff, m->oargs.farg[3], m->oargs.farg[4], m->oargs.farg[5]); /* diffuse transmittance */ setcolor(nd.tdiff, m->oargs.farg[6], m->oargs.farg[7], m->oargs.farg[8]); /* get modifiers */ raytexture(r, m->omod); hastexture = DOT(r->pert,r->pert) > FTINY*FTINY; if (hastexture) { /* perturb normal */ nd.pdot = raynormal(nd.pnorm, r); } else { VCOPY(nd.pnorm, r->ron); nd.pdot = r->rod; } if (r->rod < 0.0) { /* orient perturbed values */ nd.pdot = -nd.pdot; for (i = 0; i < 3; i++) { nd.pnorm[i] = -nd.pnorm[i]; r->pert[i] = -r->pert[i]; } hitfront = 0; } copycolor(nd.mcolor, r->pcol); /* get pattern color */ multcolor(nd.rdiff, nd.mcolor); /* modify diffuse values */ multcolor(nd.tdiff, nd.mcolor); hasrefl = bright(nd.rdiff) > FTINY; hastrans = bright(nd.tdiff) > FTINY; /* load cal file */ nd.dp = NULL; mf = getfunc(m, 9, 0x3f, 0); /* compute transmitted ray */ setbrdfunc(&nd); errno = 0; setcolor(ctmp, evalue(mf->ep[3]), evalue(mf->ep[4]), evalue(mf->ep[5])); if ((errno == EDOM) | (errno == ERANGE)) objerror(m, WARNING, "compute error"); else if (rayorigin(&sr, TRANS, r, ctmp) == 0) { if (!(r->crtype & SHADOW) && hastexture) { /* perturb direction */ VSUM(sr.rdir, r->rdir, r->pert, -.75); if (normalize(sr.rdir) == 0.0) { objerror(m, WARNING, "illegal perturbation"); VCOPY(sr.rdir, r->rdir); } } else { VCOPY(sr.rdir, r->rdir); } rayvalue(&sr); multcolor(sr.rcol, sr.rcoef); addcolor(r->rcol, sr.rcol); if (!hastexture) { transtest = 2.0*bright(sr.rcol); transdist = r->rot + sr.rt; } } if (r->crtype & SHADOW) /* the rest is shadow */ return(1); /* compute reflected ray */ setbrdfunc(&nd); errno = 0; setcolor(ctmp, evalue(mf->ep[0]), evalue(mf->ep[1]), evalue(mf->ep[2])); if ((errno == EDOM) | (errno == ERANGE)) objerror(m, WARNING, "compute error"); else if (rayorigin(&sr, REFLECTED, r, ctmp) == 0) { VSUM(sr.rdir, r->rdir, nd.pnorm, 2.*nd.pdot); checknorm(sr.rdir); rayvalue(&sr); multcolor(sr.rcol, sr.rcoef); addcolor(r->rcol, sr.rcol); if (!hastexture && r->ro != NULL && isflat(r->ro->otype)) { mirtest = 2.0*bright(sr.rcol); mirdist = r->rot + sr.rt; } } /* compute ambient */ if (hasrefl) { if (!hitfront) flipsurface(r); copycolor(ctmp, nd.rdiff); multambient(ctmp, r, nd.pnorm); addcolor(r->rcol, ctmp); /* add to returned color */ if (!hitfront) flipsurface(r); } if (hastrans) { /* from other side */ if (hitfront) flipsurface(r); vtmp[0] = -nd.pnorm[0]; vtmp[1] = -nd.pnorm[1]; vtmp[2] = -nd.pnorm[2]; copycolor(ctmp, nd.tdiff); multambient(ctmp, r, vtmp); addcolor(r->rcol, ctmp); if (hitfront) flipsurface(r); } if (hasrefl | hastrans || m->oargs.sarg[6][0] != '0') direct(r, dirbrdf, &nd); /* add direct component */ d = bright(r->rcol); /* set effective distance */ if (transtest > d) r->rt = transdist; else if (mirtest > d) r->rt = mirdist; return(1); }
extern void /* add sources smaller than rad to computed subimage */ drawsources( COLOR *pic[], /* subimage pixel value array */ float *zbf[], /* subimage distance array (opt.) */ int x0, /* origin and size of subimage */ int xsiz, int y0, int ysiz ) { RREAL spoly[MAXVERT][2], ppoly[MAXVERT][2]; int nsv, npv; int xmin, xmax, ymin, ymax, x, y; RREAL cxy[2]; double w; RAY sr; register SPLIST *sp; register int i; /* check each source in our list */ for (sp = sphead; sp != NULL; sp = sp->next) { /* clip source poly to subimage */ nsv = box_clip_poly(sp->vl, sp->nv, (double)x0/hres, (double)(x0+xsiz)/hres, (double)y0/vres, (double)(y0+ysiz)/vres, spoly); if (!nsv) continue; /* find common subimage (BBox) */ xmin = x0 + xsiz; xmax = x0; ymin = y0 + ysiz; ymax = y0; for (i = 0; i < nsv; i++) { if ((double)xmin/hres > spoly[i][0]) xmin = spoly[i][0]*hres + FTINY; if ((double)xmax/hres < spoly[i][0]) xmax = spoly[i][0]*hres - FTINY; if ((double)ymin/vres > spoly[i][1]) ymin = spoly[i][1]*vres + FTINY; if ((double)ymax/vres < spoly[i][1]) ymax = spoly[i][1]*vres - FTINY; } /* evaluate each pixel in BBox */ for (y = ymin; y <= ymax; y++) for (x = xmin; x <= xmax; x++) { /* subarea for pixel */ npv = box_clip_poly(spoly, nsv, (double)x/hres, (x+1.)/hres, (double)y/vres, (y+1.)/vres, ppoly); if (!npv) continue; /* no overlap */ convex_center(ppoly, npv, cxy); if ((sr.rmax = viewray(sr.rorg,sr.rdir,&ourview, cxy[0],cxy[1])) < -FTINY) continue; /* not in view */ if (source[sp->sn].sflags & SSPOT && spotout(&sr, source[sp->sn].sl.s)) continue; /* outside spot */ rayorigin(&sr, SHADOW, NULL, NULL); sr.rsrc = sp->sn; rayvalue(&sr); /* compute value */ if (bright(sr.rcol) <= FTINY) continue; /* missed/blocked */ /* modify pixel */ w = poly_area(ppoly, npv) * hres * vres; if (zbf[y-y0] != NULL && sr.rt < 0.99*zbf[y-y0][x-x0]) { zbf[y-y0][x-x0] = sr.rt; } else if (!bigdiff(sr.rcol, pic[y-y0][x-x0], 0.01)) { /* source sample */ scalecolor(pic[y-y0][x-x0], w); continue; } scalecolor(sr.rcol, w); scalecolor(pic[y-y0][x-x0], 1.-w); addcolor(pic[y-y0][x-x0], sr.rcol); } } }