// All Setup Keyword functions must be static. It allow to create script to automatically update the shaders with a script if code change static public void SetupBaseLitKeywords(Material material) { material.SetupBaseUnlitKeywords(); bool doubleSidedEnable = material.HasProperty(kDoubleSidedEnable) ? material.GetFloat(kDoubleSidedEnable) > 0.0f : false; if (doubleSidedEnable) { DoubleSidedNormalMode doubleSidedNormalMode = (DoubleSidedNormalMode)material.GetFloat(kDoubleSidedNormalMode); switch (doubleSidedNormalMode) { case DoubleSidedNormalMode.Mirror: // Mirror mode (in tangent space) material.SetVector("_DoubleSidedConstants", new Vector4(1.0f, 1.0f, -1.0f, 0.0f)); break; case DoubleSidedNormalMode.Flip: // Flip mode (in tangent space) material.SetVector("_DoubleSidedConstants", new Vector4(-1.0f, -1.0f, -1.0f, 0.0f)); break; case DoubleSidedNormalMode.None: // None mode (in tangent space) material.SetVector("_DoubleSidedConstants", new Vector4(1.0f, 1.0f, 1.0f, 0.0f)); break; } } if (material.HasProperty(kDisplacementMode)) { bool enableDisplacement = (DisplacementMode)material.GetFloat(kDisplacementMode) != DisplacementMode.None; bool enableVertexDisplacement = (DisplacementMode)material.GetFloat(kDisplacementMode) == DisplacementMode.Vertex; bool enablePixelDisplacement = (DisplacementMode)material.GetFloat(kDisplacementMode) == DisplacementMode.Pixel; bool enableTessellationDisplacement = ((DisplacementMode)material.GetFloat(kDisplacementMode) == DisplacementMode.Tessellation) && material.HasProperty(kTessellationMode); CoreUtils.SetKeyword(material, "_VERTEX_DISPLACEMENT", enableVertexDisplacement); CoreUtils.SetKeyword(material, "_PIXEL_DISPLACEMENT", enablePixelDisplacement); // Only set if tessellation exist CoreUtils.SetKeyword(material, "_TESSELLATION_DISPLACEMENT", enableTessellationDisplacement); bool displacementLockObjectScale = material.GetFloat(kDisplacementLockObjectScale) > 0.0; bool displacementLockTilingScale = material.GetFloat(kDisplacementLockTilingScale) > 0.0; // Tessellation reuse vertex flag. CoreUtils.SetKeyword(material, "_VERTEX_DISPLACEMENT_LOCK_OBJECT_SCALE", displacementLockObjectScale && (enableVertexDisplacement || enableTessellationDisplacement)); CoreUtils.SetKeyword(material, "_PIXEL_DISPLACEMENT_LOCK_OBJECT_SCALE", displacementLockObjectScale && enablePixelDisplacement); CoreUtils.SetKeyword(material, "_DISPLACEMENT_LOCK_TILING_SCALE", displacementLockTilingScale && enableDisplacement); // Depth offset is only enabled if per pixel displacement is bool depthOffsetEnable = (material.GetFloat(kDepthOffsetEnable) > 0.0f) && enablePixelDisplacement; CoreUtils.SetKeyword(material, "_DEPTHOFFSET_ON", depthOffsetEnable); } CoreUtils.SetKeyword(material, "_VERTEX_WIND", false); if (material.HasProperty(kTessellationMode)) { TessellationMode tessMode = (TessellationMode)material.GetFloat(kTessellationMode); CoreUtils.SetKeyword(material, "_TESSELLATION_PHONG", tessMode == TessellationMode.Phong); } material.SetupMainTexForAlphaTestGI("_BaseColorMap", "_BaseColor"); // Use negation so we don't create keyword by default CoreUtils.SetKeyword(material, "_DISABLE_DECALS", material.HasProperty(kSupportDecals) && material.GetFloat(kSupportDecals) == 0.0); CoreUtils.SetKeyword(material, "_DISABLE_SSR", material.HasProperty(kReceivesSSR) && material.GetFloat(kReceivesSSR) == 0.0); CoreUtils.SetKeyword(material, "_DISABLE_SSR_TRANSPARENT", material.HasProperty(kReceivesSSRTransparent) && material.GetFloat(kReceivesSSRTransparent) == 0.0); CoreUtils.SetKeyword(material, "_ENABLE_GEOMETRIC_SPECULAR_AA", material.HasProperty(kEnableGeometricSpecularAA) && material.GetFloat(kEnableGeometricSpecularAA) == 1.0); if (material.HasProperty(kRefractionModel)) { var refractionModelValue = (ScreenSpaceRefraction.RefractionModel)material.GetFloat(kRefractionModel); // We can't have refraction in pre-refraction queue and the material needs to be transparent var canHaveRefraction = material.GetSurfaceType() == SurfaceType.Transparent && !HDRenderQueue.k_RenderQueue_PreRefraction.Contains(material.renderQueue); CoreUtils.SetKeyword(material, "_REFRACTION_PLANE", (refractionModelValue == ScreenSpaceRefraction.RefractionModel.Box) && canHaveRefraction); CoreUtils.SetKeyword(material, "_REFRACTION_SPHERE", (refractionModelValue == ScreenSpaceRefraction.RefractionModel.Sphere) && canHaveRefraction); CoreUtils.SetKeyword(material, "_REFRACTION_THIN", (refractionModelValue == ScreenSpaceRefraction.RefractionModel.Thin) && canHaveRefraction); } if (material.HasProperty(kForceForwardEmissive)) { CoreUtils.SetKeyword(material, "_FORCE_FORWARD_EMISSIVE", material.GetInt(kForceForwardEmissive) != 0); } }
// All Setup Keyword functions must be static. It allow to create script to automatically update the shaders with a script if code change static public void SetupBaseLitKeywords(Material material) { SetupBaseUnlitKeywords(material); bool doubleSidedEnable = material.HasProperty(kDoubleSidedEnable) ? material.GetFloat(kDoubleSidedEnable) > 0.0f : false; if (doubleSidedEnable) { DoubleSidedNormalMode doubleSidedNormalMode = (DoubleSidedNormalMode)material.GetFloat(kDoubleSidedNormalMode); switch (doubleSidedNormalMode) { case DoubleSidedNormalMode.Mirror: // Mirror mode (in tangent space) material.SetVector("_DoubleSidedConstants", new Vector4(1.0f, 1.0f, -1.0f, 0.0f)); break; case DoubleSidedNormalMode.Flip: // Flip mode (in tangent space) material.SetVector("_DoubleSidedConstants", new Vector4(-1.0f, -1.0f, -1.0f, 0.0f)); break; case DoubleSidedNormalMode.None: // None mode (in tangent space) material.SetVector("_DoubleSidedConstants", new Vector4(1.0f, 1.0f, 1.0f, 0.0f)); break; } } // Stencil usage rules: // DoesntReceiveSSR and DecalsForwardOutputNormalBuffer need to be tagged during depth prepass // LightingMask need to be tagged during either GBuffer or Forward pass // ObjectMotionVectors need to be tagged in velocity pass. // As motion vectors pass can be use as a replacement of depth prepass it also need to have DoesntReceiveSSR and DecalsForwardOutputNormalBuffer // As GBuffer pass can have no depth prepass, it also need to have DoesntReceiveSSR and DecalsForwardOutputNormalBuffer // Object motion vectors is always render after a full depth buffer (if there is no depth prepass for GBuffer all object motion vectors are render after GBuffer) // so we have a guarantee than when we write object motion vectors no other object will be draw on top (and so would have require to overwrite motion vectors). // Final combination is: // Prepass: DoesntReceiveSSR, DecalsForwardOutputNormalBuffer // Motion vectors: DoesntReceiveSSR, DecalsForwardOutputNormalBuffer, ObjectVelocity // GBuffer: LightingMask, DecalsForwardOutputNormalBuffer, ObjectVelocity // Forward: LightingMask int stencilRef = (int)StencilLightingUsage.RegularLighting; // Forward case int stencilWriteMask = (int)HDRenderPipeline.StencilBitMask.LightingMask; int stencilRefDepth = 0; int stencilWriteMaskDepth = 0; int stencilRefGBuffer = (int)StencilLightingUsage.RegularLighting; int stencilWriteMaskGBuffer = (int)HDRenderPipeline.StencilBitMask.LightingMask; int stencilRefMV = (int)HDRenderPipeline.StencilBitMask.ObjectMotionVectors; int stencilWriteMaskMV = (int)HDRenderPipeline.StencilBitMask.ObjectMotionVectors; if (material.HasProperty(kMaterialID) && (int)material.GetFloat(kMaterialID) == (int)MaterialId.LitSSS) { stencilRefGBuffer = stencilRef = (int)StencilLightingUsage.SplitLighting; } if (material.HasProperty(kReceivesSSR) && material.GetInt(kReceivesSSR) == 0) { stencilRefDepth |= (int)HDRenderPipeline.StencilBitMask.DoesntReceiveSSR; stencilRefGBuffer |= (int)HDRenderPipeline.StencilBitMask.DoesntReceiveSSR; stencilRefMV |= (int)HDRenderPipeline.StencilBitMask.DoesntReceiveSSR; } stencilWriteMaskDepth |= (int)HDRenderPipeline.StencilBitMask.DoesntReceiveSSR | (int)HDRenderPipeline.StencilBitMask.DecalsForwardOutputNormalBuffer; stencilWriteMaskGBuffer |= (int)HDRenderPipeline.StencilBitMask.DoesntReceiveSSR | (int)HDRenderPipeline.StencilBitMask.DecalsForwardOutputNormalBuffer; stencilWriteMaskMV |= (int)HDRenderPipeline.StencilBitMask.DoesntReceiveSSR | (int)HDRenderPipeline.StencilBitMask.DecalsForwardOutputNormalBuffer; // As we tag both during motion vector pass and Gbuffer pass we need a separate state and we need to use the write mask material.SetInt(kStencilRef, stencilRef); material.SetInt(kStencilWriteMask, stencilWriteMask); material.SetInt(kStencilRefDepth, stencilRefDepth); material.SetInt(kStencilWriteMaskDepth, stencilWriteMaskDepth); material.SetInt(kStencilRefGBuffer, stencilRefGBuffer); material.SetInt(kStencilWriteMaskGBuffer, stencilWriteMaskGBuffer); material.SetInt(kStencilRefMV, stencilRefMV); material.SetInt(kStencilWriteMaskMV, stencilWriteMaskMV); material.SetInt(kStencilRefDistortionVec, (int)HDRenderPipeline.StencilBitMask.DistortionVectors); material.SetInt(kStencilWriteMaskDistortionVec, (int)HDRenderPipeline.StencilBitMask.DistortionVectors); if (material.HasProperty(kDisplacementMode)) { bool enableDisplacement = (DisplacementMode)material.GetFloat(kDisplacementMode) != DisplacementMode.None; bool enableVertexDisplacement = (DisplacementMode)material.GetFloat(kDisplacementMode) == DisplacementMode.Vertex; bool enablePixelDisplacement = (DisplacementMode)material.GetFloat(kDisplacementMode) == DisplacementMode.Pixel; bool enableTessellationDisplacement = ((DisplacementMode)material.GetFloat(kDisplacementMode) == DisplacementMode.Tessellation) && material.HasProperty(kTessellationMode); CoreUtils.SetKeyword(material, "_VERTEX_DISPLACEMENT", enableVertexDisplacement); CoreUtils.SetKeyword(material, "_PIXEL_DISPLACEMENT", enablePixelDisplacement); // Only set if tessellation exist CoreUtils.SetKeyword(material, "_TESSELLATION_DISPLACEMENT", enableTessellationDisplacement); bool displacementLockObjectScale = material.GetFloat(kDisplacementLockObjectScale) > 0.0; bool displacementLockTilingScale = material.GetFloat(kDisplacementLockTilingScale) > 0.0; // Tessellation reuse vertex flag. CoreUtils.SetKeyword(material, "_VERTEX_DISPLACEMENT_LOCK_OBJECT_SCALE", displacementLockObjectScale && (enableVertexDisplacement || enableTessellationDisplacement)); CoreUtils.SetKeyword(material, "_PIXEL_DISPLACEMENT_LOCK_OBJECT_SCALE", displacementLockObjectScale && enablePixelDisplacement); CoreUtils.SetKeyword(material, "_DISPLACEMENT_LOCK_TILING_SCALE", displacementLockTilingScale && enableDisplacement); // Depth offset is only enabled if per pixel displacement is bool depthOffsetEnable = (material.GetFloat(kDepthOffsetEnable) > 0.0f) && enablePixelDisplacement; CoreUtils.SetKeyword(material, "_DEPTHOFFSET_ON", depthOffsetEnable); } bool windEnabled = material.HasProperty(kWindEnabled) && material.GetFloat(kWindEnabled) > 0.0f; CoreUtils.SetKeyword(material, "_VERTEX_WIND", windEnabled); if (material.HasProperty(kTessellationMode)) { TessellationMode tessMode = (TessellationMode)material.GetFloat(kTessellationMode); CoreUtils.SetKeyword(material, "_TESSELLATION_PHONG", tessMode == TessellationMode.Phong); } SetupMainTexForAlphaTestGI("_BaseColorMap", "_BaseColor", material); // Use negation so we don't create keyword by default CoreUtils.SetKeyword(material, "_DISABLE_DECALS", material.HasProperty(kSupportDecals) && material.GetFloat(kSupportDecals) == 0.0); CoreUtils.SetKeyword(material, "_DISABLE_SSR", material.HasProperty(kReceivesSSR) && material.GetFloat(kReceivesSSR) == 0.0); CoreUtils.SetKeyword(material, "_ENABLE_GEOMETRIC_SPECULAR_AA", material.HasProperty(kEnableGeometricSpecularAA) && material.GetFloat(kEnableGeometricSpecularAA) == 1.0); }
// All Setup Keyword functions must be static. It allow to create script to automatically update the shaders with a script if code change static public void SetupBaseLitKeywords(Material material) { material.SetupBaseUnlitKeywords(); bool doubleSidedEnable = material.HasProperty(kDoubleSidedEnable) ? material.GetFloat(kDoubleSidedEnable) > 0.0f : false; if (doubleSidedEnable) { DoubleSidedNormalMode doubleSidedNormalMode = (DoubleSidedNormalMode)material.GetFloat(kDoubleSidedNormalMode); switch (doubleSidedNormalMode) { case DoubleSidedNormalMode.Mirror: // Mirror mode (in tangent space) material.SetVector("_DoubleSidedConstants", new Vector4(1.0f, 1.0f, -1.0f, 0.0f)); break; case DoubleSidedNormalMode.Flip: // Flip mode (in tangent space) material.SetVector("_DoubleSidedConstants", new Vector4(-1.0f, -1.0f, -1.0f, 0.0f)); break; case DoubleSidedNormalMode.None: // None mode (in tangent space) material.SetVector("_DoubleSidedConstants", new Vector4(1.0f, 1.0f, 1.0f, 0.0f)); break; } } if (material.HasProperty(kDisplacementMode)) { bool enableDisplacement = (DisplacementMode)material.GetFloat(kDisplacementMode) != DisplacementMode.None; bool enableVertexDisplacement = (DisplacementMode)material.GetFloat(kDisplacementMode) == DisplacementMode.Vertex; bool enablePixelDisplacement = (DisplacementMode)material.GetFloat(kDisplacementMode) == DisplacementMode.Pixel; bool enableTessellationDisplacement = ((DisplacementMode)material.GetFloat(kDisplacementMode) == DisplacementMode.Tessellation) && material.HasProperty(kTessellationMode); CoreUtils.SetKeyword(material, "_VERTEX_DISPLACEMENT", enableVertexDisplacement); CoreUtils.SetKeyword(material, "_PIXEL_DISPLACEMENT", enablePixelDisplacement); // Only set if tessellation exist CoreUtils.SetKeyword(material, "_TESSELLATION_DISPLACEMENT", enableTessellationDisplacement); bool displacementLockObjectScale = material.GetFloat(kDisplacementLockObjectScale) > 0.0; bool displacementLockTilingScale = material.GetFloat(kDisplacementLockTilingScale) > 0.0; // Tessellation reuse vertex flag. CoreUtils.SetKeyword(material, "_VERTEX_DISPLACEMENT_LOCK_OBJECT_SCALE", displacementLockObjectScale && (enableVertexDisplacement || enableTessellationDisplacement)); CoreUtils.SetKeyword(material, "_PIXEL_DISPLACEMENT_LOCK_OBJECT_SCALE", displacementLockObjectScale && enablePixelDisplacement); CoreUtils.SetKeyword(material, "_DISPLACEMENT_LOCK_TILING_SCALE", displacementLockTilingScale && enableDisplacement); // Depth offset is only enabled if per pixel displacement is bool depthOffsetEnable = (material.GetFloat(kDepthOffsetEnable) > 0.0f) && enablePixelDisplacement; CoreUtils.SetKeyword(material, "_DEPTHOFFSET_ON", depthOffsetEnable); } CoreUtils.SetKeyword(material, "_VERTEX_WIND", false); if (material.HasProperty(kTessellationMode)) { TessellationMode tessMode = (TessellationMode)material.GetFloat(kTessellationMode); CoreUtils.SetKeyword(material, "_TESSELLATION_PHONG", tessMode == TessellationMode.Phong); } material.SetupMainTexForAlphaTestGI("_BaseColorMap", "_BaseColor"); // Use negation so we don't create keyword by default CoreUtils.SetKeyword(material, "_DISABLE_DECALS", material.HasProperty(kSupportDecals) && material.GetFloat(kSupportDecals) == 0.0); CoreUtils.SetKeyword(material, "_DISABLE_SSR", material.HasProperty(kReceivesSSR) && material.GetFloat(kReceivesSSR) == 0.0); CoreUtils.SetKeyword(material, "_ENABLE_GEOMETRIC_SPECULAR_AA", material.HasProperty(kEnableGeometricSpecularAA) && material.GetFloat(kEnableGeometricSpecularAA) == 1.0); }
// All Setup Keyword functions must be static. It allow to create script to automatically update the shaders with a script if code change static public void SetupBaseLitKeywords(Material material) { SetupBaseUnlitKeywords(material); bool doubleSidedEnable = material.GetFloat(kDoubleSidedEnable) > 0.0f; if (doubleSidedEnable) { DoubleSidedNormalMode doubleSidedNormalMode = (DoubleSidedNormalMode)material.GetFloat(kDoubleSidedNormalMode); switch (doubleSidedNormalMode) { case DoubleSidedNormalMode.Mirror: // Mirror mode (in tangent space) material.SetVector("_DoubleSidedConstants", new Vector4(1.0f, 1.0f, -1.0f, 0.0f)); break; case DoubleSidedNormalMode.Flip: // Flip mode (in tangent space) material.SetVector("_DoubleSidedConstants", new Vector4(-1.0f, -1.0f, -1.0f, 0.0f)); break; case DoubleSidedNormalMode.None: // None mode (in tangent space) material.SetVector("_DoubleSidedConstants", new Vector4(1.0f, 1.0f, 1.0f, 0.0f)); break; } } // Set the reference value for the stencil test. int stencilRef = (int)StencilLightingUsage.RegularLighting; if ((int)material.GetFloat(kMaterialID) == (int)BaseLitGUI.MaterialId.LitSSS) { stencilRef = (int)StencilLightingUsage.SplitLighting; } // As we tag both during velocity pass and Gbuffer pass we need a separate state and we need to use the write mask material.SetInt(kStencilRef, stencilRef); material.SetInt(kStencilWriteMask, (int)HDRenderPipeline.StencilBitMask.LightingMask); material.SetInt(kStencilRefMV, (int)HDRenderPipeline.StencilBitMask.ObjectVelocity); material.SetInt(kStencilWriteMaskMV, (int)HDRenderPipeline.StencilBitMask.ObjectVelocity); bool enableDisplacement = (DisplacementMode)material.GetFloat(kDisplacementMode) != DisplacementMode.None; bool enableVertexDisplacement = (DisplacementMode)material.GetFloat(kDisplacementMode) == DisplacementMode.Vertex; bool enablePixelDisplacement = (DisplacementMode)material.GetFloat(kDisplacementMode) == DisplacementMode.Pixel; bool enableTessellationDisplacement = ((DisplacementMode)material.GetFloat(kDisplacementMode) == DisplacementMode.Tessellation) && material.HasProperty(kTessellationMode); CoreUtils.SetKeyword(material, "_VERTEX_DISPLACEMENT", enableVertexDisplacement); CoreUtils.SetKeyword(material, "_PIXEL_DISPLACEMENT", enablePixelDisplacement); // Only set if tessellation exist CoreUtils.SetKeyword(material, "_TESSELLATION_DISPLACEMENT", enableTessellationDisplacement); bool displacementLockObjectScale = material.GetFloat(kDisplacementLockObjectScale) > 0.0; bool displacementLockTilingScale = material.GetFloat(kDisplacementLockTilingScale) > 0.0; // Tessellation reuse vertex flag. CoreUtils.SetKeyword(material, "_VERTEX_DISPLACEMENT_LOCK_OBJECT_SCALE", displacementLockObjectScale && (enableVertexDisplacement || enableTessellationDisplacement)); CoreUtils.SetKeyword(material, "_PIXEL_DISPLACEMENT_LOCK_OBJECT_SCALE", displacementLockObjectScale && enablePixelDisplacement); CoreUtils.SetKeyword(material, "_DISPLACEMENT_LOCK_TILING_SCALE", displacementLockTilingScale && enableDisplacement); bool windEnabled = material.GetFloat(kWindEnabled) > 0.0f; CoreUtils.SetKeyword(material, "_VERTEX_WIND", windEnabled); // Depth offset is only enabled if per pixel displacement is bool depthOffsetEnable = (material.GetFloat(kDepthOffsetEnable) > 0.0f) && enablePixelDisplacement; CoreUtils.SetKeyword(material, "_DEPTHOFFSET_ON", depthOffsetEnable); if (material.HasProperty(kTessellationMode)) { TessellationMode tessMode = (TessellationMode)material.GetFloat(kTessellationMode); CoreUtils.SetKeyword(material, "_TESSELLATION_PHONG", tessMode == TessellationMode.Phong); } SetupMainTexForAlphaTestGI("_BaseColorMap", "_BaseColor", material); // Use negation so we don't create keyword by default CoreUtils.SetKeyword(material, "_DISABLE_DBUFFER", material.GetFloat(kSupportDBuffer) == 0.0); }
// All Setup Keyword functions must be static. It allow to create script to automatically update the shaders with a script if code change static public void SetupMaterialKeywordsAndPass(Material material) { //TODO see BaseLitUI.cs:SetupBaseLitKeywords (stencil etc) SetupBaseUnlitKeywords(material); SetupBaseUnlitMaterialPass(material); bool doubleSidedEnable = material.GetFloat(kDoubleSidedEnable) > 0.0f; if (doubleSidedEnable) { DoubleSidedNormalMode doubleSidedNormalMode = (DoubleSidedNormalMode)material.GetFloat(kDoubleSidedNormalMode); switch (doubleSidedNormalMode) { case DoubleSidedNormalMode.Mirror: // Mirror mode (in tangent space) material.SetVector("_DoubleSidedConstants", new Vector4(1.0f, 1.0f, -1.0f, 0.0f)); break; case DoubleSidedNormalMode.Flip: // Flip mode (in tangent space) material.SetVector("_DoubleSidedConstants", new Vector4(-1.0f, -1.0f, -1.0f, 0.0f)); break; case DoubleSidedNormalMode.None: // None mode (in tangent space) material.SetVector("_DoubleSidedConstants", new Vector4(1.0f, 1.0f, 1.0f, 0.0f)); break; } } //NOTE: For SSS in forward and split lighting, obviously we don't have a gbuffer pass, // so no stencil tagging there, but velocity? To check... //TODO: stencil state, displacement, wind, depthoffset, tesselation SetupMainTexForAlphaTestGI("_BaseColorMap", "_BaseColor", material); //TODO: disable DBUFFER CoreUtils.SetKeyword(material, "_NORMALMAP_TANGENT_SPACE", true); CoreUtils.SetKeyword(material, "_NORMALMAP", material.GetTexture(kNormalMap)); CoreUtils.SetKeyword(material, "_MASKMAPA", material.GetTexture(kMaskMapA)); CoreUtils.SetKeyword(material, "_MASKMAPB", material.GetTexture(kMaskMapB)); bool needUV2 = (UVBaseMapping)material.GetFloat(kUVBase) == UVBaseMapping.UV2; bool needUV3 = (UVBaseMapping)material.GetFloat(kUVBase) == UVBaseMapping.UV3; if (needUV3) { material.DisableKeyword("_REQUIRE_UV2"); material.EnableKeyword("_REQUIRE_UV3"); } else if (needUV2) { material.EnableKeyword("_REQUIRE_UV2"); material.DisableKeyword("_REQUIRE_UV3"); } else { material.DisableKeyword("_REQUIRE_UV2"); material.DisableKeyword("_REQUIRE_UV3"); } CoreUtils.SetKeyword(material, "_EMISSIVE_COLOR_MAP", material.GetTexture(kEmissiveColorMap)); }
// All Setup Keyword functions must be static. It allow to create script to automatically update the shaders with a script if code change static public void SetupBaseLitKeywords(Material material) { SetupBaseUnlitKeywords(material); bool doubleSidedEnable = material.GetFloat(kDoubleSidedEnable) > 0.0f; if (doubleSidedEnable) { DoubleSidedNormalMode doubleSidedNormalMode = (DoubleSidedNormalMode)material.GetFloat(kDoubleSidedNormalMode); switch (doubleSidedNormalMode) { case DoubleSidedNormalMode.None: material.SetVector("_DoubleSidedConstants", new Vector4(1.0f, 1.0f, 1.0f, 0.0f)); break; case DoubleSidedNormalMode.Mirror: // Mirror mode (in tangent space) material.SetVector("_DoubleSidedConstants", new Vector4(1.0f, 1.0f, -1.0f, 0.0f)); break; case DoubleSidedNormalMode.Flip: // Flip mode (in tangent space) material.SetVector("_DoubleSidedConstants", new Vector4(-1.0f, -1.0f, -1.0f, 0.0f)); break; } } // Set the reference value for the stencil test. int stencilRef = (int)StencilLightingUsage.RegularLighting; if ((int)material.GetFloat(kMaterialID) == (int)Lit.MaterialId.LitSSS) { stencilRef = (int)StencilLightingUsage.SplitLighting; } material.SetInt(kStencilRef, stencilRef); bool enableDisplacement = (DisplacementMode)material.GetFloat(kDisplacementMode) != DisplacementMode.None; bool enableVertexDisplacement = (DisplacementMode)material.GetFloat(kDisplacementMode) == DisplacementMode.Vertex; bool enablePixelDisplacement = (DisplacementMode)material.GetFloat(kDisplacementMode) == DisplacementMode.Pixel; bool enableTessellationDisplacement = ((DisplacementMode)material.GetFloat(kDisplacementMode) == DisplacementMode.Tessellation) && material.HasProperty(kTessellationMode); CoreUtils.SetKeyword(material, "_VERTEX_DISPLACEMENT", enableVertexDisplacement); CoreUtils.SetKeyword(material, "_PIXEL_DISPLACEMENT", enablePixelDisplacement); // Only set if tessellation exist CoreUtils.SetKeyword(material, "_TESSELLATION_DISPLACEMENT", enableTessellationDisplacement); bool displacementLockObjectScale = material.GetFloat(kDisplacementLockObjectScale) > 0.0; bool displacementLockTilingScale = material.GetFloat(kDisplacementLockTilingScale) > 0.0; // Tessellation reuse vertex flag. CoreUtils.SetKeyword(material, "_VERTEX_DISPLACEMENT_LOCK_OBJECT_SCALE", displacementLockObjectScale && (enableVertexDisplacement || enableTessellationDisplacement)); CoreUtils.SetKeyword(material, "_PIXEL_DISPLACEMENT_LOCK_OBJECT_SCALE", displacementLockObjectScale && enablePixelDisplacement); CoreUtils.SetKeyword(material, "_DISPLACEMENT_LOCK_TILING_SCALE", displacementLockTilingScale && enableDisplacement); bool windEnabled = material.GetFloat(kWindEnabled) > 0.0f; CoreUtils.SetKeyword(material, "_VERTEX_WIND", windEnabled); // Depth offset is only enabled if per pixel displacement is bool depthOffsetEnable = (material.GetFloat(kDepthOffsetEnable) > 0.0f) && enablePixelDisplacement; CoreUtils.SetKeyword(material, "_DEPTHOFFSET_ON", depthOffsetEnable); if (material.HasProperty(kTessellationMode)) { TessellationMode tessMode = (TessellationMode)material.GetFloat(kTessellationMode); CoreUtils.SetKeyword(material, "_TESSELLATION_PHONG", tessMode == TessellationMode.Phong); } SetupMainTexForAlphaTestGI("_BaseColorMap", "_BaseColor", material); }
static void SetMaterialKeywords(Material material) { // Note: keywords must be based on Material value not on MaterialProperty due to multi-edit & material animation // (MaterialProperty value might come from renderer material property block) bool isSpecularWorkFlow = (WorkflowMode)material.GetFloat("_WorkflowMode") == WorkflowMode.Specular; bool hasGlossMap = false; if (isSpecularWorkFlow) { hasGlossMap = material.GetTexture("_SpecGlossMap"); } else { hasGlossMap = material.GetTexture("_MetallicGlossMap"); } bool doubleSidedEnable = material.GetFloat(kDoubleSidedEnable) == 1.0f; if (doubleSidedEnable) { DoubleSidedNormalMode doubleSidedNormalMode = (DoubleSidedNormalMode)material.GetFloat(kDoubleSidedNormalMode); switch (doubleSidedNormalMode) { case DoubleSidedNormalMode.Mirror: // Mirror mode (in tangent space) material.SetVector("_DoubleSidedConstants", new Vector4(1.0f, 1.0f, -1.0f, 0.0f)); break; case DoubleSidedNormalMode.Flip: // Flip mode (in tangent space) material.SetVector("_DoubleSidedConstants", new Vector4(-1.0f, -1.0f, -1.0f, 0.0f)); break; case DoubleSidedNormalMode.None: // None mode (in tangent space) material.SetVector("_DoubleSidedConstants", new Vector4(1.0f, 1.0f, 1.0f, 0.0f)); break; } } //#if defined(_ENABLE_WIND_SINGLE) || defined(_ENABLE_WIND_HIERARCHY) || defined(_ENABLE_WIND_PROCEDURAL) VertexAnimationMode vertAnimMode = (VertexAnimationMode)material.GetFloat("_VertexAnimation"); switch (vertAnimMode) { case VertexAnimationMode.None: CoreUtils.SetKeyword(material, "_ENABLE_WIND_SINGLE", false); CoreUtils.SetKeyword(material, "_ENABLE_WIND_HIERARCHY", false); CoreUtils.SetKeyword(material, "_ENABLE_WIND_PROCEDURAL", false); break; case VertexAnimationMode.Hierarchy: CoreUtils.SetKeyword(material, "_ENABLE_WIND_SINGLE", false); CoreUtils.SetKeyword(material, "_ENABLE_WIND_HIERARCHY", true); CoreUtils.SetKeyword(material, "_ENABLE_WIND_PROCEDURAL", false); break; case VertexAnimationMode.Single: CoreUtils.SetKeyword(material, "_ENABLE_WIND_SINGLE", true); CoreUtils.SetKeyword(material, "_ENABLE_WIND_HIERARCHY", false); CoreUtils.SetKeyword(material, "_ENABLE_WIND_PROCEDURAL", false); break; case VertexAnimationMode.Procedural: CoreUtils.SetKeyword(material, "_ENABLE_WIND_SINGLE", false); CoreUtils.SetKeyword(material, "_ENABLE_WIND_HIERARCHY", false); CoreUtils.SetKeyword(material, "_ENABLE_WIND_PROCEDURAL", true); break; } CoreUtils.SetKeyword(material, "_DOUBLESIDED_ON", doubleSidedEnable); bool isAnisotropic = (BRDFMode)material.GetFloat("_BRDFMode") == BRDFMode.Anisotropic && material.GetTexture("_TangentMap"); CoreUtils.SetKeyword(material, "_BRDF_ANISO", isAnisotropic); CoreUtils.SetKeyword(material, "_BRDF_STANDARD", !isAnisotropic); CoreUtils.SetKeyword(material, "_SPECULAR_SETUP", isSpecularWorkFlow); CoreUtils.SetKeyword(material, "_METALLICSPECGLOSSMAP", hasGlossMap); CoreUtils.SetKeyword(material, "_SPECGLOSSMAP", hasGlossMap && isSpecularWorkFlow); CoreUtils.SetKeyword(material, "_METALLICGLOSSMAP", hasGlossMap && !isSpecularWorkFlow); CoreUtils.SetKeyword(material, "_NORMALMAP", material.GetTexture("_BumpMap") || material.GetTexture("_DetailNormalMap")); CoreUtils.SetKeyword(material, "_SPECULARHIGHLIGHTS_OFF", material.GetFloat("_SpecularHighlights") == 0.0f); CoreUtils.SetKeyword(material, "_GLOSSYREFLECTIONS_OFF", material.GetFloat("_GlossyReflections") == 0.0f); CoreUtils.SetKeyword(material, "_OCCLUSIONMAP", material.GetTexture("_OcclusionMap")); CoreUtils.SetKeyword(material, "_PARALLAXMAP", material.GetTexture("_ParallaxMap")); CoreUtils.SetKeyword(material, "_DETAIL_MASK", material.GetTexture("_DetailMask")); CoreUtils.SetKeyword(material, "_DETAIL", material.GetTexture("_DetailAlbedoMap") || material.GetTexture("_DetailNormalMap")); CoreUtils.SetKeyword(material, "_DETAIL_MULX2", material.GetTexture("_DetailAlbedoMap") || material.GetTexture("_DetailNormalMap")); // A material's GI flag internally keeps track of whether emission is enabled at all, it's enabled but has no effect // or is enabled and may be modified at runtime. This state depends on the values of the current flag and emissive color. // The fixup routine makes sure that the material is in the correct state if/when changes are made to the mode or color. MaterialEditor.FixupEmissiveFlag(material); bool shouldEmissionBeEnabled = (material.globalIlluminationFlags & MaterialGlobalIlluminationFlags.EmissiveIsBlack) == 0; CoreUtils.SetKeyword(material, "_EMISSION", shouldEmissionBeEnabled); if (material.HasProperty("_SmoothnessTextureChannel")) { CoreUtils.SetKeyword(material, "_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A", GetSmoothnessMapChannel(material) == SmoothnessMapChannel.AlbedoAlpha); } }
// All Setup Keyword functions must be static. It allow to create script to automatically update the shaders with a script if code change static public void SetupBaseLitKeywords(Material material) { SetupBaseUnlitKeywords(material); bool doubleSidedEnable = material.GetFloat(kDoubleSidedEnable) > 0.0f; if (doubleSidedEnable) { DoubleSidedNormalMode doubleSidedNormalMode = (DoubleSidedNormalMode)material.GetFloat(kDoubleSidedNormalMode); switch (doubleSidedNormalMode) { case DoubleSidedNormalMode.None: material.SetVector("_DoubleSidedConstants", new Vector4(1.0f, 1.0f, 1.0f, 0.0f)); break; case DoubleSidedNormalMode.Mirror: // Mirror mode (in tangent space) material.SetVector("_DoubleSidedConstants", new Vector4(1.0f, 1.0f, -1.0f, 0.0f)); break; case DoubleSidedNormalMode.Flip: // Flip mode (in tangent space) material.SetVector("_DoubleSidedConstants", new Vector4(-1.0f, -1.0f, -1.0f, 0.0f)); break; } } // Depth offset is only enabled if per pixel displacement is bool depthOffsetEnable = (material.GetFloat(kDepthOffsetEnable) > 0.0f) && (material.GetFloat(kEnablePerPixelDisplacement) > 0.0f); SetKeyword(material, "_DEPTHOFFSET_ON", depthOffsetEnable); // Set the reference value for the stencil test. int stencilRef = (int)StencilLightingUsage.RegularLighting; if (material.HasProperty(kMaterialID)) { if ((int)material.GetFloat(kMaterialID) == (int)UnityEngine.Experimental.Rendering.HDPipeline.Lit.MaterialId.LitSSS) { stencilRef = (int)StencilLightingUsage.SplitLighting; } } material.SetInt(kStencilRef, stencilRef); bool enablePerPixelDisplacement = material.GetFloat(kEnablePerPixelDisplacement) > 0.0f; SetKeyword(material, "_PER_PIXEL_DISPLACEMENT", enablePerPixelDisplacement); if (material.HasProperty(kTessellationMode)) { TessellationMode tessMode = (TessellationMode)material.GetFloat(kTessellationMode); if (tessMode == TessellationMode.Phong) { material.DisableKeyword("_TESSELLATION_DISPLACEMENT"); material.DisableKeyword("_TESSELLATION_DISPLACEMENT_PHONG"); } else if (tessMode == TessellationMode.Displacement) { material.EnableKeyword("_TESSELLATION_DISPLACEMENT"); material.DisableKeyword("_TESSELLATION_DISPLACEMENT_PHONG"); } else { material.DisableKeyword("_TESSELLATION_DISPLACEMENT"); material.EnableKeyword("_TESSELLATION_DISPLACEMENT_PHONG"); } bool tessellationObjectScaleEnable = material.GetFloat(kTessellationObjectScale) > 0.0; SetKeyword(material, "_TESSELLATION_OBJECT_SCALE", tessellationObjectScaleEnable); bool tessellationTilingScaleEnable = material.GetFloat(kTessellationTilingScale) > 0.0; SetKeyword(material, "_TESSELLATION_TILING_SCALE", tessellationTilingScaleEnable); } bool windEnabled = material.GetFloat(kWindEnabled) > 0.0f; SetKeyword(material, "_VERTEX_WIND", windEnabled); }
// All Setup Keyword functions must be static. It allow to create script to automatically update the shaders with a script if code change static public void SetupBaseLitKeywords(Material material) { SetupBaseUnlitKeywords(material); bool doubleSidedEnable = material.GetFloat(kDoubleSidedEnable) > 0.0f; if (doubleSidedEnable) { DoubleSidedNormalMode doubleSidedNormalMode = (DoubleSidedNormalMode)material.GetFloat(kDoubleSidedNormalMode); switch (doubleSidedNormalMode) { case DoubleSidedNormalMode.Mirror: // Mirror mode (in tangent space) material.SetVector("_DoubleSidedConstants", new Vector4(1.0f, 1.0f, -1.0f, 0.0f)); break; case DoubleSidedNormalMode.Flip: // Flip mode (in tangent space) material.SetVector("_DoubleSidedConstants", new Vector4(-1.0f, -1.0f, -1.0f, 0.0f)); break; case DoubleSidedNormalMode.None: // None mode (in tangent space) material.SetVector("_DoubleSidedConstants", new Vector4(1.0f, 1.0f, 1.0f, 0.0f)); break; } } // Set the reference value for the stencil test. int stencilRef = (int)StencilLightingUsage.RegularLighting; if ((int)material.GetFloat(kMaterialID) == (int)BaseLitGUI.MaterialId.LitSSS) { stencilRef = (int)StencilLightingUsage.SplitLighting; } // As we tag both during velocity pass and Gbuffer pass we need a separate state and we need to use the write mask material.SetInt(kStencilRef, stencilRef); material.SetInt(kStencilWriteMask, (int)HDRenderPipeline.StencilBitMask.LightingMask); material.SetInt(kStencilRefMV, (int)HDRenderPipeline.StencilBitMask.ObjectVelocity); material.SetInt(kStencilWriteMaskMV, (int)HDRenderPipeline.StencilBitMask.ObjectVelocity); bool enableDisplacement = (DisplacementMode)material.GetFloat(kDisplacementMode) != DisplacementMode.None; bool enableVertexDisplacement = (DisplacementMode)material.GetFloat(kDisplacementMode) == DisplacementMode.Vertex; bool enablePixelDisplacement = (DisplacementMode)material.GetFloat(kDisplacementMode) == DisplacementMode.Pixel; bool enableTessellationDisplacement = ((DisplacementMode)material.GetFloat(kDisplacementMode) == DisplacementMode.Tessellation) && material.HasProperty(kTessellationMode); CoreUtils.SetKeyword(material, "_VERTEX_DISPLACEMENT", enableVertexDisplacement); CoreUtils.SetKeyword(material, "_PIXEL_DISPLACEMENT", enablePixelDisplacement); // Only set if tessellation exist CoreUtils.SetKeyword(material, "_TESSELLATION_DISPLACEMENT", enableTessellationDisplacement); bool displacementLockObjectScale = material.GetFloat(kDisplacementLockObjectScale) > 0.0; bool displacementLockTilingScale = material.GetFloat(kDisplacementLockTilingScale) > 0.0; // Tessellation reuse vertex flag. CoreUtils.SetKeyword(material, "_VERTEX_DISPLACEMENT_LOCK_OBJECT_SCALE", displacementLockObjectScale && (enableVertexDisplacement || enableTessellationDisplacement)); CoreUtils.SetKeyword(material, "_PIXEL_DISPLACEMENT_LOCK_OBJECT_SCALE", displacementLockObjectScale && enablePixelDisplacement); CoreUtils.SetKeyword(material, "_DISPLACEMENT_LOCK_TILING_SCALE", displacementLockTilingScale && enableDisplacement); //forest-begin: Added vertex animation if (material.HasProperty(kWindEnabled)) { var windMode = material.GetFloat(kWindEnabled); CoreUtils.SetKeyword(material, "_ANIM_SINGLE_PIVOT_COLOR", windMode > 2.5f && windMode < 3.5f); CoreUtils.SetKeyword(material, "_ANIM_HIERARCHY_PIVOT", windMode > 3.5f && windMode < 4.5f); CoreUtils.SetKeyword(material, "_ANIM_PROCEDURAL_BRANCH", windMode > 5.5f && windMode < 6.5f); //forest-begin: G-Buffer motion vectors if (windMode > 2.5f) { var hdrpa = UnityEngine.Rendering.GraphicsSettings.renderPipelineAsset as HDRenderPipelineAsset; if (hdrpa && hdrpa.GetFrameSettings().enableGBufferMotionVectors) { material.SetInt(kStencilRef, stencilRef | (int)HDRenderPipeline.StencilBitMask.ObjectVelocity); material.SetInt(kStencilWriteMask, (int)HDRenderPipeline.StencilBitMask.LightingMask | (int)HDRenderPipeline.StencilBitMask.ObjectVelocity); } } //forest-end: } //forest-end: // Depth offset is only enabled if per pixel displacement is bool depthOffsetEnable = (material.GetFloat(kDepthOffsetEnable) > 0.0f) && enablePixelDisplacement; CoreUtils.SetKeyword(material, "_DEPTHOFFSET_ON", depthOffsetEnable); if (material.HasProperty(kTessellationMode)) { TessellationMode tessMode = (TessellationMode)material.GetFloat(kTessellationMode); CoreUtils.SetKeyword(material, "_TESSELLATION_PHONG", tessMode == TessellationMode.Phong); } SetupMainTexForAlphaTestGI("_BaseColorMap", "_BaseColor", material); // Use negation so we don't create keyword by default CoreUtils.SetKeyword(material, "_DISABLE_DBUFFER", material.GetFloat(kSupportDBuffer) == 0.0); CoreUtils.SetKeyword(material, "_ENABLE_GEOMETRIC_SPECULAR_AA", material.GetFloat(kEnableGeometricSpecularAA) == 1.0); }