30fee96c43
Renamed document related buses and components to have generic names Added a base document class with default implementation from which other application specific documents can be derived to work with the document system Added document factory function registration to the document system request bus so that each application can specify the type of document it creates Updated all comments and messaging to only refer to documents, not materials or material documents Updated material editor and shader management console to conform to the new buses This will provide a first pass of a common interface for a document management system that can be shared by multiple applications Corrected status bar message copy and paste errors Updated all test scripts to use the new buses Signed-off-by: Guthrie Adams <guthadam@amazon.com>
176 lines
7.1 KiB
Python
Executable File
176 lines
7.1 KiB
Python
Executable File
"""
|
|
Copyright (c) Contributors to the Open 3D Engine Project.
|
|
For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
|
|
|
SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
"""
|
|
|
|
import sys
|
|
import os
|
|
import azlmbr.asset as asset
|
|
import azlmbr.atom
|
|
import azlmbr.bus
|
|
import azlmbr.math as math
|
|
import azlmbr.name
|
|
import azlmbr.paths
|
|
import azlmbr.shadermanagementconsole
|
|
import azlmbr.shader
|
|
import collections
|
|
from PySide2 import QtWidgets
|
|
|
|
PROJECT_SHADER_VARIANTS_FOLDER = "ShaderVariants"
|
|
|
|
def clean_existing_shadervariantlist_files(filePaths):
|
|
for file in filePaths:
|
|
if os.path.exists(file):
|
|
os.remove(file)
|
|
|
|
def main():
|
|
print("==== Begin shader variant script ==========================================================")
|
|
|
|
if len(sys.argv) != 2:
|
|
print("The script requires a .shader file as input argument")
|
|
return
|
|
|
|
filename = sys.argv[1]
|
|
suffix, extension = filename.split(".", 1)
|
|
|
|
if extension != "shader":
|
|
print("The input argument for the script is not a valid .shader file")
|
|
return
|
|
|
|
# Get info such as relative path of the file and asset id
|
|
shaderAssetInfo = azlmbr.shadermanagementconsole.ShaderManagementConsoleRequestBus(
|
|
azlmbr.bus.Broadcast,
|
|
'GetSourceAssetInfo',
|
|
filename
|
|
)
|
|
|
|
# retrieves a list of all material source files that use the shader. Note that materials inherit from materialtype files, which are actual files that refer to shader files.
|
|
materialAssetIds = azlmbr.shadermanagementconsole.ShaderManagementConsoleRequestBus(
|
|
azlmbr.bus.Broadcast,
|
|
'FindMaterialAssetsUsingShader',
|
|
shaderAssetInfo.relativePath
|
|
)
|
|
|
|
msgBox = QtWidgets.QMessageBox(
|
|
QtWidgets.QMessageBox.Question,
|
|
"Choose Save Location for .shadervariantlist File",
|
|
"Save .shadervariantlist file in Project folder or in the same folder as shader file?"
|
|
)
|
|
projectButton = msgBox.addButton("Project Folder", QtWidgets.QMessageBox.AcceptRole)
|
|
msgBox.addButton("Same Folder as Shader", QtWidgets.QMessageBox.AcceptRole)
|
|
cancelButton = msgBox.addButton("Cancel", QtWidgets.QMessageBox.RejectRole)
|
|
msgBox.exec()
|
|
|
|
is_save_in_project_folder = False
|
|
if msgBox.clickedButton() == projectButton:
|
|
is_save_in_project_folder = True
|
|
elif msgBox.clickedButton() == cancelButton:
|
|
return
|
|
|
|
# This loop collects all uniquely-identified shader items used by the materials based on its shader variant id.
|
|
shader_file = os.path.basename(filename)
|
|
shaderVariantIds = []
|
|
shaderVariantListShaderOptionGroups = []
|
|
progressDialog = QtWidgets.QProgressDialog(f"Generating .shadervariantlist file for:\n{shader_file}", "Cancel", 0, len(materialAssetIds))
|
|
progressDialog.setMaximumWidth(400)
|
|
progressDialog.setMaximumHeight(100)
|
|
progressDialog.setModal(True)
|
|
progressDialog.setWindowTitle("Generating Shader Variant List")
|
|
for i, materialAssetId in enumerate(materialAssetIds):
|
|
materialInstanceShaderItems = azlmbr.shadermanagementconsole.ShaderManagementConsoleRequestBus(azlmbr.bus.Broadcast, 'GetMaterialInstanceShaderItems', materialAssetId)
|
|
|
|
for shaderItem in materialInstanceShaderItems:
|
|
shaderAssetId = shaderItem.GetShaderAsset().get_id()
|
|
if shaderAssetInfo.assetId == shaderAssetId:
|
|
shaderVariantId = shaderItem.GetShaderVariantId()
|
|
if not shaderVariantId.IsEmpty():
|
|
# Check for repeat shader variant ids. We are using a list here
|
|
# instead of a set to check for duplicates on shaderVariantIds because
|
|
# shaderVariantId is not hashed by the ID like it is in the C++ side.
|
|
has_repeat = False
|
|
for variantId in shaderVariantIds:
|
|
if shaderVariantId == variantId:
|
|
has_repeat = True
|
|
break
|
|
if has_repeat:
|
|
continue
|
|
|
|
shaderVariantIds.append(shaderVariantId)
|
|
shaderVariantListShaderOptionGroups.append(shaderItem.GetShaderOptionGroup())
|
|
|
|
progressDialog.setValue(i)
|
|
if progressDialog.wasCanceled():
|
|
return
|
|
|
|
progressDialog.close()
|
|
|
|
# Generate the shader variant list data by collecting shader option name-value pairs.s
|
|
shaderVariantList = azlmbr.shader.ShaderVariantListSourceData()
|
|
shaderVariantList.shaderFilePath = shaderAssetInfo.relativePath
|
|
shaderVariants = []
|
|
stableId = 1
|
|
for shaderOptionGroup in shaderVariantListShaderOptionGroups:
|
|
variantInfo = azlmbr.shader.ShaderVariantInfo()
|
|
variantInfo.stableId = stableId
|
|
options = {}
|
|
|
|
shaderOptionDescriptors = shaderOptionGroup.GetShaderOptionDescriptors()
|
|
for shaderOptionDescriptor in shaderOptionDescriptors:
|
|
optionName = shaderOptionDescriptor.GetName()
|
|
optionValue = shaderOptionGroup.GetValueByOptionName(optionName)
|
|
if not optionValue.IsValid():
|
|
continue
|
|
|
|
valueName = shaderOptionDescriptor.GetValueName(optionValue)
|
|
options[optionName.ToString()] = valueName.ToString()
|
|
|
|
if len(options) != 0:
|
|
variantInfo.options = options
|
|
shaderVariants.append(variantInfo)
|
|
stableId += 1
|
|
|
|
shaderVariantList.shaderVariants = shaderVariants
|
|
|
|
# clean previously generated shader variant list file so they don't clash.
|
|
pre, ext = os.path.splitext(shaderAssetInfo.relativePath)
|
|
projectShaderVariantListFilePath = os.path.join(azlmbr.paths.devassets, PROJECT_SHADER_VARIANTS_FOLDER, f'{pre}.shadervariantlist')
|
|
|
|
pre, ext = os.path.splitext(filename)
|
|
defaultShaderVariantListFilePath = f'{pre}.shadervariantlist'
|
|
|
|
clean_existing_shadervariantlist_files([
|
|
projectShaderVariantListFilePath
|
|
])
|
|
# Save the shader variant list file
|
|
if is_save_in_project_folder:
|
|
shaderVariantListFilePath = projectShaderVariantListFilePath
|
|
else:
|
|
shaderVariantListFilePath = defaultShaderVariantListFilePath
|
|
|
|
shaderVariantListFilePath = shaderVariantListFilePath.replace("\\", "/")
|
|
azlmbr.shader.SaveShaderVariantListSourceData(shaderVariantListFilePath, shaderVariantList)
|
|
|
|
# Open the document in shader management console
|
|
result = azlmbr.atomtools.AtomToolsDocumentSystemRequestBus(
|
|
azlmbr.bus.Broadcast,
|
|
'OpenDocument',
|
|
shaderVariantListFilePath
|
|
)
|
|
|
|
if not result.IsNull():
|
|
msgBox = QtWidgets.QMessageBox(
|
|
QtWidgets.QMessageBox.Information,
|
|
"Shader Variant List File Successfully Generated",
|
|
f".shadervariantlist file was saved in:\n{shaderVariantListFilePath}",
|
|
QtWidgets.QMessageBox.Ok
|
|
)
|
|
msgBox.exec()
|
|
|
|
print("==== End shader variant script ============================================================")
|
|
|
|
if __name__ == "__main__":
|
|
main()
|
|
|