double AntiVignettingFilter::real_attenuation(double r1, double r2, double dist_center) { if (!m_settings.addvignetting) { return (attenuation(r1, r2, dist_center)); } else { return (1.0 / attenuation(r1, r2, dist_center)); } }
/** * Calculate the attenuation correction factor the volume given a start and * end point. * @param rng A reference to a PseudoRandomNumberGenerator producing * random number between [0,1] * @param startPos Origin of the initial track * @param endPos Final position of neutron after scattering (assumed to be * outside of the "volume") * @param lambdaBefore Wavelength, in \f$\\A^-1\f$, before scattering * @param lambdaAfter Wavelength, in \f$\\A^-1\f$, after scattering * @return The fraction of the beam that has been attenuated. A negative number * indicates the track was not valid. */ double MCInteractionVolume::calculateAbsorption( Kernel::PseudoRandomNumberGenerator &rng, const Kernel::V3D &startPos, const Kernel::V3D &endPos, double lambdaBefore, double lambdaAfter) const { // Generate scatter point. If there is an environment present then // first select whether the scattering occurs on the sample or the // environment. The attenuation for the path leading to the scatter point // is calculated in reverse, i.e. defining the track from the scatter pt // backwards for simplicity with how the Track object works. This avoids // having to understand exactly which object the scattering occurred in. V3D scatterPos; if (m_env && (rng.nextValue() > 0.5)) { scatterPos = m_env->generatePoint(rng, m_activeRegion, MAX_SCATTER_ATTEMPTS); } else { scatterPos = m_sample.generatePointInObject(rng, m_activeRegion, MAX_SCATTER_ATTEMPTS); } auto toStart = startPos - scatterPos; toStart.normalize(); Track beforeScatter(scatterPos, toStart); int nlinks = m_sample.interceptSurface(beforeScatter); if (m_env) { nlinks += m_env->interceptSurfaces(beforeScatter); } // This should not happen but numerical precision means that it can // occasionally occur with tracks that are very close to the surface if (nlinks == 0) { return -1.0; } // Function to calculate total attenuation for a track auto calculateAttenuation = [](const Track &path, double lambda) { double factor(1.0); for (const auto &segment : path) { const double length = segment.distInsideObject; const auto &segObj = *(segment.object); const auto &segMat = segObj.material(); factor *= attenuation(segMat.numberDensity(), segMat.totalScatterXSection(lambda) + segMat.absorbXSection(lambda), length); } return factor; }; // Now track to final destination V3D scatteredDirec = endPos - scatterPos; scatteredDirec.normalize(); Track afterScatter(scatterPos, scatteredDirec); m_sample.interceptSurface(afterScatter); if (m_env) { m_env->interceptSurfaces(afterScatter); } return calculateAttenuation(beforeScatter, lambdaBefore) * calculateAttenuation(afterScatter, lambdaAfter); }
void MICROSTRIP::calc() { /* effective permeability */ mur_eff_ms(); /* static impedance */ microstrip_Z0(); /* calculate freq dependence of er and Z0 */ dispersion(); /* calculate electrical lengths */ line_angle(); /* calculate losses */ attenuation(); }
/* computes the diffuse component by iterating through all lights within the scene * much the like sphere. * note: only difference is the barycentric coordinates are an * additional weighing factor in the final output * */ Color3 Triangle:: compute_diffuse(const Scene* scene, const Vector3 &normal,const Vector3 &surface_pos)const{ Color3 total_diff = Color3::Black; int num_lights = scene->num_lights(); int num_shapes = scene->num_geometries(); Geometry* const* sceneObjects = scene->get_geometries(); const PointLight* lights = scene->get_lights(); // iterate throught all lights in the scene for(int i=0;i<num_lights;i++){ real_t b_i = 1.0; Vector3 light_pos = lights[i].position; Vector3 light_vector = normalize(light_pos - surface_pos); real_t dist = distance(light_pos,surface_pos); // apply slope factor of some arbitrarily small epsilon // to the surface position, we will shoot out shadow ray from here Vector3 slope_pos = surface_pos + EPSILON*light_vector; // check if a geometry casts a shadow, in which case // this light contributes nothing to the diffuse color for(int j=0; j<num_shapes; j++){ real_t t = sceneObjects[j]->shadow_intersection(light_vector, slope_pos); // check if the intersection point is in front of the light if(t != -1.0){ Vector3 geo_surface = slope_pos + light_vector*t; real_t geo_dis = distance(geo_surface,surface_pos); if(geo_dis < dist){ b_i = 0.0; //light contributes nothing break; } } } if(b_i == 1.0){ Color3 atten = attenuation(dist,lights[i], light_pos,surface_pos); total_diff = total_diff + atten*max(dot(light_vector,normal),0); } } return total_diff; }
Vec4 SpotLight::calculateColor(Vec4 pit, Vec4 n,Vec4 viewer, Material *m,Vec4 pos,Vec4 texColor,int mode_texture) { if(mode_texture==TYPE_ONLY_TEXTURE){ Vec4 direction(direction_light->x1,direction_light->x2,direction_light->x3); Vec4 position(position_light->x1,position_light->x2,position_light->x3); Vec4 l = (position-pit)/(position-pit).module(); float fator = fmax((n*l)/(n.module()*l.module()),0); Vec4 Diffuse; Diffuse.x1 = (texColor.x() * diffuse_light->x1)*fator; Diffuse.x2 = (texColor.y() * diffuse_light->x2)*fator; Diffuse.x3 = (texColor.z() * diffuse_light->x3)*fator; l = l.unitary(); Vec4 r = (n*((l*n)*2) - l); Vec4 v = (viewer-pit)/(viewer-pit).module(); r = (r+v)/(r+v).module(); float fator2 = fmax(pow((r*v),m->shininess*128),0); if(r*n<0) fator2 = 0; Vec4 especular; especular.x1 = (texColor.x() * specular_light->x1)*fator2; especular.x2 = (texColor.y() * specular_light->x2)*fator2; especular.x3 = (texColor.z() * specular_light->x3)*fator2; Vec4 ambiente; ambiente.x1 = texColor.x() * ambient_light->x1; ambiente.x2 = texColor.y() * ambient_light->x2; ambiente.x3 = texColor.z() * ambient_light->x3; Vec4 color = ((Diffuse+especular))*isInDualConeSpot(pit)*pow(direction*(l*-1),expoent_light)*attenuation((position-viewer).module()); return color; }else if(mode_texture==TYPE_REPLACE_TEXTURE){ Vec4 direction(direction_light->x1,direction_light->x2,direction_light->x3); //calculo da contribuição difusa Vec4 position(position_light->x1,position_light->x2,position_light->x3); if ((position-pit).unitary()*n<=0) return Vec4(); //direction = (direction)/(direction).module(); Vec4 l = (position-pit)/(position-pit).module(); float fator = fmax((n*l)/(n.module()*l.module()),0); Vec4 Diffuse; Diffuse.x1 = (m->diffuse[0] * diffuse_light->x1)*fator; Diffuse.x2 = (m->diffuse[1] * diffuse_light->x2)*fator; Diffuse.x3 = (m->diffuse[2] * diffuse_light->x3)*fator; //calculo da contribuicao especular l = l.unitary(); Vec4 r = (n*((l*n)*2) - l); Vec4 v = (viewer-pit)/(viewer-pit).module(); r = (r+v)/(r+v).module(); float fator2 = fmax(pow((r*v),m->shininess*128),0); if(r*n<0) fator2 = 0; Vec4 especular; especular.x1 = (m->specular[0] * specular_light->x1)*fator2; especular.x2 = (m->specular[1] * specular_light->x2)*fator2; especular.x3 = (m->specular[2] * specular_light->x3)*fator2; //calculo da contribuição ambiente Vec4 ambiente; ambiente.x1 = m->ambient[0] * ambient_light->x1; ambiente.x2 = m->ambient[1] * ambient_light->x2; ambiente.x3 = m->ambient[2] * ambient_light->x3; Vec4 color = texColor.mult(((Diffuse+especular))*isInDualConeSpot(pit)*pow(direction*(l*-1),expoent_light)*attenuation((position-viewer).module())); return color; }else{ Vec4 direction(direction_light->x1,direction_light->x2,direction_light->x3); //calculo da contribuição difusa Vec4 position(position_light->x1,position_light->x2,position_light->x3); if ((position-pit).unitary()*n<=0) return Vec4(); //direction = (direction)/(direction).module(); Vec4 l = (position-pit)/(position-pit).module(); float fator = fmax((n*l)/(n.module()*l.module()),0); Vec4 Diffuse; Diffuse.x1 = (m->diffuse[0] * diffuse_light->x1)*fator; Diffuse.x2 = (m->diffuse[1] * diffuse_light->x2)*fator; Diffuse.x3 = (m->diffuse[2] * diffuse_light->x3)*fator; //calculo da contribuicao especular l = l.unitary(); Vec4 r = (n*((l*n)*2) - l); Vec4 v = (viewer-pit)/(viewer-pit).module(); r = (r+v)/(r+v).module(); float fator2 = fmax(pow((r*v),m->shininess*128),0); if(r*n<0) fator2 = 0; Vec4 especular; especular.x1 = (m->specular[0] * specular_light->x1)*fator2; especular.x2 = (m->specular[1] * specular_light->x2)*fator2; especular.x3 = (m->specular[2] * specular_light->x3)*fator2; //calculo da contribuição ambiente Vec4 ambiente; ambiente.x1 = m->ambient[0] * ambient_light->x1; ambiente.x2 = m->ambient[1] * ambient_light->x2; ambiente.x3 = m->ambient[2] * ambient_light->x3; Vec4 color = ((Diffuse+especular))*isInDualConeSpot(pit)*pow(direction*(l*-1),expoent_light)*attenuation((position-viewer).module()); return color; } }
//----------------------------------------------------------------------------- // Recurse through the collada scene to add <light>s to the Torque scene static void processNodeLights(AppNode* appNode, const MatrixF& offset, SimGroup* group) { const domNode* node = dynamic_cast<ColladaAppNode*>(appNode)->getDomNode(); for (S32 iLight = 0; iLight < node->getInstance_light_array().getCount(); iLight++) { domInstance_light* instLight = node->getInstance_light_array()[iLight]; domLight* p_domLight = daeSafeCast<domLight>(instLight->getUrl().getElement()); if (!p_domLight) { Log::warnf("Failed to find light for URL \"%s\"", instLight->getUrl().getOriginalURI()); continue; } String lightName = Sim::getUniqueName(_GetNameOrId(node)); const char* lightType = ""; domLight::domTechnique_common* technique = p_domLight->getTechnique_common(); if (!technique) { Log::warnf("No <technique_common> for light \"%s\"", lightName.c_str()); continue; } LightBase* pLight = 0; ColorF color(ColorF::WHITE); Point3F attenuation(0, 1, 1); if (technique->getAmbient()) { domLight::domTechnique_common::domAmbient* ambient = technique->getAmbient(); // No explicit support for ambient lights, so use a PointLight instead lightType = "ambient"; pLight = new PointLight; resolveLightColor(ambient, color); } else if (technique->getDirectional()) { domLight::domTechnique_common::domDirectional* directional = technique->getDirectional(); // No explicit support for directional lights, so use a SpotLight instead lightType = "directional"; pLight = new SpotLight; resolveLightColor(directional, color); } else if (technique->getPoint()) { domLight::domTechnique_common::domPoint* point = technique->getPoint(); lightType = "point"; pLight = new PointLight; resolveLightColor(point, color); resolveLightAttenuation(point, attenuation); } else if (technique->getSpot()) { domLight::domTechnique_common::domSpot* spot = technique->getSpot(); lightType = "spot"; pLight = new SpotLight; resolveLightColor(spot, color); resolveLightAttenuation(spot, attenuation); } else continue; Log::printf("Adding <%s> light \"%s\" as a %s", lightType, lightName.c_str(), pLight->getClassName()); MatrixF mat(offset); mat.mul(appNode->getNodeTransform(TSShapeLoader::DefaultTime)); pLight->setDataField("color", 0, avar("%f %f %f %f", color.red, color.green, color.blue, color.alpha)); pLight->setDataField("attenuationRatio", 0, avar("%f %f %f", attenuation.x, attenuation.y, attenuation.z)); pLight->setTransform(mat); if (!pLight->registerObject(lightName)) { Log::errorf(LogEntry::General, "Failed to register light for \"%s\"", lightName.c_str()); delete pLight; } if (group) group->addObject(pLight); } // Recurse child nodes for (S32 iChild = 0; iChild < appNode->getNumChildNodes(); iChild++) processNodeLights(appNode->getChildNode(iChild), offset, group); }