浏览代码

First integration for a *suitable* approach of MaterialGraph & ScriptableRenderloop (MasterNode description is draft, that's why MaterialIDAttribute is tagget as "WIP")

/scriptablerenderloop-materialgraph
Paul Demeulenaere 8 年前
当前提交
f286e852
共有 8 个文件被更改,包括 459 次插入40 次删除
  1. 224
      Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs
  2. 25
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/Lit.cs
  3. 114
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/Lit.template
  4. 8
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/Lit.template.meta
  5. 19
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/LitData.template
  6. 8
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/LitData.template.meta
  7. 93
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/LitShare.template
  8. 8
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/LitShare.template.meta

224
Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs


using System;
using System.Linq;
using UnityEditor;
using UnityEngine.MaterialGraph;
public class HDRenderLoopNodeProvider : UnityEngine.MaterialGraphInterface.IMasterNodeDescProvider
[Serializable]
public abstract class AbstractHDRenderLoopMasterNode : AbstractMasterNode
public UnityEngine.MaterialGraphInterface.MasterNodeDesc[] Nodes
public override void GenerateLightFunction(ShaderGenerator lightFunction)
{
//TODO
}
public override void GenerateSurfaceOutput(ShaderGenerator surfaceOutput)
{
//TODO
}
public override string shaderTemplate
var materials = new string[] { "Lit", "Unlit" }; //TODO : List Folder
var masterNodeDesc = new UnityEngine.MaterialGraphInterface.MasterNodeDesc[materials.Length];
var path = "Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/Lit.template";
if (!System.IO.File.Exists(path))
return "";
var content = System.IO.File.ReadAllText(path);
for (int i = 0; i < masterNodeDesc.Length; ++i)
var regex = new System.Text.RegularExpressions.Regex("#include {1,}\"Assets/.*.template\"");
var innerRegex = new System.Text.RegularExpressions.Regex("\".*\"");
while (regex.IsMatch(content))
var surfaceType = Type.GetType(string.Format("UnityEngine.Experimental.ScriptableRenderLoop.{0}.SurfaceData", materials[i]));
var match = regex.Match(content);
var includePath = innerRegex.Match(match.Value).Value;
includePath = includePath.Substring(1, includePath.Length - 2);
if (surfaceType != null)
if (!System.IO.File.Exists(includePath))
masterNodeDesc[i].name = "HDRenderLoop/" + materials[i];
masterNodeDesc[i].templateShader = "todo.template";
var fieldsSurface = surfaceType.GetFields();
var fieldsBuiltIn = typeof(Builtin.BuiltinData).GetFields();
masterNodeDesc[i].slots = fieldsSurface.Concat(fieldsBuiltIn).Select(field =>
{
var attribute = (SurfaceDataAttributes[])field.GetCustomAttributes(typeof(SurfaceDataAttributes), false);
var valueType = UnityEngine.MaterialGraphInterface.SlotValueType.Dynamic;
var fieldType = field.FieldType;
if (fieldType == typeof(float))
{
valueType = MaterialGraphInterface.SlotValueType.Vector1;
}
else if (fieldType == typeof(Vector2))
{
valueType = MaterialGraphInterface.SlotValueType.Vector2;
}
else if (fieldType == typeof(Vector3))
{
valueType = MaterialGraphInterface.SlotValueType.Vector3;
}
else if (fieldType == typeof(Vector2))
{
valueType = MaterialGraphInterface.SlotValueType.Vector4;
}
Debug.Log("Cannot unroll Lit.template file");
return "";
}
return new UnityEngine.MaterialGraphInterface.MaterialSlotDesc()
{
displayName = attribute.Length > 0 ? attribute[0].displayName : field.Name,
shaderOutputName = field.Name,
valueType = valueType
};
}).Where(o => o.valueType != MaterialGraphInterface.SlotValueType.Dynamic).ToArray(); //For now, ignore materialID type
var includeContent = string.Format("//Begin include : {0}\n{1}\n//End include : {0}", includePath, System.IO.File.ReadAllText(includePath));
content = content.Replace(match.Value, includeContent);
}
return content;
}
}
public AbstractHDRenderLoopMasterNode()
{
name = GetName();
UpdateNodeAfterDeserialization();
}
protected abstract Type GetSurfaceType();
protected abstract string GetName();
protected abstract int GetMatchingMaterialID();
public sealed override void UpdateNodeAfterDeserialization()
{
var surfaceType = GetSurfaceType();
if (surfaceType != null)
{
var fieldsBuiltIn = typeof(Builtin.BuiltinData).GetFields();
var fieldsSurface = surfaceType.GetFields();
var slots = fieldsSurface.Concat(fieldsBuiltIn).Select((field, index) =>
{
var attribute = (SurfaceDataAttributes[])field.GetCustomAttributes(typeof(SurfaceDataAttributes), false);
var materialAttribute = (MaterialIdAttributes_WIP[])field.GetCustomAttributes(typeof(MaterialIdAttributes_WIP), false);
var valueType = SlotValueType.Dynamic;
var fieldType = field.FieldType;
if (fieldType == typeof(float))
{
valueType = SlotValueType.Vector1;
else if (fieldType == typeof(Vector2))
{
valueType = SlotValueType.Vector2;
}
else if (fieldType == typeof(Vector3))
{
valueType = SlotValueType.Vector3;
}
else if (fieldType == typeof(Vector2))
{
valueType = SlotValueType.Vector4;
}
return new
{
index = index,
displayName = attribute.Length > 0 ? attribute[0].displayName : field.Name,
materialID = materialAttribute.Length > 0 ? materialAttribute[0].materialID : new int[] { },
shaderOutputName = field.Name,
valueType = valueType
};
}).Where(o => o.materialID.Contains(GetMatchingMaterialID())).ToArray();
foreach (var slot in slots)
{
AddSlot(new MaterialSlot(slot.index, slot.displayName, slot.shaderOutputName, Graphing.SlotType.Input, slot.valueType, Vector4.zero));
return masterNodeDesc;
[AttributeUsage(AttributeTargets.Field)]
public class MaterialIdAttributes_WIP : System.Attribute
{
public int[] materialID;
public MaterialIdAttributes_WIP(int[] materialID)
{
this.materialID = materialID;
}
}
[Serializable]
[Title("HDRenderLoop/StandardLit")]
public class StandardtLit : AbstractHDRenderLoopMasterNode
{
protected override string GetName()
{
return "MasterNodeStandardLit";
}
protected override Type GetSurfaceType()
{
return typeof(Lit.SurfaceData);
}
protected override int GetMatchingMaterialID()
{
return (int)Lit.MaterialId.LitStandard;
}
}
[Serializable]
[Title("HDRenderLoop/SubsurfaceScatteringLit")]
public class SubsurfaceScatteringLit : AbstractHDRenderLoopMasterNode
{
protected override string GetName()
{
return "MasterNodeSubsurfaceScatteringLit";
}
protected override Type GetSurfaceType()
{
return typeof(Lit.SurfaceData);
}
protected override int GetMatchingMaterialID()
{
return (int)Lit.MaterialId.LitSSS;
}
}
[Serializable]
[Title("HDRenderLoop/SubsurfaceClearCoatLit")]
public class SubsurfaceClearCoatLit : AbstractHDRenderLoopMasterNode
{
protected override string GetName()
{
return "MasterNodeSubsurfaceClearCoatLit";
}
protected override Type GetSurfaceType()
{
return typeof(Lit.SurfaceData);
}
protected override int GetMatchingMaterialID()
{
return (int)Lit.MaterialId.LitClearCoat;
}
}
[Serializable]
[Title("HDRenderLoop/SpecularColorLit")]
public class SpecularColorLit : AbstractHDRenderLoopMasterNode
{
protected override string GetName()
{
return "MasterNodeSpecularColorLit";
}
protected override Type GetSurfaceType()
{
return typeof(Lit.SurfaceData);
}
protected override int GetMatchingMaterialID()
{
return (int)Lit.MaterialId.LitSpecular;
}
}
}
namespace UnityEngine.Experimental.ScriptableRenderLoop
{
[ExecuteInEditMode]
// This HDRenderLoop assume linear lighting. Don't work with gamma.
public class HDRenderLoop : ScriptableRenderLoop

25
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/Lit.cs


using UnityEngine;
using UnityEngine.Rendering;
using System;
using System.Linq;
namespace UnityEngine.Experimental.ScriptableRenderLoop
{

[GenerateHLSL(PackingRules.Exact, false, true, 1000)]
public struct SurfaceData
{
[MaterialIdAttributes_WIP(new int[] { (int)MaterialId.LitStandard, (int)MaterialId.LitSSS, (int)MaterialId.LitClearCoat, (int)MaterialId.LitSpecular })]
[MaterialIdAttributes_WIP(new int[] { (int)MaterialId.LitStandard, (int)MaterialId.LitSSS, (int)MaterialId.LitClearCoat, (int)MaterialId.LitSpecular })]
[MaterialIdAttributes_WIP(new int[] { (int)MaterialId.LitStandard, (int)MaterialId.LitSSS, (int)MaterialId.LitClearCoat, (int)MaterialId.LitSpecular })]
[MaterialIdAttributes_WIP(new int[] { (int)MaterialId.LitStandard, (int)MaterialId.LitSSS, (int)MaterialId.LitClearCoat, (int)MaterialId.LitSpecular })]
[MaterialIdAttributes_WIP(new int[] { (int)MaterialId.LitStandard, (int)MaterialId.LitSSS, (int)MaterialId.LitClearCoat, (int)MaterialId.LitSpecular })]
[SurfaceDataAttributes("Ambient Occlusion")]
public float ambientOcclusion;

[MaterialIdAttributes_WIP(new int[] { (int)MaterialId.LitStandard })]
[MaterialIdAttributes_WIP(new int[] { (int)MaterialId.LitStandard })]
[MaterialIdAttributes_WIP(new int[] { (int)MaterialId.LitStandard })]
[MaterialIdAttributes_WIP(new int[] { (int)MaterialId.LitStandard })]
[MaterialIdAttributes_WIP(new int[] { (int)MaterialId.LitSSS })]
[MaterialIdAttributes_WIP(new int[] { (int)MaterialId.LitSSS })]
[MaterialIdAttributes_WIP(new int[] { (int)MaterialId.LitSSS })]
[MaterialIdAttributes_WIP(new int[] { (int)MaterialId.LitClearCoat })]
[MaterialIdAttributes_WIP(new int[] { (int)MaterialId.LitClearCoat })]
[MaterialIdAttributes_WIP(new int[] { (int)MaterialId.LitSpecular })]
[SurfaceDataAttributes("Specular Color")]
public Vector3 specularColor;
};

114
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/Lit.template


Shader "Unity/Lit/${ShaderName}"
{
Properties
{
${ShaderPropertiesHeader}
}
HLSLINCLUDE
#pragma target 5.0
#pragma only_renderers d3d11 // TEMP: unitl we go futher in dev
#define UNITY_MATERIAL_LIT // Need to be define before including Material.hlsl
//-------------------------------------------------------------------------------------
// Include
//-------------------------------------------------------------------------------------
#include "common.hlsl"
#include "Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/ShaderPass/ShaderPass.cs.hlsl"
#include "Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/ShaderVariables.hlsl"
#include "Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Debug/DebugViewMaterial.hlsl"
//-------------------------------------------------------------------------------------
// variable declaration
//-------------------------------------------------------------------------------------
// Set of users variables
${LightingFunction}
${ShaderFunctions}
${ShaderPropertyUsages}
ENDHLSL
SubShader
{
Tags { "RenderType"="Opaque" "PerformanceChecks"="False" }
LOD 300
// ------------------------------------------------------------------
// Deferred pass
// ------------------------------------------------------------------
Pass
{
Name "GBuffer" // Name is not used
Tags { "LightMode" = "GBuffer" } // This will be only for opaque object based on the RenderQueue index
Cull [_CullMode]
HLSLPROGRAM
#pragma vertex VertDefault
#pragma fragment Frag
#define SHADERPASS SHADERPASS_GBUFFER
#include "Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Material.hlsl"
#include "Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/LitData.template"
#include "Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/LitShare.template"
#include "Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/ShaderPass/ShaderPassGBuffer.hlsl"
ENDHLSL
}
// ------------------------------------------------------------------
// Debug pass
// ------------------------------------------------------------------
//TODO
// ------------------------------------------------------------------
// Extracts information for lightmapping, GI (emission, albedo, ...)
// This pass it not used during regular rendering.
// ------------------------------------------------------------------
//TODO
// ------------------------------------------------------------------
// Depth only
// ------------------------------------------------------------------
//TODO
// ------------------------------------------------------------------
// forward pass
// ------------------------------------------------------------------
/* //Preview doesn't work for now
Pass
{
Name "Forward" // Name is not used
Tags{ "LightMode" = "Forward" } // This will be only for transparent object based on the RenderQueue index
Blend[_SrcBlend][_DstBlend]
ZWrite[_ZWrite]
Cull[_CullMode]
HLSLPROGRAM
#pragma vertex VertDefault
#pragma fragment Frag
#define SHADERPASS SHADERPASS_FORWARD
// TEMP until pragma work in include
// #include "../../Lighting/Forward.hlsl"
#pragma multi_compile LIGHTLOOP_SINGLE_PASS
#pragma multi_compile SHADOWFILTERING_FIXED_SIZE_PCF
#include "Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/Lighting.hlsl"
#include "Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/LitData.template"
#include "Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/LitShare.template"
#include "Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/ShaderPass/ShaderPassForward.hlsl"
ENDHLSL
}*/
}
}

8
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/Lit.template.meta


fileFormatVersion: 2
guid: 810d1d06c0329e0488541cc00c884938
timeCreated: 1477907157
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

19
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/LitData.template


struct FragInput
{
float4 positionHS;
float3 positionWS;
float2 meshUV0;
float2 meshUV1;
float2 meshUV2;
float3 tangentToWorld[3];
bool isFrontFace;
};
void GetSurfaceAndBuiltinData(FragInput IN, out SurfaceData o, out BuiltinData builtinData)
{
o = (SurfaceData)0;
builtinData = (BuiltinData)0;
float3 vertexNormalWS = IN.tangentToWorld[2].xyz;
o.normalWS = vertexNormalWS;
${PixelShaderBody}
}

8
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/LitData.template.meta


fileFormatVersion: 2
guid: d6c7ab7e8a2de574d88d5358af9647df
timeCreated: 1477915331
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

93
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/LitShare.template


//-------------------------------------------------------------------------------------
// Attribute/Varying
//-------------------------------------------------------------------------------------
struct Attributes
{
float3 positionOS : POSITION;
float3 normalOS : NORMAL;
float2 uv0 : TEXCOORD0;
float2 uv1 : TEXCOORD1;
float2 uv2 : TEXCOORD2;
float4 tangentOS : TANGENT;
};
struct Varyings
{
float4 positionHS;
float3 positionWS;
float2 meshUV0;
float2 meshUV1;
float2 meshUV2;
float3 tangentToWorld[3];
};
struct PackedVaryings
{
float4 positionHS : SV_Position;
float4 interpolators[5] : TEXCOORD0;
};
// Function to pack data to use as few interpolator as possible, the ShaderGraph should generate these functions
PackedVaryings PackVaryings(Varyings input)
{
PackedVaryings output;
output.positionHS = input.positionHS;
output.interpolators[0].xyz = input.positionWS.xyz;
output.interpolators[1].xyz = input.tangentToWorld[0];
output.interpolators[2].xyz = input.tangentToWorld[1];
output.interpolators[3].xyz = input.tangentToWorld[2];
output.interpolators[0].w = input.meshUV0.x;
output.interpolators[1].w = input.meshUV0.y;
output.interpolators[2].w = input.meshUV1.x;
output.interpolators[3].w = input.meshUV1.y;
output.interpolators[4] = float4(input.meshUV1.xy, 0.0, 0.0);
return output;
}
FragInput UnpackVaryings(PackedVaryings input)
{
FragInput output;
ZERO_INITIALIZE(FragInput, output);
output.positionHS = input.positionHS;
output.positionWS.xyz = input.interpolators[0].xyz;
output.tangentToWorld[0] = input.interpolators[1].xyz;
output.tangentToWorld[1] = input.interpolators[2].xyz;
output.tangentToWorld[2] = input.interpolators[3].xyz;
output.meshUV0.xy = float2(input.interpolators[0].w, input.interpolators[1].w);
output.meshUV1.xy = float2(input.interpolators[2].w, input.interpolators[3].w);
output.meshUV2 = input.interpolators[4].xy;
return output;
}
//-------------------------------------------------------------------------------------
// Vertex shader
//-------------------------------------------------------------------------------------
// TODO: Here we will also have all the vertex deformation (GPU skinning, vertex animation, morph target...) or we will need to generate a compute shaders instead (better! but require work to deal with unpacking like fp16)
PackedVaryings VertDefault(Attributes input)
{
Varyings output;
output.positionWS = TransformObjectToWorld(input.positionOS);
output.positionHS = TransformWorldToHClip(output.positionWS);
float3 normalWS = TransformObjectToWorldNormal(input.normalOS);
output.meshUV0 = input.uv0;
output.meshUV1 = input.uv1;
output.meshUV2 = input.uv2;
float4 tangentWS = float4(TransformObjectToWorldDir(input.tangentOS.xyz), input.tangentOS.w);
float3x3 tangentToWorld = CreateTangentToWorld(normalWS, tangentWS.xyz, tangentWS.w);
output.tangentToWorld[0] = tangentToWorld[0];
output.tangentToWorld[1] = tangentToWorld[1];
output.tangentToWorld[2] = tangentToWorld[2];
return PackVaryings(output);
}

8
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/LitShare.template.meta


fileFormatVersion: 2
guid: 81531b5e1c67b7f41b9307691ecd9d23
timeCreated: 1477915331
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存