private static bool GenerateShaderPassHair(HairMasterNode masterNode, Pass pass, GenerationMode mode, ShaderGenerator result, List <string> sourceAssetDependencyPaths) { if (mode == GenerationMode.ForReals || pass.UseInPreview) { pass.OnGeneratePass(masterNode); // apply master node options to active fields var activeFields = GetActiveFieldsFromMasterNode(masterNode, pass); // use standard shader pass generation bool vertexActive = false; if (masterNode.IsSlotConnected(HairMasterNode.PositionSlotId) || masterNode.IsSlotConnected(HairMasterNode.VertexNormalSlotId) || masterNode.IsSlotConnected(HairMasterNode.VertexNormalSlotId)) { vertexActive = true; } return(HDSubShaderUtilities.GenerateShaderPass(masterNode, pass, mode, activeFields, result, sourceAssetDependencyPaths, vertexActive)); } else { return(false); } }
private static ActiveFields GetActiveFieldsFromMasterNode(AbstractMaterialNode iMasterNode, Pass pass) { var activeFields = new ActiveFields(); var baseActiveFields = activeFields.baseInstance; HairMasterNode masterNode = iMasterNode as HairMasterNode; if (masterNode == null) { return(activeFields); } if (masterNode.doubleSidedMode != DoubleSidedMode.Disabled) { if (pass.ShaderPassName != "SHADERPASS_MOTION_VECTORS") // HACK to get around lack of a good interpolator dependency system { // we need to be able to build interpolators using multiple input structs // also: should only require isFrontFace if Normals are required... // Important: the following is used in SharedCode.template.hlsl for determining the normal flip mode baseActiveFields.Add("FragInputs.isFrontFace"); } } switch (masterNode.materialType) { case HairMasterNode.MaterialType.KajiyaKay: baseActiveFields.Add("Material.KajiyaKay"); break; default: UnityEngine.Debug.LogError("Unknown material type: " + masterNode.materialType); break; } if (masterNode.alphaTest.isOn) { int count = 0; // If alpha test shadow is enable, we use it, otherwise we use the regular test if (pass.PixelShaderUsesSlot(HairMasterNode.AlphaClipThresholdShadowSlotId) && masterNode.alphaTestShadow.isOn) { baseActiveFields.Add("AlphaTestShadow"); ++count; } else if (pass.PixelShaderUsesSlot(HairMasterNode.AlphaClipThresholdSlotId)) { baseActiveFields.Add("AlphaTest"); ++count; } // Other alpha test are suppose to be alone else if (pass.PixelShaderUsesSlot(HairMasterNode.AlphaClipThresholdDepthPrepassSlotId)) { baseActiveFields.Add("AlphaTestPrepass"); ++count; } else if (pass.PixelShaderUsesSlot(HairMasterNode.AlphaClipThresholdDepthPostpassSlotId)) { baseActiveFields.Add("AlphaTestPostpass"); ++count; } UnityEngine.Debug.Assert(count == 1, "Alpha test value not set correctly"); } if (masterNode.surfaceType != SurfaceType.Opaque) { if (masterNode.transparencyFog.isOn) { baseActiveFields.Add("AlphaFog"); } if (masterNode.transparentWritesMotionVec.isOn) { baseActiveFields.Add("TransparentWritesMotionVec"); } if (masterNode.blendPreserveSpecular.isOn) { baseActiveFields.Add("BlendMode.PreserveSpecular"); } } if (!masterNode.receiveDecals.isOn) { baseActiveFields.Add("DisableDecals"); } if (!masterNode.receiveSSR.isOn) { baseActiveFields.Add("DisableSSR"); } if (masterNode.addPrecomputedVelocity.isOn) { baseActiveFields.Add("AddPrecomputedVelocity"); } if (masterNode.specularAA.isOn && pass.PixelShaderUsesSlot(HairMasterNode.SpecularAAThresholdSlotId) && pass.PixelShaderUsesSlot(HairMasterNode.SpecularAAScreenSpaceVarianceSlotId)) { baseActiveFields.Add("Specular.AA"); } if (masterNode.IsSlotConnected(HairMasterNode.BentNormalSlotId) && pass.PixelShaderUsesSlot(HairMasterNode.BentNormalSlotId)) { baseActiveFields.Add("BentNormal"); } if (masterNode.IsSlotConnected(HairMasterNode.HairStrandDirectionSlotId) && pass.PixelShaderUsesSlot(HairMasterNode.HairStrandDirectionSlotId)) { baseActiveFields.Add("HairStrandDirection"); } if (masterNode.IsSlotConnected(HairMasterNode.TransmittanceSlotId) && pass.PixelShaderUsesSlot(HairMasterNode.TransmittanceSlotId)) { baseActiveFields.Add(HairMasterNode.TransmittanceSlotName); } if (masterNode.IsSlotConnected(HairMasterNode.RimTransmissionIntensitySlotId) && pass.PixelShaderUsesSlot(HairMasterNode.RimTransmissionIntensitySlotId)) { baseActiveFields.Add(HairMasterNode.RimTransmissionIntensitySlotName); } if (masterNode.useLightFacingNormal.isOn) { baseActiveFields.Add("UseLightFacingNormal"); } switch (masterNode.specularOcclusionMode) { case SpecularOcclusionMode.Off: break; case SpecularOcclusionMode.FromAO: baseActiveFields.Add("SpecularOcclusionFromAO"); break; case SpecularOcclusionMode.FromAOAndBentNormal: baseActiveFields.Add("SpecularOcclusionFromAOBentNormal"); break; case SpecularOcclusionMode.Custom: baseActiveFields.Add("SpecularOcclusionCustom"); break; default: break; } if (pass.PixelShaderUsesSlot(HairMasterNode.AmbientOcclusionSlotId)) { var occlusionSlot = masterNode.FindSlot <Vector1MaterialSlot>(HairMasterNode.AmbientOcclusionSlotId); bool connected = masterNode.IsSlotConnected(HairMasterNode.AmbientOcclusionSlotId); if (connected || occlusionSlot.value != occlusionSlot.defaultValue) { baseActiveFields.Add("AmbientOcclusion"); } } if (masterNode.IsSlotConnected(HairMasterNode.LightingSlotId) && pass.PixelShaderUsesSlot(HairMasterNode.LightingSlotId)) { baseActiveFields.Add("LightingGI"); } if (masterNode.IsSlotConnected(HairMasterNode.BackLightingSlotId) && pass.PixelShaderUsesSlot(HairMasterNode.LightingSlotId)) { baseActiveFields.Add("BackLightingGI"); } if (masterNode.depthOffset.isOn && pass.PixelShaderUsesSlot(HairMasterNode.DepthOffsetSlotId)) { baseActiveFields.Add("DepthOffset"); } if (masterNode.supportLodCrossFade.isOn) { baseActiveFields.AddAll("LodCrossFade"); } return(activeFields); }