[Enum(Use Emissive Color, 0, Use Emissive Mask, 1)] _EmissiveColorMode("Emissive color mode", Float) = 1
_TexWorldScale2("Tiling", Float) = 1.0
_TexWorldScale3("Tiling", Float) = 1.0
[Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Planar, 4, Triplanar, 5)] _UVBase0("UV Set for base0", Float) = 0
[Enum(UV0, 0, Planar, 4, Triplanar, 5)] _UVBase0("UV Set for base0", Float) = 0 // no UV1/2/3 for main layer (matching Lit.shader and for PPDisplacement restriction)
[Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Planar, 4, Triplanar, 5)] _UVBase1("UV Set for base1", Float) = 0
[Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Planar, 4, Triplanar, 5)] _UVBase2("UV Set for base2", Float) = 0
[Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Planar, 4, Triplanar, 5)] _UVBase3("UV Set for base3", Float) = 0
[Enum(Use Emissive Color, 0, Use Emissive Mask, 1)] _EmissiveColorMode("Emissive color mode", Float) = 1
_TexWorldScale2("Tiling", Float) = 1.0
_TexWorldScale3("Tiling", Float) = 1.0
[Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Planar, 4, Triplanar, 5)] _UVBase0("UV Set for base0", Float) = 0
[Enum(UV0, 0, Planar, 4, Triplanar, 5)] _UVBase0("UV Set for base0", Float) = 0 // no UV1/2/3 for main layer (matching Lit.shader and for PPDisplacement restriction)
[Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Planar, 4, Triplanar, 5)] _UVBase1("UV Set for base1", Float) = 0
[Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Planar, 4, Triplanar, 5)] _UVBase2("UV Set for base2", Float) = 0
[Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Planar, 4, Triplanar, 5)] _UVBase3("UV Set for base3", Float) = 0
publicstaticGUIContentenablePerPixelDisplacementText=newGUIContent("Enable Per Pixel Displacement","");
publicstaticGUIContentppdMinSamplesText=newGUIContent("Minimum samples","Minimun samples to use with per pixel displacement mapping");
publicstaticGUIContentppdMaxSamplesText=newGUIContent("Maximum samples","Maximum samples to use with per pxiel displacement mapping");
publicstaticGUIContentppdLodThresholdText=newGUIContent("Fading LOD start","Starting Lod where the parallax occlusion mapping effect start to disappear");
publicstaticGUIContentdetailMapModeText=newGUIContent("Detail Map with Normal","Detail Map with AO / Height");
publicstaticGUIContentUVDetailMappingText=newGUIContent("UV set for Detail","");
publicstaticGUIContentemissiveColorModeText=newGUIContent("Emissive Color Usage","Use emissive color or emissive mask");
publicstaticGUIContenttessellationBackFaceCullEpsilonText=newGUIContent("Triangle culling Epsilon","If -1.0 back face culling is enabled for tessellation, higher number mean more aggressive culling and better performance");
publicstaticGUIContenttessellationObjectScaleText=newGUIContent("Enable object scale","Tesselation displacement will take into account the object scale - Only work with uniform positive scale");
publicstaticGUIContentmaterialIDText=newGUIContent("Material Class","Subsurface Scattering: enable for translucent materials such as skin, vegetation, fruit, marble, wax and milk.");
publicstaticGUIContentsubsurfaceProfileText=newGUIContent("Subsurface scattering profile","A profile determines the shape of the blur filter.");
publicstaticGUIContentsubsurfaceRadiusText=newGUIContent("Subsurface scattering radius","Determines the range of the blur.");
publicstaticGUIContentsubsurfaceRadiusMapText=newGUIContent("Subsurface scattering radius map","Determines the range of the blur.");
publicstaticGUIContentthicknessText=newGUIContent("Thickness","If subsurface scattering is enabled, low values allow some light to be transmitted through the object.");
publicstaticGUIContentthicknessMapText=newGUIContent("Thickness map","If subsurface scattering is enabled, low values allow some light to be transmitted through the object.");
publicstaticGUIContentmaterialIDText=newGUIContent("Material type","Subsurface Scattering: enable for translucent materials such as skin, vegetation, fruit, marble, wax and milk.");
publicstaticGUIContentsubsurfaceProfileText=newGUIContent("Subsurface profile","A profile determines the shape of the blur filter.");
publicstaticGUIContentsubsurfaceRadiusText=newGUIContent("Subsurface radius","Determines the range of the blur.");
publicstaticGUIContentsubsurfaceRadiusMapText=newGUIContent("Subsurface radius map","Determines the range of the blur.");
publicstaticGUIContentthicknessText=newGUIContent("Thickness","If subsurface scattering is enabled, low values allow some light to be transmitted through the object.");
publicstaticGUIContentthicknessMapText=newGUIContent("Thickness map","If subsurface scattering is enabled, low values allow some light to be transmitted through the object.");
// We will add smoothly the contribution of the normal map by using lower mips with help of bias sampling. InfluenceFactor must be [0..numMips] // Caution it cause banding...
// Note: that we don't take details map into account here.
float maxMipBias = log2(max(_NormalMap0_TexelSize.z, _NormalMap0_TexelSize.w)); // don't do + 1 as it is for bias, not lod
// PPD is affecting only one mapping at the same time, mean we need to execute it for each mapping (UV0, UV1, 3 times for triplanar etc..)
// We chose to not support all this case that are extremely hard to manage (for example mixing different mapping, mean it also require different tangent space that is not supported in Unity)
// For these reasons we put the following rules
// Rules:
// - Mapping is the same for all layers that use an Heightmap (i.e all are UV, planar or triplanar)
// - Mapping UV is UV0 only because we need to convert view vector in texture space and this is only available for UV0
// - Heightmap can be enabled per layer
// - Blend Mask use same mapping as main layer (UVO, Planar, Triplanar)
// From these rules it mean that PPD is enable only if the user 1) ask for it, 2) if there is one heightmap enabled on active layer, 3) if mapping is the same for all layer respecting 2), 4) if mapping is UV0, planar or triplanar mapping
// Most contraint are handled by the inspector (i.e the UI) like the mapping constraint and is assumed in the shader.
// To know if we are planar or triplanar just need to check if any of the active heightmap layer is true as they are enforce to be the same mapping
#if defined(_HEIGHTMAP0)
ppdEnable = true;
isPlanar = layerTexCoord.base0.isPlanar;
isTriplanar = layerTexCoord.base0.isTriplanar;
#endif
#if defined(_HEIGHTMAP1)
ppdEnable = true;
isPlanar = layerTexCoord.base1.isPlanar;
isTriplanar = layerTexCoord.base1.isTriplanar;
#endif
#if _LAYER_COUNT >= 3
#if defined(_HEIGHTMAP2)
ppdEnable = true;
isPlanar = layerTexCoord.base2.isPlanar;
isTriplanar = layerTexCoord.base2.isTriplanar;
#endif
#endif
#if _LAYER_COUNT >= 4
#if defined(_HEIGHTMAP3)
ppdEnable = true;
isPlanar = layerTexCoord.base3.isPlanar;
isTriplanar = layerTexCoord.base3.isTriplanar;
#endif
#endif
#endif // _PER_PIXEL_DISPLACEMENT
if (ppdEnable)
{
// Even if we use same mapping we can have different tiling. For per pixel displacement we will perform the ray marching with already tiled uv
float maxHeight = GetMaxDisplacement();
// Compute lod as we will sample inside a loop(so can't use regular sampling)
// Note: It appear that CALCULATE_TEXTURE2D_LOD only return interger lod. We want to use float lod to have smoother transition and fading, so do our own calculation.
// Approximation of lod to used. Be conservative here, we will take the highest mip of all layers.
// Remember, we assume that we used the same mapping for all layer, so only size matter.
// We will add smoothly the contribution of the normal map by using lower mips with help of bias sampling. InfluenceFactor must be [0..numMips] // Caution it cause banding...
// Note: that we don't take details map into account here.
float maxMipBias = log2(max(_NormalMap0_TexelSize.z, _NormalMap0_TexelSize.w)); // don't do + 1 as it is for bias, not lod
// Note: If per pixel displacement is enabled it mean we will fetch again the various heightmaps at the intersection location. Not sure the compiler can optimize.
// As I haven't change the variables name yet, I simply don't define anything, and I put the transform function at the end of the file outside the guard header.
// This need to be fixed.
float4x4 glstate_matrix_inv_projection;
#define UNITY_MATRIX_M unity_ObjectToWorld
// These are updated per eye in VR
float4x4 GetWorldToHClipMatrix()
{
return UNITY_MATRIX_VP;
}
// Transform from clip space to homogenous world space
// This is implementation of parallax occlusion mapping (POM)
// This function require that the caller define a callback for the height sampling name ComputePerPixelHeightDisplacement
// A PerPixelHeightDisplacementParam is used to provide all data necessary to calculate the heights to ComputePerPixelHeightDisplacement it doesn't need to be
// visible by the POM algorithm.
// This function is compatible with tiled uv.
// it return the offset to apply to the UVSet provide in PerPixelHeightDisplacementParam
// viewDirTS is view vector in texture space matching the UVSet