浏览代码

Merge pull request #65 from Unity-Technologies/LayeredLit

First version of Layered Lit shader height based blending.
/main
GitHub 8 年前
当前提交
8760c4f3
共有 4 个文件被更改,包括 143 次插入31 次删除
  1. 49
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/LayeredLit/Editor/LayeredLitUI.cs
  2. 30
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/LayeredLit/LayeredLit.shader
  3. 43
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitData.hlsl
  4. 52
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitSurfaceData.hlsl

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


public readonly GUIContent layerTexWorldScaleText = new GUIContent("Tiling", "Tiling factor applied to Planar/Trilinear mapping");
public readonly GUIContent UVBaseText = new GUIContent("Base UV Mapping", "Base UV Mapping mode of the layer.");
public readonly GUIContent UVDetailText = new GUIContent("Detail UV Mapping", "Detail UV Mapping mode of the layer.");
public readonly GUIContent useHeightBasedBlendText = new GUIContent("Use Height Based Blend", "Layer will be blended with the underlying layer based on the height.");
public readonly GUIContent heightOffsetText = new GUIContent("HeightOffset", "Height offset from the previous layer.");
public readonly GUIContent heightFactorText = new GUIContent("Height Multiplier", "Scale applied to the height of the layer.");
public readonly GUIContent blendSizeText = new GUIContent("Blend Size", "Thickness over which the layer will be blended with the previous one.");
}
static StylesLayer s_Styles = null;

MaterialProperty[] layerUVDetail = new MaterialProperty[kMaxLayerCount];
MaterialProperty[] layerUVDetailsMappingMask = new MaterialProperty[kMaxLayerCount];
const string kUseHeightBasedBlend = "_UseHeightBasedBlend";
MaterialProperty[] useHeightBasedBlend = new MaterialProperty[kMaxLayerCount-1];
const string kHeightOffset = "_HeightOffset";
MaterialProperty[] heightOffset = new MaterialProperty[kMaxLayerCount-1];
const string kHeightFactor = "_HeightFactor";
MaterialProperty[] heightFactor = new MaterialProperty[kMaxLayerCount-1];
const string kBlendSize = "_BlendSize";
MaterialProperty[] blendSize = new MaterialProperty[kMaxLayerCount-1];
MaterialProperty layerEmissiveColor = null;
MaterialProperty layerEmissiveColorMap = null;
MaterialProperty layerEmissiveIntensity = null;

layerUVMappingPlanar[i] = FindProperty(string.Format("{0}{1}", kUVMappingPlanar, i), props);
layerUVDetail[i] = FindProperty(string.Format("{0}{1}", kUVDetail, i), props);
layerUVDetailsMappingMask[i] = FindProperty(string.Format("{0}{1}", kUVDetailsMappingMask, i), props);
if(i != 0)
{
useHeightBasedBlend[i-1] = FindProperty(string.Format("{0}{1}", kUseHeightBasedBlend, i), props);
heightOffset[i-1] = FindProperty(string.Format("{0}{1}", kHeightOffset, i), props);
heightFactor[i-1] = FindProperty(string.Format("{0}{1}", kHeightFactor, i), props);
blendSize[i-1] = FindProperty(string.Format("{0}{1}", kBlendSize, i), props);
}
}
layerEmissiveColor = FindProperty(kEmissiveColor, props);

void SynchronizeLayerProperties(int layerIndex)
{
string[] exclusionList = { kTexWorldScale, kUVBase, kUVMappingMask, kUVDetail, kUVDetailsMappingMask };
string[] exclusionList = { kTexWorldScale, kUVBase, kUVMappingMask, kUVDetail, kUVMappingPlanar, kUVDetailsMappingMask };
Material material = m_MaterialEditor.target as Material;
Material layerMaterial = m_MaterialLayers[layerIndex];

}
}
if(layerIndex > 0)
{
int heightParamIndex = layerIndex - 1;
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = useHeightBasedBlend[heightParamIndex].hasMixedValue;
bool enabled = EditorGUILayout.Toggle(styles.useHeightBasedBlendText, useHeightBasedBlend[heightParamIndex].floatValue > 0.0f);
if(EditorGUI.EndChangeCheck())
{
useHeightBasedBlend[heightParamIndex].floatValue = enabled ? 1.0f : 0.0f;
}
if(enabled)
{
m_MaterialEditor.ShaderProperty(heightOffset[heightParamIndex], styles.heightOffsetText);
m_MaterialEditor.ShaderProperty(heightFactor[heightParamIndex], styles.heightFactorText);
m_MaterialEditor.ShaderProperty(blendSize[heightParamIndex], styles.blendSizeText);
}
}
EditorGUI.indentLevel--;
return result;

}
m_MaterialEditor.serializedObject.ApplyModifiedProperties();
if (layerChanged)
{
materialImporter.SaveAndReimport();
}
}
}
} // namespace UnityEditor

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


_LayerMaskMap("LayerMaskMap", 2D) = "white" {}
[ToggleOff] _LayerMaskVertexColor("Use Vertex Color Mask", Float) = 0.0
// Height based blend (layer 0 does not need it)
_UseHeightBasedBlend1("UseHeightBasedBlend1", Float) = 0.0
_UseHeightBasedBlend2("UseHeightBasedBlend2", Float) = 0.0
_UseHeightBasedBlend3("UseHeightBasedBlend3", Float) = 0.0
_HeightOffset1("_HeightOffset1", Range(-0.3, 0.3)) = 0.0
_HeightOffset2("_HeightOffset2", Range(-0.3, 0.3)) = 0.0
_HeightOffset3("_HeightOffset3", Range(-0.3, 0.3)) = 0.0
_HeightFactor1("_HeightFactor1", Range(0, 5)) = 1
_HeightFactor2("_HeightFactor2", Range(0, 5)) = 1
_HeightFactor3("_HeightFactor3", Range(0, 5)) = 1
_BlendSize1("_BlendSize1", Range(0, 0.05)) = 0.0
_BlendSize2("_BlendSize2", Range(0, 0.05)) = 0.0
_BlendSize3("_BlendSize3", Range(0, 0.05)) = 0.0
_DistortionVectorMap("DistortionVectorMap", 2D) = "black" {}
_EmissiveColor("EmissiveColor", Color) = (0, 0, 0)

TEXTURE2D(_LayerMaskMap);
SAMPLER2D(sampler_LayerMaskMap);
float _UseHeightBasedBlend1;
float _UseHeightBasedBlend2;
float _UseHeightBasedBlend3;
float _HeightOffset1;
float _HeightOffset2;
float _HeightOffset3;
float _HeightFactor1;
float _HeightFactor2;
float _HeightFactor3;
float _BlendSize1;
float _BlendSize2;
float _BlendSize3;
float3 _EmissiveColor;
TEXTURE2D(_EmissiveColorMap);

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


return result;
}
float ApplyHeightBasedBlend(inout float inputFactor, float previousLayerHeight, float layerHeight, float heightOffset, float heightFactor, float edgeBlendStrength)
{
float finalLayerHeight = layerHeight * heightFactor + heightOffset;
edgeBlendStrength = max(0.001, edgeBlendStrength);
float heightThreshold = previousLayerHeight + edgeBlendStrength;
if (previousLayerHeight >= finalLayerHeight)
{
inputFactor = 0.0;
}
else if (finalLayerHeight > previousLayerHeight && finalLayerHeight < previousLayerHeight + edgeBlendStrength)
{
inputFactor = inputFactor * pow((finalLayerHeight - previousLayerHeight) / edgeBlendStrength, 0.5);
}
return max(finalLayerHeight, previousLayerHeight);
}
#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);

// Transform view vector in tangent space
float3 viewDirTS = TransformWorldToTangent(V, input.tangentToWorld);
ApplyDisplacement0(input, viewDirTS, layerTexCoord);
ApplyDisplacement1(input, viewDirTS, layerTexCoord);
ApplyDisplacement2(input, viewDirTS, layerTexCoord);
ApplyDisplacement3(input, viewDirTS, layerTexCoord);
float height0 = ApplyDisplacement0(input, viewDirTS, layerTexCoord);
float height1 = ApplyDisplacement1(input, viewDirTS, layerTexCoord);
float height2 = ApplyDisplacement2(input, viewDirTS, layerTexCoord);
float height3 = ApplyDisplacement3(input, viewDirTS, layerTexCoord);
float depthOffset = 0.0;
#ifdef _DEPTHOFFSET_ON

#if defined(_LAYER_MASK_VERTEX_COLOR)
maskValues *= input.vertexColor.rgb;
#endif
float baseLayerHeight = height0;
if (_UseHeightBasedBlend1 > 0.0f)
{
baseLayerHeight = ApplyHeightBasedBlend(maskValues.r, baseLayerHeight, height1, _HeightOffset1, _HeightFactor1, _BlendSize1);
}
if (_UseHeightBasedBlend2 > 0.0f)
{
baseLayerHeight = ApplyHeightBasedBlend(maskValues.g, baseLayerHeight, height2, _HeightOffset2 + _HeightOffset1, _HeightFactor2, _BlendSize2);
}
if (_UseHeightBasedBlend3 > 0.0f)
{
ApplyHeightBasedBlend(maskValues.b, baseLayerHeight, height3, _HeightOffset3 + _HeightOffset2 + _HeightOffset1, _HeightFactor3, _BlendSize3);
}
float weights[_MAX_LAYER];
ComputeMaskWeights(maskValues, weights);

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


ADD_IDX(layerTexCoord.details).uvXY = TRANSFORM_TEX(uvXY, ADD_IDX(_DetailMap));
}
void ADD_IDX(ApplyDisplacement)(inout FragInputs input, float3 viewDirTS, inout LayerTexCoord layerTexCoord)
float ADD_IDX(ApplyDisplacement)(inout FragInputs input, float3 viewDirTS, inout LayerTexCoord layerTexCoord)
float height = 0.0f;
#ifndef _HEIGHTMAP_AS_DISPLACEMENT
float height = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_HeightMap), ADD_ZERO_IDX(sampler_HeightMap), ADD_IDX(layerTexCoord.base)).r * ADD_IDX(_HeightScale) + ADD_IDX(_HeightBias);
float2 offset = ParallaxOffset(viewDirTS, height);
height = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_HeightMap), ADD_ZERO_IDX(sampler_HeightMap), ADD_IDX(layerTexCoord.base)).r * ADD_IDX(_HeightScale) + ADD_IDX(_HeightBias);
ADD_IDX(layerTexCoord.base).uv += offset;
ADD_IDX(layerTexCoord.base).uvYZ += offset;
ADD_IDX(layerTexCoord.base).uvZX += offset;
ADD_IDX(layerTexCoord.base).uvXY += offset;
//#ifndef _HEIGHTMAP_AS_DISPLACEMENT
// //height = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_HeightMap), ADD_ZERO_IDX(sampler_HeightMap), ADD_IDX(layerTexCoord.base)).r * ADD_IDX(_HeightScale) + ADD_IDX(_HeightBias);
// float2 offset = ParallaxOffset(viewDirTS, height);
ADD_IDX(layerTexCoord.details).uv += offset;
ADD_IDX(layerTexCoord.details).uvYZ += offset;
ADD_IDX(layerTexCoord.details).uvZX += offset;
ADD_IDX(layerTexCoord.details).uvXY += offset;
// ADD_IDX(layerTexCoord.base).uv += offset;
// ADD_IDX(layerTexCoord.base).uvYZ += offset;
// ADD_IDX(layerTexCoord.base).uvZX += offset;
// ADD_IDX(layerTexCoord.base).uvXY += offset;
// Only modify texcoord for first layer, this will be use by for builtin data (like lightmap)
if (LAYER_INDEX == 0)
{
input.texCoord0 += offset;
input.texCoord1 += offset;
input.texCoord2 += offset;
input.texCoord3 += offset;
}
#endif
// ADD_IDX(layerTexCoord.details).uv += offset;
// ADD_IDX(layerTexCoord.details).uvYZ += offset;
// ADD_IDX(layerTexCoord.details).uvZX += offset;
// ADD_IDX(layerTexCoord.details).uvXY += offset;
// // Only modify texcoord for first layer, this will be use by for builtin data (like lightmap)
// if (LAYER_INDEX == 0)
// {
// input.texCoord0 += offset;
// input.texCoord1 += offset;
// input.texCoord2 += offset;
// input.texCoord3 += offset;
// }
// // Need to refetch for the right parallaxed height for layer blending to behave correctly...
// height = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_HeightMap), ADD_ZERO_IDX(sampler_HeightMap), ADD_IDX(layerTexCoord.base)).r * ADD_IDX(_HeightScale) + ADD_IDX(_HeightBias);
// #endif
return height;
}
// Return opacity

正在加载...
取消
保存