Exemplo n.º 1
0
RGBA Plate::EvalColor(ShadeContext& sc) {
	BMM_Color_64 c;
	IPoint2 s;
	int id = sc.NodeID();
	PlateMap *pmap = FindMap(id);
	if (gbufID) sc.SetGBufferID(gbufID);
	if (pmap) {
		s = sc.ScreenCoord();
		int w = pmap->bm->Width(); 
		int h = pmap->bm->Height();

		Point3 view = sc.OrigView();
		Point3 v2 = sc.V();
		Point3 p = sc.P();
		Point3 dV,dvf;
		Point3 N0 = sc.OrigNormal();

		Point3 vf = RefractVector(sc, N0, view, sc.GetIOR()); 
		
		RenderGlobalContext *gc = sc.globContext;
		if (gc==NULL) return blackrgba;

		// total deflection due to refraction
		dV = view-v2;

		// deflection due to flat refracton (no bumps)
		dvf = view-vf;

		dV = refrAmt*(dV-dvf) + thick*dvf;

		// compute screen deflection: This is really a cheat, and the
		// scale factor is arbitrary. Infact it depends on the distance 
		// between to the point on the glass plate and  to the point being
		// seen behind it, which we don't know.
		// these should be multiplied by the factor (Zbehind-Zcur)/Zcur
		// This assumes that the factor is .1

		float dsx,dsy;
		if (gc->projType==0) {
			// perspective
			dsx = dV.x*0.1f*gc->xscale;
			dsy = dV.y*0.1f*gc->yscale;
			}
		else {
			// parallel projection
			dsx = -dV.x*gc->xscale*10.0f;
			dsy = -dV.y*gc->yscale*10.0f;
			}

		if (gc->fieldRender) dsy *= 2.0f;		
		int x = s.x - (pmap->org.x+gc->devWidth/2);
		int y = s.y - (pmap->org.y+gc->devHeight/2);

		if (applyBlur) {
			float du = 1.0f/float(w);
			float dv = 1.0f/float(h);

			float u = (float(x)+dsx)*du; 
			float v = (float(y)+dsy)*dv; 
			if (u<0.0f||u>1.0f||v<0.0f||v>1.0f) {
				if (useEnvMap) {
					return sc.EvalGlobalEnvironMap(view-dvf);
					}
				else 
					return blackrgba;
				}
			else 
				pmap->bm->GetFiltered(u,v, du*blur, dv*blur,&c);
			}
		else {
			int ix = x + int(dsx); 
			int iy = y + int(dsy); 
			if (ix<0||ix>=w||iy<0||iy>=h) {
				if (useEnvMap)
					return sc.EvalGlobalEnvironMap(view-dvf);
				else 
					return blackrgba;
				}
			else 
				pmap->bm->GetLinearPixels(ix,iy,1,&c);
			}
		return c;
		}
	else 
		return blackrgba;
	}