浏览代码

Merge pull request #110 from Unity-Technologies/LayeredLit

Added V2 of height base blend + inherit from base layer albedo option.
/main
GitHub 8 年前
当前提交
272bdc72
共有 8 个文件被更改,包括 404 次插入151 次删除
  1. 82
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/LayeredLit/Editor/LayeredLitUI.cs
  2. 42
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/LayeredLit/LayeredLit.shader
  3. 250
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LitData.hlsl
  4. 75
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LitDataInternal.hlsl
  5. 28
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LitProperties.hlsl
  6. 4
      Assets/ScriptableRenderLoop/ShaderLibrary/API/D3D11.hlsl
  7. 4
      Assets/ScriptableRenderLoop/ShaderLibrary/API/PSSL.hlsl
  8. 70
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LayeredLitNormalSampling.hlsl

82
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/LayeredLit/Editor/LayeredLitUI.cs


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.");
public readonly GUIContent heightCenterOffsetText = new GUIContent("Height Center Offset", "Offset applied to the center of the height of the layer.");
public readonly GUIContent useHeightBasedBlendV2Text = new GUIContent("Use Height Based Blend V2", "Layer will be blended with the underlying layer based on the height.");
public readonly GUIContent blendUsingHeight = new GUIContent("Blend Using Height", "Blend Layers using height.");
public readonly GUIContent inheritBaseNormalText = new GUIContent("Inherit Base Layer Normal", "Inherit the normal from the base layer.");
public readonly GUIContent inheritBaseHeightText = new GUIContent("Inherit Base Layer Height", "Inherit the height from the base layer.");
public readonly GUIContent inheritBaseColorText = new GUIContent("Inherit Base Layer Color", "Inherit the base color from the base layer.");
public readonly GUIContent inheritBaseColorThresholdText = new GUIContent("Threshold", "Inherit the base color from the base layer.");
public readonly GUIContent minimumOpacityText = new GUIContent("Minimum Opacity", "Minimum Opacity.");
public readonly GUIContent opacityAsDensityText = new GUIContent("Use Opacity as Density", "Use Opacity as Density.");
public StylesLayer()
{
layerLabelColors[1].normal.textColor = Color.red;

const string kUseHeightBasedBlend = "_UseHeightBasedBlend";
MaterialProperty useHeightBasedBlend = null;
const string kUseHeightBasedBlendV2 = "_UseHeightBasedBlendV2";
MaterialProperty useHeightBasedBlendV2 = null;
const string kBlendUsingHeight = "_BlendUsingHeight";
MaterialProperty[] blendUsingHeight = new MaterialProperty[kMaxLayerCount - 1];
const string kHeightOffset = "_HeightOffset";
MaterialProperty[] heightOffset = new MaterialProperty[kMaxLayerCount-1];
const string kInheritBaseLayer = "_InheritBaseLayer";

const string kHeightCenterOffset = "_HeightCenterOffset";
MaterialProperty[] heightCenterOffset = new MaterialProperty[kMaxLayerCount - 1];
// Height blend V2
const string kInheritBaseNormal = "_InheritBaseNormal";
MaterialProperty[] inheritBaseNormal = new MaterialProperty[kMaxLayerCount - 1];
const string kInheritBaseHeight = "_InheritBaseHeight";
MaterialProperty[] inheritBaseHeight = new MaterialProperty[kMaxLayerCount - 1];
const string kInheritBaseColor = "_InheritBaseColor";
MaterialProperty[] inheritBaseColor = new MaterialProperty[kMaxLayerCount - 1];
const string kInheritBaseColorThreshold = "_InheritBaseColorThreshold";
MaterialProperty[] inheritBaseColorThreshold = new MaterialProperty[kMaxLayerCount - 1];
const string kOpacityAsDensity = "_OpacityAsDensity";
MaterialProperty[] opacityAsDensity = new MaterialProperty[kMaxLayerCount - 1];
const string kMinimumOpacity = "_MinimumOpacity";
MaterialProperty[] minimumOpacity = new MaterialProperty[kMaxLayerCount - 1];
MaterialProperty layerEmissiveColor = null;
MaterialProperty layerEmissiveColorMap = null;
MaterialProperty layerEmissiveIntensity = null;

vertexColorHeightFactor = FindProperty(kVertexColorHeightFactor, props);
layerCount = FindProperty(kLayerCount, props);
useHeightBasedBlend = FindProperty(kUseHeightBasedBlend, props);
useHeightBasedBlendV2 = FindProperty(kUseHeightBasedBlendV2, props);
for (int i = 0; i < kMaxLayerCount; ++i)
{

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);
heightCenterOffset[i - 1] = FindProperty(string.Format("{0}{1}", kHeightCenterOffset, i), props);
blendUsingHeight[i - 1] = FindProperty(string.Format("{0}{1}", kBlendUsingHeight, i), props);
inheritBaseNormal[i - 1] = FindProperty(string.Format("{0}{1}", kInheritBaseNormal, i), props);
inheritBaseHeight[i - 1] = FindProperty(string.Format("{0}{1}", kInheritBaseHeight, i), props);
inheritBaseColor[i - 1] = FindProperty(string.Format("{0}{1}", kInheritBaseColor, i), props);
inheritBaseColorThreshold[i - 1] = FindProperty(string.Format("{0}{1}", kInheritBaseColorThreshold, i), props);
minimumOpacity[i - 1] = FindProperty(string.Format("{0}{1}", kMinimumOpacity, i), props);
opacityAsDensity[i - 1] = FindProperty(string.Format("{0}{1}", kOpacityAsDensity, i), props);
}
}

{
int heightParamIndex = layerIndex - 1;
m_MaterialEditor.ShaderProperty(inheritBaseLayer[heightParamIndex], styles.inheritBaseLayerText);
m_MaterialEditor.ShaderProperty(heightOffset[heightParamIndex], styles.heightOffsetText);
m_MaterialEditor.ShaderProperty(heightFactor[heightParamIndex], styles.heightFactorText);
m_MaterialEditor.ShaderProperty(blendSize[heightParamIndex], styles.blendSizeText);
if(useHeightBasedBlendV2.floatValue != 1.0f)
{
//m_MaterialEditor.ShaderProperty(inheritBaseLayer[heightParamIndex], styles.inheritBaseLayerText);
m_MaterialEditor.ShaderProperty(heightOffset[heightParamIndex], styles.heightOffsetText);
m_MaterialEditor.ShaderProperty(heightFactor[heightParamIndex], styles.heightFactorText);
m_MaterialEditor.ShaderProperty(blendSize[heightParamIndex], styles.blendSizeText);
m_MaterialEditor.ShaderProperty(inheritBaseColor[heightParamIndex], styles.inheritBaseColorText);
EditorGUI.indentLevel++;
m_MaterialEditor.ShaderProperty(inheritBaseColorThreshold[heightParamIndex], styles.inheritBaseColorThresholdText);
EditorGUI.indentLevel--;
m_MaterialEditor.ShaderProperty(inheritBaseNormal[heightParamIndex], styles.inheritBaseNormalText);
}
else
{
m_MaterialEditor.ShaderProperty(heightFactor[heightParamIndex], styles.heightFactorText);
m_MaterialEditor.ShaderProperty(heightCenterOffset[heightParamIndex], styles.heightCenterOffsetText);
m_MaterialEditor.ShaderProperty(blendUsingHeight[heightParamIndex], styles.blendUsingHeight);
m_MaterialEditor.ShaderProperty(inheritBaseColor[heightParamIndex], styles.inheritBaseColorText);
EditorGUI.indentLevel++;
m_MaterialEditor.ShaderProperty(inheritBaseColorThreshold[heightParamIndex], styles.inheritBaseColorThresholdText);
EditorGUI.indentLevel--;
m_MaterialEditor.ShaderProperty(inheritBaseNormal[heightParamIndex], styles.inheritBaseNormalText);
m_MaterialEditor.ShaderProperty(inheritBaseHeight[heightParamIndex], styles.inheritBaseHeightText);
m_MaterialEditor.ShaderProperty(opacityAsDensity[heightParamIndex], styles.opacityAsDensityText);
m_MaterialEditor.ShaderProperty(minimumOpacity[heightParamIndex], styles.minimumOpacityText);
}
}
}

}
if (enabled)
{
m_MaterialEditor.ShaderProperty(vertexColorHeightFactor, styles.vertexColorHeightMultiplierText);
EditorGUI.BeginChangeCheck();
bool enabledV2 = EditorGUILayout.Toggle(styles.useHeightBasedBlendV2Text, useHeightBasedBlendV2.floatValue > 0.0f);
if (EditorGUI.EndChangeCheck())
{
useHeightBasedBlendV2.floatValue = enabledV2 ? 1.0f : 0.0f;
}
if(!enabledV2)
m_MaterialEditor.ShaderProperty(vertexColorHeightFactor, styles.vertexColorHeightMultiplierText);
}
else
{

bool useHeightBasedBlend = material.GetFloat(kUseHeightBasedBlend) != 0.0f;
if(useHeightBasedBlend)
{
bool useHeightBasedBlendV2 = material.GetFloat(kUseHeightBasedBlendV2) != 0.0f;
SetKeyword(material, "_HEIGHT_BASED_BLEND_V2", useHeightBasedBlendV2);
}
else
{

42
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/LayeredLit/LayeredLit.shader


_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
_HeightFactor1("_HeightFactor1", Float) = 1
_HeightFactor2("_HeightFactor2", Float) = 1
_HeightFactor3("_HeightFactor3", Float) = 1
_BlendSize1("_BlendSize1", Range(0, 0.30)) = 0.0
_BlendSize2("_BlendSize2", Range(0, 0.30)) = 0.0

_InheritBaseLayer3("_InheritBaseLayer3", Range(0, 1.0)) = 0.0
_VertexColorHeightFactor("_VertexColorHeightFactor", Float) = 0.3
// Layer blending options V2
[ToggleOff] _UseHeightBasedBlendV2("Use Height Blend V2", Float) = 0.0
_HeightCenterOffset1("_HeightCenterOffset1", Float) = 0.0
_HeightCenterOffset2("_HeightCenterOffset2", Float) = 0.0
_HeightCenterOffset3("_HeightCenterOffset3", Float) = 0.0
_BlendUsingHeight1("_BlendUsingHeight1", Float) = 0.0
_BlendUsingHeight2("_BlendUsingHeight2", Float) = 0.0
_BlendUsingHeight3("_BlendUsingHeight3", Float) = 0.0
_InheritBaseNormal1("_InheritBaseNormal1", Range(0, 1.0)) = 0.0
_InheritBaseNormal2("_InheritBaseNormal2", Range(0, 1.0)) = 0.0
_InheritBaseNormal3("_InheritBaseNormal3", Range(0, 1.0)) = 0.0
_InheritBaseHeight1("_InheritBaseHeight1", Range(0, 1.0)) = 0.0
_InheritBaseHeight2("_InheritBaseHeight2", Range(0, 1.0)) = 0.0
_InheritBaseHeight3("_InheritBaseHeight3", Range(0, 1.0)) = 0.0
_InheritBaseColor1("_InheritBaseColor1", Range(0, 1.0)) = 0.0
_InheritBaseColor2("_InheritBaseColor2", Range(0, 1.0)) = 0.0
_InheritBaseColor3("_InheritBaseColor3", Range(0, 1.0)) = 0.0
_InheritBaseColorThreshold1("_InheritBaseColorThreshold1", Range(0, 1.0)) = 1.0
_InheritBaseColorThreshold2("_InheritBaseColorThreshold2", Range(0, 1.0)) = 1.0
_InheritBaseColorThreshold3("_InheritBaseColorThreshold3", Range(0, 1.0)) = 1.0
_MinimumOpacity1("_MinimumOpacity1", Range(0, 1.0)) = 1.0
_MinimumOpacity2("_MinimumOpacity2", Range(0, 1.0)) = 1.0
_MinimumOpacity3("_MinimumOpacity3", Range(0, 1.0)) = 1.0
_OpacityAsDensity1("_OpacityAsDensity1", Range(0, 1.0)) = 0.0
_OpacityAsDensity2("_OpacityAsDensity2", Range(0, 1.0)) = 0.0
_OpacityAsDensity3("_OpacityAsDensity3", Range(0, 1.0)) = 0.0
_DistortionVectorMap("DistortionVectorMap", 2D) = "black" {}

#pragma shader_feature _DETAIL_MAP
#pragma shader_feature _ _LAYER_MASK_VERTEX_COLOR_MUL _LAYER_MASK_VERTEX_COLOR_ADD
#pragma shader_feature _HEIGHT_BASED_BLEND
#pragma shader_feature _HEIGHT_BASED_BLEND_V2
#pragma shader_feature _ _LAYEREDLIT_3_LAYERS _LAYEREDLIT_4_LAYERS
#pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON

250
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LitData.hlsl


}
}
// TODO: Handle BC5 format, currently this code is for DXT5nm
// THis function below must call UnpackNormalmapRGorAG
float3 SampleLayerNormal(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV layerUV, float3 weights, float scale)
{
if (layerUV.isTriplanar)
{
float3 val = float3(0.0, 0.0, 0.0);
if (weights.x > 0.0)
val += weights.x * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvYZ), scale);
if (weights.y > 0.0)
val += weights.y * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvZX), scale);
if (weights.z > 0.0)
val += weights.z * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvXY), scale);
return normalize(val);
}
else
{
return UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uv), scale);
}
}
#define ADD_FUNC_SUFFIX(Name) Name
#define NORMAL_SAMPLE_FUNC(layerTex, layerSampler, layerUV, bias) SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV)
#include "LayeredLitNormalSampling.hlsl"
#undef ADD_FUNC_SUFFIX
#undef NORMAL_SAMPLE_FUNC
// This version is for normalmap with AG encoding only (use with details map)
float3 SampleLayerNormalAG(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV layerUV, float3 weights, float scale)
{
if (layerUV.isTriplanar)
{
float3 val = float3(0.0, 0.0, 0.0);
if (weights.x > 0.0)
val += weights.x * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvYZ), scale);
if (weights.y > 0.0)
val += weights.y * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvZX), scale);
if (weights.z > 0.0)
val += weights.z * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvXY), scale);
return normalize(val);
}
else
{
return UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uv), scale);
}
}
// This version is for normalmap with RGB encoding only, i.e non encoding. It is necessary to use this abstraction to handle correctly triplanar
// plus consistent with the normal scale parameter
float3 SampleLayerNormalRGB(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV layerUV, float3 weights, float scale)
{
if (layerUV.isTriplanar)
{
float3 val = float3(0.0, 0.0, 0.0);
if (weights.x > 0.0)
val += weights.x * UnpackNormalRGB(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvYZ), scale);
if (weights.y > 0.0)
val += weights.y * UnpackNormalRGB(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvZX), scale);
if (weights.z > 0.0)
val += weights.z * UnpackNormalRGB(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvXY), scale);
return normalize(val);
}
else
{
return UnpackNormalRGB(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uv), scale);
}
}
#define ADD_FUNC_SUFFIX(Name) Name##_Bias
#define NORMAL_SAMPLE_FUNC(layerTex, layerSampler, layerUV, bias) SAMPLE_TEXTURE2D_BIAS(layerTex, layerSampler, layerUV, bias)
#include "LayeredLitNormalSampling.hlsl"
#undef ADD_FUNC_SUFFIX
#undef NORMAL_SAMPLE_FUNC
#define SAMPLE_LAYER_NORMALMAP(textureName, samplerName, coord, scale) SampleLayerNormal(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights, scale)
#define SAMPLE_LAYER_NORMALMAP_AG(textureName, samplerName, coord, scale) SampleLayerNormalAG(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights, scale)
#define SAMPLE_LAYER_NORMALMAP_RGB(textureName, samplerName, coord, scale) SampleLayerNormalRGB(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights, scale)
#define SAMPLE_LAYER_NORMALMAP(textureName, samplerName, coord, scale, useBias, bias) useBias ? SampleLayerNormal_Bias(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights, scale, bias) : SampleLayerNormal(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights, scale, bias)
#define SAMPLE_LAYER_NORMALMAP_AG(textureName, samplerName, coord, scale, useBias, bias) useBias ? SampleLayerNormalAG_Bias(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights, scale, bias) : SampleLayerNormalAG(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights, scale, bias)
#define SAMPLE_LAYER_NORMALMAP_RGB(textureName, samplerName, coord, scale, useBias, bias) useBias ? SampleLayerNormalRGB_Bias(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights, scale, bias) : SampleLayerNormalRGB(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights, scale, bias)
#ifndef LAYERED_LIT_SHADER

return max(finalLayerHeight, previousLayerHeight);
}
float3 ApplyHeightBasedBlendV2(float3 inputMask, float3 inputHeight, float3 blendUsingHeight)
{
return saturate(lerp(inputMask * inputHeight * blendUsingHeight * 100, 1, inputMask * inputMask)); // 100 arbitrary scale to limit blendUsingHeight values.
}
#define SURFACEDATA_BLEND_COLOR(surfaceData, name, mask) BlendLayeredFloat3(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);

#endif
}
float3 ComputeInheritedNormalTS(float3 normalTS0, float3 normalTS1, float3 normalTS2, float3 normalTS3, LayerTexCoord layerTexCoord, float weights[_MAX_LAYER])
{
float3 normalTS;
//#if !defined(_HEIGHT_BASED_BLEND_V2)
// float _InheritBaseLayer0 = 1.0f; // Default value for lerp when all weights but base layer are zero.
//
// // Compute the combined inheritance factor of layers 1,2 and 3
// float inheritFactor = PROP_BLEND_SCALAR(_InheritBaseLayer, weights);
// float3 vertexNormalTS = float3(0.0, 0.0, 1.0);
// // The idea here is to lerp toward vertex normal. This way when we don't want to inherit, we will combine layer 1/2/3 normal with a vertex normal which is neutral.
// float3 baseLayerNormalTS = normalize(lerp(vertexNormalTS, normalTS0, inheritFactor));
// // Blend layer 1/2/3 normals before combining to the base layer. Again we need to have a neutral value for base layer (vertex normal) in case all weights are zero.
// float3 layersNormalTS = BlendLayeredFloat3(vertexNormalTS, normalTS1, normalTS2, normalTS3, weights);
// normalTS = BlendNormalRNM(baseLayerNormalTS, layersNormalTS);
//#else
// Compute how much we want to inherit from base layer normal base on the mask. Base layer always fully inherit from "itself" if it's the visible layer.
float inheritBaseNormal = BlendLayeredScalar(1.0f, _InheritBaseNormal1, _InheritBaseNormal2, _InheritBaseNormal3, weights);
// Based on this inheritance parameters, fetch a lower level of the base layer normal map so that the less we inherit the more this tends to be "vertex normal"
float maxMipBias = 12.0f; // We arbitrarly choose the max bias for a 2048 texture. Smaller texture will bias toward vertex normal faster.
float3 inheritedBaseNormalTS = GetNormalTS0(layerTexCoord, float3(0.0, 0.0, 0.0), 0.0f, true, maxMipBias * (1.0 - inheritBaseNormal));
// Blend all layers but the base one. This will then be added to the "inherited" normal of base layer (that's why base layer here is tangent space vertex normal so that if it's the visible layer we add nothing in term of normal map).
float3 layersNormalTS = BlendLayeredFloat3(float3(0.0, 0.0, 1.0), normalTS1, normalTS2, normalTS3, weights);
// Add the inherited normal to the blended top layers.
normalTS = BlendNormalRNM(inheritedBaseNormalTS, layersNormalTS);
//#endif
return normalTS;
}
float3 ComputeInheritedColor(float3 baseColor0, float3 baseColor1, float3 baseColor2, float3 baseColor3, float compoMask, LayerTexCoord layerTexCoord, float weights[_MAX_LAYER])
{
//return BlendLayeredFloat3(baseColor0, baseColor1, baseColor2, baseColor3, weights);
float inheritBaseColor = BlendLayeredScalar(1.0f, _InheritBaseColor1, _InheritBaseColor2, _InheritBaseColor3, weights);
float inheritBaseColorThreshold = BlendLayeredScalar(1.0f, _InheritBaseColorThreshold1, _InheritBaseColorThreshold2, _InheritBaseColorThreshold3, weights);
inheritBaseColor = inheritBaseColor * (1.0 - saturate(compoMask / inheritBaseColorThreshold));
float textureBias = 12.0f;
float3 baseMeanColor0 = SAMPLE_TEXTURE2D_BIAS(_BaseColorMap0, sampler_BaseColorMap0, layerTexCoord.base0.uv, textureBias).rgb * _BaseColor0.rgb;
float3 baseMeanColor1 = SAMPLE_TEXTURE2D_BIAS(_BaseColorMap1, sampler_BaseColorMap0, layerTexCoord.base1.uv, textureBias).rgb * _BaseColor1.rgb;
float3 baseMeanColor2 = SAMPLE_TEXTURE2D_BIAS(_BaseColorMap2, sampler_BaseColorMap0, layerTexCoord.base2.uv, textureBias).rgb * _BaseColor2.rgb;
float3 baseMeanColor3 = SAMPLE_TEXTURE2D_BIAS(_BaseColorMap3, sampler_BaseColorMap0, layerTexCoord.base3.uv, textureBias).rgb * _BaseColor3.rgb;
//float3 toto1 = lerp(baseMeanColor1, baseMeanColor0, _InheritBaseColor1) + baseColor1 - baseMeanColor1;
//float3 toto2 = lerp(baseMeanColor2, baseMeanColor0, _InheritBaseColor2) + baseColor2 - baseMeanColor2;
//float3 toto3 = lerp(baseMeanColor3, baseMeanColor0, _InheritBaseColor3) + baseColor3 - baseMeanColor3;
//return BlendLayeredFloat3(baseColor0, toto1, toto3, toto3, weights);
float3 meanColor = BlendLayeredFloat3(baseMeanColor0, baseMeanColor1, baseMeanColor2, baseMeanColor3, weights);
float3 baseColor = BlendLayeredFloat3(baseColor0, baseColor1, baseColor2, baseColor3, weights);
//return lerp(baseMeanColor1, baseColor0, _InheritBaseColor1) + (baseColor1 - baseMeanColor1);
return lerp(meanColor, baseColor0, inheritBaseColor) + (baseColor - meanColor);
}
void ComputeLayerWeights(FragInputs input, LayerTexCoord layerTexCoord, float4 inputAlphaMask, out float outWeights[_MAX_LAYER])
{
float height0 = SampleHeightmap0(layerTexCoord);
float height1 = SampleHeightmap1(layerTexCoord, _HeightCenterOffset1, _HeightFactor1);
float height2 = SampleHeightmap2(layerTexCoord, _HeightCenterOffset2, _HeightFactor2);
float height3 = SampleHeightmap3(layerTexCoord, _HeightCenterOffset3, _HeightFactor3);
float4 heights = float4(height0, height1, height2, height3);
// Mask Values : Layer 1, 2, 3 are r, g, b
float3 inputMaskValues = SAMPLE_TEXTURE2D(_LayerMaskMap, sampler_LayerMaskMap, input.texCoord0).rgb;
// Mutually exclusive with _HEIGHT_BASED_BLEND
#if defined(_LAYER_MASK_VERTEX_COLOR_MUL) // Used when no layer mask is set
inputMaskValues *= input.color.rgb;
#elif defined(_LAYER_MASK_VERTEX_COLOR_ADD) || defined(_HEIGHT_BASED_BLEND_V2) // When layer mask is set, color is additive to enable user to override it.
inputMaskValues = saturate(inputMaskValues + input.color.rgb * 2.0 - 1.0);
#endif
#if defined(_HEIGHT_BASED_BLEND)
#if !defined(_HEIGHT_BASED_BLEND_V2)
float baseLayerHeight = heights.x;
baseLayerHeight = ApplyHeightBasedBlend(inputMaskValues.r, baseLayerHeight, heights.y, _HeightOffset1, _HeightFactor1, _BlendSize1, input.color.r);
baseLayerHeight = ApplyHeightBasedBlend(inputMaskValues.g, baseLayerHeight, heights.z, _HeightOffset2 + _HeightOffset1, _HeightFactor2, _BlendSize2, input.color.g);
ApplyHeightBasedBlend(inputMaskValues.b, baseLayerHeight, heights.w, _HeightOffset3 + _HeightOffset2 + _HeightOffset1, _HeightFactor3, _BlendSize3, input.color.b);
#else
float3 minOpaParam = float3(_MinimumOpacity1, _MinimumOpacity2, _MinimumOpacity3);
float3 remapedOpacity = (float3(1.0, 1.0, 1.0) - minOpaParam) * inputAlphaMask.yzw + minOpaParam; // Remap opacity mask from [0..1] to [minOpa..1]
float3 opacityAsDensity = saturate((inputAlphaMask.yzw - (float3(1.0, 1.0, 1.0) - inputMaskValues))*20.0);
float3 useOpacityAsDensityParam = float3(_OpacityAsDensity1, _OpacityAsDensity2, _OpacityAsDensity3);
inputMaskValues = lerp(inputMaskValues * remapedOpacity, opacityAsDensity, useOpacityAsDensityParam);
// HACK, use height0 to avoid compiler error for unused sampler
// To remove once we have POM
heights.y += (heights.x * 0.0001);
inputMaskValues = ApplyHeightBasedBlendV2(inputMaskValues, heights.yzw, float3(_BlendUsingHeight1, _BlendUsingHeight2, _BlendUsingHeight3));
#endif
#endif
ComputeMaskWeights(inputMaskValues, outWeights);
//#if defined(_HEIGHT_BASED_BLEND_V2)
// float inheritBaseHeight = BlendLayeredScalar(0.0f, _InheritBaseHeight1, _InheritBaseHeight2, _InheritBaseHeight3, weights);
// float blendedLayerHeight = BlendLayeredScalar(heights.x, heights.y, heights.z, heights.w, weights);
// float finalHeight = heights.x * inheritBaseHeight + blendedLayerHeight;
// // Use this for POM/Tesselation
//#endif
}
void GetSurfaceAndBuiltinData(FragInputs input, float3 V, inout PositionInputs posInput, out SurfaceData surfaceData, out BuiltinData builtinData)
{
LayerTexCoord layerTexCoord;

ApplyPerPixelDisplacement(input, V, layerTexCoord);
float height0 = SampleHeightmap0(layerTexCoord);
float height1 = SampleHeightmap1(layerTexCoord);
float height2 = SampleHeightmap2(layerTexCoord);
float height3 = SampleHeightmap3(layerTexCoord);
SurfaceData surfaceData0;
SurfaceData surfaceData1;
SurfaceData surfaceData2;
SurfaceData surfaceData3;
float3 normalTS0;
float3 normalTS1;
float3 normalTS2;
float3 normalTS3;
SurfaceData surfaceData0, surfaceData1, surfaceData2, surfaceData3;
float3 normalTS0, normalTS1, normalTS2, normalTS3;
// Mask Values : Layer 1, 2, 3 are r, g, b
float3 maskValues = SAMPLE_TEXTURE2D(_LayerMaskMap, sampler_LayerMaskMap, input.texCoord0).rgb;
float weights[_MAX_LAYER];
ComputeLayerWeights(input, layerTexCoord, float4(alpha0, alpha1, alpha2, alpha3), weights);
// Mutually exclusive with _HEIGHT_BASED_BLEND
#if defined(_LAYER_MASK_VERTEX_COLOR_MUL) // Used when no layer mask is set
maskValues *= input.color.rgb;
#elif defined(_LAYER_MASK_VERTEX_COLOR_ADD) // When layer mask is set, color is additive to enable user to override it.
maskValues = saturate(maskValues + input.color.rgb * 2.0 - 1.0);
#endif
// For layered shader, alpha of base color is used as either an opacity mask, a composition mask for inheritance parameters or a density mask.
float alpha = PROP_BLEND_SCALAR(alpha, weights);
float baseLayerHeight = height0;
baseLayerHeight = ApplyHeightBasedBlend(maskValues.r, baseLayerHeight, height1, _HeightOffset1, _HeightFactor1, _BlendSize1, input.color.r);
baseLayerHeight = ApplyHeightBasedBlend(maskValues.g, baseLayerHeight, height2, _HeightOffset2 + _HeightOffset1, _HeightFactor2, _BlendSize2, input.color.g);
ApplyHeightBasedBlend(maskValues.b, baseLayerHeight, height3, _HeightOffset3 + _HeightOffset2 + _HeightOffset1, _HeightFactor3, _BlendSize3, input.color.b);
surfaceData.baseColor = ComputeInheritedColor(surfaceData0.baseColor, surfaceData1.baseColor, surfaceData2.baseColor, surfaceData3.baseColor, alpha, layerTexCoord, weights);
#else
surfaceData.baseColor = SURFACEDATA_BLEND_COLOR(surfaceData, baseColor, weights);
float weights[_MAX_LAYER];
ComputeMaskWeights(maskValues, weights);
surfaceData.baseColor = SURFACEDATA_BLEND_COLOR(surfaceData, baseColor, weights);
surfaceData.specularOcclusion = SURFACEDATA_BLEND_SCALAR(surfaceData, specularOcclusion, weights);
surfaceData.perceptualSmoothness = SURFACEDATA_BLEND_SCALAR(surfaceData, perceptualSmoothness, weights);
surfaceData.ambientOcclusion = SURFACEDATA_BLEND_SCALAR(surfaceData, ambientOcclusion, weights);

#if defined(_HEIGHT_BASED_BLEND)
float _InheritBaseLayer0 = 1.0f; // Default value for lerp when all weights but base layer are zero.
// Compute the combined inheritance factor of layers 1,2 and 3
float inheritFactor = PROP_BLEND_SCALAR(_InheritBaseLayer, weights);
float3 vertexNormalTS = float3(0.0, 0.0, 1.0);
// The idea here is to lerp toward vertex normal. This way when we don't want to inherit, we will combine layer 1/2/3 normal with a vertex normal which is neutral.
float3 baseLayerNormalTS = normalize(lerp(vertexNormalTS, normalTS0, inheritFactor));
// Blend layer 1/2/3 normals before combining to the base layer. Again we need to have a neutral value for base layer (vertex normal) in case all weights are zero.
float3 layersNormalTS = BlendLayeredFloat3(vertexNormalTS, normalTS1, normalTS2, normalTS3, weights);
normalTS = BlendNormalRNM(baseLayerNormalTS, layersNormalTS);
normalTS = ComputeInheritedNormalTS(normalTS0, normalTS1, normalTS2, normalTS3, layerTexCoord, weights);
surfaceData.normalWS = TransformTangentToWorld(normalTS, input.tangentToWorld);
surfaceData.tangentWS = input.tangentToWorld[0].xyz;

surfaceData.coatPerceptualSmoothness = 1.0;
surfaceData.specularColor = float3(0.0, 0.0, 0.0);
float alpha = PROP_BLEND_SCALAR(alpha, weights);
GetBuiltinData(input, surfaceData, alpha, depthOffset, builtinData);
}

75
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LitDataInternal.hlsl


ADD_IDX(layerTexCoord.details).uvXY = TRANSFORM_TEX(uvXY, ADD_IDX(_DetailMap));
}
float ADD_IDX(SampleHeightmap)(LayerTexCoord layerTexCoord)
float ADD_IDX(SampleHeightmap)(LayerTexCoord layerTexCoord, float centerOffset = 0.0f, float multiplier = 1.0f)
return (SAMPLE_TEXTURE2D(ADD_IDX(_HeightMap), ADD_ZERO_IDX(sampler_HeightMap), ADD_IDX(layerTexCoord.base).uv).r - ADD_IDX(_HeightCenter)) * ADD_IDX(_HeightAmplitude);
return (SAMPLE_TEXTURE2D(ADD_IDX(_HeightMap), ADD_ZERO_IDX(sampler_HeightMap), ADD_IDX(layerTexCoord.base).uv).r - ADD_IDX(_HeightCenter) - centerOffset) * ADD_IDX(_HeightAmplitude) * multiplier;
#else
return 0.0;
#endif

ADD_IDX(layerTexCoord.base).uv += offset;
}
float3 ADD_IDX(GetNormalTS)(LayerTexCoord layerTexCoord, float3 detailNormalTS, float detailMask, bool useBias, float bias)
{
float3 normalTS;
#ifdef _NORMALMAP
#ifdef _NORMALMAP_TANGENT_SPACE
normalTS = SAMPLE_LAYER_NORMALMAP(ADD_IDX(_NormalMap), ADD_ZERO_IDX(sampler_NormalMap), ADD_IDX(layerTexCoord.base), ADD_ZERO_IDX(_NormalScale), useBias, bias);
#else // Object space
float3 normalOS = SAMPLE_LAYER_NORMALMAP_RGB(ADD_IDX(_NormalMap), ADD_ZERO_IDX(sampler_NormalMap), ADD_IDX(layerTexCoord.base), ADD_ZERO_IDX(_NormalScale), useBias, bias).rgb;
normalTS = TransformObjectToTangent(normalOS, input.tangentToWorld);
#endif
#ifdef _DETAIL_MAP
normalTS = lerp(normalTS, BlendNormalRNM(normalTS, detailNormalTS), detailMask);
#endif
#else
normalTS = float3(0.0, 0.0, 1.0);
#endif
#if defined(_DOUBLESIDED_LIGHTING_FLIP) || defined(_DOUBLESIDED_LIGHTING_MIRROR)
#ifdef _DOUBLESIDED_LIGHTING_FLIP
float3 oppositeNormalTS = -normalTS;
#else
// Mirror the normal with the plane define by vertex normal
float3 oppositeNormalTS = reflect(normalTS, float3(0.0, 0.0, 1.0)); // Reflect around vertex normal (in tangent space this is z)
#endif
// TODO : Test if GetOddNegativeScale() is necessary here in case of normal map, as GetOddNegativeScale is take into account in CreateTangentToWorld();
normalTS = input.isFrontFace ?
(GetOddNegativeScale() >= 0.0 ? normalTS : oppositeNormalTS) :
(-GetOddNegativeScale() >= 0.0 ? normalTS : oppositeNormalTS);
#endif
return normalTS;
}
// Return opacity
float ADD_IDX(GetSurfaceData)(FragInputs input, LayerTexCoord layerTexCoord, out SurfaceData surfaceData, out float3 normalTS)
{

clip(alpha - _AlphaCutoff);
#endif
float3 detailNormalTS = float3(0.0, 0.0, 0.0);
float detailMask = 0.0;
float detailMask = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_DetailMask), ADD_ZERO_IDX(sampler_DetailMask), ADD_IDX(layerTexCoord.base)).b;
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.g;

float3 detailNormalTS = SAMPLE_LAYER_NORMALMAP_AG(ADD_IDX(_DetailMap), ADD_ZERO_IDX(sampler_DetailMap), ADD_IDX(layerTexCoord.details), ADD_ZERO_IDX(_DetailNormalScale));
detailNormalTS = SAMPLE_LAYER_NORMALMAP_AG(ADD_IDX(_DetailMap), ADD_ZERO_IDX(sampler_DetailMap), ADD_IDX(layerTexCoord.details), ADD_ZERO_IDX(_DetailNormalScale), false, 0.0f);
float3 detailNormalTS = float3(0.0, 0.0, 1.0);
detailNormalTS = float3(0.0, 0.0, 1.0);
//float detailAO = detail.b;
#endif
#endif

surfaceData.normalWS = float3(0.0, 0.0, 0.0); // Need to init this so that the compiler leaves us alone.
// TODO: think about using BC5
#ifdef _NORMALMAP
#ifdef _NORMALMAP_TANGENT_SPACE
normalTS = SAMPLE_LAYER_NORMALMAP(ADD_IDX(_NormalMap), ADD_ZERO_IDX(sampler_NormalMap), ADD_IDX(layerTexCoord.base), ADD_ZERO_IDX(_NormalScale));
#else // Object space
float3 normalOS = SAMPLE_LAYER_NORMALMAP_RGB(ADD_IDX(_NormalMap), ADD_ZERO_IDX(sampler_NormalMap), ADD_IDX(layerTexCoord.base), ADD_ZERO_IDX(_NormalScale)).rgb;
normalTS = TransformObjectToTangent(normalOS, input.tangentToWorld);
#endif
#ifdef _DETAIL_MAP
normalTS = lerp(normalTS, BlendNormalRNM(normalTS, detailNormalTS), detailMask);
#endif
#else
normalTS = float3(0.0, 0.0, 1.0);
#endif
#if defined(_DOUBLESIDED_LIGHTING_FLIP) || defined(_DOUBLESIDED_LIGHTING_MIRROR)
#ifdef _DOUBLESIDED_LIGHTING_FLIP
float3 oppositeNormalTS = -normalTS;
#else
// Mirror the normal with the plane define by vertex normal
float3 oppositeNormalTS = reflect(normalTS, float3(0.0, 0.0, 1.0)); // Reflect around vertex normal (in tangent space this is z)
#endif
// TODO : Test if GetOddNegativeScale() is necessary here in case of normal map, as GetOddNegativeScale is take into account in CreateTangentToWorld();
normalTS = input.isFrontFace ?
(GetOddNegativeScale() >= 0.0 ? normalTS : oppositeNormalTS) :
(-GetOddNegativeScale() >= 0.0 ? normalTS : oppositeNormalTS);
#endif
normalTS = ADD_IDX(GetNormalTS)(layerTexCoord, detailNormalTS, detailMask, false, 0.0f);
#ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
surfaceData.perceptualSmoothness = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_BaseColorMap), ADD_ZERO_IDX(sampler_BaseColorMap), ADD_IDX(layerTexCoord.base)).a;

28
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LitProperties.hlsl


float _InheritBaseLayer2;
float _InheritBaseLayer3;
// Blend Properties V2
float _UseHeightBasedBlendV2;
float _HeightCenterOffset1;
float _HeightCenterOffset2;
float _HeightCenterOffset3;
float _BlendUsingHeight1;
float _BlendUsingHeight2;
float _BlendUsingHeight3;
float _InheritBaseNormal1;
float _InheritBaseNormal2;
float _InheritBaseNormal3;
float _InheritBaseHeight1;
float _InheritBaseHeight2;
float _InheritBaseHeight3;
float _InheritBaseColor1;
float _InheritBaseColor2;
float _InheritBaseColor3;
float _InheritBaseColorThreshold1;
float _InheritBaseColorThreshold2;
float _InheritBaseColorThreshold3;
float _MinimumOpacity1;
float _MinimumOpacity2;
float _MinimumOpacity3;
float _OpacityAsDensity1;
float _OpacityAsDensity2;
float _OpacityAsDensity3;
float3 _EmissiveColor;
TEXTURE2D(_EmissiveColorMap);
SAMPLER2D(sampler_EmissiveColorMap);

4
Assets/ScriptableRenderLoop/ShaderLibrary/API/D3D11.hlsl


#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)
#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)
#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)
#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)
#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)
#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)
#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)
#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)
#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)

4
Assets/ScriptableRenderLoop/ShaderLibrary/API/PSSL.hlsl


#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)
#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)
#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)
#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)
#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)
#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)
#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)
#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)
#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)

70
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LayeredLitNormalSampling.hlsl


// TODO: Handle BC5 format, currently this code is for DXT5nm
// THis function below must call UnpackNormalmapRGorAG
float3 ADD_FUNC_SUFFIX(SampleLayerNormal)(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV layerUV, float3 weights, float scale, float bias)
{
if (layerUV.isTriplanar)
{
float3 val = float3(0.0, 0.0, 0.0);
if (weights.x > 0.0)
val += weights.x * UnpackNormalAG(NORMAL_SAMPLE_FUNC(layerTex, layerSampler, layerUV.uvYZ, bias), scale);
if (weights.y > 0.0)
val += weights.y * UnpackNormalAG(NORMAL_SAMPLE_FUNC(layerTex, layerSampler, layerUV.uvZX, bias), scale);
if (weights.z > 0.0)
val += weights.z * UnpackNormalAG(NORMAL_SAMPLE_FUNC(layerTex, layerSampler, layerUV.uvXY, bias), scale);
return normalize(val);
}
else
{
return UnpackNormalAG(NORMAL_SAMPLE_FUNC(layerTex, layerSampler, layerUV.uv, bias), scale);
}
}
// This version is for normalmap with AG encoding only (use with details map)
float3 ADD_FUNC_SUFFIX(SampleLayerNormalAG)(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV layerUV, float3 weights, float scale, float bias)
{
if (layerUV.isTriplanar)
{
float3 val = float3(0.0, 0.0, 0.0);
if (weights.x > 0.0)
val += weights.x * UnpackNormalAG(NORMAL_SAMPLE_FUNC(layerTex, layerSampler, layerUV.uvYZ, bias), scale);
if (weights.y > 0.0)
val += weights.y * UnpackNormalAG(NORMAL_SAMPLE_FUNC(layerTex, layerSampler, layerUV.uvZX, bias), scale);
if (weights.z > 0.0)
val += weights.z * UnpackNormalAG(NORMAL_SAMPLE_FUNC(layerTex, layerSampler, layerUV.uvXY, bias), scale);
return normalize(val);
}
else
{
return UnpackNormalAG(NORMAL_SAMPLE_FUNC(layerTex, layerSampler, layerUV.uv, bias), scale);
}
}
// This version is for normalmap with RGB encoding only, i.e non encoding. It is necessary to use this abstraction to handle correctly triplanar
// plus consistent with the normal scale parameter
float3 ADD_FUNC_SUFFIX(SampleLayerNormalRGB)(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV layerUV, float3 weights, float scale, float bias)
{
if (layerUV.isTriplanar)
{
float3 val = float3(0.0, 0.0, 0.0);
if (weights.x > 0.0)
val += weights.x * UnpackNormalRGB(NORMAL_SAMPLE_FUNC(layerTex, layerSampler, layerUV.uvYZ, bias), scale);
if (weights.y > 0.0)
val += weights.y * UnpackNormalRGB(NORMAL_SAMPLE_FUNC(layerTex, layerSampler, layerUV.uvZX, bias), scale);
if (weights.z > 0.0)
val += weights.z * UnpackNormalRGB(NORMAL_SAMPLE_FUNC(layerTex, layerSampler, layerUV.uvXY, bias), scale);
return normalize(val);
}
else
{
return UnpackNormalRGB(NORMAL_SAMPLE_FUNC(layerTex, layerSampler, layerUV.uv, bias), scale);
}
}
正在加载...
取消
保存