浏览代码

Merge pull request #1430 from Unity-Technologies/sg/facesign

Add Face Sign functionality
/main
GitHub 7 年前
当前提交
900da40e
共有 17 个文件被更改,包括 148 次插入11 次删除
  1. 2
      com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/HDPBRPass.template
  2. 21
      com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/HDSubShaderUtilities.cs
  3. 2
      com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/HDUnlitPassForward.template
  4. 12
      com.unity.render-pipelines.lightweight/LWRP/Editor/ShaderGraph/LightWeightPBRSubShader.cs
  5. 12
      com.unity.render-pipelines.lightweight/LWRP/Editor/ShaderGraph/LightWeightUnlitSubShader.cs
  6. 2
      com.unity.render-pipelines.lightweight/LWRP/Editor/ShaderGraph/lightweightPBRForwardPass.template
  7. 2
      com.unity.render-pipelines.lightweight/LWRP/Editor/ShaderGraph/lightweightUnlitPass.template
  8. 6
      com.unity.shadergraph/CHANGELOG.md
  9. 4
      com.unity.shadergraph/Editor/Data/Graphs/ShaderGraphRequirements.cs
  10. 5
      com.unity.shadergraph/Editor/Data/Util/GraphUtil.cs
  11. 14
      com.unity.shadergraph/Editor/Data/Util/ShaderGenerator.cs
  12. 1
      com.unity.shadergraph/Editor/Data/Util/ShaderGeneratorNames.cs
  13. 3
      com.unity.shadergraph/.data/face_sign.png
  14. 18
      com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireFaceSign.cs
  15. 3
      com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireFaceSign.cs.meta
  16. 41
      com.unity.shadergraph/Editor/Data/Nodes/Utility/Logic/IsFrontFaceNode.cs
  17. 11
      com.unity.shadergraph/Editor/Data/Nodes/Utility/Logic/IsFrontFaceNode.cs.meta

2
com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/HDPBRPass.template


$SurfaceDescriptionInputs.VertexColor: output.VertexColor = input.color;
$SurfaceDescriptionInputs.FaceSign: output.FaceSign = input.isFrontFace;
return output;
}

21
com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/HDSubShaderUtilities.cs


struct AttributesMesh
{
[Semantic("POSITION")] Vector3 positionOS;
[Semantic("NORMAL")][Optional] Vector3 normalOS;
[Semantic("TANGENT")][Optional] Vector4 tangentOS; // Stores bi-tangent sign in w
[Semantic("TEXCOORD0")][Optional] Vector2 uv0;
[Semantic("TEXCOORD1")][Optional] Vector2 uv1;
[Semantic("TEXCOORD2")][Optional] Vector2 uv2;
[Semantic("TEXCOORD3")][Optional] Vector2 uv3;
[Semantic("COLOR")][Optional] Vector4 color;
[Semantic("NORMAL")][Optional] Vector3 normalOS;
[Semantic("TANGENT")][Optional] Vector4 tangentOS; // Stores bi-tangent sign in w
[Semantic("TEXCOORD0")][Optional] Vector2 uv0;
[Semantic("TEXCOORD1")][Optional] Vector2 uv1;
[Semantic("TEXCOORD2")][Optional] Vector2 uv2;
[Semantic("TEXCOORD3")][Optional] Vector2 uv3;
[Semantic("COLOR")][Optional] Vector4 color;
};
struct VaryingsMeshToPS

[Optional] Vector4 uv2;
[Optional] Vector4 uv3;
[Optional] Vector4 VertexColor;
[Optional] float FaceSign;
public static Dependency[] dependencies = new Dependency[]
{

new Dependency("SurfaceDescriptionInputs.uv2", "FragInputs.texCoord2"),
new Dependency("SurfaceDescriptionInputs.uv3", "FragInputs.texCoord3"),
new Dependency("SurfaceDescriptionInputs.VertexColor", "FragInputs.color"),
new Dependency("SurfaceDescriptionInputs.FaceSign", "FragInputs.isFrontFace"),
};
};

if (requirements.requiresVertexColor)
{
activeFields.Add("SurfaceDescriptionInputs.VertexColor");
}
if (requirements.requiresFaceSign)
{
activeFields.Add("SurfaceDescriptionInputs.FaceSign");
}
if (requirements.requiresNormal != 0)

2
com.unity.render-pipelines.high-definition/HDRP/Editor/ShaderGraph/HDUnlitPassForward.template


$SurfaceDescriptionInputs.VertexColor: output.VertexColor = input.color;
$SurfaceDescriptionInputs.FaceSign: output.FaceSign = input.isFrontFace;
return output;
}

12
com.unity.render-pipelines.lightweight/LWRP/Editor/ShaderGraph/LightWeightPBRSubShader.cs


if (surfaceRequirements.requiresScreenPosition)
surfaceDescriptionInputStruct.AppendLine("float4 {0};", ShaderGeneratorNames.ScreenPosition);
if (surfaceRequirements.requiresFaceSign)
surfaceDescriptionInputStruct.AppendLine("float {0};", ShaderGeneratorNames.FaceSign);
foreach (var channel in surfaceRequirements.requiresMeshUVs.Distinct())
surfaceDescriptionInputStruct.AppendLine("half4 {0};", channel.GetUVName());
}

pixelShaderSurfaceRemap.AppendLine("{0} = surf.{0};", slot.shaderOutputName);
}
// -------------------------------------
// Extra pixel shader work
var faceSign = new ShaderStringBuilder();
if (pixelRequirements.requiresFaceSign)
faceSign.AppendLine(", half FaceSign : VFACE");
// ----------------------------------------------------- //
// FINALIZE //
// ----------------------------------------------------- //

resultPass = resultPass.Replace("${VertexShaderDescriptionInputs}", vertexShaderDescriptionInputs.ToString());
resultPass = resultPass.Replace("${VertexShaderOutputs}", vertexShaderOutputs.ToString());
resultPass = resultPass.Replace("${FaceSign}", faceSign.ToString());
resultPass = resultPass.Replace("${PixelShader}", pixelShader.ToString());
resultPass = resultPass.Replace("${PixelShaderSurfaceInputs}", pixelShaderSurfaceInputs.ToString());
resultPass = resultPass.Replace("${PixelShaderSurfaceRemap}", pixelShaderSurfaceRemap.ToString());

12
com.unity.render-pipelines.lightweight/LWRP/Editor/ShaderGraph/LightWeightUnlitSubShader.cs


if (surfaceRequirements.requiresScreenPosition)
surfaceDescriptionInputStruct.AppendLine("float4 {0};", ShaderGeneratorNames.ScreenPosition);
if (surfaceRequirements.requiresFaceSign)
surfaceDescriptionInputStruct.AppendLine("float {0};", ShaderGeneratorNames.FaceSign);
foreach (var channel in surfaceRequirements.requiresMeshUVs.Distinct())
surfaceDescriptionInputStruct.AppendLine("half4 {0};", channel.GetUVName());
}

pixelShaderSurfaceRemap.AppendLine("{0} = surf.{0};", slot.shaderOutputName);
}
// -------------------------------------
// Extra pixel shader work
var faceSign = new ShaderStringBuilder();
if (pixelRequirements.requiresFaceSign)
faceSign.AppendLine(", half FaceSign : VFACE");
// ----------------------------------------------------- //
// FINALIZE //
// ----------------------------------------------------- //

resultPass = resultPass.Replace("${VertexShaderDescriptionInputs}", vertexShaderDescriptionInputs.ToString());
resultPass = resultPass.Replace("${VertexShaderOutputs}", vertexShaderOutputs.ToString());
resultPass = resultPass.Replace("${FaceSign}", faceSign.ToString());
resultPass = resultPass.Replace("${PixelShader}", pixelShader.ToString());
resultPass = resultPass.Replace("${PixelShaderSurfaceInputs}", pixelShaderSurfaceInputs.ToString());
resultPass = resultPass.Replace("${PixelShaderSurfaceRemap}", pixelShaderSurfaceRemap.ToString());

2
com.unity.render-pipelines.lightweight/LWRP/Editor/ShaderGraph/lightweightPBRForwardPass.template


return o;
}
half4 frag (GraphVertexOutput IN) : SV_Target
half4 frag (GraphVertexOutput IN ${FaceSign}) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(IN);

2
com.unity.render-pipelines.lightweight/LWRP/Editor/ShaderGraph/lightweightUnlitPass.template


return o;
}
half4 frag (GraphVertexOutput IN) : SV_Target
half4 frag (GraphVertexOutput IN ${FaceSign}) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(IN);

6
com.unity.shadergraph/CHANGELOG.md


You can now change the path of Shader Graphs and Sub Graphs. When you change the path of a Shader Graph, this modifies the location it has in the shader selection list. When you change the path of Sub Graph, it will have a different location in the node creation menu.
### Is Front Face node
![](.data/face_sign.png)
With this node, you can change graph output depending on the face sign of a given fragment. If the current fragment is part of a front face, the node returns True. For a back face, the node returns False.
Note: This functionality requires that you have enabled **two sided** on the Master node.
### Gradient nodes

4
com.unity.shadergraph/Editor/Data/Graphs/ShaderGraphRequirements.cs


public NeededCoordinateSpace requiresPosition;
public bool requiresScreenPosition;
public bool requiresVertexColor;
public bool requiresFaceSign;
public List<UVChannel> requiresMeshUVs;
public static ShaderGraphRequirements none

newReqs.requiresPosition = other.requiresPosition | requiresPosition;
newReqs.requiresScreenPosition = other.requiresScreenPosition | requiresScreenPosition;
newReqs.requiresVertexColor = other.requiresVertexColor | requiresVertexColor;
newReqs.requiresFaceSign = other.requiresFaceSign | requiresFaceSign;
newReqs.requiresMeshUVs = new List<UVChannel>();
if (requiresMeshUVs != null)

NeededCoordinateSpace requiresPosition = nodes.OfType<IMayRequirePosition>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresPosition(stageCapability));
bool requiresScreenPosition = nodes.OfType<IMayRequireScreenPosition>().Any(x => x.RequiresScreenPosition());
bool requiresVertexColor = nodes.OfType<IMayRequireVertexColor>().Any(x => x.RequiresVertexColor());
bool requiresFaceSign = nodes.OfType<IMayRequireFaceSign>().Any(x => x.RequiresFaceSign());
var meshUV = new List<UVChannel>();
for (int uvIndex = 0; uvIndex < ShaderGeneratorNames.UVCount; ++uvIndex)

requiresPosition = requiresPosition,
requiresScreenPosition = requiresScreenPosition,
requiresVertexColor = requiresVertexColor,
requiresFaceSign = requiresFaceSign,
requiresMeshUVs = meshUV
};

5
com.unity.shadergraph/Editor/Data/Util/GraphUtil.cs


{
return 2;
}
else if (typeName.Equals("float"))
else if (typeName.Equals("Single"))
{
return 1;
}

if (requirements.requiresScreenPosition)
surfaceDescriptionInputStruct.AppendLine("float4 {0};", ShaderGeneratorNames.ScreenPosition);
if (requirements.requiresFaceSign)
surfaceDescriptionInputStruct.AppendLine("float {0};", ShaderGeneratorNames.FaceSign);
results.previewMode = PreviewMode.Preview3D;
if (!isUber)

14
com.unity.shadergraph/Editor/Data/Util/ShaderGenerator.cs


if (pixelRequirements.requiresScreenPosition)
pixelShaderSurfaceInputs.AppendLine("surfaceInput.{0} = {0};", ShaderGeneratorNames.ScreenPosition);
if (pixelRequirements.requiresFaceSign)
pixelShaderSurfaceInputs.AppendLine("surfaceInput.{0} = {0};", ShaderGeneratorNames.FaceSign);
foreach (var channel in pixelRequirements.requiresMeshUVs.Distinct())
pixelShaderSurfaceInputs.AppendLine("surfaceInput.{0} = {0};", ShaderGeneratorNames.GetUVName(channel));

pixelShaderSurfaceRemap.AppendLine("return surf.PreviewOutput;");
}
// -------------------------------------
// Extra pixel shader work
var faceSign = new ShaderStringBuilder();
if (shaderGraphRequirements.requiresFaceSign)
faceSign.AppendLine(", half FaceSign : VFACE");
res = res.Replace("${FaceSign}", faceSign.ToString());
res = res.Replace("${LocalPixelShader}", pixelShader.ToString());
res = res.Replace("${SurfaceInputs}", pixelShaderSurfaceInputs.ToString());
res = res.Replace("${SurfaceOutputRemap}", pixelShaderSurfaceRemap.ToString());

return o;
}
float4 frag (GraphVertexOutput IN) : SV_Target
float4 frag (GraphVertexOutput IN ${FaceSign}) : SV_Target
{
${LocalPixelShader}
SurfaceDescriptionInputs surfaceInput = (SurfaceDescriptionInputs)0;;

1
com.unity.shadergraph/Editor/Data/Util/ShaderGeneratorNames.cs


public const string ScreenPosition = "ScreenPosition";
public const string VertexColor = "VertexColor";
public const string FaceSign = "FaceSign";
public static string GetUVName(this UVChannel channel)

3
com.unity.shadergraph/.data/face_sign.png


version https://git-lfs.github.com/spec/v1
oid sha256:056f160ee81fcdeb3f3a26a0116846de50b68bafa0c65db8731f5aca37ee74e7
size 43759

18
com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireFaceSign.cs


using UnityEditor.Graphing;
namespace UnityEditor.ShaderGraph
{
public interface IMayRequireFaceSign
{
bool RequiresFaceSign(ShaderStageCapability stageCapability = ShaderStageCapability.Fragment);
}
public static class IMayRequireFaceSignExtensions
{
public static bool RequiresFaceSign(this ISlot slot)
{
var mayRequireFaceSign = slot as IMayRequireFaceSign;
return mayRequireFaceSign != null && mayRequireFaceSign.RequiresFaceSign();
}
}
}

3
com.unity.shadergraph/Editor/Data/Interfaces/IMayRequireFaceSign.cs.meta


fileFormatVersion: 2
guid: 23f5d9c2f1ec442a7b8c59e893a6724d
timeCreated: 1512469767

41
com.unity.shadergraph/Editor/Data/Nodes/Utility/Logic/IsFrontFaceNode.cs


using UnityEngine;
using UnityEditor.Graphing;
namespace UnityEditor.ShaderGraph
{
[Title("Utility", "Logic", "Is Front Face")]
public class IsFrontFaceNode : AbstractMaterialNode, IGeneratesBodyCode, IMayRequireFaceSign
{
public IsFrontFaceNode()
{
name = "Is Front Face";
UpdateNodeAfterDeserialization();
}
public override string documentationURL
{
get { return "https://github.com/Unity-Technologies/ShaderGraph/wiki/Is-Front-Face-Node"; }
}
public override bool hasPreview { get { return false; } }
public const int OutputSlotId = 0;
private const string kOutputSlotName = "Out";
public override void UpdateNodeAfterDeserialization()
{
AddSlot(new BooleanMaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, true, ShaderStageCapability.Fragment));
RemoveSlotsNameNotMatching(new[] { OutputSlotId });
}
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
visitor.AddShaderChunk(string.Format("{0} {1} = max(0, IN.{2});", precision, GetVariableNameForSlot(OutputSlotId), ShaderGeneratorNames.FaceSign), true);
}
public bool RequiresFaceSign(ShaderStageCapability stageCapability = ShaderStageCapability.Fragment)
{
return true;
}
}
}

11
com.unity.shadergraph/Editor/Data/Nodes/Utility/Logic/IsFrontFaceNode.cs.meta


fileFormatVersion: 2
guid: c7e3dd61523f54e52ade29765e299d3f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存