float3 Random::getFloat3(float maxRadius) { float3 result; do { result = getFloat3(-float3::ONE, float3::ONE); } while (lengthSquared(result) >= 1.0f); return result * maxRadius; }
void InstantRadiosityRenderer::beginFrame() { auto lightPathDepth = m_nMaxDepth - 2; m_EmissionVPLBuffer.clear(); m_EmissionVPLBuffer.reserve(m_nLightPathCount); m_SurfaceVPLBuffer.clear(); m_SurfaceVPLBuffer.reserve(m_nLightPathCount * lightPathDepth); for(auto i: range(m_nLightPathCount)) { auto power = Vec3f(1.f / m_nLightPathCount); EmissionVPL vpl; vpl.pLight = m_Sampler.sample(getScene(), getFloat(0u), vpl.lightPdf); if(vpl.pLight && vpl.lightPdf) { float emissionVertexPdf; RaySample exitantRaySample; vpl.emissionVertexSample = getFloat2(0u); auto Le = vpl.pLight->sampleExitantRay(getScene(), vpl.emissionVertexSample, getFloat2(0u), exitantRaySample, emissionVertexPdf); m_EmissionVPLBuffer.emplace_back(vpl); if(Le != zero<Vec3f>() && exitantRaySample.pdf) { auto intersection = getScene().intersect(exitantRaySample.value); if(intersection) { power *= Le / (vpl.lightPdf * exitantRaySample.pdf); m_SurfaceVPLBuffer.emplace_back(intersection, -exitantRaySample.value.dir, getScene(), power); for(auto depth = 1u; depth < lightPathDepth; ++depth) { Sample3f outgoingDir; float cosThetaOutDir; auto fs = m_SurfaceVPLBuffer.back().bsdf.sample(getFloat3(0u), outgoingDir, cosThetaOutDir, nullptr, true); if(fs != zero<Vec3f>() && outgoingDir.pdf) { Ray ray(m_SurfaceVPLBuffer.back().intersection, outgoingDir.value); auto intersection = getScene().intersect(ray); if(intersection) { power *= fs * abs(cosThetaOutDir) / outgoingDir.pdf; m_SurfaceVPLBuffer.emplace_back(intersection, -ray.dir, getScene(), power); } } } } } } } }
/* virtual */ MStatus hwUnlitShader::bind(const MDrawRequest& request, M3dView& view) { MStatus status; // white, opaque. float bgColor[4] = {1,1,1,1}; // Get path of current object in draw request currentObjectPath = request.multiPath(); MString currentPathName( currentObjectPath.partialPathName() ); updateTransparencyFlags(currentPathName); // Get decal texture name MString decalName = ""; ShadingConnection colorConnection(thisMObject(), currentPathName, "color"); // If the color attribute is ultimately connected to a file texture, find its filename. // otherwise use the default color texture. if (colorConnection.type() == ShadingConnection::TEXTURE && colorConnection.texture().hasFn(MFn::kFileTexture)) { // Get the filename of the texture. MFnDependencyNode textureNode(colorConnection.texture()); MPlug filenamePlug( colorConnection.texture(), textureNode.attribute(MString("fileTextureName")) ); filenamePlug.getValue(decalName); if (decalName == "") getFloat3(color, bgColor); } else { decalName = ""; getFloat3(color, bgColor); } assert(glGetError() == GL_NO_ERROR); view.beginGL(); glPushAttrib( GL_ALL_ATTRIB_BITS ); glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); // Set the standard OpenGL blending mode. glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Change the constant alpha value. float alpha = 1.0f - fConstantTransparency; // Set a color (with alpha). This color will be used directly if // the shader is not textured. Otherwise, the texture will get modulated // by the alpha. glColor4f(bgColor[0], bgColor[1], bgColor[2], alpha); // If the shader is textured... if (decalName.length() != 0) { // Enable 2D texturing. glEnable(GL_TEXTURE_2D); assert(glGetError() == GL_NO_ERROR); // Bind the 2D texture through the texture cache. The cache will keep // the texture around, so that it will only be loaded in video // memory once. In this example, the third parameter (mipmapping) is // false, so no mipmaps are generated. Note that mipmaps only work if // the texture has even dimensions. if(m_pTextureCache) m_pTextureCache->bind(colorConnection.texture(), MTexture::RGBA, false); // Set minification and magnification filtering to linear interpolation. // For better quality, you could enable mipmapping while binding and // use GL_MIPMAP_LINEAR_MIPMAP in for minification filtering. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); } // Disable lighting. glDisable(GL_LIGHTING); view.endGL(); return MS::kSuccess; }
float3 Random::getFloat3(float minRadius, float maxRadius) { float3 v = getFloat3(1.0f); float ratio = minRadius / maxRadius; return lerp(v, normalize(v), ratio) * maxRadius; }