浏览代码

Add support for triplanar + handle local/world space

/main
sebastienlagarde 7 年前
当前提交
44ad647c
共有 4 个文件被更改,包括 124 次插入62 次删除
  1. 42
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/StackLit/StackLitUI.cs
  2. 18
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLit.shader
  3. 125
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLitData.hlsl
  4. 1
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLitProperties.hlsl

42
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/StackLit/StackLitUI.cs


{
class StackLitGUI : BaseMaterialGUI
{
protected static class StylesStackLit
{
public static GUIContent useLocalPlanarMapping = new GUIContent("Use Local Planar Mapping", "Use local space for planar/triplanar mapping instead of world space");
};
#region Strings
protected const string k_DoubleSidedNormalMode = "_DoubleSidedNormalMode";

//protected const string kRefractionModel = "_RefractionModel";
//protected MaterialProperty refractionSSRayModel = null;
//protected const string kRefractionSSRayModel = "_RefractionSSRayModel";
protected MaterialProperty useLocalPlanarMapping = null;
protected const string k_UseLocalPlanarMapping = "_UseLocalPlanarMapping";
#endregion
// Add the properties into an array.

_baseMaterialProperties = new GroupProperty(this, "_BaseMaterial", new BaseProperty[]
{
// JFFTODO: Find the proper condition, and proper way to display this.
new Property(this, k_DoubleSidedNormalMode, "Normal mode", "This will modify the normal base on the selected mode. Mirror: Mirror the normal with vertex normal plane, Flip: Flip the normal.", false),
new Property(this, k_DoubleSidedNormalMode, "Normal mode", "This will modify the normal base on the selected mode. Mirror: Mirror the normal with vertex normal plane, Flip: Flip the normal.", false),
});
_materialProperties = new GroupProperty(this, "_Material", new BaseProperty[]

new TextureProperty(this, k_BaseColorMap, k_BaseColor, "Base Color + Opacity", "Albedo (RGB) and Opacity (A)", true, false),
new TextureProperty(this, k_MetallicMap, k_Metallic, "Metallic", "Metallic", false, false),
new TextureProperty(this, k_MetallicMap, k_Metallic, "Metallic", "Metallic", false, false),
new TextureProperty(this, k_Smoothness1Map, k_Smoothness1, "Smoothness", "Smoothness", false, false),
// TODO: Special case for normal maps.
new TextureProperty(this, k_NormalMap, k_NormalScale, "Normal TODO", "Normal Map", false, false, true),

new GroupProperty(this, "_Lobe2", "Second Specular Lobe", new BaseProperty[]
{
new TextureProperty(this, k_Smoothness2Map, k_Smoothness2, "Smoothness2", "Smoothness2", false, false),
new Property(this, k_LobeMix, "Lobe Mix", "Lobe Mix", false),
new Property(this, k_LobeMix, "Lobe Mix", "Lobe Mix", false),
}),
//new GroupProperty(this, "_Anisotropy", "Anisotropy", new BaseProperty[]

protected override void FindMaterialProperties(MaterialProperty[] props)
{
//base.FindMaterialProperties(props);
useLocalPlanarMapping = FindProperty(k_UseLocalPlanarMapping, props);
}
}
m_MaterialEditor.ShaderProperty(useLocalPlanarMapping, StylesStackLit.useLocalPlanarMapping);
_baseMaterialProperties.OnGUI();
}

}
}
//NOTE: For SSS in forward and split lighting, obviously we don't have a gbuffer pass,
//NOTE: For SSS in forward and split lighting, obviously we don't have a gbuffer pass,
// so no stencil tagging there, but velocity? To check...
//TODO: stencil state, displacement, wind, depthoffset, tessellation

bool requireUv2 = false;
bool requireUv3 = false;
bool requireTriplanar = false;
requireTriplanar = requireTriplanar || uvIndices[i] == TextureProperty.UVMapping.Triplanar;
if (requireUv2)
{
material.EnableKeyword("_REQUIRE_UV2");
}
else
{
material.DisableKeyword("_REQUIRE_UV2");
}
if (requireUv3)
{
material.EnableKeyword("_REQUIRE_UV3");
}
else
{
material.DisableKeyword("_REQUIRE_UV3");
}
CoreUtils.SetKeyword(material, "_USE_UV2", requireUv2);
CoreUtils.SetKeyword(material, "_USE_UV3", requireUv3);
CoreUtils.SetKeyword(material, "_USE_TRIPLANAR", requireTriplanar);
}
}
} // namespace UnityEditor

18
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLit.shader


_AlphaCutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5
_TransparentSortPriority("_TransparentSortPriority", Float) = 0
// global control
[ToggleUI] _UseLocalPlanarMapping("Use Local Planar Mapping", Float) = 0.0
// Stencil state
[HideInInspector] _StencilRef("_StencilRef", Int) = 2 // StencilLightingUsage.RegularLighting (fixed at compile time)

[ToggleUI] _EnableFogOnTransparent("Enable Fog", Float) = 1.0
[ToggleUI] _EnableBlendModePreserveSpecularLighting("Enable Blend Mode Preserve Specular Lighting", Float) = 1.0
[ToggleUI] _DoubleSidedEnable("Double sided enable", Float) = 0.0
[Enum(Flip, 0, Mirror, 1, None, 2)] _DoubleSidedNormalMode("Double sided normal mode", Float) = 1 // This is for the editor only, see BaseLitUI.cs: _DoubleSidedConstants will be set based on the mode.
[HideInInspector] _DoubleSidedConstants("_DoubleSidedConstants", Vector) = (1, 1, -1, 0)

#pragma shader_feature _DOUBLESIDED_ON
#pragma shader_feature _NORMALMAP_TANGENT_SPACE
#pragma shader_feature _ _REQUIRE_UV2 _REQUIRE_UV3
// ...TODO: for surface gradient framework eg see litdata.hlsl,
// but we need it right away for toggle with LayerTexCoord mapping so we might need them
#pragma shader_feature _USE_UV2
#pragma shader_feature _USE_UV3
#pragma shader_feature _USE_TRIPLANAR
// ...TODO: for surface gradient framework eg see litdata.hlsl,
// but we need it right away for toggle with LayerTexCoord mapping so we might need them
// from the Frag input right away. See also ShaderPass/StackLitSharePass.hlsl.
#pragma shader_feature _NORMALMAP

#pragma shader_feature _ _BLENDMODE_ALPHA _BLENDMODE_ADD _BLENDMODE_PRE_MULTIPLY
#pragma shader_feature _BLENDMODE_PRESERVE_SPECULAR_LIGHTING // easily handled in material.hlsl, so adding this already.
#pragma shader_feature _ENABLE_FOG_ON_TRANSPARENT
//enable GPU instancing support
#pragma multi_compile_instancing

ZWrite [_ZWrite]
Cull [_CullModeForward]
//
// NOTE: For _CullModeForward, see BaseLitUI and the handling of TransparentBackfaceEnable:
// NOTE: For _CullModeForward, see BaseLitUI and the handling of TransparentBackfaceEnable:
// Basically, we need to use it to support a TransparentBackface pass before this pass
// (and it should be placed just before this one) for separate backface and frontface rendering,
// eg for "hair shader style" approximate sorting, see eg Thorsten Scheuermann writeups on this:

//
// See Lit.shader and the order of the passes after a DistortionVectors, we have:
// See Lit.shader and the order of the passes after a DistortionVectors, we have:
// TransparentDepthPrepass, TransparentBackface, Forward, TransparentDepthPostpass
HLSLPROGRAM

125
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLitData.hlsl


#include "../MaterialUtilities.hlsl"
////-----------------------------------------------------------------------------
//// Texture Mapping (think of LayerTexCoord as simply TexCoordMappings,
//// Texture Mapping (think of LayerTexCoord as simply TexCoordMappings,
//// ie no more layers here - cf Lit materials)
////-----------------------------------------------------------------------------
//

////
//// NEWLITTODO: Eventually, we could quickly share GetBuiltinData of LitBuiltinData.hlsl
//// NEWLITTODO: Eventually, we could quickly share GetBuiltinData of LitBuiltinData.hlsl
//// in our GetSurfaceAndBuiltinData( ) here, since we will use the LayerTexCoord identifier,
//// and an identical ComputeLayerTexCoord( ) prototype
////

//};
//
//// Want to use only one sampler for normalmap/bentnormalmap either we use OS or TS. And either we have normal map or bent normal or both.
////
//// Note (compared to Lit shader):
//// We don't have a layered material with which we are sharing code here like the LayeredLit shader, but we can also save a couple of
//// Note (compared to Lit shader):
////
//// We don't have a layered material with which we are sharing code here like the LayeredLit shader, but we can also save a couple of
//// _IDX suffix is meaningless here, could use the name SAMPLER_NORMALMAP_ID instead of SAMPLER_NORMALMAP_IDX and replace all
//// indirect #ifdef _NORMALMAP_TANGENT_SPACE_IDX #ifdef and _NORMALMAP_IDX tests with the more direct
//// _IDX suffix is meaningless here, could use the name SAMPLER_NORMALMAP_ID instead of SAMPLER_NORMALMAP_IDX and replace all
//// indirect #ifdef _NORMALMAP_TANGENT_SPACE_IDX #ifdef and _NORMALMAP_IDX tests with the more direct
//// shader_feature keywords _NORMALMAP_TANGENT_SPACE and _NORMALMAP.
////
//// (Originally in the LayeredLit shader, shader_feature keywords like _NORMALMAP become _NORMALMAP0 but since files are shared,

float3 normalTS;
// Note we don't use the _NORMALMAP_IDX mechanism of the Lit shader, since we don't have "layers", we can
// Note we don't use the _NORMALMAP_IDX mechanism of the Lit shader, since we don't have "layers", we can
normalTS = SAMPLE_UVMAPPING_NORMALMAP(_NormalMap, SAMPLER_NORMALMAP_ID, texCoord, _NormalScale);
normalTS = float3(0.0, 0.0, 1.0); //normalTS = SAMPLE_UVMAPPING_NORMALMAP(_NormalMap, SAMPLER_NORMALMAP_ID, texCoord, _NormalScale);
#else
normalTS = float3(0.0, 0.0, 1.0);
#endif

//-----------------------------------------------------------------------------
// ...Texture Mapping
// Texture Mapping
//-----------------------------------------------------------------------------
#define TEXCOORD_INDEX_UV0 (0)

#define TEXCOORD_INDEX_PLANAR_YZ (5)
#define TEXCOORD_INDEX_PLANAR_ZX (6)
#define TEXCOORD_INDEX_TRIPLANAR (7)
#define TEXCOORD_INDEX_COUNT (8)
#define TEXCOORD_INDEX_COUNT (TEXCOORD_INDEX_TRIPLANAR) // Triplanar is not consider as having mapping
// If we use triplanar on any of the properties, then we enable the triplanar path
#ifdef _USE_TRIPLANAR
float4 SampleTexture2DTriplanar(TEXTURE2D_ARGS(textureName, samplerName), float textureNameUV, float4 textureNameST, float2 texcoords[TEXCOORD_INDEX_COUNT], float3 triplanarWeights)
{
if (textureNameUV == TEXCOORD_INDEX_TRIPLANAR)
{
float4 val = float4(0.0, 0.0, 0.0, 0.0);
if (triplanarWeights.x > 0.0)
val += triplanarWeights.x * SAMPLE_TEXTURE2D(textureName, samplerName, (texcoords[TEXCOORD_INDEX_PLANAR_YZ] * textureNameST.xy + textureNameST.zw));
if (triplanarWeights.y > 0.0)
val += triplanarWeights.y * SAMPLE_TEXTURE2D(textureName, samplerName, (texcoords[TEXCOORD_INDEX_PLANAR_ZX] * textureNameST.xy + textureNameST.zw));
if (triplanarWeights.z > 0.0)
val += triplanarWeights.z * SAMPLE_TEXTURE2D(textureName, samplerName, (texcoords[TEXCOORD_INDEX_PLANAR_XY] * textureNameST.xy + textureNameST.zw));
return val;
}
else
{
return SAMPLE_TEXTURE2D(textureName, samplerName, (texcoords[textureNameUV] * textureNameST.xy + textureNameST.zw));
}
}
#define SAMPLE_TEXTURE2D_SCALE_BIAS(name) SampleTexture2DTriplanar(name, sampler##name, name##UV, name##_ST, texcoords, triplanarWeights)
#else
#define SAMPLE_TEXTURE2D_SCALE_BIAS(name) SAMPLE_TEXTURE2D(name, sampler##name, (texcoords[name##UV] * name##_ST.xy + name##_ST.zw))
#endif // _USE_TRIPLANAR
void InitializeMappingData(FragInputs input, out float2 texcoords[TEXCOORD_INDEX_COUNT], out float3 triplanarWeights)
{
float3 position = GetAbsolutePositionWS(input.positionWS);
// If we use local planar mapping, convert to local space
position = _UseLocalPlanarMapping ? TransformWorldToObject(position) : position;
// planar/triplanar
float2 uvXZ;
float2 uvXY;
float2 uvZY;
GetTriplanarCoordinate(position, uvXZ, uvXY, uvZY);
#ifdef _USE_TRIPLANAR
float3 vertexNormal = input.worldToTangent[2].xyz; // normal in WS
vertexNormal = _UseLocalPlanarMapping ? TransformWorldToObjectDir(vertexNormal) : vertexNormal;
triplanarWeights = ComputeTriplanarWeights(vertexNormal);
#else
triplanarWeights = float3(0.0, 0.0, 0.0);
#endif
// Build the texcoords array.
texcoords[TEXCOORD_INDEX_UV0] = input.texCoord0;
texcoords[TEXCOORD_INDEX_UV1] = input.texCoord1;
#ifdef _USE_UV2
texcoords[TEXCOORD_INDEX_UV2] = input.texCoord2;
#else
texcoords[TEXCOORD_INDEX_UV2] = float2(0.0, 0.0);
#endif
#ifdef _USE_UV3
texcoords[TEXCOORD_INDEX_UV3] = input.texCoord3;
#else
texcoords[TEXCOORD_INDEX_UV3] = float2(0.0, 0.0);
#endif
texcoords[TEXCOORD_INDEX_PLANAR_XY] = uvXY;
texcoords[TEXCOORD_INDEX_PLANAR_YZ] = uvZY;
texcoords[TEXCOORD_INDEX_PLANAR_ZX] = uvXZ;
}
#define SAMPLE_TEXTURE2D_SCALE_BIAS(name) \
SAMPLE_TEXTURE2D(name, sampler##name, (texcoords[name##UV] * name##_ST.xy + name##_ST.zw))
//-----------------------------------------------------------------------------
// GetSurfaceAndBuiltinData
//-----------------------------------------------------------------------------
// cf with
// cf with
// LitBuiltinData.hlsl:GetBuiltinData()
// LitBuiltinData.hlsl:GetBuiltinData()
//
// Here we can combine them
//

// Build the texcoords array.
float3 positionWS = GetAbsolutePositionWS(input.positionWS);
texcoords[TEXCOORD_INDEX_UV0] = input.texCoord0;
texcoords[TEXCOORD_INDEX_UV1] = input.texCoord1;
texcoords[TEXCOORD_INDEX_UV2] = input.texCoord2;
texcoords[TEXCOORD_INDEX_UV3] = input.texCoord3;
texcoords[TEXCOORD_INDEX_PLANAR_XY] = float2(positionWS.x, positionWS.y);
texcoords[TEXCOORD_INDEX_PLANAR_YZ] = float2(positionWS.y, positionWS.z);
texcoords[TEXCOORD_INDEX_PLANAR_ZX] = float2(positionWS.z, positionWS.x);
texcoords[TEXCOORD_INDEX_TRIPLANAR] = input.texCoord0;
float3 triplanarWeights;
InitializeMappingData(input, texcoords, triplanarWeights);
// -------------------------------------------------------------
// Surface Data:

surfaceData.perceptualSmoothnessA = dot(SAMPLE_TEXTURE2D_SCALE_BIAS(_SmoothnessAMap), _SmoothnessAMapChannelMask);
surfaceData.perceptualSmoothnessA = lerp(_SmoothnessARange.x, _SmoothnessARange.y, surfaceData.perceptualSmoothnessA);
surfaceData.metallic = lerp(_SmoothnessA, surfaceData.perceptualSmoothnessA, _SmoothnessAUseMap);
surfaceData.perceptualSmoothnessA = lerp(_SmoothnessA, surfaceData.perceptualSmoothnessA, _SmoothnessAUseMap);
surfaceData.metallic = lerp(_SmoothnessB, surfaceData.perceptualSmoothnessB, _SmoothnessBUseMap);
surfaceData.perceptualSmoothnessB = lerp(_SmoothnessB, surfaceData.perceptualSmoothnessB, _SmoothnessBUseMap);
// TODOSTACKLIT: lobe weighting
surfaceData.lobeMix = _LobeMix;

surfaceData.metallic = lerp(_Metallic, surfaceData.metallic, _MetallicUseMap);
// These static material feature allow compile time optimization
// TODO: As we add features, or-set the flags eg MATERIALFEATUREFLAGS_LIT_* with #ifdef
// on corresponding _MATERIAL_FEATURE_* shader_feature kerwords (set by UI) so the compiler
// TODO: As we add features, or-set the flags eg MATERIALFEATUREFLAGS_LIT_* with #ifdef
// on corresponding _MATERIAL_FEATURE_* shader_feature kerwords (set by UI) so the compiler
// knows the value of surfaceData.materialFeatures.
surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD;

// Builtin Data:
// -------------------------------------------------------------
// NEWLITTODO: for all BuiltinData, might need to just refactor and use a comon function like that
// NEWLITTODO: for all BuiltinData, might need to just refactor and use a comon function like that
// contained in LitBuiltinData.hlsl
builtinData.opacity = alpha;

builtinData.emissiveColor *= SAMPLE_TEXTURE2D_SCALE_BIAS(_EmissiveColorMap).rgb;
builtinData.velocity = float2(0.0, 0.0);
//NEWLITTODO: shader feature SHADOWS_SHADOWMASK not there yet.
//NEWLITTODO: shader feature SHADOWS_SHADOWMASK not there yet.
builtinData.shadowMask0 = 0.0;
builtinData.shadowMask1 = 0.0;
builtinData.shadowMask2 = 0.0;

1
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/StackLit/StackLitProperties.hlsl


float _DistortionBlurRemapMin;
float _DistortionBlurRemapMax;
float _UseLocalPlanarMapping;
// Caution: C# code in BaseLitUI.cs call LightmapEmissionFlagsProperty() which assume that there is an existing "_EmissionColor"
// value that exist to identify if the GI emission need to be enabled.

正在加载...
取消
保存