void gltfWriter::AdditionalTechniqueParameters (FbxNode *pNode, web::json::value &techniqueParameters, bool bHasNormals /*=false*/) { if ( bHasNormals ) { techniqueParameters [U("normalMatrix")] =web::json::value::object ({ // normal matrix { U("semantic"), web::json::value::string (U("MODELVIEWINVERSETRANSPOSE")) }, { U("type"), web::json::value::number ((int)IOglTF::FLOAT_MAT3) } }) ; } techniqueParameters [U("modelViewMatrix")] =web::json::value::object ({ // modeliew matrix { U("semantic"), web::json::value::string (U("MODELVIEW")) }, { U("type"), web::json::value::number ((int)IOglTF::FLOAT_MAT4) } }) ; techniqueParameters [U("projectionMatrix")] =web::json::value::object ({ // projection matrix { U("semantic"), web::json::value::string (U("PROJECTION")) }, { U("type"), web::json::value::number ((int)IOglTF::FLOAT_MAT4) } }) ; //d:\projects\gltf\converter\collada2gltf\shaders\commonprofileshaders.cpp #905 //if ( hasSkinning ) { // addSemantic ("vs", "attribute", // "JOINT", "joint", 1, false); // addSemantic ("vs", "attribute", // "WEIGHT", "weight", 1, false); // assert (techniqueExtras != nullptr); // addSemantic ("vs", "uniform", // JOINTMATRIX, "jointMat", jointsCount, false, true /* force as an array */); //} // We ignore lighting if the only light we have is ambient int lightCount =pNode->GetScene ()->RootProperty.GetSrcObjectCount<FbxLight> () ; for ( int i =0 ; i < lightCount ; i++ ) { FbxLight *pLight =pNode->GetScene ()->RootProperty.GetSrcObject<FbxLight> (i) ; if ( lightCount == 1 && pLight->LightType.Get () == FbxLight::EType::ePoint ) return ; //utility::string_t name =nodeId (pLight->GetNode ()) ; utility::string_t name =utility::conversions::to_string_t (pLight->GetTypeName ()) ; std::transform (name.begin (), name.end (), name.begin (), ::tolower) ; if ( pLight->LightType.Get () == FbxLight::EType::ePoint ) { techniqueParameters [name + utility::conversions::to_string_t (i) + U("Color")] =web::json::value::object ({ // Color { U("type"), web::json::value::number ((int)IOglTF::FLOAT_VEC3) }, { U("value"), web::json::value::array ({{ pLight->Color.Get () [0], pLight->Color.Get () [1], pLight->Color.Get () [2] }}) } }) ; } else { techniqueParameters [name + utility::conversions::to_string_t (i) + U("Color")] =web::json::value::object ({ // Color { U("type"), web::json::value::number ((int)IOglTF::FLOAT_VEC3) }, { U("value"), web::json::value::array ({{ pLight->Color.Get () [0], pLight->Color.Get () [1], pLight->Color.Get () [2] }}) } }) ; techniqueParameters [name + utility::conversions::to_string_t (i) + U("Transform")] =web::json::value::object ({ // Transform { U("semantic"), web::json::value::string (U("MODELVIEW")) }, { U("source"), web::json::value::string (utility::conversions::to_string_t (pLight->GetNode ()->GetName ())) }, { U("type"), web::json::value::number ((int)IOglTF::FLOAT_MAT4) } }) ; if ( pLight->LightType.Get () == FbxLight::EType::eDirectional ) { web::json::value lightDef =web::json::value::object () ; lightAttenuation (pLight, lightDef) ; if ( !lightDef [U("constantAttenuation")].is_null () ) techniqueParameters [name + utility::conversions::to_string_t (i) + U("ConstantAttenuation")] =web::json::value::object ({ { U("type"), web::json::value::number ((int)IOglTF::FLOAT) }, { U("value"), lightDef [U("constantAttenuation")] } }) ; if ( !lightDef [U("linearAttenuation")].is_null () ) techniqueParameters [name + utility::conversions::to_string_t (i) + U("LinearAttenuation")] =web::json::value::object ({ { U("type"), web::json::value::number ((int)IOglTF::FLOAT) }, { U("value"), lightDef [U("linearAttenuation")] } }) ; if ( !lightDef [U("quadraticAttenuation")].is_null () ) techniqueParameters [name + utility::conversions::to_string_t (i) + U("QuadraticAttenuation")] =web::json::value::object ({ { U("type"), web::json::value::number ((int)IOglTF::FLOAT) }, { U("value"), lightDef [U("quadraticAttenuation")] } }) ; } if ( pLight->LightType.Get () == FbxLight::EType::eSpot ) { techniqueParameters [name + utility::conversions::to_string_t (i) + U("InverseTransform")] =web::json::value::object ({ { U("semantic"), web::json::value::string (U("MODELVIEWINVERSE")) }, { U("source"), web::json::value::string (utility::conversions::to_string_t (pLight->GetNode ()->GetName ())) }, { U("type"), web::json::value::number ((int)IOglTF::FLOAT_MAT4) } }) ; techniqueParameters [name + utility::conversions::to_string_t (i) + U("FallOffAngle")] =web::json::value::object ({ { U("type"), web::json::value::number ((int)IOglTF::FLOAT) }, { U("value"), web::json::value::number (DEG2RAD (pLight->OuterAngle)) } }) ; techniqueParameters [name + utility::conversions::to_string_t (i) + U("FallOffExponent")] =web::json::value::object ({ { U("type"), web::json::value::number ((int)IOglTF::FLOAT) }, { U("value"), web::json::value::number ((double)0.) } }) ; } } } }
/* static */ GlfSimpleLightingContextRefPtr px_vp20Utils::GetLightingContextFromDrawContext( const MHWRender::MDrawContext& context) { const GfVec4f blackColor(0.0f, 0.0f, 0.0f, 1.0f); const GfVec4f whiteColor(1.0f, 1.0f, 1.0f, 1.0f); GlfSimpleLightingContextRefPtr lightingContext = GlfSimpleLightingContext::New(); MStatus status; unsigned int numMayaLights = context.numberOfActiveLights(MHWRender::MDrawContext::kFilteredToLightLimit, &status); if (status != MS::kSuccess || numMayaLights < 1) { return lightingContext; } bool viewDirectionAlongNegZ = context.viewDirectionAlongNegZ(&status); if (status != MS::kSuccess) { // If we fail to find out the view direction for some reason, assume // that it's along the negative Z axis (OpenGL). viewDirectionAlongNegZ = true; } GlfSimpleLightVector lights; for (unsigned int i = 0; i < numMayaLights; ++i) { MHWRender::MLightParameterInformation* mayaLightParamInfo = context.getLightParameterInformation(i); if (!mayaLightParamInfo) { continue; } // Setup some default values before we read the light parameters. bool lightEnabled = true; bool lightHasPosition = false; GfVec4f lightPosition(0.0f, 0.0f, 0.0f, 1.0f); bool lightHasDirection = false; GfVec3f lightDirection(0.0f, 0.0f, -1.0f); if (!viewDirectionAlongNegZ) { // The convention for DirectX is positive Z. lightDirection[2] = 1.0f; } float lightIntensity = 1.0f; GfVec4f lightColor = blackColor; bool lightEmitsDiffuse = true; bool lightEmitsSpecular = false; float lightDecayRate = 0.0f; float lightDropoff = 0.0f; // The cone angle is 180 degrees by default. GfVec2f lightCosineConeAngle(-1.0f); float lightShadowBias = 0.0f; bool lightShadowOn = false; bool globalShadowOn = false; MStringArray paramNames; mayaLightParamInfo->parameterList(paramNames); for (unsigned int paramIndex = 0; paramIndex < paramNames.length(); ++paramIndex) { const MString paramName = paramNames[paramIndex]; const MHWRender::MLightParameterInformation::ParameterType paramType = mayaLightParamInfo->parameterType(paramName); const MHWRender::MLightParameterInformation::StockParameterSemantic paramSemantic = mayaLightParamInfo->parameterSemantic(paramName); MIntArray intValues; MFloatArray floatValues; switch (paramType) { case MHWRender::MLightParameterInformation::kBoolean: case MHWRender::MLightParameterInformation::kInteger: mayaLightParamInfo->getParameter(paramName, intValues); break; case MHWRender::MLightParameterInformation::kFloat: case MHWRender::MLightParameterInformation::kFloat2: case MHWRender::MLightParameterInformation::kFloat3: case MHWRender::MLightParameterInformation::kFloat4: mayaLightParamInfo->getParameter(paramName, floatValues); break; default: // Unsupported paramType. continue; break; } switch (paramSemantic) { case MHWRender::MLightParameterInformation::kLightEnabled: _GetLightingParam(intValues, floatValues, lightEnabled); break; case MHWRender::MLightParameterInformation::kWorldPosition: if (_GetLightingParam(intValues, floatValues, lightPosition)) { lightHasPosition = true; } break; case MHWRender::MLightParameterInformation::kWorldDirection: if (_GetLightingParam(intValues, floatValues, lightDirection)) { lightHasDirection = true; } break; case MHWRender::MLightParameterInformation::kIntensity: _GetLightingParam(intValues, floatValues, lightIntensity); break; case MHWRender::MLightParameterInformation::kColor: _GetLightingParam(intValues, floatValues, lightColor); break; case MHWRender::MLightParameterInformation::kEmitsDiffuse: _GetLightingParam(intValues, floatValues, lightEmitsDiffuse); break; case MHWRender::MLightParameterInformation::kEmitsSpecular: _GetLightingParam(intValues, floatValues, lightEmitsSpecular); break; case MHWRender::MLightParameterInformation::kDecayRate: _GetLightingParam(intValues, floatValues, lightDecayRate); break; case MHWRender::MLightParameterInformation::kDropoff: _GetLightingParam(intValues, floatValues, lightDropoff); break; case MHWRender::MLightParameterInformation::kCosConeAngle: _GetLightingParam(intValues, floatValues, lightCosineConeAngle); break; case MHWRender::MLightParameterInformation::kShadowBias: _GetLightingParam(intValues, floatValues, lightShadowBias); break; case MHWRender::MLightParameterInformation::kShadowOn: _GetLightingParam(intValues, floatValues, lightShadowOn); break; case MHWRender::MLightParameterInformation::kGlobalShadowOn: _GetLightingParam(intValues, floatValues, globalShadowOn); break; default: // Unsupported paramSemantic. continue; break; } if (!lightEnabled) { // Stop reading light parameters if the light is disabled. break; } } if (!lightEnabled) { // Skip to the next light if this light is disabled. continue; } lightColor[0] *= lightIntensity; lightColor[1] *= lightIntensity; lightColor[2] *= lightIntensity; // Populate a GlfSimpleLight from the light information from Maya. GlfSimpleLight light; GfVec4f lightAmbient = blackColor; GfVec4f lightDiffuse = blackColor; GfVec4f lightSpecular = blackColor; // We receive the cone angle from Maya as a pair of floats which // includes the penumbra, but GlfSimpleLights don't currently support // that, so we only use the primary cone angle value. float lightCutoff = GfRadiansToDegrees(std::acos(lightCosineConeAngle[0])); float lightFalloff = lightDropoff; // decayRate is actually an enum in Maya that we receive as a float: // - 0.0 = no attenuation // - 1.0 = linear attenuation // - 2.0 = quadratic attenuation // - 3.0 = cubic attenuation (not supported by GlfSimpleLight) GfVec3f lightAttenuation(0.0f); if (lightDecayRate > 1.5) { // Quadratic attenuation. lightAttenuation[2] = 1.0f; } else if (lightDecayRate > 0.5f) { // Linear attenuation. lightAttenuation[1] = 1.0f; } else { // No/constant attenuation. lightAttenuation[0] = 1.0f; } if (lightHasDirection && !lightHasPosition) { // This is a directional light. Set the direction as its position. lightPosition[0] = -lightDirection[0]; lightPosition[1] = -lightDirection[1]; lightPosition[2] = -lightDirection[2]; lightPosition[3] = 0.0f; // Revert direction to the default value. lightDirection = GfVec3f(0.0f, 0.0f, -1.0f); if (!viewDirectionAlongNegZ) { lightDirection[2] = 1.0f; } } if (!lightHasPosition && !lightHasDirection) { // This is an ambient light. lightAmbient = lightColor; } else { if (lightEmitsDiffuse) { lightDiffuse = lightColor; } if (lightEmitsSpecular) { // XXX: It seems that the specular color cannot be specified // separately from the diffuse color on Maya lights. lightSpecular = lightColor; } } light.SetAmbient(lightAmbient); light.SetDiffuse(lightDiffuse); light.SetSpecular(lightSpecular); light.SetPosition(lightPosition); light.SetSpotDirection(lightDirection); light.SetSpotCutoff(lightCutoff); light.SetSpotFalloff(lightFalloff); light.SetAttenuation(lightAttenuation); light.SetShadowBias(lightShadowBias); light.SetHasShadow(lightShadowOn && globalShadowOn); lights.push_back(light); } lightingContext->SetLights(lights); // XXX: These material settings match what we used to get when we read the // material from OpenGL. This should probably eventually be something more // sophisticated. GlfSimpleMaterial material; material.SetAmbient(whiteColor); material.SetDiffuse(whiteColor); material.SetSpecular(blackColor); material.SetEmission(blackColor); material.SetShininess(0.0001f); lightingContext->SetMaterial(material); lightingContext->SetSceneAmbient(blackColor); return lightingContext; }