UnlitMasterNode masterNode = iMasterNode as UnlitMasterNode ;
if ( masterNode = = null )
{
return null ;
return activeFields ;
}
if ( masterNode . twoSided . isOn )
activeFields . Add ( "AlphaTest" ) ;
}
// if (kTesselationMode != TessellationMode.None)
// {
// defines.AddShaderChunk("#define _TESSELLATION_PHONG 1", true);
// }
// #pragma shader_feature _ _VERTEX_DISPLACEMENT _PIXEL_DISPLACEMENT
// switch (kDisplacementMode)
// {
// case DisplacementMode.None:
// break;
// case DisplacementMode.Vertex:
// defines.AddShaderChunk("#define _VERTEX_DISPLACEMENT 1", true);
// break;
// case DisplacementMode.Pixel:
// defines.AddShaderChunk("#define _PIXEL_DISPLACEMENT 1", true);
// Depth offset is only enabled if per pixel displacement is
// if (kDepthOffsetEnable)
// {
// // #pragma shader_feature _DEPTHOFFSET_ON
// defines.AddShaderChunk("#define _DEPTHOFFSET_ON 1", true);
// }
// break;
// case DisplacementMode.Tessellation:
// if (kTessellationEnabled)
// {
// defines.AddShaderChunk("#define _TESSELLATION_DISPLACEMENT 1", true);
// }
// break;
// }
// #pragma shader_feature _VERTEX_DISPLACEMENT_LOCK_OBJECT_SCALE
// #pragma shader_feature _DISPLACEMENT_LOCK_TILING_SCALE
// #pragma shader_feature _PIXEL_DISPLACEMENT_LOCK_OBJECT_SCALE
// #pragma shader_feature _VERTEX_WIND
// #pragma shader_feature _ _REFRACTION_PLANE _REFRACTION_SPHERE
//
// #pragma shader_feature _ _MAPPING_PLANAR _MAPPING_TRIPLANAR // MOVE to a node
// #pragma shader_feature _NORMALMAP_TANGENT_SPACE
// #pragma shader_feature _ _REQUIRE_UV2 _REQUIRE_UV3
// #pragma shader_feature _MASKMAP
// #pragma shader_feature _BENTNORMALMAP
// #pragma shader_feature _EMISSIVE_COLOR_MAP
// #pragma shader_feature _ENABLESPECULAROCCLUSION
// #pragma shader_feature _HEIGHTMAP
// #pragma shader_feature _TANGENTMAP
// #pragma shader_feature _ANISOTROPYMAP
// #pragma shader_feature _SUBSURFACE_RADIUS_MAP
// #pragma shader_feature _THICKNESSMAP
// #pragma shader_feature _SPECULARCOLORMAP
// #pragma shader_feature _TRANSMITTANCECOLORMAP
// Keywords for transparent
// #pragma shader_feature _SURFACE_TYPE_TRANSPARENT
if ( masterNode . surfaceType ! = SurfaceType . Opaque )
// {
// defines.AddShaderChunk("#define _BLENDMODE_PRE_MULTIPLY 1", true);
// }
// #pragma shader_feature _BLENDMODE_PRESERVE_SPECULAR_LIGHTING
// if (kEnableBlendModePreserveSpecularLighting)
// {
// defines.AddShaderChunk("#define _BLENDMODE_PRESERVE_SPECULAR_LIGHTING 1", true);
// }
// #pragma shader_feature _ENABLE_FOG_ON_TRANSPARENT
// if (kEnableFogOnTransparent)
// {
// defines.AddShaderChunk("#define _ENABLE_FOG_ON_TRANSPARENT 1", true);
// }
}
else
{
private static bool GenerateShaderPassUnlit ( AbstractMaterialNode masterNode , Pass pass , GenerationMode mode , SurfaceMaterialOptions materialOptions , ShaderGenerator result , List < string > sourceAssetDependencyPaths )
{
var templateLocation = Path . Combine ( Path . Combine ( Path . Combine ( HDEditorUtils . GetHDRenderPipelinePath ( ) , "Editor" ) , "ShaderGraph" ) , pass . TemplateName ) ;
if ( ! File . Exists ( templateLocation ) )
{
// TODO: produce error here
return false ;
}
if ( sourceAssetDependencyPaths ! = null )
sourceAssetDependencyPaths . Add ( templateLocation ) ;
// grab all of the active nodes (for pixel and vertex graphs)
var vertexNodes = ListPool < INode > . Get ( ) ;
NodeUtils . DepthFirstCollectNodesFromNode ( vertexNodes , masterNode , NodeUtils . IncludeSelf . Include , pass . VertexShaderSlots ) ;
var pixelNodes = ListPool < INode > . Get ( ) ;
NodeUtils . DepthFirstCollectNodesFromNode ( pixelNodes , masterNode , NodeUtils . IncludeSelf . Include , pass . PixelShaderSlots ) ;
// graph requirements describe what the graph itself requires
var pixelRequirements = ShaderGraphRequirements . FromNodes ( pixelNodes , ShaderStageCapability . Fragment , false ) ; // TODO: is ShaderStageCapability.Fragment correct?
var vertexRequirements = ShaderGraphRequirements . FromNodes ( vertexNodes , ShaderStageCapability . Vertex , false ) ;
// Function Registry tracks functions to remove duplicates, it wraps a string builder that stores the combined function string
ShaderStringBuilder graphNodeFunctions = new ShaderStringBuilder ( ) ;
graphNodeFunctions . IncreaseIndent ( ) ;
var functionRegistry = new FunctionRegistry ( graphNodeFunctions ) ;
// TODO: this can be a shared function for all HDRP master nodes -- From here through GraphUtil.GenerateSurfaceDescription(..)
// Build the list of active slots based on what the pass requires
var pixelSlots = HDSubShaderUtilities . FindMaterialSlotsOnNode ( pass . PixelShaderSlots , masterNode ) ;
var vertexSlots = HDSubShaderUtilities . FindMaterialSlotsOnNode ( pass . VertexShaderSlots , masterNode ) ;
// properties used by either pixel and vertex shader
PropertyCollector sharedProperties = new PropertyCollector ( ) ;
// build the graph outputs structure to hold the results of each active slots (and fill out activeFields to indicate they are active)
string pixelGraphInputStructName = "SurfaceDescriptionInputs" ;
string pixelGraphOutputStructName = "SurfaceDescription" ;
string pixelGraphEvalFunctionName = "SurfaceDescriptionFunction" ;
ShaderStringBuilder pixelGraphEvalFunction = new ShaderStringBuilder ( ) ;
ShaderStringBuilder pixelGraphOutputs = new ShaderStringBuilder ( ) ;
// dependency tracker -- set of active fields
// apply master node options to active fields
// build initial requirements
HDRPShaderStructs . AddActiveFieldsFromPixelGraphRequirements ( activeFields , pixelRequirements ) ;
// build the graph outputs structure, and populate activeFields with the fields of that structure
GraphUtil . GenerateSurfaceDescriptionStruct ( pixelGraphOutputs , pixelSlots , true , pixelGraphOutputStructName , activeFields ) ;
// Build the graph evaluation code, to evaluate the specified slots
GraphUtil . GenerateSurfaceDescriptionFunction (
pixelNodes ,
masterNode ,
masterNode . owner as AbstractMaterialGraph ,
pixelGraphEvalFunction ,
functionRegistry ,
sharedProperties ,
pixelRequirements , // TODO : REMOVE UNUSED
mode ,
pixelGraphEvalFunctionName ,
pixelGraphOutputStructName ,
null ,
pixelSlots ,
pixelGraphInputStructName ) ;
string vertexGraphInputStructName = "VertexDescriptionInputs" ;
string vertexGraphOutputStructName = "VertexDescription" ;
string vertexGraphEvalFunctionName = "VertexDescriptionFunction" ;
ShaderStringBuilder vertexGraphEvalFunction = new ShaderStringBuilder ( ) ;
ShaderStringBuilder vertexGraphOutputs = new ShaderStringBuilder ( ) ;
// check for vertex animation -- enables HAVE_VERTEX_MODIFICATION
bool vertexActive = false ;
if ( masterNode . IsSlotConnected ( PBRMasterNode . PositionSlotId ) )
{
vertexActive = true ;
activeFields . Add ( "features.modifyMesh" ) ;
HDRPShaderStructs . AddActiveFieldsFromVertexGraphRequirements ( activeFields , vertexRequirements ) ;
// -------------------------------------
// Generate Output structure for Vertex Description function
GraphUtil . GenerateVertexDescriptionStruct ( vertexGraphOutputs , vertexSlots , vertexGraphOutputStructName , activeFields ) ;
// -------------------------------------
// Generate Vertex Description function
GraphUtil . GenerateVertexDescriptionFunction (
masterNode . owner as AbstractMaterialGraph ,
vertexGraphEvalFunction ,
functionRegistry ,
sharedProperties ,
mode ,
vertexNodes ,
vertexSlots ,
vertexGraphInputStructName ,
vertexGraphEvalFunctionName ,
vertexGraphOutputStructName ) ;
}
var blendCode = new ShaderStringBuilder ( ) ;
var cullCode = new ShaderStringBuilder ( ) ;
var zTestCode = new ShaderStringBuilder ( ) ;
var zWriteCode = new ShaderStringBuilder ( ) ;
var stencilCode = new ShaderStringBuilder ( ) ;
var colorMaskCode = new ShaderStringBuilder ( ) ;
HDSubShaderUtilities . BuildRenderStatesFromPassAndMaterialOptions ( pass , materialOptions , blendCode , cullCode , zTestCode , zWriteCode , stencilCode , colorMaskCode ) ;
HDRPShaderStructs . AddRequiredFields ( pass . RequiredFields , activeFields ) ;
// apply dependencies to the active fields, and build interpolators (TODO: split this function)
var packedInterpolatorCode = new ShaderGenerator ( ) ;
HDRPShaderStructs . Generate (
packedInterpolatorCode ,
activeFields ) ;
// debug output all active fields
var interpolatorDefines = new ShaderGenerator ( ) ;
{
interpolatorDefines . AddShaderChunk ( "// ACTIVE FIELDS:" ) ;
foreach ( string f in activeFields )
{
interpolatorDefines . AddShaderChunk ( "// " + f ) ;
}
}
// build graph inputs structures
ShaderGenerator pixelGraphInputs = new ShaderGenerator ( ) ;
ShaderSpliceUtil . BuildType ( typeof ( HDRPShaderStructs . SurfaceDescriptionInputs ) , activeFields , pixelGraphInputs ) ;
ShaderGenerator vertexGraphInputs = new ShaderGenerator ( ) ;
ShaderSpliceUtil . BuildType ( typeof ( HDRPShaderStructs . VertexDescriptionInputs ) , activeFields , vertexGraphInputs ) ;
ShaderGenerator defines = new ShaderGenerator ( ) ;
{
defines . AddShaderChunk ( string . Format ( "#define SHADERPASS {0}" , pass . ShaderPassName ) , true ) ;
if ( pass . ExtraDefines ! = null )
{
foreach ( var define in pass . ExtraDefines )
defines . AddShaderChunk ( define ) ;
}
defines . AddGenerator ( interpolatorDefines ) ;
}
var shaderPassIncludes = new ShaderGenerator ( ) ;
if ( pass . Includes ! = null )
{
foreach ( var include in pass . Includes )
shaderPassIncludes . AddShaderChunk ( include ) ;
}
// build graph code
var graph = new ShaderGenerator ( ) ;
{
graph . AddShaderChunk ( "// Shared Graph Properties (uniform inputs)" ) ;
graph . AddShaderChunk ( sharedProperties . GetPropertiesDeclaration ( 1 ) ) ;
graph . AddShaderChunk ( "// Shared Graph Node Functions" ) ;
graph . AddShaderChunk ( graphNodeFunctions . ToString ( ) ) ;
if ( vertexActive )
{
graph . AddShaderChunk ( "// Vertex Graph Inputs" ) ;
graph . Indent ( ) ;
graph . AddGenerator ( vertexGraphInputs ) ;
graph . Deindent ( ) ;
graph . AddShaderChunk ( "// Vertex Graph Outputs" ) ;
graph . Indent ( ) ;
graph . AddShaderChunk ( vertexGraphOutputs . ToString ( ) ) ;
graph . Deindent ( ) ;
graph . AddShaderChunk ( "// Vertex Graph Evaluation" ) ;
graph . Indent ( ) ;
graph . AddShaderChunk ( vertexGraphEvalFunction . ToString ( ) ) ;
graph . Deindent ( ) ;
}
graph . AddShaderChunk ( "// Pixel Graph Inputs" ) ;
graph . Indent ( ) ;
graph . AddGenerator ( pixelGraphInputs ) ;
graph . Deindent ( ) ;
graph . AddShaderChunk ( "// Pixel Graph Outputs" ) ;
graph . Indent ( ) ;
graph . AddShaderChunk ( pixelGraphOutputs . ToString ( ) ) ;
graph . Deindent ( ) ;
graph . AddShaderChunk ( "// Pixel Graph Evaluation" ) ;
graph . Indent ( ) ;
graph . AddShaderChunk ( pixelGraphEvalFunction . ToString ( ) ) ;
graph . Deindent ( ) ;
}
// build the hash table of all named fragments TODO: could make this Dictionary<string, ShaderGenerator / string> ?
Dictionary < string , string > namedFragments = new Dictionary < string , string > ( ) ;
namedFragments . Add ( "${Defines}" , defines . GetShaderString ( 2 , false ) ) ;
namedFragments . Add ( "${Graph}" , graph . GetShaderString ( 2 , false ) ) ;
namedFragments . Add ( "${LightMode}" , pass . LightMode ) ;
namedFragments . Add ( "${PassName}" , pass . Name ) ;
namedFragments . Add ( "${Includes}" , shaderPassIncludes . GetShaderString ( 2 , false ) ) ;
namedFragments . Add ( "${InterpolatorPacking}" , packedInterpolatorCode . GetShaderString ( 2 , false ) ) ;
namedFragments . Add ( "${Blending}" , blendCode . ToString ( ) ) ;
namedFragments . Add ( "${Culling}" , cullCode . ToString ( ) ) ;
namedFragments . Add ( "${ZTest}" , zTestCode . ToString ( ) ) ;
namedFragments . Add ( "${ZWrite}" , zWriteCode . ToString ( ) ) ;
namedFragments . Add ( "${Stencil}" , stencilCode . ToString ( ) ) ;
namedFragments . Add ( "${ColorMask}" , colorMaskCode . ToString ( ) ) ;
namedFragments . Add ( "${LOD}" , materialOptions . lod . ToString ( ) ) ;
// process the template to generate the shader code for this pass TODO: could make this a shared function
string [ ] templateLines = File . ReadAllLines ( templateLocation ) ;
System . Text . StringBuilder builder = new System . Text . StringBuilder ( ) ;
foreach ( string line in templateLines )
{
ShaderSpliceUtil . PreprocessShaderCode ( line , activeFields , namedFragments , builder ) ;
builder . AppendLine ( ) ;
}
result . AddShaderChunk ( builder . ToString ( ) , false ) ;
return true ;
// use standard shader pass generation
return HDSubShaderUtilities . GenerateShaderPass ( masterNode , pass , mode , materialOptions , activeFields , result , sourceAssetDependencyPaths ) ;
public string GetSubshader ( IMasterNode inMasterNode , GenerationMode mode , List < string > sourceAssetDependencyPaths = null )
public string GetSubshader ( IMasterNode iMasterNode , GenerationMode mode , List < string > sourceAssetDependencyPaths = null )
{
if ( sourceAssetDependencyPaths ! = null )
{
sourceAssetDependencyPaths . Add ( AssetDatabase . GUIDToAssetPath ( "713ced4e6eef4a44799a4dd59041484b" ) ) ;
}
var masterNode = in MasterNode as UnlitMasterNode ;
var masterNode = iMasterNode as UnlitMasterNode ;
var subShader = new ShaderGenerator ( ) ;
subShader . AddShaderChunk ( "SubShader" , true ) ;
subShader . AddShaderChunk ( "{" , true ) ;