// #### updateRegistry // // Evaluates dirty flags and updates the effect registry if any // attributes have changed that require the shader to be rebuilt // void OpenSubdivShader::updateRegistry() { /* If adaptive flag has changed, update the effectRegistry accordingly */ if (_adaptiveDirty) { g_effectRegistry.setIsAdaptive(_adaptive); _adaptiveDirty = false; } MHWRender::MRenderer *theRenderer = MHWRender::MRenderer::theRenderer(); _theTextureManager = theRenderer->getTextureManager(); /* If diffuse texture has changed, update the effectRegistry accordingly */ if (_diffuseMapDirty) { GLuint diffMapId = bindTexture( _diffuseMapFile, DIFF_TEXTURE_UNIT ); g_effectRegistry.setDiffuseId(diffMapId); _diffuseMapDirty = false; } /* If shader source has changed, update the effectRegistry accordingly */ if (_shaderSourceDirty) { if ( _shaderSource.empty() ) { if ( g_effectRegistry.getShaderSource() != defaultShaderSource ) { g_effectRegistry.setShaderSource(defaultShaderSource); } } else { if ( g_effectRegistry.getShaderSource() != _shaderSource ) { g_effectRegistry.setShaderSource(_shaderSource); } } _shaderSourceDirty = false; } }
simpleNoiseShaderOverride::~simpleNoiseShaderOverride() { // Release texture MHWRender::MRenderer* renderer = MHWRender::MRenderer::theRenderer(); if (renderer) { MHWRender::MTextureManager* textureMgr = renderer->getTextureManager(); if (textureMgr) { textureMgr->releaseTexture(fNoiseTexture); fNoiseTexture = NULL; } } // Release sampler state MHWRender::MStateManager::releaseSamplerState(fNoiseSamplerState); fNoiseSamplerState = NULL; }
// // updateRegistry // // When attributes change which affect the shader compilation the // effectRegistry needs to be updated with the new values // void OpenSubdivPtexShader::updateRegistry() { // adaptive toggle if (_adaptiveDirty) { effectRegistry.setIsAdaptive(_adaptive); _adaptiveDirty = false; } // ptex color file if (_ptexColorDirty) { bool ptexColorValid = bindPtexTexture(_colorFile, &_ptexColor, CLR_TEXTURE_UNIT); effectRegistry.setPtexColorValid(ptexColorValid); _ptexColorDirty = false; } // ptex displacement file if (_ptexDisplacementDirty) { bool ptexDisplacementValid = bindPtexTexture(_displacementFile, &_ptexDisplacement, DISP_TEXTURE_UNIT); effectRegistry.setPtexDisplacementValid(ptexDisplacementValid); _ptexDisplacementDirty = false; } // ptex occlusion file if (_ptexOcclusionDirty) { bool ptexOcclusionValid = bindPtexTexture(_occlusionFile, &_ptexOcclusion, OCC_TEXTURE_UNIT); effectRegistry.setPtexOcclusionValid(ptexOcclusionValid); _ptexOcclusionDirty = false; } MHWRender::MRenderer *theRenderer = MHWRender::MRenderer::theRenderer(); _theTextureManager = theRenderer->getTextureManager(); // diffuse environment map file if (_diffEnvMapDirty) { GLuint diffEnvMapId = bindTexture( _diffEnvMapFile, DIFF_TEXTURE_UNIT ); effectRegistry.setDiffuseEnvironmentId(diffEnvMapId); _diffEnvMapDirty = false; } // specular environment map file if (_specEnvMapDirty) { GLuint specEnvMapId = bindTexture( _specEnvMapFile, ENV_TEXTURE_UNIT ); effectRegistry.setSpecularEnvironmentId(specEnvMapId); _specEnvMapDirty = false; } // shader source if (_shaderSourceDirty) { if ( _shaderSource.empty() ) { if ( effectRegistry.getShaderSource() != defaultShaderSource ) { effectRegistry.setShaderSource(defaultShaderSource); } } else { if ( effectRegistry.getShaderSource() != _shaderSource ) { effectRegistry.setShaderSource(_shaderSource); } } _shaderSourceDirty = false; } }
/* Utility method to update shader parameters based on available lighting information. */ static void updateLightShader( MHWRender::MShaderInstance *shaderInstance, const MHWRender::MDrawContext & context, const MSelectionList * lightList ) { if (!shaderInstance) return; // Check pass context information to see if we are in a shadow // map update pass. If so do nothing. // const MHWRender::MPassContext & passCtx = context.getPassContext(); const MStringArray & passSem = passCtx.passSemantics(); bool handlePass = true; for (unsigned int i=0; i<passSem.length() && handlePass; i++) { // Handle special pass drawing. // if (passSem[i] == MHWRender::MPassContext::kShadowPassSemantic) { handlePass = false; } } if (!handlePass) return; // // Perform light shader update with lighting information // If the light list is not empty then use that light's information. // Otherwise choose the first appropriate light which can cast shadows. // // Defaults in case there are no lights // bool globalShadowsOn = false; bool localShadowsOn = false; bool shadowDirty = false; MFloatVector direction(0.0f, 0.0f, 1.0f); float lightIntensity = 0.0f; // If no lights then black out the light float lightColor[3] = { 0.0f, 0.0f, 0.0f }; MStatus status; // Scan to find the first N lights that has a direction component in it // It's possible we find no lights. // MHWRender::MDrawContext::LightFilter considerAllSceneLights = MHWRender::MDrawContext::kFilteredIgnoreLightLimit; unsigned int lightCount = context.numberOfActiveLights(considerAllSceneLights); if (lightCount) { MFloatArray floatVals; MIntArray intVals; MHWRender::MTextureAssignment shadowResource; shadowResource.texture = NULL; MHWRender::MSamplerStateDesc samplerDesc; MMatrix shadowViewProj; float shadowColor[3] = { 0.0f, 0.0f, 0.0f }; unsigned int i=0; bool foundDirectional = false; for (i=0; i<lightCount && !foundDirectional ; i++) { MHWRender::MLightParameterInformation *lightParam = context.getLightParameterInformation( i, considerAllSceneLights ); if (lightParam) { // Prune against light list if any. if (lightList && lightList->length()) { if (!lightList->hasItem(lightParam->lightPath())) continue; } MStringArray params; lightParam->parameterList(params); for (unsigned int p=0; p<params.length(); p++) { MString pname = params[p]; MHWRender::MLightParameterInformation::StockParameterSemantic semantic = lightParam->parameterSemantic( pname ); switch (semantic) { // Pick a few light parameters to pick up as an example case MHWRender::MLightParameterInformation::kWorldDirection: lightParam->getParameter( pname, floatVals ); direction = MFloatVector( floatVals[0], floatVals[1], floatVals[2] ); foundDirectional = true; break; case MHWRender::MLightParameterInformation::kIntensity: lightParam->getParameter( pname, floatVals ); lightIntensity = floatVals[0]; break; case MHWRender::MLightParameterInformation::kColor: lightParam->getParameter( pname, floatVals ); lightColor[0] = floatVals[0]; lightColor[1] = floatVals[1]; lightColor[2] = floatVals[2]; break; // Pick up shadowing parameters case MHWRender::MLightParameterInformation::kGlobalShadowOn: lightParam->getParameter( pname, intVals ); if (intVals.length()) globalShadowsOn = (intVals[0] != 0) ? true : false; break; case MHWRender::MLightParameterInformation::kShadowOn: lightParam->getParameter( pname, intVals ); if (intVals.length()) localShadowsOn = (intVals[0] != 0) ? true : false; break; case MHWRender::MLightParameterInformation::kShadowViewProj: lightParam->getParameter( pname, shadowViewProj); break; case MHWRender::MLightParameterInformation::kShadowMap: lightParam->getParameter( pname, shadowResource ); break; case MHWRender::MLightParameterInformation::kShadowDirty: if (intVals.length()) shadowDirty = (intVals[0] != 0) ? true : false; break; case MHWRender::MLightParameterInformation::kShadowSamp: lightParam->getParameter( pname, samplerDesc ); break; case MHWRender::MLightParameterInformation::kShadowColor: lightParam->getParameter( pname, floatVals ); shadowColor[0] = floatVals[0]; shadowColor[1] = floatVals[1]; shadowColor[2] = floatVals[2]; break; default: break; } } /* for params */ } if (foundDirectional && globalShadowsOn && localShadowsOn && shadowResource.texture) { void *resourceHandle = shadowResource.texture->resourceHandle(); if (resourceHandle) { static bool debugShadowBindings = false; status = shaderInstance->setParameter("mayaShadowPCF1_shadowMap", shadowResource ); if (status == MStatus::kSuccess && debugShadowBindings) fprintf(stderr, "Bound shadow map to shader param mayaShadowPCF1_shadowMap\n"); status = shaderInstance->setParameter("mayaShadowPCF1_shadowViewProj", shadowViewProj ); if (status == MStatus::kSuccess && debugShadowBindings) fprintf(stderr, "Bound shadow map transform to shader param mayaShadowPCF1_shadowViewProj\n"); status = shaderInstance->setParameter("mayaShadowPCF1_shadowColor", &shadowColor[0] ); if (status == MStatus::kSuccess && debugShadowBindings) fprintf(stderr, "Bound shadow map color to shader param mayaShadowPCF1_shadowColor\n"); } MHWRender::MRenderer* renderer = MHWRender::MRenderer::theRenderer(); if (renderer) { MHWRender::MTextureManager* textureManager = renderer->getTextureManager(); if (textureManager) { textureManager->releaseTexture(shadowResource.texture); } } shadowResource.texture = NULL; } } } // Set up parameters which should be set regardless of light existence. status = shaderInstance->setParameter("mayaDirectionalLight_direction", &( direction[0] )); status = shaderInstance->setParameter("mayaDirectionalLight_intensity", lightIntensity ); status = shaderInstance->setParameter("mayaDirectionalLight_color", &( lightColor[0] )); status = shaderInstance->setParameter("mayaShadowPCF1_mayaGlobalShadowOn", globalShadowsOn); status = shaderInstance->setParameter("mayaShadowPCF1_mayaShadowOn", localShadowsOn); }
void simpleNoiseShaderOverride::updateShader( MHWRender::MShaderInstance& shader, const MHWRender::MAttributeParameterMappingList& mappings) { // Handle resolved name caching if (fResolvedNoiseMapName.length() == 0) { const MHWRender::MAttributeParameterMapping* mapping = mappings.findByParameterName("noiseLookupMap"); if (mapping) { fResolvedNoiseMapName = mapping->resolvedParameterName(); } } if (fResolvedNoiseSamplerName.length() == 0) { const MHWRender::MAttributeParameterMapping* mapping = mappings.findByParameterName("noiseLookupMapSampler"); if (mapping) { fResolvedNoiseSamplerName = mapping->resolvedParameterName(); } } // Set the parameters on the shader if (fResolvedNoiseMapName.length() > 0 && fResolvedNoiseSamplerName.length() > 0) { // Set a point-clamp sampler to the shader if (!fNoiseSamplerState) { MHWRender::MSamplerStateDesc desc; desc.filter = MHWRender::MSamplerState::kMinMagMipPoint; desc.addressU = desc.addressV = desc.addressW = MHWRender::MSamplerState::kTexClamp; desc.minLOD = 0; desc.maxLOD = 0; fNoiseSamplerState = MHWRender::MStateManager::acquireSamplerState(desc); } if (fNoiseSamplerState) { shader.setParameter(fResolvedNoiseSamplerName, *fNoiseSamplerState); } // Generate the noise lookup table texture if necessary if (!fNoiseTexture) { MHWRender::MRenderer* renderer = MHWRender::MRenderer::theRenderer(); MHWRender::MTextureManager* textureMgr = renderer ? renderer->getTextureManager() : NULL; if (textureMgr) { // First, search the texture cache to see if another instance of // this override has already generated the texture. We can reuse // it to save GPU memory since the noise data is constant. fNoiseTexture = textureMgr->findTexture(sNoiseLookupTextureName); // Not in cache, so we need to actually build the texture if (!fNoiseTexture) { // Get Maya's noise table const std::vector<float>& noiseData = GetMayaNoiseTable(); // Create a 3D texture containing the data MHWRender::MTextureDescription desc; desc.setToDefault2DTexture(); desc.fWidth = desc.fHeight = desc.fDepth = MRenderUtil::noiseTableCubeSide(); desc.fFormat = MHWRender::kR32_FLOAT; desc.fTextureType = MHWRender::kVolumeTexture; desc.fMipmaps = 1; fNoiseTexture = textureMgr->acquireTexture( sNoiseLookupTextureName, desc, (const void*)&(noiseData[0]), false); } } } // Set the texture to the shader instance if (fNoiseTexture) { MHWRender::MTextureAssignment textureAssignment; textureAssignment.texture = fNoiseTexture; shader.setParameter(fResolvedNoiseMapName, textureAssignment); } } }