Files
UnrealEngine/Engine/Source/ThirdParty/MaterialX/MaterialX-1.38.10/source/MaterialXGenShader/HwShaderGenerator.h
2025-05-18 13:04:45 +08:00

396 lines
20 KiB
C++

//
// Copyright Contributors to the MaterialX Project
// SPDX-License-Identifier: Apache-2.0
//
#ifndef MATERIALX_HWSHADERGENERATOR_H
#define MATERIALX_HWSHADERGENERATOR_H
/// @file
/// Hardware shader generator base class
#include <MaterialXGenShader/Export.h>
#include <MaterialXGenShader/GenContext.h>
#include <MaterialXGenShader/ShaderGenerator.h>
MATERIALX_NAMESPACE_BEGIN
/*
The HW shader generators have a number of predefined variables (inputs and uniforms) with binding rules.
When these are used by a shader the application must bind them to the expected data. The following table is
a listing of the variables with a description of what data they should be bound to.
However, different renderers can have different requirements on naming conventions for these variables.
In order to facilitate this the generators will use token substitution for naming the variables. The
first colum below shows the token names that should be used in source code before the token substitution
is done. The second row shows the real identifier names that will be used by default after substitution.
An generator can override these identifier names in order to use a custom naming convention for these.
Overriding identifier names is done by changing the entries in the identifiers map given to the function
replaceIdentifiers(), which is handling the token substitution on a shader stage.
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
TOKEN NAME DEFAULT IDENTIFIER NAME TYPE BINDING
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Vertex input variables :
$inPosition i_position vec3 Vertex position in object space
$inNormal i_normal vec3 Vertex normal in object space
$inTangent i_tangent vec3 Vertex tangent in object space
$inBitangent i_bitangent vec3 Vertex bitangent in object space
$inTexcoord_N i_texcoord_N vec2 Vertex texture coordinate for the N:th uv set
$inColor_N i_color_N vec4 Vertex color for the N:th color set (RGBA)
Uniform variables :
$worldMatrix u_worldMatrix mat4 World transformation
$worldInverseMatrix u_worldInverseMatrix mat4 World transformation, inverted
$worldTransposeMatrix u_worldTransposeMatrix mat4 World transformation, transposed
$worldInverseTransposeMatrix u_worldInverseTransposeMatrix mat4 World transformation, inverted and transposed
$viewMatrix u_viewMatrix mat4 View transformation
$viewInverseMatrix u_viewInverseMatrix mat4 View transformation, inverted
$viewTransposeMatrix u_viewTransposeMatrix mat4 View transformation, transposed
$viewInverseTransposeMatrix u_viewInverseTransposeMatrix mat4 View transformation, inverted and transposed
$projectionMatrix u_projectionMatrix mat4 Projection transformation
$projectionInverseMatrix u_projectionInverseMatrix mat4 Projection transformation, inverted
$projectionTransposeMatrix u_projectionTransposeMatrix mat4 Projection transformation, transposed
$projectionInverseTransposeMatrix u_projectionInverseTransposeMatrix mat4 Projection transformation, inverted and transposed
$worldViewMatrix u_worldViewMatrix mat4 World-view transformation
$viewProjectionMatrix u_viewProjectionMatrix mat4 View-projection transformation
$worldViewProjectionMatrix u_worldViewProjectionMatrix mat4 World-view-projection transformation
$viewPosition u_viewPosition vec3 World-space position of the view (camera)
$viewDirection u_viewDirection vec3 World-space direction of the view (camera)
$frame u_frame float The current frame number as defined by the host application
$time u_time float The current time in seconds
$geomprop_<name> u_geomprop_<name> <type> A named property of given <type> where <name> is the name of the variable on the geometry
$numActiveLightSources u_numActiveLightSources int The number of currently active light sources. Note that in shader this is clamped against
the maximum allowed number of lights sources. The maximum number is set by the generation
option GenOptions.hwMaxActiveLightSources.
$lightData[] u_lightData[] struct Array of struct LightData holding parameters for active light sources.
The LightData struct is built dynamically depending on requirements for
bound light shaders.
$envMatrix u_envMatrix mat4 Rotation matrix for the environment.
$envIrradiance u_envIrradiance sampler2D Sampler for the texture used for diffuse environment lighting.
$envRadiance u_envRadiance sampler2D Sampler for the texture used for specular environment lighting.
$envLightIntensity u_envLightIntensity float Linear multiplier for environment lighting
$envRadianceMips u_envRadianceMips int Number of mipmaps used on the specular environment texture.
$envRadianceSamples u_envRadianceSamples int Samples to use if Filtered Importance Sampling is used for specular environment lighting.
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
*/
/// HW specific identifiers.
namespace HW
{
/// Token identifiers
extern MX_GENSHADER_API const string T_IN_POSITION;
extern MX_GENSHADER_API const string T_IN_NORMAL;
extern MX_GENSHADER_API const string T_IN_TANGENT;
extern MX_GENSHADER_API const string T_IN_BITANGENT;
extern MX_GENSHADER_API const string T_IN_TEXCOORD;
extern MX_GENSHADER_API const string T_IN_GEOMPROP;
extern MX_GENSHADER_API const string T_IN_COLOR;
extern MX_GENSHADER_API const string T_POSITION_WORLD;
extern MX_GENSHADER_API const string T_NORMAL_WORLD;
extern MX_GENSHADER_API const string T_TANGENT_WORLD;
extern MX_GENSHADER_API const string T_BITANGENT_WORLD;
extern MX_GENSHADER_API const string T_POSITION_OBJECT;
extern MX_GENSHADER_API const string T_NORMAL_OBJECT;
extern MX_GENSHADER_API const string T_TANGENT_OBJECT;
extern MX_GENSHADER_API const string T_BITANGENT_OBJECT;
extern MX_GENSHADER_API const string T_TEXCOORD;
extern MX_GENSHADER_API const string T_COLOR;
extern MX_GENSHADER_API const string T_WORLD_MATRIX;
extern MX_GENSHADER_API const string T_WORLD_INVERSE_MATRIX;
extern MX_GENSHADER_API const string T_WORLD_TRANSPOSE_MATRIX;
extern MX_GENSHADER_API const string T_WORLD_INVERSE_TRANSPOSE_MATRIX;
extern MX_GENSHADER_API const string T_VIEW_MATRIX;
extern MX_GENSHADER_API const string T_VIEW_INVERSE_MATRIX;
extern MX_GENSHADER_API const string T_VIEW_TRANSPOSE_MATRIX;
extern MX_GENSHADER_API const string T_VIEW_INVERSE_TRANSPOSE_MATRIX;
extern MX_GENSHADER_API const string T_PROJ_MATRIX;
extern MX_GENSHADER_API const string T_PROJ_INVERSE_MATRIX;
extern MX_GENSHADER_API const string T_PROJ_TRANSPOSE_MATRIX;
extern MX_GENSHADER_API const string T_PROJ_INVERSE_TRANSPOSE_MATRIX;
extern MX_GENSHADER_API const string T_WORLD_VIEW_MATRIX;
extern MX_GENSHADER_API const string T_VIEW_PROJECTION_MATRIX;
extern MX_GENSHADER_API const string T_WORLD_VIEW_PROJECTION_MATRIX;
extern MX_GENSHADER_API const string T_VIEW_POSITION;
extern MX_GENSHADER_API const string T_VIEW_DIRECTION;
extern MX_GENSHADER_API const string T_FRAME;
extern MX_GENSHADER_API const string T_TIME;
extern MX_GENSHADER_API const string T_GEOMPROP;
extern MX_GENSHADER_API const string T_ALPHA_THRESHOLD;
extern MX_GENSHADER_API const string T_NUM_ACTIVE_LIGHT_SOURCES;
extern MX_GENSHADER_API const string T_ENV_MATRIX;
extern MX_GENSHADER_API const string T_ENV_RADIANCE;
extern MX_GENSHADER_API const string T_ENV_RADIANCE_MIPS;
extern MX_GENSHADER_API const string T_ENV_RADIANCE_SAMPLES;
extern MX_GENSHADER_API const string T_ENV_IRRADIANCE;
extern MX_GENSHADER_API const string T_ENV_LIGHT_INTENSITY;
extern MX_GENSHADER_API const string T_ENV_PREFILTER_MIP;
extern MX_GENSHADER_API const string T_REFRACTION_TWO_SIDED;
extern MX_GENSHADER_API const string T_ALBEDO_TABLE;
extern MX_GENSHADER_API const string T_ALBEDO_TABLE_SIZE;
extern MX_GENSHADER_API const string T_AMB_OCC_MAP;
extern MX_GENSHADER_API const string T_AMB_OCC_GAIN;
extern MX_GENSHADER_API const string T_SHADOW_MAP;
extern MX_GENSHADER_API const string T_SHADOW_MATRIX;
extern MX_GENSHADER_API const string T_VERTEX_DATA_INSTANCE;
extern MX_GENSHADER_API const string T_LIGHT_DATA_INSTANCE;
/// Default names for identifiers.
/// Replacing above tokens in final code.
extern MX_GENSHADER_API const string IN_POSITION;
extern MX_GENSHADER_API const string IN_NORMAL;
extern MX_GENSHADER_API const string IN_TANGENT;
extern MX_GENSHADER_API const string IN_BITANGENT;
extern MX_GENSHADER_API const string IN_TEXCOORD;
extern MX_GENSHADER_API const string IN_GEOMPROP;
extern MX_GENSHADER_API const string IN_COLOR;
extern MX_GENSHADER_API const string POSITION_WORLD;
extern MX_GENSHADER_API const string NORMAL_WORLD;
extern MX_GENSHADER_API const string TANGENT_WORLD;
extern MX_GENSHADER_API const string BITANGENT_WORLD;
extern MX_GENSHADER_API const string POSITION_OBJECT;
extern MX_GENSHADER_API const string NORMAL_OBJECT;
extern MX_GENSHADER_API const string TANGENT_OBJECT;
extern MX_GENSHADER_API const string BITANGENT_OBJECT;
extern MX_GENSHADER_API const string TEXCOORD;
extern MX_GENSHADER_API const string COLOR;
extern MX_GENSHADER_API const string WORLD_MATRIX;
extern MX_GENSHADER_API const string WORLD_INVERSE_MATRIX;
extern MX_GENSHADER_API const string WORLD_TRANSPOSE_MATRIX;
extern MX_GENSHADER_API const string WORLD_INVERSE_TRANSPOSE_MATRIX;
extern MX_GENSHADER_API const string VIEW_MATRIX;
extern MX_GENSHADER_API const string VIEW_INVERSE_MATRIX;
extern MX_GENSHADER_API const string VIEW_TRANSPOSE_MATRIX;
extern MX_GENSHADER_API const string VIEW_INVERSE_TRANSPOSE_MATRIX;
extern MX_GENSHADER_API const string PROJ_MATRIX;
extern MX_GENSHADER_API const string PROJ_INVERSE_MATRIX;
extern MX_GENSHADER_API const string PROJ_TRANSPOSE_MATRIX;
extern MX_GENSHADER_API const string PROJ_INVERSE_TRANSPOSE_MATRIX;
extern MX_GENSHADER_API const string WORLD_VIEW_MATRIX;
extern MX_GENSHADER_API const string VIEW_PROJECTION_MATRIX;
extern MX_GENSHADER_API const string WORLD_VIEW_PROJECTION_MATRIX;
extern MX_GENSHADER_API const string VIEW_POSITION;
extern MX_GENSHADER_API const string VIEW_DIRECTION;
extern MX_GENSHADER_API const string FRAME;
extern MX_GENSHADER_API const string TIME;
extern MX_GENSHADER_API const string GEOMPROP;
extern MX_GENSHADER_API const string ALPHA_THRESHOLD;
extern MX_GENSHADER_API const string NUM_ACTIVE_LIGHT_SOURCES;
extern MX_GENSHADER_API const string ENV_MATRIX;
extern MX_GENSHADER_API const string ENV_RADIANCE;
extern MX_GENSHADER_API const string ENV_RADIANCE_MIPS;
extern MX_GENSHADER_API const string ENV_RADIANCE_SAMPLES;
extern MX_GENSHADER_API const string ENV_IRRADIANCE;
extern MX_GENSHADER_API const string ENV_LIGHT_INTENSITY;
extern MX_GENSHADER_API const string ENV_PREFILTER_MIP;
extern MX_GENSHADER_API const string REFRACTION_TWO_SIDED;
extern MX_GENSHADER_API const string ALBEDO_TABLE;
extern MX_GENSHADER_API const string ALBEDO_TABLE_SIZE;
extern MX_GENSHADER_API const string AMB_OCC_MAP;
extern MX_GENSHADER_API const string AMB_OCC_GAIN;
extern MX_GENSHADER_API const string SHADOW_MAP;
extern MX_GENSHADER_API const string SHADOW_MATRIX;
extern MX_GENSHADER_API const string VERTEX_DATA_INSTANCE;
extern MX_GENSHADER_API const string LIGHT_DATA_INSTANCE;
extern MX_GENSHADER_API const string LIGHT_DATA_MAX_LIGHT_SOURCES;
/// Variable blocks names.
extern MX_GENSHADER_API const string VERTEX_INPUTS; // Geometric inputs for vertex stage.
extern MX_GENSHADER_API const string VERTEX_DATA; // Connector block for data transfer from vertex stage to pixel stage.
extern MX_GENSHADER_API const string PRIVATE_UNIFORMS; // Uniform inputs set privately by application.
extern MX_GENSHADER_API const string PUBLIC_UNIFORMS; // Uniform inputs visible in UI and set by user.
extern MX_GENSHADER_API const string LIGHT_DATA; // Uniform inputs for light sources.
extern MX_GENSHADER_API const string PIXEL_OUTPUTS; // Outputs from the main/pixel stage.
/// Variable names for lighting parameters.
extern MX_GENSHADER_API const string DIR_N;
extern MX_GENSHADER_API const string DIR_L;
extern MX_GENSHADER_API const string DIR_V;
extern MX_GENSHADER_API const string WORLD_POSITION;
extern MX_GENSHADER_API const string OCCLUSION;
/// Attribute names.
extern MX_GENSHADER_API const string ATTR_TRANSPARENT;
/// User data names.
extern MX_GENSHADER_API const string USER_DATA_LIGHT_SHADERS;
extern MX_GENSHADER_API const string USER_DATA_BINDING_CONTEXT;
} // namespace HW
namespace Stage
{
/// Identifier for vertex stage.
extern MX_GENSHADER_API const string VERTEX;
} // namespace Stage
class HwLightShaders;
class HwShaderGenerator;
class HwResourceBindingContext;
/// Shared pointer to a HwLightShaders
using HwLightShadersPtr = shared_ptr<class HwLightShaders>;
/// Shared pointer to a HwShaderGenerator
using HwShaderGeneratorPtr = shared_ptr<class HwShaderGenerator>;
/// Shared pointer to a HwResourceBindingContext
using HwResourceBindingContextPtr = shared_ptr<class HwResourceBindingContext>;
/// @class HwLightShaders
/// Hardware light shader user data
class MX_GENSHADER_API HwLightShaders : public GenUserData
{
public:
/// Create and return a new instance.
static HwLightShadersPtr create()
{
return std::make_shared<HwLightShaders>();
}
/// Bind a light shader to a light type id.
void bind(unsigned int type, ShaderNodePtr shader)
{
_shaders[type] = shader;
}
/// Unbind a light shader previously bound to a light type id.
void unbind(unsigned int type)
{
_shaders.erase(type);
}
/// Clear all light shaders previously bound.
void clear()
{
_shaders.clear();
}
/// Return the light shader bound to the given light type,
/// or nullptr if not light shader is bound to this type.
const ShaderNode* get(unsigned int type) const
{
auto it = _shaders.find(type);
return it != _shaders.end() ? it->second.get() : nullptr;
}
/// Return the map of bound light shaders.
const std::unordered_map<unsigned int, ShaderNodePtr>& get() const
{
return _shaders;
}
protected:
std::unordered_map<unsigned int, ShaderNodePtr> _shaders;
};
/// @class HwShaderGenerator
/// Base class for shader generators targeting HW rendering.
class MX_GENSHADER_API HwShaderGenerator : public ShaderGenerator
{
public:
/// Add the function call for a single node.
void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override;
/// Emit code for active light count definitions and uniforms
virtual void addStageLightingUniforms(GenContext& context, ShaderStage& stage) const;
/// Return the closure contexts defined for the given node.
void getClosureContexts(const ShaderNode& node, vector<ClosureContext*>& cct) const override;
/// Bind a light shader to a light type id, for usage in surface shaders created
/// by the generator. The lightTypeId should be a unique identifier for the light
/// type (node definition) and the same id should be used when setting light parameters on a
/// generated surface shader.
static void bindLightShader(const NodeDef& nodeDef, unsigned int lightTypeId, GenContext& context);
/// Unbind a light shader previously bound to the given light type id.
static void unbindLightShader(unsigned int lightTypeId, GenContext& context);
/// Unbind all light shaders previously bound.
static void unbindLightShaders(GenContext& context);
/// Determine the prefix of vertex data variables.
virtual string getVertexDataPrefix(const VariableBlock& vertexData) const = 0;
/// Types of closure contexts for HW.
enum ClosureContextType
{
DEFAULT,
REFLECTION,
TRANSMISSION,
INDIRECT,
EMISSION
};
/// String constants for closure context suffixes.
static const string CLOSURE_CONTEXT_SUFFIX_REFLECTION;
static const string CLOSURE_CONTEXT_SUFFIX_TRANSMISSION;
static const string CLOSURE_CONTEXT_SUFFIX_INDIRECT;
protected:
HwShaderGenerator(SyntaxPtr syntax);
/// Create and initialize a new HW shader for shader generation.
virtual ShaderPtr createShader(const string& name, ElementPtr element, GenContext& context) const;
/// Closure contexts for defining closure functions.
mutable ClosureContext _defDefault;
mutable ClosureContext _defReflection;
mutable ClosureContext _defTransmission;
mutable ClosureContext _defIndirect;
mutable ClosureContext _defEmission;
};
/// @class HwShaderGenerator
/// Base class for HW node implementations.
class MX_GENSHADER_API HwImplementation : public ShaderNodeImpl
{
public:
bool isEditable(const ShaderInput& input) const override;
protected:
HwImplementation() { }
// Integer identifiers for coordinate spaces.
// The order must match the order given for the space enum string in stdlib.
enum Space
{
MODEL_SPACE = 0,
OBJECT_SPACE = 1,
WORLD_SPACE = 2
};
/// Internal string constants
static const string SPACE;
static const string INDEX;
static const string GEOMPROP;
};
/// @class HwResourceBindingContext
/// Class representing a context for resource binding for hardware resources.
class MX_GENSHADER_API HwResourceBindingContext : public GenUserData
{
public:
virtual ~HwResourceBindingContext() { }
// Initialize the context before generation starts.
virtual void initialize() = 0;
// Emit directives required for binding support
virtual void emitDirectives(GenContext& context, ShaderStage& stage) = 0;
// Emit uniforms with binding information
virtual void emitResourceBindings(GenContext& context, const VariableBlock& uniforms, ShaderStage& stage) = 0;
// Emit struct uniforms with binding information
virtual void emitStructuredResourceBindings(GenContext& context, const VariableBlock& uniforms,
ShaderStage& stage, const std::string& structInstanceName,
const std::string& arraySuffix = EMPTY_STRING) = 0;
};
MATERIALX_NAMESPACE_END
#endif