浏览代码

HDRenderLoop: Finish cleaning LayeredLit (some bug left)

/main
Sebastien Lagarde 8 年前
当前提交
cb8aa00b
共有 7 个文件被更改,包括 131 次插入89 次删除
  1. 69
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/LayeredLit/Editor/LayeredLitUI.cs
  2. 14
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/LayeredLit/LayeredLit.shader
  3. 17
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Editor/LitUI.cs
  4. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Lit.shader
  5. 96
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitData.hlsl
  6. 20
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitSurfaceData.hlsl
  7. 2
      Assets/ScriptableRenderLoop/ShaderLibrary/CommonMaterial.hlsl

69
Assets/ScriptableRenderLoop/HDRenderLoop/Material/LayeredLit/Editor/LayeredLitUI.cs


MaterialProperty[] layerUVDetailsMappingMask = new MaterialProperty[kMaxLayerCount];
const string kLayerUVDetailsMappingMask = "_UVDetailsMappingMask";
MaterialProperty layerEmissiveColor = null;
const string kLayerEmissiveColor = "_EmissiveColor";
MaterialProperty layerEmissiveColorMap = null;
const string kLayerEmissiveColorMap = "_EmissiveColorMap";
MaterialProperty layerEmissiveIntensity = null;
const string kLayerEmissiveIntensity = "_EmissiveIntensity";
private void FindLayerProperties(MaterialProperty[] props)
{
layerMaskMap = FindProperty(kLayerMaskMap, props);

layerUVDetail[i] = FindProperty(string.Format("{0}{1}", kLayerUVDetail, i), props);
layerUVDetailsMappingMask[i] = FindProperty(string.Format("{0}{1}", kLayerUVDetailsMappingMask, i), props);
}
layerEmissiveColor = FindProperty(kLayerEmissiveColor, props);
layerEmissiveColorMap = FindProperty(kLayerEmissiveColorMap, props);
layerEmissiveIntensity = FindProperty(kLayerEmissiveIntensity, props);
}
int numLayer

SetKeyword(material, "_LAYER_MASK_VERTEX_COLOR", material.GetFloat(kLayerMaskVertexColor) != 0.0f);
}
protected override void SetupEmissionGIFlags(Material material)
{
// Setup lightmap emissive flags
bool nonNullEmissive = false;
for(int i = 0 ; i < numLayer; ++i)
{
string paramName = string.Format("_EmissiveIntensity{0}", i);
if (material.GetFloat(paramName) > 0.0f)
{
nonNullEmissive = true;
break;
}
}
var realtimeEmission = (material.globalIlluminationFlags & MaterialGlobalIlluminationFlags.RealtimeEmissive) > 0;
bool shouldEmissionBeEnabled = nonNullEmissive || realtimeEmission;
MaterialGlobalIlluminationFlags flags = material.globalIlluminationFlags;
if ((flags & (MaterialGlobalIlluminationFlags.BakedEmissive | MaterialGlobalIlluminationFlags.RealtimeEmissive)) != 0)
{
if (shouldEmissionBeEnabled)
flags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack;
else
flags |= MaterialGlobalIlluminationFlags.EmissiveIsBlack;
material.globalIlluminationFlags = flags;
}
}
void SetupMaterialForLayers(Material material)
{
if (numLayer == 4)

SetKeyword(material, currentLayerMappingTriplanar, true);
}
X = (layerUVDetailMapping == LayerUVDetailMapping.UV0) ? 1.0f : 0.0f;
Y = (layerUVDetailMapping == LayerUVDetailMapping.UV1) ? 1.0f : 0.0f;
Z = (layerUVDetailMapping == LayerUVDetailMapping.UV3) ? 1.0f : 0.0f;
layerUVDetailsMappingMask[i].colorValue = new Color(X, Y, Z, 0.0f);
// If base is planar mode, detail is planar too
if (W > 0.0f)
{
X = Y = Z = 0.0f;
}
else
{
X = (layerUVDetailMapping == LayerUVDetailMapping.UV0) ? 1.0f : 0.0f;
Y = (layerUVDetailMapping == LayerUVDetailMapping.UV1) ? 1.0f : 0.0f;
Z = (layerUVDetailMapping == LayerUVDetailMapping.UV3) ? 1.0f : 0.0f;
}
layerUVDetailsMappingMask[i].colorValue = new Color(X, Y, Z, 0.0f); // W Reuse planar mode from base
}
}

EditorGUI.BeginChangeCheck();
{
ShaderOptionsGUI();
EditorGUI.indentLevel++;
EditorGUILayout.LabelField(styles.emissiveText);
m_MaterialEditor.TexturePropertySingleLine(Styles.emissiveText, emissiveColorMap, emissiveColor);
m_MaterialEditor.ShaderProperty(emissiveIntensity, Styles.emissiveIntensityText);
m_MaterialEditor.LightmapEmissionProperty(1);
EditorGUI.indentLevel--;
EditorGUILayout.Space();
}
if (EditorGUI.EndChangeCheck())

bool layerChanged = DoLayersGUI(materialImporter);
EditorGUILayout.Space();
GUILayout.Label(Styles.emissiveText, EditorStyles.boldLabel);
EditorGUI.indentLevel++;
m_MaterialEditor.TexturePropertySingleLine(Styles.emissiveText, layerEmissiveColorMap, layerEmissiveColor);
m_MaterialEditor.ShaderProperty(layerEmissiveIntensity, Styles.emissiveIntensityText);
m_MaterialEditor.LightmapEmissionProperty(1);
EditorGUI.indentLevel--;
CheckLayerConsistency();

14
Assets/ScriptableRenderLoop/HDRenderLoop/Material/LayeredLit/LayeredLit.shader


[HideInInspector] _UVDetailsMappingMask1("_UVDetailsMappingMask1", Float) = 0
[HideInInspector] _UVDetailsMappingMask2("_UVDetailsMappingMask2", Float) = 0
[HideInInspector] _UVDetailsMappingMask3("_UVDetailsMappingMask3", Float) = 0
// Unused but to be able to share litUI.Sahder and layeredUI.Shader
[HideInInspector] _UVBase("UV Set for base", Float) = 0
[HideInInspector] _UVDetail("UV Set for base", Float) = 0
[HideInInspector] _TexWorldScale("Scale to apply on world coordinate", Float) = 1.0
[HideInInspector] _UVMappingMask("_UVMappingMask", Color) = (1, 0, 0, 0)
[HideInInspector] _UVDetailsMappingMask("_UVDetailsMappingMask", Color) = (1, 0, 0, 0)
}
HLSLINCLUDE

PROP_DECL_TEX2D(_DetailMask);
PROP_DECL_TEX2D(_DetailMap);
PROP_DECL(float4, _DetailMap_ST);
float4 _DetailMap0_ST;
float4 _DetailMap1_ST;
float4 _DetailMap2_ST;
float4 _DetailMap3_ST;
PROP_DECL(float, _UVDetail);
PROP_DECL(float, _DetailAlbedoScale);
PROP_DECL(float, _DetailNormalScale);

PROP_DECL(float, _TexWorldScale);
PROP_DECL(float4, _UVMappingMask);
PROP_DECL(float4, _UVDetailMappingMask);
PROP_DECL(float4, _UVDetailsMappingMask);
float _AlphaCutoff;

17
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Editor/LitUI.cs


protected MaterialProperty baseColorMap = null;
protected const string kBaseColorMap = "_BaseColorMap";
protected MaterialProperty metallic = null;
protected const string kMettalic = "_Mettalic";
protected const string kMetallic = "_Metallic";
protected MaterialProperty smoothness = null;
protected const string kSmoothness = "_Smoothness";
protected MaterialProperty maskMap = null;

{
m_MaterialEditor.ShaderProperty(UVDetail, Styles.UVDetailMappingText.text);
}
X = ((UVDetailMapping)UVDetail.floatValue == UVDetailMapping.UV0) ? 1.0f : 0.0f;
Y = ((UVDetailMapping)UVDetail.floatValue == UVDetailMapping.UV1) ? 1.0f : 0.0f;
Z = ((UVDetailMapping)UVDetail.floatValue == UVDetailMapping.UV3) ? 1.0f : 0.0f;
// If base is planar mode, detail is planar too
if (W > 0.0f)
{
X = Y = Z = 0.0f;
}
else
{
X = ((UVDetailMapping)UVDetail.floatValue == UVDetailMapping.UV0) ? 1.0f : 0.0f;
Y = ((UVDetailMapping)UVDetail.floatValue == UVDetailMapping.UV1) ? 1.0f : 0.0f;
Z = ((UVDetailMapping)UVDetail.floatValue == UVDetailMapping.UV3) ? 1.0f : 0.0f;
}
UVDetailsMappingMask.colorValue = new Color(X, Y, Z, 0.0f); // W Reuse planar mode from base
m_MaterialEditor.ShaderProperty(detailMapMode, Styles.detailMapModeText.text);

2
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Lit.shader


float _TexWorldScale;
float4 _UVMappingMask;
float4 _UVDetailMappingMask;
float4 _UVDetailsMappingMask;
ENDHLSL

96
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitData.hlsl


struct LayerTexCoord
{
#ifndef LAYERED_LIT_SHADER
LayerUV base;
LayerUV details;
#else
// Regular texcoord
LayerUV base0;
LayerUV base1;

LayerUV details1;
LayerUV details2;
LayerUV details3;
#endif
// triplanar weight
float3 weights;

float4 val = float4(0.0, 0.0, 0.0, 0.0);
if (weights.x > 0.0)
val += outCoord.blendWeights.x * SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvYZ);
val += weights.x * SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvYZ);
val += outCoord.blendWeights.y * SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvZX);
val += weights.y * SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvZX);
val += outCoord.blendWeights.z * SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvXY);
val += weights.z * SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvXY);
return val;
}

// TODO: Handle BC5 format, currently this code is for DXT5nm
// THis function below must call UnpackNormalmapRGorAG
float4 SampleNormalLayer(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV layerUV, float3 weights)
float3 SampleNormalLayer(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV layerUV, float3 weights)
float4 val = float4(0.0, 0.0, 0.0, 0.0);
float3 val = float3(0.0, 0.0, 0.0);
val += outCoord.blendWeights.x * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvYZ));
val += weights.x * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvYZ));
val += outCoord.blendWeights.y * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvZX));
val += weights.y * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvZX));
val += outCoord.blendWeights.z * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvXY));
val += weights.z * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvXY));
return val;
return normalize(val);
}
else
{

// This version is for normalmap with AG encoding only (use with details map)
float4 SampleNormalLayerAG(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV layerUV, float3 weights)
float3 SampleNormalLayerAG(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV layerUV, float3 weights)
float4 val = float4(0.0, 0.0, 0.0, 0.0);
float3 val = float3(0.0, 0.0, 0.0);
val += outCoord.blendWeights.x * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvYZ));
val += weights.x * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvYZ));
val += outCoord.blendWeights.y * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvZX));
val += weights.y * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvZX));
val += outCoord.blendWeights.z * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvXY));
val += weights.z * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvXY));
return val;
return normalize(val);
}
else
{

// Macro to improve readibility of surface data
#define SAMPLE_LAYER_TEXTURE2D(textureName, samplerName, coord) SampleLayer(TEXTURE2D_PASS(textureName, samplerName), coord, coord.weights);
#define SAMPLE_LAYER_NORMALMAP(textureName, samplerName, coord) SampleNormalLayer(TEXTURE2D_PASS(textureName, samplerName), coord, coord.weights);
#define SAMPLE_LAYER_NORMALMAP_AG(textureName, samplerName, coord) SampleNormalLayerAG(TEXTURE2D_PASS(textureName, samplerName), coord, coord.weights);
#define SAMPLE_LAYER_TEXTURE2D(textureName, samplerName, coord) SampleLayer(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights)
#define SAMPLE_LAYER_NORMALMAP(textureName, samplerName, coord) SampleNormalLayer(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights)
#define SAMPLE_LAYER_NORMALMAP_AG(textureName, samplerName, coord) SampleNormalLayerAG(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights)
// Transforms 2D UV by scale/bias property
#define TRANSFORM_TEX(tex,name) ((tex.xy) * name##_ST.xy + name##_ST.zw)

void GetSurfaceAndBuiltinData(FragInput input, out SurfaceData surfaceData, out BuiltinData builtinData)
{
LayerTexCoord layerTexCoord;
ZERO_INITIALIZE(LayerTexCoord, layerTexCoord);
#ifdef _MAPPING_TRIPLANAR
layerTexCoord.weights = ComputeTriplanarWeights(input.tangentToWorld[2].xyz); // Will be remove if triplanar not used
layerTexCoord.weights = ComputeTriplanarWeights(input.tangentToWorld[2].xyz);
#endif
_UVMappingMask.yz = flat2(0.0, 0.0);
_UVMappingMask.yz = float2(0.0, 0.0);
#ifdef MAPPING_TRIPLANAR
#ifdef _MAPPING_TRIPLANAR
isTriplanar = true;
#endif
ComputeLayerTexCoord(input, isTriplanar, layerTexCoord);

return result;
}
#define PROP_BLEND_COLOR(name, mask) name = BlendLayeredColor(name##0, name##1, name##2, name##3, mask);
#define PROP_BLEND_NORMAL(name, mask) name = BlendLayeredNormal(name##0, name##1, name##2, name##3, mask);
#define PROP_BLEND_SCALAR(name, mask) name = BlendLayeredScalar(name##0, name##1, name##2, name##3, mask);
#define SURFACEDATA_BLEND_COLOR(surfaceData, name, mask) BlendLayeredColor(surfaceData##0.##name, surfaceData##1.##name, surfaceData##2.##name, surfaceData##3.##name, mask);
#define SURFACEDATA_BLEND_NORMAL(surfaceData, name, mask) BlendLayeredNormal(surfaceData##0.##name, surfaceData##1.##name, surfaceData##2.##name, surfaceData##3.##name, mask);
#define SURFACEDATA_BLEND_SCALAR(surfaceData, name, mask) BlendLayeredScalar(surfaceData##0.##name, surfaceData##1.##name, surfaceData##2.##name, surfaceData##3.##name, mask);
#define PROP_BLEND_SCALAR(name, mask) BlendLayeredScalar(name##0, name##1, name##2, name##3, mask);
ZERO_INITIALIZE(LayerTexCoord, layerTexCoord);
#if defined(_LAYER_MAPPING_TRIPLANAR_0) || defined(_LAYER_MAPPING_TRIPLANAR_1) || defined(_LAYER_MAPPING_TRIPLANAR_2) || defined(_LAYER_MAPPING_TRIPLANAR_3)
layerTexCoord.weights = ComputeTriplanarWeights(input.tangentToWorld[2].xyz); // Will be remove if triplanar not used
layerTexCoord.weights = ComputeTriplanarWeights(input.tangentToWorld[2].xyz);
#endif
bool isTriplanar = false;
#ifdef _LAYER_MAPPING_TRIPLANAR_0

isTriplanar = false;
#ifdef _LAYER_MAPPING_TRIPLANAR_1
isTriplanar = true;
#endif
isTriplanar = false;
#ifdef _LAYER_MAPPING_TRIPLANAR_2
isTriplanar = true;
#endif
isTriplanar = false;
#ifdef _LAYER_MAPPING_TRIPLANAR_3
isTriplanar = true;
#endif
ComputeLayerTexCoord3(input, isTriplanar, layerTexCoord);
ApplyDisplacement0(input, layerTexCoord);
ApplyDisplacement1(input, layerTexCoord);

float alpha3 = GetSurfaceData3(input, layerTexCoord, surfaceData3);
// Mask Values : Layer 1, 2, 3 are r, g, b
float3 maskValues = float3(1.0, 1.0, 1.0);
float3 maskValues = float3(0.0, 0.0, 0.0);
maskValues *= SAMPLE_TEXTURE2D(_LayerMaskMap, sampler_LayerMaskMap, input.texCoord0).rgb;
maskValues = SAMPLE_TEXTURE2D(_LayerMaskMap, sampler_LayerMaskMap, input.texCoord0).rgb;
maskValues *= input.vertexColor.rgb;
maskValues = input.vertexColor.rgb;
#endif
#if defined(_LAYER_MASK_MAP) && defined(_LAYER_MASK_VERTEX_COLOR)
maskValues = input.vertexColor.rgb * SAMPLE_TEXTURE2D(_LayerMaskMap, sampler_LayerMaskMap, input.texCoord0).rgb;
surfaceData.baseColor = PROP_BLEND_COLOR(surfaceData.baseColor, weights);
surfaceData.specularOcclusion = PROP_BLEND_SCALAR(surfaceData.specularOcclusion, weights);
surfaceData.baseColor = SURFACEDATA_BLEND_COLOR(surfaceData, baseColor, weights);
surfaceData.specularOcclusion = SURFACEDATA_BLEND_SCALAR(surfaceData, specularOcclusion, weights);
surfaceData.normalWS = PROP_BLEND_NORMAL(surfaceData.normalWS, weights);
surfaceData.perceptualSmoothness = PROP_BLEND_SCALAR(surfaceData.perceptualSmoothness, weights);
surfaceData.ambientOcclusion = PROP_BLEND_SCALAR(surfaceData.ambientOcclusion, weights);
surfaceData.metallic = PROP_BLEND_SCALAR(surfaceData.metallic, weights);
surfaceData.normalWS = SURFACEDATA_BLEND_NORMAL(surfaceData, normalWS, weights);
surfaceData.perceptualSmoothness = SURFACEDATA_BLEND_SCALAR(surfaceData, perceptualSmoothness, weights);
surfaceData.ambientOcclusion = SURFACEDATA_BLEND_SCALAR(surfaceData, ambientOcclusion, weights);
surfaceData.metallic = SURFACEDATA_BLEND_SCALAR(surfaceData, metallic, weights);
// Init other unused parameter
surfaceData.materialId = 0;

20
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitSurfaceData.hlsl


void ADD_IDX(ComputeLayerTexCoord)(FragInput input, bool isTriplanar, inout LayerTexCoord outLayerTexCoord)
void ADD_IDX(ComputeLayerTexCoord)(FragInput input, bool isTriplanar, inout LayerTexCoord layerTexCoord)
{
// TODO: Do we want to manage local or world triplanar/planar
//float3 position = localTriplanar ? TransformWorldToObject(input.positionWS) : input.positionWS;

ADD_IDX(layerTexCoord.base).uv = ADD_IDX(_UVMappingMask).x * input.texCoord0 +
ADD_IDX(_UVMappingMask).y * input.texCoord1 +
ADD_IDX(_UVMappingMask).z * input.texCoord3 +
ADD_IDX(_UVMappingMask).w * positionWS.xz;
ADD_IDX(_UVMappingMask).w * position.xz;
ADD_IDX(_UVMappingMask).w * positionWS.xz;
ADD_IDX(_UVMappingMask).w * position.xz;
ADD_IDX(layerTexCoord.details).uv = TRANSFORM_TEX(uvDetails, ADD_IDX(_DetailMap));

ADD_IDX(layerTexCoord.base).uvYZ = position.yz;
ADD_IDX(layerTexCoord.base).uvZX = position.xy;
ADD_IDX(layerTexCoord.base).uvXY = position.xz;
ADD_IDX(layerTexCoord.base).uvZX = position.zx;
ADD_IDX(layerTexCoord.base).uvXY = position.xy;
ADD_IDX(layerTexCoord.details).isTriplanar = isTriplanar;
ADD_IDX(layerTexCoord.details).uvZX = TRANSFORM_TEX(position.xy, ADD_IDX(_DetailMap));
ADD_IDX(layerTexCoord.details).uvXY = TRANSFORM_TEX(position.xz, ADD_IDX(_DetailMap));
ADD_IDX(layerTexCoord.details).uvZX = TRANSFORM_TEX(position.zx, ADD_IDX(_DetailMap));
ADD_IDX(layerTexCoord.details).uvXY = TRANSFORM_TEX(position.xy, ADD_IDX(_DetailMap));
}
void ADD_IDX(ApplyDisplacement)(inout FragInput input, inout LayerTexCoord layerTexCoord)

float detailMask = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_DetailMask), ADD_ZERO_IDX(sampler_DetailMask), ADD_IDX(layerTexCoord.base)).b;
float2 detailAlbedoAndSmoothness = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_DetailMap), ADD_ZERO_IDX(sampler_DetailMap), ADD_IDX(layerTexCoord.details)).rb;
float detailAlbedo = detailAlbedoAndSmoothness.r;
float detailSmoothness = detailAlbedoAndSmoothness.b;
float detailSmoothness = detailAlbedoAndSmoothness.g;
float3 detailNormalTS = SAMPLE_LAYER_NORMALMAP_AG(ADD_IDX(_DetailMap), ADD_ZERO_IDX(sampler_DetailMap), ADD_IDX(layerTexCoord.details)).rb;
float3 detailNormalTS = SAMPLE_LAYER_NORMALMAP_AG(ADD_IDX(_DetailMap), ADD_ZERO_IDX(sampler_DetailMap), ADD_IDX(layerTexCoord.details));
//float detailAO = 0.0;
#else
// TODO: Use heightmap as a derivative with Morten Mikklesen approach, how this work with our abstraction and triplanar ?

2
Assets/ScriptableRenderLoop/ShaderLibrary/CommonMaterial.hlsl


blendWeights = (blendWeights - 0.2) * 7.0;
// Force weights to sum to 1.0 (very important!)
blendWeights = max(blendWeights, float3(0.0, 0.0, 0.0));
blendWeights /= dot(blendWeights.x, 1.0);
blendWeights /= dot(blendWeights, 1.0);
return blendWeights;
}

正在加载...
取消
保存