void ShadowManager::updateViewMatrix(const Light *const light) { ShadowData *shadowData = shadowDatas[light]; if(light->hasParallelBeams()) { //sun light Vector3<float> lightDirection = light->getDirections()[0]; const Vector3<float> &f = lightDirection.normalize(); const Vector3<float> &s = f.crossProduct(Vector3<float>(0.0, 1.0, 0.0)).normalize(); const Vector3<float> &u = s.crossProduct(f).normalize(); Matrix4<float> M( s[0], s[1], s[2], 0, u[0], u[1], u[2], 0, -f[0], -f[1], -f[2], 0, 0, 0, 0, 1); Matrix4<float> eye; eye.buildTranslation(lightDirection.X, lightDirection.Y, lightDirection.Z); Matrix4<float> mViewShadow = M * eye; shadowData->setLightViewMatrix(mViewShadow); }else { throw std::runtime_error("Shadow currently not supported on omnidirectional light."); } }
ShadowData ShadowData::blend(const ShadowData& from, double progress, const Color& currentColor) const { ASSERT(style() == from.style()); return ShadowData(blink::blend(from.location(), location(), progress), clampTo(blink::blend(from.blur(), blur(), progress), 0.0f), blink::blend(from.spread(), spread(), progress), style(), blink::blend(from.color().resolve(currentColor), color().resolve(currentColor), progress)); }
ShadowData ShadowData::blend(const ShadowData& from, double progress) const { if (style() != from.style()) return *this; return ShadowData(WebCore::blend(from.location(), location(), progress), clampTo<int>(WebCore::blend(from.blur(), blur(), progress), 0), WebCore::blend(from.spread(), spread(), progress), style(), WebCore::blend(from.color(), color(), progress)); }
void ShadowManager::updateShadowMaps() { glBindTexture(GL_TEXTURE_2D, 0); for(std::map<const Light *, ShadowData *>::const_iterator it = shadowDatas.begin(); it!=shadowDatas.end(); ++it) { ShadowData *shadowData = it->second; glViewport(0, 0, shadowMapResolution, shadowMapResolution); glBindFramebuffer(GL_FRAMEBUFFER, shadowData->getFboID()); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); shadowUniform->setUniformData(shadowData); shadowModelUniform->setModelUniformData(shadowData); shadowModelDisplayer->setModels(shadowData->retrieveModels()); shadowModelDisplayer->display(shadowData->getLightViewMatrix()); if(blurShadow!=BlurShadow::NO_BLUR) { shadowData->getVerticalBlurFilter()->applyOn(shadowData->getShadowMapTextureID()); shadowData->getHorizontalBlurFilter()->applyOn(shadowData->getVerticalBlurFilter()->getTextureID()); } } glViewport(0, 0, sceneWidth, sceneHeight); glBindTexture(GL_TEXTURE_2D_ARRAY, 0); }
void ObjectLoader::processShadow(XmlTreeNode* lightNode, ObjectLight* light){ XmlTreeNode* shadowNode = lightNode->searchDirectChild("Shadow", 0); if(!shadowNode){ Logger::getInstance()->logDebug(new Log("ObjectLoader#processShadow: Falta el nodo \"Shadow\" en etiqueta Light definida como \"castShadow\", se ignora la sombra")); return; } XmlTreeNode* shadowMapNode = shadowNode->searchDirectChild("ShadowMap", 0); if(!shadowMapNode){ Logger::getInstance()->logDebug(new Log("ObjectLoader#processShadow: Falta el nodo \"ShadowMap\" en etiqueta Shadow, se ignora la sombra")); return; } //El tamaño de shadowMap ShadowData* shadow = light->getShadowData(); vec2 size = getVec2ShadowParam("Size", shadowMapNode); shadow->setShadowMapSize(size); //La perspectiva fovy del shadowMap float perspectiveFovy = getFloatParam("Perspective", shadowMapNode); shadow->setPerspectiveFovy(perspectiveFovy); //El factor del filtro de shadow si es que hay XmlTreeNode* filterNode = lightNode->searchDirectChild("ShadowFilter", 0); if(filterNode != NULL){ float filterFactor = getFloatParam("Factor", filterNode); shadow->setFilterFactor(filterFactor); } XmlNodeAttribute* preBankedAtt = shadowNode->searchForAttribute("prebanked"); //Es si prebanqueada, la seteo como tal if((preBankedAtt)&&(preBankedAtt->getValue().compare("true")==0)){ shadow->setPrebanked(true); } //Activo la sombra (falta activarla realmente cuando se agrega el objeto a la escena) shadow->setActive(true); }
FilterOperation* FilterInterpolationFunctions::createFilter(const InterpolableValue& interpolableValue, const NonInterpolableValue& untypedNonInterpolableValue, const StyleResolverState& state) { const FilterNonInterpolableValue& nonInterpolableValue = toFilterNonInterpolableValue(untypedNonInterpolableValue); FilterOperation::OperationType type = nonInterpolableValue.type(); switch (type) { case FilterOperation::GRAYSCALE: case FilterOperation::HUE_ROTATE: case FilterOperation::SATURATE: case FilterOperation::SEPIA: { double value = clampParameter(toInterpolableNumber(interpolableValue).value(), type); return BasicColorMatrixFilterOperation::create(value, type); } case FilterOperation::BRIGHTNESS: case FilterOperation::CONTRAST: case FilterOperation::INVERT: case FilterOperation::OPACITY: { double value = clampParameter(toInterpolableNumber(interpolableValue).value(), type); return BasicComponentTransferFilterOperation::create(value, type); } case FilterOperation::BLUR: { Length stdDeviation = CSSLengthInterpolationType::resolveInterpolableLength(interpolableValue, nonInterpolableValue.typeNonInterpolableValue(), state.cssToLengthConversionData(), ValueRangeNonNegative); return BlurFilterOperation::create(stdDeviation); } case FilterOperation::DROP_SHADOW: { ShadowData shadowData = ShadowInterpolationFunctions::createShadowData(interpolableValue, nonInterpolableValue.typeNonInterpolableValue(), state); Color color = shadowData.color().isCurrentColor() ? Color::black : shadowData.color().getColor(); return DropShadowFilterOperation::create(IntPoint(shadowData.x(), shadowData.y()), shadowData.blur(), color); } default: ASSERT_NOT_REACHED(); return nullptr; } }
void ObjectLoader::serializeShadow(SceneLight* light, XmlTreeNode* lightNode){ ShadowData* shadow = light->getShadowData(); if(shadow->isActive()){ lightNode->createAttribute("castShadow", "true"); // Agrego la propiedades de la sombra y su atributo de prebanked XmlTreeNode* shadowNode = new XmlTreeNode("Shadow", lightNode); lightNode->addChild(shadowNode); string prebank = "false"; if(shadow->isPrebanked()){ prebank = "true"; } shadowNode->createAttribute("prebanked", prebank); // Agrego la propiedad del shadowMap XmlTreeNode* shadowMapNode = new XmlTreeNode("ShadowMap", shadowNode); shadowNode->addChild(shadowMapNode); serializeToNode("Size", shadow->getShadowMapSize(), shadowMapNode); serializeToNode("Perspective", shadow->getPerspectiveFovy(), shadowMapNode); XmlTreeNode* shadowFilterNode = new XmlTreeNode("ShadowFilter", shadowNode); shadowNode->addChild(shadowFilterNode); serializeToNode("Factor", shadow->getPerspectiveFovy(), shadowFilterNode); } }