This commit is contained in:
2024-09-20 20:30:10 +02:00
commit 4fabf1a6fd
29169 changed files with 1706941 additions and 0 deletions

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: b52d68e305b98a94bac88855d8ea5936
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 6fa64bbd0ffaf8843b041c6e42bb5f82
folderAsset: yes
timeCreated: 1472140530
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,161 @@
// This file assume SHADER_API_D3D11 is defined
#define UNITY_UV_STARTS_AT_TOP 1
#define UNITY_REVERSED_Z 1
#define UNITY_NEAR_CLIP_VALUE (1.0)
// This value will not go through any matrix projection conversion
#define UNITY_RAW_FAR_CLIP_VALUE (0.0)
#define VERTEXID_SEMANTIC SV_VertexID
#define INSTANCEID_SEMANTIC SV_InstanceID
#define FRONT_FACE_SEMANTIC SV_IsFrontFace
#define FRONT_FACE_TYPE bool
#define IS_FRONT_VFACE(VAL, FRONT, BACK) ((VAL) ? (FRONT) : (BACK))
// Only for d3d11 we need to have specific sv_position qualifiers in the case of a conservative depth offset
#ifdef _CONSERVATIVE_DEPTH_OFFSET
#undef SV_POSITION_QUALIFIERS
#define SV_POSITION_QUALIFIERS linear noperspective centroid
#undef DEPTH_OFFSET_SEMANTIC
#define DEPTH_OFFSET_SEMANTIC SV_DepthLessEqual
#endif
#define CBUFFER_START(name) cbuffer name {
#define CBUFFER_END };
#define PLATFORM_SUPPORTS_EXPLICIT_BINDING
#define PLATFORM_NEEDS_UNORM_UAV_SPECIFIER
#define PLATFORM_SUPPORTS_BUFFER_ATOMICS_IN_PIXEL_SHADER
#define PLATFORM_SUPPORTS_PRIMITIVE_ID_IN_PIXEL_SHADER
// flow control attributes
#define UNITY_BRANCH [branch]
#define UNITY_FLATTEN [flatten]
#define UNITY_UNROLL [unroll]
#define UNITY_UNROLLX(_x) [unroll(_x)]
#define UNITY_LOOP [loop]
// Initialize arbitrary structure with zero values.
// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0
#define ZERO_INITIALIZE(type, name) name = (type)0;
#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }
// Texture util abstraction
#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)
// Texture abstraction
#define TEXTURE2D(textureName) Texture2D textureName
#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName
#define TEXTURECUBE(textureName) TextureCube textureName
#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName
#define TEXTURE3D(textureName) Texture3D textureName
#define TEXTURE2D_FLOAT(textureName) TEXTURE2D(textureName)
#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURE2D_ARRAY(textureName)
#define TEXTURECUBE_FLOAT(textureName) TEXTURECUBE(textureName)
#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_ARRAY(textureName)
#define TEXTURE3D_FLOAT(textureName) TEXTURE3D(textureName)
#define TEXTURE2D_HALF(textureName) TEXTURE2D(textureName)
#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURE2D_ARRAY(textureName)
#define TEXTURECUBE_HALF(textureName) TEXTURECUBE(textureName)
#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_ARRAY(textureName)
#define TEXTURE3D_HALF(textureName) TEXTURE3D(textureName)
#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)
#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)
#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)
#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)
#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName
#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName
#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName
#define SAMPLER(samplerName) SamplerState samplerName
#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName
#define ASSIGN_SAMPLER(samplerName, samplerValue) samplerName = samplerValue
#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)
#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)
#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)
#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)
#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)
#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)
#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)
#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)
#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)
#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
#define PLATFORM_SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)
#define PLATFORM_SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)
#define PLATFORM_SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)
#define PLATFORM_SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)
#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))
#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)
#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)
#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)
#define PLATFORM_SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)
#define PLATFORM_SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)
#define PLATFORM_SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)
#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))
#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)
#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)
#define PLATFORM_SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)
#define PLATFORM_SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)
#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) PLATFORM_SAMPLE_TEXTURE2D(textureName, samplerName, coord2)
#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) PLATFORM_SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod)
#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) PLATFORM_SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias)
#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) PLATFORM_SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy)
#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) PLATFORM_SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index)
#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) PLATFORM_SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod)
#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) PLATFORM_SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias)
#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) PLATFORM_SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy)
#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) PLATFORM_SAMPLE_TEXTURECUBE(textureName, samplerName, coord3)
#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) PLATFORM_SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod)
#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) PLATFORM_SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias)
#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) PLATFORM_SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index)
#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod)
#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias)
#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) PLATFORM_SAMPLE_TEXTURE3D(textureName, samplerName, coord3)
#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) PLATFORM_SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod)
#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)
#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)
#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)
#define SAMPLE_DEPTH_TEXTURE(textureName, samplerName, coord2) SAMPLE_TEXTURE2D(textureName, samplerName, coord2).r
#define SAMPLE_DEPTH_TEXTURE_LOD(textureName, samplerName, coord2, lod) SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod).r
#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))
#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))
#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)
#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))
#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)
#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))
#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))
#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))
#define PLATFORM_SUPPORT_GATHER
#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)
#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))
#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)
#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))
#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)
#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)
#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)
#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9c7140d7b956a4547bb71f8ed0dd9049
timeCreated: 1472140530
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,122 @@
#ifndef UNITY_FOVEATED_RENDERING_METAL_INCLUDED
#define UNITY_FOVEATED_RENDERING_METAL_INCLUDED
#if defined(SHADER_API_METAL) && defined(_FOVEATED_RENDERING_NON_UNIFORM_RASTER) && !defined(UNITY_COMPILER_DXC)
// These are tokens that hlslcc is looking for in order
// to inject variable rasterization rate MSL code.
// DO NOT RENAME unless you also change logic in translation
float3 _UV_HlslccVRRDistort0 = float3(0.0, 0.0, 0.0);
float3 _UV_HlslccVRRDistort1 = float3(0.0, 0.0, 0.0);
float3 _UV_HlslccVRRResolve0 = float3(0.0, 0.0, 0.0);
float3 _UV_HlslccVRRResolve1 = float3(0.0, 0.0, 0.0);
float2 RemapFoveatedRenderingLinearToNonUniform(float2 uv, bool yFlip = false)
{
if (yFlip)
uv.y = 1.0 - uv.y;
// TODO: This is not ideal looking code, but our hlsl to msl translation
// layer can rearrange instructions while doing optimizations.
// That can easily break things because we expect certain tokens and swizzles.
// When changing this make sure to check the compiled msl code for foveation.
if (unity_StereoEyeIndex == 1)
{
uv += _UV_HlslccVRRResolve0.yz;
uv = uv * _UV_HlslccVRRResolve1.xy;
}
else
{
uv += _UV_HlslccVRRResolve1.yz;
uv = uv * _UV_HlslccVRRResolve0.xy;
}
if (yFlip)
uv.y = 1.0 - uv.y;
return uv;
}
float2 RemapFoveatedRenderingPrevFrameLinearToNonUniform(float2 uv, bool yFlip = false)
{
// TODO : implement me to support eye tracking that can change the remap each frame
return RemapFoveatedRenderingLinearToNonUniform(uv, yFlip);
}
float2 RemapFoveatedRenderingDensity(float2 uv, bool yFlip = false)
{
// TODO: Implement density look up
return uv;
}
float2 RemapFoveatedRenderingPrevFrameDensity(float2 uv, bool yFlip = false)
{
// TODO : implement me to support eye tracking that can change the remap each frame
return RemapFoveatedRenderingDensity(uv, yFlip);
}
float2 RemapFoveatedRenderingNonUniformToLinear(float2 uv, bool yFlip = false)
{
if (yFlip)
uv.y = 1.0 - uv.y;
// NOTE: Check comment for similar code in RemapFoveatedRenderingLinearToNonUniform
if (unity_StereoEyeIndex == 1)
{
uv += _UV_HlslccVRRDistort0.yz;
uv = uv * _UV_HlslccVRRDistort1.xy;
}
else
{
uv += _UV_HlslccVRRDistort1.yz;
uv = uv * _UV_HlslccVRRDistort0.xy;
}
if (yFlip)
uv.y = 1.0 - uv.y;
return uv;
}
float2 RemapFoveatedRenderingPrevFrameNonUniformToLinear(float2 uv, bool yFlip = false)
{
// TODO : implement me to support eye tracking that can change the remap each frame
return RemapFoveatedRenderingNonUniformToLinear(uv, yFlip);
}
float2 RemapFoveatedRenderingNonUniformToLinearCS(float2 uv, bool yFlip = false)
{
uv /= _ScreenSize.xy;
if (yFlip)
uv.y = 1.0 - uv.y;
// NOTE: Check comment for similar code in RemapFoveatedRenderingLinearToNonUniform
if (unity_StereoEyeIndex == 1)
{
uv += _UV_HlslccVRRDistort0.yz;
uv = uv * _UV_HlslccVRRDistort1.xy;
}
else
{
uv += _UV_HlslccVRRDistort1.yz;
uv = uv * _UV_HlslccVRRDistort0.xy;
}
if (yFlip)
uv.y = 1.0 - uv.y;
return uv * _ScreenSize.xy;
}
// Adapt old remap functions to their new name
float2 RemapFoveatedRenderingResolve(float2 uv) { return RemapFoveatedRenderingLinearToNonUniform(uv); }
float2 RemapFoveatedRenderingPrevFrameResolve(float2 uv) {return RemapFoveatedRenderingPrevFrameLinearToNonUniform(uv); }
float2 RemapFoveatedRenderingDistort(float2 uv) { return RemapFoveatedRenderingNonUniformToLinear(uv); }
float2 RemapFoveatedRenderingPrevFrameDistort(float2 uv) { return RemapFoveatedRenderingPrevFrameNonUniformToLinear(uv); }
int2 RemapFoveatedRenderingDistortCS(int2 positionCS, bool yflip) { return RemapFoveatedRenderingNonUniformToLinearCS(positionCS, yflip); }
#endif // SHADER_API_METAL && _FOVEATED_RENDERING_NON_UNIFORM_RASTER && !UNITY_COMPILER_DXC
#endif // UNITY_FOVEATED_RENDERING_METAL_INCLUDED

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: e885d2d1e5bc4382b9f742451fef9b1f
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,181 @@
#ifndef SHADER_API_GLCORE
#error GLES.hlsl should not be included if SHADER_API_GLCORE is not defined
#endif
#define UNITY_NEAR_CLIP_VALUE (-1.0)
// This value will not go through any matrix projection convertion
#define UNITY_RAW_FAR_CLIP_VALUE (1.0)
#define VERTEXID_SEMANTIC SV_VertexID
#define INSTANCEID_SEMANTIC SV_InstanceID
#define FRONT_FACE_SEMANTIC VFACE
#define FRONT_FACE_TYPE float
#define IS_FRONT_VFACE(VAL, FRONT, BACK) ((VAL > 0.0) ? (FRONT) : (BACK))
#define ERROR_ON_UNSUPPORTED_FUNCTION(funcName) #error #funcName is not supported on GLCORE
#define CBUFFER_START(name) cbuffer name {
#define CBUFFER_END };
#define PLATFORM_SUPPORTS_EXPLICIT_BINDING
// flow control attributes
#define UNITY_BRANCH [branch]
#define UNITY_FLATTEN [flatten]
#define UNITY_UNROLL [unroll]
#define UNITY_UNROLLX(_x) [unroll(_x)]
#define UNITY_LOOP [loop]
// Initialize arbitrary structure with zero values.
// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0
#define ZERO_INITIALIZE(type, name) name = (type)0;
#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }
// Texture util abstraction
#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)
// Texture abstraction
#define TEXTURE2D(textureName) Texture2D textureName
#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName
#define TEXTURECUBE(textureName) TextureCube textureName
#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName
#define TEXTURE3D(textureName) Texture3D textureName
#define TEXTURE2D_FLOAT(textureName) TEXTURE2D(textureName)
#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURE2D_ARRAY(textureName)
#define TEXTURECUBE_FLOAT(textureName) TEXTURECUBE(textureName)
#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_ARRAY(textureName)
#define TEXTURE3D_FLOAT(textureName) TEXTURE3D(textureName)
#define TEXTURE2D_HALF(textureName) TEXTURE2D(textureName)
#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURE2D_ARRAY(textureName)
#define TEXTURECUBE_HALF(textureName) TEXTURECUBE(textureName)
#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_ARRAY(textureName)
#define TEXTURE3D_HALF(textureName) TEXTURE3D(textureName)
#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)
#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)
#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)
#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)
#if SHADER_AVAILABLE_RANDOMWRITE
#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName
#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName
#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName
#else
#define RW_TEXTURE2D(type, textureName) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture2D)
#define RW_TEXTURE2D_ARRAY(type, textureName) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture2DArray)
#define RW_TEXTURE3D(type, textureName) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture3D)
#endif
#define SAMPLER(samplerName) SamplerState samplerName
#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName
#define ASSIGN_SAMPLER(samplerName, samplerValue) samplerName = samplerValue
#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)
#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)
#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)
#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)
#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)
#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)
#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)
#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)
#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)
#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
#define PLATFORM_SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)
#define PLATFORM_SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)
#define PLATFORM_SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)
#define PLATFORM_SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, ddx, ddy) textureName.SampleGrad(samplerName, coord2, ddx, ddy)
#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))
#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)
#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)
#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)
#define PLATFORM_SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)
#define PLATFORM_SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)
#define PLATFORM_SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)
#if SHADER_AVAILABLE_CUBEARRAY
#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))
#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)
#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)
#else
#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY)
#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_LOD)
#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_BIAS)
#endif
#define PLATFORM_SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)
#define PLATFORM_SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)
#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) PLATFORM_SAMPLE_TEXTURE2D(textureName, samplerName, coord2)
#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) PLATFORM_SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod)
#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) PLATFORM_SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias)
#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) PLATFORM_SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy)
#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) PLATFORM_SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index)
#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) PLATFORM_SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod)
#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) PLATFORM_SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias)
#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) PLATFORM_SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy)
#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) PLATFORM_SAMPLE_TEXTURECUBE(textureName, samplerName, coord3)
#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) PLATFORM_SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod)
#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) PLATFORM_SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias)
#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) PLATFORM_SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index)
#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod)
#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias)
#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) PLATFORM_SAMPLE_TEXTURE3D(textureName, samplerName, coord3)
#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) PLATFORM_SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod)
#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)
#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)
#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)
#define SAMPLE_DEPTH_TEXTURE(textureName, samplerName, coord2) SAMPLE_TEXTURE2D(textureName, samplerName, coord2).r
#define SAMPLE_DEPTH_TEXTURE_LOD(textureName, samplerName, coord2, lod) SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod).r
#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))
#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))
#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)
#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))
#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)
#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))
#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))
#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))
#if SHADER_TARGET >= 45
#define PLATFORM_SUPPORT_GATHER
#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)
#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))
#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)
#if SHADER_AVAILABLE_CUBEARRAY
#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))
#else
#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE_ARRAY)
#endif
#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)
#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)
#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)
#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)
#else
#define GATHER_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D)
#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D_ARRAY)
#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE)
#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE_ARRAY)
#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_RED_TEXTURE2D)
#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_GREEN_TEXTURE2D)
#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_BLUE_TEXTURE2D)
#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_ALPHA_TEXTURE2D)
#endif

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 17e9ff94ac9e8aa4e81b23222a4dc205
timeCreated: 1506072929
licenseType: Pro
ShaderImporter:
externalObjects: {}
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,179 @@
#ifndef SHADER_API_GLES
#error GLES.hlsl should not be included if SHADER_API_GLES is not defined
#endif
#define UNITY_NEAR_CLIP_VALUE (-1.0)
// This value will not go through any matrix projection convertion
#define UNITY_RAW_FAR_CLIP_VALUE (1.0)
#define VERTEXID_SEMANTIC gl_VertexID
#define INSTANCEID_SEMANTIC gl_InstanceID
#define FRONT_FACE_SEMANTIC VFACE
#define FRONT_FACE_TYPE float
#define IS_FRONT_VFACE(VAL, FRONT, BACK) ((VAL > 0.0) ? (FRONT) : (BACK))
#define CBUFFER_START(name)
#define CBUFFER_END
// flow control attributes
#define UNITY_BRANCH [branch]
#define UNITY_FLATTEN [flatten]
#define UNITY_UNROLL [unroll]
#define UNITY_UNROLLX(_x) [unroll(_x)]
#define UNITY_LOOP [loop]
#define uint int
#define rcp(x) 1.0 / (x)
#define ddx_fine ddx
#define ddy_fine ddy
#define asfloat
#define asuint(x) asint(x)
#define f32tof16
#define f16tof32
#define ERROR_ON_UNSUPPORTED_FUNCTION(funcName) #error #funcName is not supported on GLES 2.0
// Initialize arbitrary structure with zero values.
// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0
#define ZERO_INITIALIZE(type, name) name = (type)0;
#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }
// GLES2 might not have shadow hardware comparison support
#if defined(UNITY_ENABLE_NATIVE_SHADOWS_LOOKUPS)
#define SHADOW2D_TEXTURE_AND_SAMPLER sampler2DShadow
#define SHADOWCUBE_TEXTURE_AND_SAMPLER samplerCUBEShadow
#define SHADOW2D_SAMPLE(textureName, samplerName, coord3) shadow2D(textureName, coord3)
#define SHADOWCUBE_SAMPLE(textureName, samplerName, coord4) ((texCUBE(textureName,(coord4).xyz) < (coord4).w) ? 0.0 : 1.0)
#else
// emulate hardware comparison
#define SHADOW2D_TEXTURE_AND_SAMPLER sampler2D_float
#define SHADOWCUBE_TEXTURE_AND_SAMPLER samplerCUBE_float
#define SHADOW2D_SAMPLE(textureName, samplerName, coord3) ((SAMPLE_DEPTH_TEXTURE(textureName, samplerName, (coord3).xy) < (coord3).z) ? 0.0 : 1.0)
#define SHADOWCUBE_SAMPLE(textureName, samplerName, coord4) ((texCUBE(textureName,(coord4).xyz).r < (coord4).w) ? 0.0 : 1.0)
#endif
// Texture util abstraction
#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) #error calculate Level of Detail not supported in GLES2
// Texture abstraction
#define TEXTURE2D(textureName) sampler2D textureName
#define TEXTURE2D_ARRAY(textureName) samplerCUBE textureName // No support to texture2DArray
#define TEXTURECUBE(textureName) samplerCUBE textureName
#define TEXTURECUBE_ARRAY(textureName) samplerCUBE textureName // No supoport to textureCubeArray and can't emulate with texture2DArray
#define TEXTURE3D(textureName) sampler3D textureName
#define TEXTURE2D_FLOAT(textureName) sampler2D_float textureName
#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURECUBE_FLOAT(textureName) // No support to texture2DArray
#define TEXTURECUBE_FLOAT(textureName) samplerCUBE_float textureName
#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_FLOAT(textureName) // No support to textureCubeArray
#define TEXTURE3D_FLOAT(textureName) sampler3D_float textureName
#define TEXTURE2D_HALF(textureName) sampler2D_half textureName
#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURECUBE_HALF(textureName) // No support to texture2DArray
#define TEXTURECUBE_HALF(textureName) samplerCUBE_half textureName
#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_HALF(textureName) // No support to textureCubeArray
#define TEXTURE3D_HALF(textureName) sampler3D_half textureName
#define TEXTURE2D_SHADOW(textureName) SHADOW2D_TEXTURE_AND_SAMPLER textureName
#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURECUBE_SHADOW(textureName) // No support to texture array
#define TEXTURECUBE_SHADOW(textureName) SHADOWCUBE_TEXTURE_AND_SAMPLER textureName
#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_SHADOW(textureName) // No support to texture array
#define RW_TEXTURE2D(type, textureNam) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture2D)
#define RW_TEXTURE2D_ARRAY(type, textureName) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture2DArray)
#define RW_TEXTURE3D(type, textureNam) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture3D)
#define SAMPLER(samplerName)
#define SAMPLER_CMP(samplerName)
#define ASSIGN_SAMPLER(samplerName, samplerValue)
#define TEXTURE2D_PARAM(textureName, samplerName) sampler2D textureName
#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) samplerCUBE textureName
#define TEXTURECUBE_PARAM(textureName, samplerName) samplerCUBE textureName
#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) samplerCUBE textureName
#define TEXTURE3D_PARAM(textureName, samplerName) sampler3D textureName
#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) SHADOW2D_TEXTURE_AND_SAMPLER textureName
#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) SHADOWCUBE_TEXTURE_AND_SAMPLER textureName
#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) SHADOWCUBE_TEXTURE_AND_SAMPLER textureName
#define TEXTURE2D_ARGS(textureName, samplerName) textureName
#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName
#define TEXTURECUBE_ARGS(textureName, samplerName) textureName
#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName
#define TEXTURE3D_ARGS(textureName, samplerName) textureName
#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName
#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName
#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName
#define PLATFORM_SAMPLE_TEXTURE2D(textureName, samplerName, coord2) tex2D(textureName, coord2)
#if (SHADER_TARGET >= 30)
#define PLATFORM_SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) tex2Dlod(textureName, float4(coord2, 0, lod))
#else
// No lod support. Very poor approximation with bias.
#define PLATFORM_SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) PLATFORM_SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, lod)
#endif
#define PLATFORM_SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) tex2Dbias(textureName, float4(coord2, 0, bias))
#define PLATFORM_SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, ddx, ddy) PLATFORM_SAMPLE_TEXTURE2D(textureName, samplerName, coord2)
#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE2D_ARRAY)
#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE2D_ARRAY_LOD)
#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE2D_ARRAY_BIAS)
#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE2D_ARRAY_GRAD)
#define PLATFORM_SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) texCUBE(textureName, coord3)
// No lod support. Very poor approximation with bias.
#define PLATFORM_SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) PLATFORM_SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, lod)
#define PLATFORM_SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) texCUBEbias(textureName, float4(coord3, bias))
#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY)
#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_LOD)
#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_BIAS)
#define PLATFORM_SAMPLE_TEXTURE3D(textureName, samplerName, coord3) tex3D(textureName, coord3)
#define PLATFORM_SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE3D_LOD)
#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) PLATFORM_SAMPLE_TEXTURE2D(textureName, samplerName, coord2)
#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) PLATFORM_SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod)
#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) PLATFORM_SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias)
#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) PLATFORM_SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy)
#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) PLATFORM_SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index)
#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) PLATFORM_SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod)
#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) PLATFORM_SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias)
#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) PLATFORM_SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy)
#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) PLATFORM_SAMPLE_TEXTURECUBE(textureName, samplerName, coord3)
#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) PLATFORM_SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod)
#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) PLATFORM_SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias)
#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) PLATFORM_SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index)
#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod)
#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias)
#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) PLATFORM_SAMPLE_TEXTURE3D(textureName, samplerName, coord3)
#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) PLATFORM_SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod)
#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) SHADOW2D_SAMPLE(textureName, samplerName, coord3)
#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE2D_ARRAY_SHADOW)
#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) SHADOWCUBE_SAMPLE(textureName, samplerName, coord4)
#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_SHADOW)
#define SAMPLE_DEPTH_TEXTURE(textureName, samplerName, coord2) SAMPLE_TEXTURE2D(textureName, samplerName, coord2).r
#define SAMPLE_DEPTH_TEXTURE_LOD(textureName, samplerName, coord2, lod) SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod).r
// Not supported. Can't define as error because shader library is calling these functions.
#define LOAD_TEXTURE2D(textureName, unCoord2) half4(0, 0, 0, 0)
#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) half4(0, 0, 0, 0)
#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) half4(0, 0, 0, 0)
#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) half4(0, 0, 0, 0)
#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) half4(0, 0, 0, 0)
#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) half4(0, 0, 0, 0)
#define LOAD_TEXTURE3D(textureName, unCoord3) ERROR_ON_UNSUPPORTED_FUNCTION(LOAD_TEXTURE3D)
#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) ERROR_ON_UNSUPPORTED_FUNCTION(LOAD_TEXTURE3D_LOD)
// Gather not supported. Fallback to regular texture sampling.
#define GATHER_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D)
#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D_ARRAY)
#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE)
#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE_ARRAY)
#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_RED_TEXTURE2D)
#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_GREEN_TEXTURE2D)
#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_BLUE_TEXTURE2D)
#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_ALPHA_TEXTURE2D)

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 4763738e37aef3949b7a83aae926cff5
timeCreated: 1506072929
licenseType: Pro
ShaderImporter:
externalObjects: {}
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,193 @@
#ifndef SHADER_API_GLES3
#error GLES.hlsl should not be included if SHADER_API_GLES3 is not defined
#endif
#define UNITY_NEAR_CLIP_VALUE (-1.0)
// This value will not go through any matrix projection convertion
#define UNITY_RAW_FAR_CLIP_VALUE (1.0)
#define VERTEXID_SEMANTIC SV_VertexID
#define INSTANCEID_SEMANTIC SV_InstanceID
#if defined(UNITY_COMPILER_DXC)
#define FRONT_FACE_SEMANTIC SV_IsFrontFace
#define FRONT_FACE_TYPE bool
#define IS_FRONT_VFACE(VAL, FRONT, BACK) ((VAL) ? (FRONT) : (BACK))
#else
#define FRONT_FACE_SEMANTIC VFACE
#define FRONT_FACE_TYPE float
#define IS_FRONT_VFACE(VAL, FRONT, BACK) ((VAL > 0.0) ? (FRONT) : (BACK))
#endif
#define ERROR_ON_UNSUPPORTED_FUNCTION(funcName) #error #funcName is not supported on GLES 3.0
#define CBUFFER_START(name) cbuffer name {
#define CBUFFER_END };
// flow control attributes
#define UNITY_BRANCH [branch]
#define UNITY_FLATTEN [flatten]
#define UNITY_UNROLL [unroll]
#define UNITY_UNROLLX(_x) [unroll(_x)]
#define UNITY_LOOP [loop]
// GLES 3.1 + AEP shader feature https://docs.unity3d.com/Manual/SL-ShaderCompileTargets.html
#if (SHADER_TARGET >= 50)
#define GLES3_1_AEP 1
#else
#define GLES3_1_AEP 0
#endif
// Initialize arbitrary structure with zero values.
// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0
#define ZERO_INITIALIZE(type, name) name = (type)0;
#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }
// Texture util abstraction
#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)
// Texture abstraction
#define TEXTURE2D(textureName) Texture2D textureName
#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName
#define TEXTURECUBE(textureName) TextureCube textureName
#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName
#define TEXTURE3D(textureName) Texture3D textureName
#define TEXTURE2D_FLOAT(textureName) Texture2D_float textureName
#define TEXTURE2D_ARRAY_FLOAT(textureName) Texture2DArray_float textureName
#define TEXTURECUBE_FLOAT(textureName) TextureCube_float textureName
#define TEXTURECUBE_ARRAY_FLOAT(textureName) TextureCubeArray_float textureName
#define TEXTURE3D_FLOAT(textureName) Texture3D_float textureName
#define TEXTURE2D_HALF(textureName) Texture2D_half textureName
#define TEXTURE2D_ARRAY_HALF(textureName) Texture2DArray_half textureName
#define TEXTURECUBE_HALF(textureName) TextureCube_half textureName
#define TEXTURECUBE_ARRAY_HALF(textureName) TextureCubeArray_half textureName
#define TEXTURE3D_HALF(textureName) Texture3D_half textureName
#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)
#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)
#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)
#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)
#if SHADER_AVAILABLE_RANDOMWRITE
#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName
#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName
#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName
#else
#define RW_TEXTURE2D(type, textureName) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture2D)
#define RW_TEXTURE2D_ARRAY(type, textureName) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture2DArray)
#define RW_TEXTURE3D(type, textureName) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture3D)
#endif
#define SAMPLER(samplerName) SamplerState samplerName
#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName
#define ASSIGN_SAMPLER(samplerName, samplerValue) samplerName = samplerValue
#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)
#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)
#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)
#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)
#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)
#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)
#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)
#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)
#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)
#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
#define PLATFORM_SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)
#define PLATFORM_SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)
#define PLATFORM_SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)
#define PLATFORM_SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, ddx, ddy) textureName.SampleGrad(samplerName, coord2, ddx, ddy)
#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))
#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)
#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)
#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)
#define PLATFORM_SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)
#define PLATFORM_SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)
#define PLATFORM_SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)
#if SHADER_AVAILABLE_CUBEARRAY
#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))
#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)
#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias)textureName.SampleBias(samplerName, float4(coord3, index), bias)
#else
#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY)
#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_LOD)
#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias)ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_BIAS)
#endif
#define PLATFORM_SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)
#define PLATFORM_SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)
#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) PLATFORM_SAMPLE_TEXTURE2D(textureName, samplerName, coord2)
#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) PLATFORM_SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod)
#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) PLATFORM_SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias)
#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) PLATFORM_SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy)
#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) PLATFORM_SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index)
#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) PLATFORM_SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod)
#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) PLATFORM_SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias)
#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) PLATFORM_SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy)
#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) PLATFORM_SAMPLE_TEXTURECUBE(textureName, samplerName, coord3)
#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) PLATFORM_SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod)
#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) PLATFORM_SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias)
#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) PLATFORM_SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index)
#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod)
#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias)
#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) PLATFORM_SAMPLE_TEXTURE3D(textureName, samplerName, coord3)
#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) PLATFORM_SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod)
#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)
#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)
#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)
#define SAMPLE_DEPTH_TEXTURE(textureName, samplerName, coord2) SAMPLE_TEXTURE2D(textureName, samplerName, coord2).r
#define SAMPLE_DEPTH_TEXTURE_LOD(textureName, samplerName, coord2, lod) SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod).r
#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))
#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))
#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)
#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))
#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)
#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))
#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))
#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))
#if SHADER_TARGET >= 45
#define PLATFORM_SUPPORT_GATHER
#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)
#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))
#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)
#if SHADER_AVAILABLE_CUBEARRAY
#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))
#else
#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE_ARRAY)
#endif
#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)
#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)
#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)
#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)
#else
#define GATHER_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D)
#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D_ARRAY)
#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE)
#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE_ARRAY)
#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_RED_TEXTURE2D)
#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_GREEN_TEXTURE2D)
#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_BLUE_TEXTURE2D)
#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_ALPHA_TEXTURE2D)
#endif

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 14a46e0dac04a0245b3f95359167b663
timeCreated: 1506072929
licenseType: Pro
ShaderImporter:
externalObjects: {}
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,154 @@
// This file assumes SHADER_API_METAL is defined
// TODO: This is a straight copy from D3D11.hlsl. Go through all this stuff and adjust where needed.
#define UNITY_UV_STARTS_AT_TOP 1
#define UNITY_REVERSED_Z 1
#define UNITY_NEAR_CLIP_VALUE (1.0)
// This value will not go through any matrix projection conversion
#define UNITY_RAW_FAR_CLIP_VALUE (0.0)
#define VERTEXID_SEMANTIC SV_VertexID
#define INSTANCEID_SEMANTIC SV_InstanceID
#define FRONT_FACE_SEMANTIC SV_IsFrontFace
#define FRONT_FACE_TYPE bool
#define IS_FRONT_VFACE(VAL, FRONT, BACK) ((VAL) ? (FRONT) : (BACK))
#define CBUFFER_START(name) cbuffer name {
#define CBUFFER_END };
#define PLATFORM_SUPPORTS_EXPLICIT_BINDING
#define PLATFORM_NEEDS_UNORM_UAV_SPECIFIER
#define PLATFORM_SUPPORTS_BUFFER_ATOMICS_IN_PIXEL_SHADER
// flow control attributes
#define UNITY_BRANCH [branch]
#define UNITY_FLATTEN [flatten]
#define UNITY_UNROLL [unroll]
#define UNITY_UNROLLX(_x) [unroll(_x)]
#define UNITY_LOOP [loop]
// Initialize arbitrary structure with zero values.
// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0
#define ZERO_INITIALIZE(type, name) name = (type)0;
#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }
// Texture util abstraction
#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)
// Texture abstraction
#define TEXTURE2D(textureName) Texture2D textureName
#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName
#define TEXTURECUBE(textureName) TextureCube textureName
#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName
#define TEXTURE3D(textureName) Texture3D textureName
#define TEXTURE2D_FLOAT(textureName) Texture2D_float textureName
#define TEXTURE2D_ARRAY_FLOAT(textureName) Texture2DArray_float textureName
#define TEXTURECUBE_FLOAT(textureName) TextureCube_float textureName
#define TEXTURECUBE_ARRAY_FLOAT(textureName) TextureCubeArray_float textureName
#define TEXTURE3D_FLOAT(textureName) Texture3D_float textureName
#define TEXTURE2D_HALF(textureName) Texture2D_half textureName
#define TEXTURE2D_ARRAY_HALF(textureName) Texture2DArray_half textureName
#define TEXTURECUBE_HALF(textureName) TextureCube_half textureName
#define TEXTURECUBE_ARRAY_HALF(textureName) TextureCubeArray_half textureName
#define TEXTURE3D_HALF(textureName) Texture3D_half textureName
#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)
#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)
#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)
#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)
#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName
#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName
#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName
#define SAMPLER(samplerName) SamplerState samplerName
#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName
#define ASSIGN_SAMPLER(samplerName, samplerValue) samplerName = samplerValue
#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)
#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)
#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)
#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)
#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)
#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)
#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)
#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)
#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)
#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
#define PLATFORM_SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)
#define PLATFORM_SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)
#define PLATFORM_SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)
#define PLATFORM_SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)
#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))
#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)
#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)
#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)
#define PLATFORM_SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)
#define PLATFORM_SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)
#define PLATFORM_SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)
#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))
#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)
#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)
#define PLATFORM_SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)
#define PLATFORM_SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)
#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) PLATFORM_SAMPLE_TEXTURE2D(textureName, samplerName, coord2)
#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) PLATFORM_SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod)
#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) PLATFORM_SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias)
#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) PLATFORM_SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy)
#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) PLATFORM_SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index)
#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) PLATFORM_SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod)
#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) PLATFORM_SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias)
#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) PLATFORM_SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy)
#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) PLATFORM_SAMPLE_TEXTURECUBE(textureName, samplerName, coord3)
#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) PLATFORM_SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod)
#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) PLATFORM_SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias)
#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) PLATFORM_SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index)
#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod)
#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias)
#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) PLATFORM_SAMPLE_TEXTURE3D(textureName, samplerName, coord3)
#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) PLATFORM_SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod)
#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)
#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)
#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)
#define SAMPLE_DEPTH_TEXTURE(textureName, samplerName, coord2) SAMPLE_TEXTURE2D(textureName, samplerName, coord2).r
#define SAMPLE_DEPTH_TEXTURE_LOD(textureName, samplerName, coord2, lod) SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod).r
#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))
#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))
#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)
#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))
#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)
#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))
#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))
#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))
#define PLATFORM_SUPPORT_GATHER
#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)
#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))
#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)
#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))
#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)
#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)
#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)
#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)
#define PLATFORM_SUPPORTS_NATIVE_RENDERPASS

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: f4d51e77f119d4dc8899ff02b46bb621
timeCreated: 1484817807
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,151 @@
// This file assume SHADER_API_SWITCH is defined
// TODO: This is a straight copy from D3D11.hlsl. Go through all this stuff and adjust where needed.
#define UNITY_UV_STARTS_AT_TOP 1
#define UNITY_REVERSED_Z 1
#define UNITY_NEAR_CLIP_VALUE (1.0)
// This value will not go through any matrix projection conversion
#define UNITY_RAW_FAR_CLIP_VALUE (0.0)
#define VERTEXID_SEMANTIC SV_VertexID
#define INSTANCEID_SEMANTIC SV_InstanceID
#define FRONT_FACE_SEMANTIC SV_IsFrontFace
#define FRONT_FACE_TYPE bool
#define IS_FRONT_VFACE(VAL, FRONT, BACK) ((VAL) ? (FRONT) : (BACK))
#define CBUFFER_START(name) cbuffer name {
#define CBUFFER_END };
#define PLATFORM_SUPPORTS_EXPLICIT_BINDING
#define PLATFORM_NEEDS_UNORM_UAV_SPECIFIER
#define PLATFORM_LANE_COUNT 32
// flow control attributes
#define UNITY_BRANCH [branch]
#define UNITY_FLATTEN [flatten]
#define UNITY_UNROLL [unroll]
#define UNITY_UNROLLX(_x) [unroll(_x)]
#define UNITY_LOOP [loop]
// Initialize arbitrary structure with zero values.
// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0
#define ZERO_INITIALIZE(type, name) name = (type)0;
#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }
// Texture util abstraction
#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)
// Texture abstraction
#define TEXTURE2D(textureName) Texture2D textureName
#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName
#define TEXTURECUBE(textureName) TextureCube textureName
#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName
#define TEXTURE3D(textureName) Texture3D textureName
#define TEXTURE2D_FLOAT(textureName) Texture2D_float textureName
#define TEXTURE2D_ARRAY_FLOAT(textureName) Texture2DArray_float textureName
#define TEXTURECUBE_FLOAT(textureName) TextureCube_float textureName
#define TEXTURECUBE_ARRAY_FLOAT(textureName) TextureCubeArray_float textureName
#define TEXTURE3D_FLOAT(textureName) Texture3D_float textureName
#define TEXTURE2D_HALF(textureName) Texture2D_half textureName
#define TEXTURE2D_ARRAY_HALF(textureName) Texture2DArray_half textureName
#define TEXTURECUBE_HALF(textureName) TextureCube_half textureName
#define TEXTURECUBE_ARRAY_HALF(textureName) TextureCubeArray_half textureName
#define TEXTURE3D_HALF(textureName) Texture3D_half textureName
#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)
#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)
#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)
#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)
#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName
#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName
#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName
#define SAMPLER(samplerName) SamplerState samplerName
#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName
#define ASSIGN_SAMPLER(samplerName, samplerValue) samplerName = samplerValue
#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)
#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)
#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)
#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)
#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)
#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)
#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)
#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)
#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)
#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
#define PLATFORM_SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)
#define PLATFORM_SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)
#define PLATFORM_SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)
#define PLATFORM_SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)
#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))
#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)
#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)
#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)
#define PLATFORM_SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)
#define PLATFORM_SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)
#define PLATFORM_SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)
#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))
#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)
#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)
#define PLATFORM_SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)
#define PLATFORM_SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)
#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) PLATFORM_SAMPLE_TEXTURE2D(textureName, samplerName, coord2)
#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) PLATFORM_SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod)
#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) PLATFORM_SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias)
#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) PLATFORM_SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy)
#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) PLATFORM_SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index)
#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) PLATFORM_SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod)
#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) PLATFORM_SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias)
#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) PLATFORM_SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy)
#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) PLATFORM_SAMPLE_TEXTURECUBE(textureName, samplerName, coord3)
#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) PLATFORM_SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod)
#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) PLATFORM_SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias)
#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) PLATFORM_SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index)
#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod)
#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias)
#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) PLATFORM_SAMPLE_TEXTURE3D(textureName, samplerName, coord3)
#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) PLATFORM_SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod)
#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)
#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)
#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)
#define SAMPLE_DEPTH_TEXTURE(textureName, samplerName, coord2) SAMPLE_TEXTURE2D(textureName, samplerName, coord2).r
#define SAMPLE_DEPTH_TEXTURE_LOD(textureName, samplerName, coord2, lod) SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod).r
#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))
#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))
#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)
#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))
#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))
#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))
#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))
#define PLATFORM_SUPPORT_GATHER
#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)
#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))
#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)
#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))
#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)
#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)
#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)
#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: e81335bf0a3c45c4fa81ed2fe67eeba0
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,38 @@
// Wait for a fix from Trunk #error not supported yet
/*
#define REQUIRE_DEFINED(X_) \
#ifndef X_ \
#error X_ must be defined (in) the platform include \
#endif X_ \
REQUIRE_DEFINED(UNITY_UV_STARTS_AT_TOP)
REQUIRE_DEFINED(UNITY_REVERSED_Z)
REQUIRE_DEFINED(UNITY_NEAR_CLIP_VALUE)
REQUIRE_DEFINED(FACE)
REQUIRE_DEFINED(CBUFFER_START)
REQUIRE_DEFINED(CBUFFER_END)
REQUIRE_DEFINED(INITIALIZE_OUTPUT)
*/
// Default values for things that have not been defined in the platform headers
// default flow control attributes
#ifndef UNITY_BRANCH
# define UNITY_BRANCH
#endif
#ifndef UNITY_FLATTEN
# define UNITY_FLATTEN
#endif
#ifndef UNITY_UNROLL
# define UNITY_UNROLL
#endif
#ifndef UNITY_UNROLLX
# define UNITY_UNROLLX(_x)
#endif
#ifndef UNITY_LOOP
# define UNITY_LOOP
#endif

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 30ba55673585a6e4f9afd796eb8b170e
timeCreated: 1474895361
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,181 @@
// This file assume SHADER_API_VULKAN is defined
// TODO: This is a straight copy from D3D11.hlsl. Go through all this stuff and adjust where needed.
#define UNITY_UV_STARTS_AT_TOP 1
#define UNITY_REVERSED_Z 1
#define UNITY_NEAR_CLIP_VALUE (1.0)
// This value will not go through any matrix projection conversion
#define UNITY_RAW_FAR_CLIP_VALUE (0.0)
#define VERTEXID_SEMANTIC SV_VertexID
#define INSTANCEID_SEMANTIC SV_InstanceID
#define FRONT_FACE_SEMANTIC SV_IsFrontFace
#define FRONT_FACE_TYPE bool
#define IS_FRONT_VFACE(VAL, FRONT, BACK) ((VAL) ? (FRONT) : (BACK))
#define CBUFFER_START(name) cbuffer name {
#define CBUFFER_END };
#define PLATFORM_SUPPORTS_EXPLICIT_BINDING
#define PLATFORM_NEEDS_UNORM_UAV_SPECIFIER
#define PLATFORM_SUPPORTS_BUFFER_ATOMICS_IN_PIXEL_SHADER
#define PLATFORM_SUPPORTS_PRIMITIVE_ID_IN_PIXEL_SHADER
// flow control attributes
#define UNITY_BRANCH [branch]
#define UNITY_FLATTEN [flatten]
#define UNITY_UNROLL [unroll]
#define UNITY_UNROLLX(_x) [unroll(_x)]
#define UNITY_LOOP [loop]
// Initialize arbitrary structure with zero values.
// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0
#define ZERO_INITIALIZE(type, name) name = (type)0;
#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }
// Texture util abstraction
#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)
// Texture abstraction
#define TEXTURE2D(textureName) Texture2D textureName
#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName
#define TEXTURECUBE(textureName) TextureCube textureName
#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName
#define TEXTURE3D(textureName) Texture3D textureName
#define TEXTURE2D_FLOAT(textureName) Texture2D_float textureName
#define TEXTURE2D_ARRAY_FLOAT(textureName) Texture2DArray_float textureName
#define TEXTURECUBE_FLOAT(textureName) TextureCube_float textureName
#define TEXTURECUBE_ARRAY_FLOAT(textureName) TextureCubeArray_float textureName
#define TEXTURE3D_FLOAT(textureName) Texture3D_float textureName
#define TEXTURE2D_HALF(textureName) Texture2D_half textureName
#define TEXTURE2D_ARRAY_HALF(textureName) Texture2DArray_half textureName
#define TEXTURECUBE_HALF(textureName) TextureCube_half textureName
#define TEXTURECUBE_ARRAY_HALF(textureName) TextureCubeArray_half textureName
#define TEXTURE3D_HALF(textureName) Texture3D_half textureName
#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)
#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)
#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)
#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)
#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName
#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName
#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName
#define SAMPLER(samplerName) SamplerState samplerName
#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName
#define ASSIGN_SAMPLER(samplerName, samplerValue) samplerName = samplerValue
#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)
#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)
#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)
#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)
#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)
#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)
#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)
#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)
#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)
#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
#define PLATFORM_SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)
#define PLATFORM_SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)
#define PLATFORM_SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)
#define PLATFORM_SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)
#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))
#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)
#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)
#define PLATFORM_SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)
#define PLATFORM_SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)
#define PLATFORM_SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)
#define PLATFORM_SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)
#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))
#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)
#define PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)
#define PLATFORM_SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)
#define PLATFORM_SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)
#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) PLATFORM_SAMPLE_TEXTURE2D(textureName, samplerName, coord2)
#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) PLATFORM_SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod)
#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) PLATFORM_SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias)
#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) PLATFORM_SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy)
#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) PLATFORM_SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index)
#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) PLATFORM_SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod)
#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) PLATFORM_SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias)
#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) PLATFORM_SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy)
#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) PLATFORM_SAMPLE_TEXTURECUBE(textureName, samplerName, coord3)
#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) PLATFORM_SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod)
#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) PLATFORM_SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias)
#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) PLATFORM_SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index)
#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod)
#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias)
#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) PLATFORM_SAMPLE_TEXTURE3D(textureName, samplerName, coord3)
#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) PLATFORM_SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod)
#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)
#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)
#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)
#define SAMPLE_DEPTH_TEXTURE(textureName, samplerName, coord2) SAMPLE_TEXTURE2D(textureName, samplerName, coord2).r
#define SAMPLE_DEPTH_TEXTURE_LOD(textureName, samplerName, coord2, lod) SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod).r
#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))
#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))
#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)
#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))
#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)
#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))
#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))
#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))
#define PLATFORM_SUPPORT_GATHER
#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)
#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))
#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)
#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))
#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)
#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)
#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)
#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)
#define PLATFORM_SUPPORTS_NATIVE_RENDERPASS
// Vulkan SwapChain pre-transform
#ifdef UNITY_PRETRANSFORM_TO_DISPLAY_ORIENTATION
# ifdef UNITY_COMPILER_DXC
[[vk::constant_id(1)]] const int UnityDisplayOrientationPreTransform = 0;
# else
cbuffer UnityDisplayOrientationPreTransformData { int UnityDisplayOrientationPreTransform; };
# endif
# define UNITY_DISPLAY_ORIENTATION_PRETRANSFORM UnityDisplayOrientationPreTransform
# define UNITY_DISPLAY_ORIENTATION_PRETRANSFORM_0 0
# define UNITY_DISPLAY_ORIENTATION_PRETRANSFORM_90 1
# define UNITY_DISPLAY_ORIENTATION_PRETRANSFORM_180 2
# define UNITY_DISPLAY_ORIENTATION_PRETRANSFORM_270 3
float4 ApplyPretransformRotation(float4 v)
{
switch (UNITY_DISPLAY_ORIENTATION_PRETRANSFORM)
{
default:
case UNITY_DISPLAY_ORIENTATION_PRETRANSFORM_0: break;
case UNITY_DISPLAY_ORIENTATION_PRETRANSFORM_90: v.xy = float2(v.y, -v.x); break;
case UNITY_DISPLAY_ORIENTATION_PRETRANSFORM_180: v.xy = -v.xy; break;
case UNITY_DISPLAY_ORIENTATION_PRETRANSFORM_270: v.xy = float2(-v.y, v.x); break;
}
return v;
}
#endif

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 05a00b34d7740a643a8a6de19c6d9aa6
timeCreated: 1506072929
licenseType: Pro
ShaderImporter:
externalObjects: {}
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,418 @@
#ifndef UNITY_AREA_LIGHTING_INCLUDED
#define UNITY_AREA_LIGHTING_INCLUDED
#define APPROXIMATE_POLY_LIGHT_AS_SPHERE_LIGHT
#define APPROXIMATE_SPHERE_LIGHT_NUMERICALLY
// Not normalized by the factor of 1/TWO_PI.
real3 ComputeEdgeFactor(real3 V1, real3 V2)
{
real V1oV2 = dot(V1, V2);
real3 V1xV2 = cross(V1, V2);
#if 0
return normalize(V1xV2) * acos(V1oV2));
#else
// Approximate: { y = rsqrt(1.0 - V1oV2 * V1oV2) * acos(V1oV2) } on [0, 1].
// Fit: HornerForm[MiniMaxApproximation[ArcCos[x]/Sqrt[1 - x^2], {x, {0, 1 - $MachineEpsilon}, 6, 0}][[2, 1]]].
// Maximum relative error: 2.6855360216340534 * 10^-6. Intensities up to 1000 are artifact-free.
real x = abs(V1oV2);
real y = 1.5707921083647782 + x * (-0.9995697178013095 + x * (0.778026455830408 + x * (-0.6173111361273548 + x * (0.4202724111150622 + x * (-0.19452783598217288 + x * 0.04232040013661036)))));
if (V1oV2 < 0)
{
// Undo range reduction.
const float epsilon = 1e-5f;
y = PI * rsqrt(max(epsilon, saturate(1 - V1oV2 * V1oV2))) - y;
}
return V1xV2 * y;
#endif
}
// Not normalized by the factor of 1/TWO_PI.
// Ref: Improving radiosity solutions through the use of analytically determined form-factors.
real IntegrateEdge(real3 V1, real3 V2)
{
// 'V1' and 'V2' are represented in a coordinate system with N = (0, 0, 1).
return ComputeEdgeFactor(V1, V2).z;
}
// 'sinSqSigma' is the sine^2 of the half-angle subtended by the sphere (aperture) as seen from the shaded point.
// 'cosOmega' is the cosine of the angle between the normal and the direction to the center of the light.
// N.b.: this function accounts for horizon clipping.
real DiffuseSphereLightIrradiance(real sinSqSigma, real cosOmega)
{
#ifdef APPROXIMATE_SPHERE_LIGHT_NUMERICALLY
real x = sinSqSigma;
real y = cosOmega;
// Use a numerical fit found in Mathematica. Mean absolute error: 0.00476944.
// You can use the following Mathematica code to reproduce our results:
// t = Flatten[Table[{x, y, f[x, y]}, {x, 0, 0.999999, 0.001}, {y, -0.999999, 0.999999, 0.002}], 1]
// m = NonlinearModelFit[t, x * (y + e) * (0.5 + (y - e) * (a + b * x + c * x^2 + d * x^3)), {a, b, c, d, e}, {x, y}]
return saturate(x * (0.9245867471551246 + y) * (0.5 + (-0.9245867471551246 + y) * (0.5359050373687144 + x * (-1.0054221851257754 + x * (1.8199061187417047 - x * 1.3172081704209504)))));
#else
#if 0 // Ref: Area Light Sources for Real-Time Graphics, page 4 (1996).
real sinSqOmega = saturate(1 - cosOmega * cosOmega);
real cosSqSigma = saturate(1 - sinSqSigma);
real sinSqGamma = saturate(cosSqSigma / sinSqOmega);
real cosSqGamma = saturate(1 - sinSqGamma);
real sinSigma = sqrt(sinSqSigma);
real sinGamma = sqrt(sinSqGamma);
real cosGamma = sqrt(cosSqGamma);
real sigma = asin(sinSigma);
real omega = acos(cosOmega);
real gamma = asin(sinGamma);
if (omega >= HALF_PI + sigma)
{
// Full horizon occlusion (case #4).
return 0;
}
real e = sinSqSigma * cosOmega;
UNITY_BRANCH
if (omega < HALF_PI - sigma)
{
// No horizon occlusion (case #1).
return e;
}
else
{
real g = (-2 * sqrt(sinSqOmega * cosSqSigma) + sinGamma) * cosGamma + (HALF_PI - gamma);
real h = cosOmega * (cosGamma * sqrt(saturate(sinSqSigma - cosSqGamma)) + sinSqSigma * asin(saturate(cosGamma / sinSigma)));
if (omega < HALF_PI)
{
// Partial horizon occlusion (case #2).
return saturate(e + INV_PI * (g - h));
}
else
{
// Partial horizon occlusion (case #3).
return saturate(INV_PI * (g + h));
}
}
#else // Ref: Moving Frostbite to Physically Based Rendering, page 47 (2015, optimized).
real cosSqOmega = cosOmega * cosOmega; // y^2
UNITY_BRANCH
if (cosSqOmega > sinSqSigma) // (y^2)>x
{
return saturate(sinSqSigma * cosOmega); // Clip[x*y,{0,1}]
}
else
{
real cotSqSigma = rcp(sinSqSigma) - 1; // 1/x-1
real tanSqSigma = rcp(cotSqSigma); // x/(1-x)
real sinSqOmega = 1 - cosSqOmega; // 1-y^2
real w = sinSqOmega * tanSqSigma; // (1-y^2)*(x/(1-x))
real x = -cosOmega * rsqrt(w); // -y*Sqrt[(1/x-1)/(1-y^2)]
real y = sqrt(sinSqOmega * tanSqSigma - cosSqOmega); // Sqrt[(1-y^2)*(x/(1-x))-y^2]
real z = y * cotSqSigma; // Sqrt[(1-y^2)*(x/(1-x))-y^2]*(1/x-1)
real a = cosOmega * acos(x) - z; // y*ArcCos[-y*Sqrt[(1/x-1)/(1-y^2)]]-Sqrt[(1-y^2)*(x/(1-x))-y^2]*(1/x-1)
real b = atan(y); // ArcTan[Sqrt[(1-y^2)*(x/(1-x))-y^2]]
return saturate(INV_PI * (a * sinSqSigma + b));
}
#endif
#endif
}
// This function does not check whether light's contribution is 0.
real3 PolygonFormFactor(real4x3 L)
{
L[0] = SafeNormalize(L[0]);
L[1] = SafeNormalize(L[1]);
L[2] = SafeNormalize(L[2]);
L[3] = SafeNormalize(L[3]);
real3 F = ComputeEdgeFactor(L[0], L[1]);
F += ComputeEdgeFactor(L[1], L[2]);
F += ComputeEdgeFactor(L[2], L[3]);
F += ComputeEdgeFactor(L[3], L[0]);
return INV_TWO_PI * F;
}
// See "Real-Time Area Lighting: a Journey from Research to Production", slide 102.
// Turns out, despite the authors claiming that this function "calculates an approximation of
// the clipped sphere form factor", that is simply not true.
// First of all, above horizon, the function should then just return 'F.z', which it does not.
// Secondly, if we use the correct function called DiffuseSphereLightIrradiance(), it results
// in severe light leaking if the light is placed vertically behind the camera.
// So this function is clearly a hack designed to work around these problems.
real PolygonIrradianceFromVectorFormFactor(float3 F)
{
#if 1
float l = length(F);
return max(0, (l * l + F.z) / (l + 1));
#else
real sff = saturate(dot(F, F));
real sinSqAperture = sqrt(sff);
real cosElevationAngle = F.z * rsqrt(sff);
return DiffuseSphereLightIrradiance(sinSqAperture, cosElevationAngle);
#endif
}
// Expects non-normalized vertex positions.
real PolygonIrradiance(real4x3 L)
{
#ifdef APPROXIMATE_POLY_LIGHT_AS_SPHERE_LIGHT
real3 F = PolygonFormFactor(L);
return PolygonIrradianceFromVectorFormFactor(F);
#else
// 1. ClipQuadToHorizon
// detect clipping config
uint config = 0;
if (L[0].z > 0) config += 1;
if (L[1].z > 0) config += 2;
if (L[2].z > 0) config += 4;
if (L[3].z > 0) config += 8;
// The fifth vertex for cases when clipping cuts off one corner.
// Due to a compiler bug, copying L into a vector array with 5 rows
// messes something up, so we need to stick with the matrix + the L4 vertex.
real3 L4 = L[3];
// This switch is surprisingly fast. Tried replacing it with a lookup array of vertices.
// Even though that replaced the switch with just some indexing and no branches, it became
// way, way slower - mem fetch stalls?
// clip
uint n = 0;
switch (config)
{
case 0: // clip all
break;
case 1: // V1 clip V2 V3 V4
n = 3;
L[1] = -L[1].z * L[0] + L[0].z * L[1];
L[2] = -L[3].z * L[0] + L[0].z * L[3];
break;
case 2: // V2 clip V1 V3 V4
n = 3;
L[0] = -L[0].z * L[1] + L[1].z * L[0];
L[2] = -L[2].z * L[1] + L[1].z * L[2];
break;
case 3: // V1 V2 clip V3 V4
n = 4;
L[2] = -L[2].z * L[1] + L[1].z * L[2];
L[3] = -L[3].z * L[0] + L[0].z * L[3];
break;
case 4: // V3 clip V1 V2 V4
n = 3;
L[0] = -L[3].z * L[2] + L[2].z * L[3];
L[1] = -L[1].z * L[2] + L[2].z * L[1];
break;
case 5: // V1 V3 clip V2 V4: impossible
break;
case 6: // V2 V3 clip V1 V4
n = 4;
L[0] = -L[0].z * L[1] + L[1].z * L[0];
L[3] = -L[3].z * L[2] + L[2].z * L[3];
break;
case 7: // V1 V2 V3 clip V4
n = 5;
L4 = -L[3].z * L[0] + L[0].z * L[3];
L[3] = -L[3].z * L[2] + L[2].z * L[3];
break;
case 8: // V4 clip V1 V2 V3
n = 3;
L[0] = -L[0].z * L[3] + L[3].z * L[0];
L[1] = -L[2].z * L[3] + L[3].z * L[2];
L[2] = L[3];
break;
case 9: // V1 V4 clip V2 V3
n = 4;
L[1] = -L[1].z * L[0] + L[0].z * L[1];
L[2] = -L[2].z * L[3] + L[3].z * L[2];
break;
case 10: // V2 V4 clip V1 V3: impossible
break;
case 11: // V1 V2 V4 clip V3
n = 5;
L[3] = -L[2].z * L[3] + L[3].z * L[2];
L[2] = -L[2].z * L[1] + L[1].z * L[2];
break;
case 12: // V3 V4 clip V1 V2
n = 4;
L[1] = -L[1].z * L[2] + L[2].z * L[1];
L[0] = -L[0].z * L[3] + L[3].z * L[0];
break;
case 13: // V1 V3 V4 clip V2
n = 5;
L[3] = L[2];
L[2] = -L[1].z * L[2] + L[2].z * L[1];
L[1] = -L[1].z * L[0] + L[0].z * L[1];
break;
case 14: // V2 V3 V4 clip V1
n = 5;
L4 = -L[0].z * L[3] + L[3].z * L[0];
L[0] = -L[0].z * L[1] + L[1].z * L[0];
break;
case 15: // V1 V2 V3 V4
n = 4;
break;
}
if (n == 0) return 0;
// 2. Project onto sphere
L[0] = normalize(L[0]);
L[1] = normalize(L[1]);
L[2] = normalize(L[2]);
switch (n)
{
case 3:
L[3] = L[0];
break;
case 4:
L[3] = normalize(L[3]);
L4 = L[0];
break;
case 5:
L[3] = normalize(L[3]);
L4 = normalize(L4);
break;
}
// 3. Integrate
real sum = 0;
sum += IntegrateEdge(L[0], L[1]);
sum += IntegrateEdge(L[1], L[2]);
sum += IntegrateEdge(L[2], L[3]);
if (n >= 4)
sum += IntegrateEdge(L[3], L4);
if (n == 5)
sum += IntegrateEdge(L4, L[0]);
sum *= INV_TWO_PI; // Normalization
sum = max(sum, 0.0);
return isfinite(sum) ? sum : 0.0;
#endif
}
real LineFpo(real tLDDL, real lrcpD, real rcpD)
{
// Compute: ((l / d) / (d * d + l * l)) + (1.0 / (d * d)) * atan(l / d).
return tLDDL + (rcpD * rcpD) * FastATan(lrcpD);
}
real LineFwt(real tLDDL, real l)
{
// Compute: l * ((l / d) / (d * d + l * l)).
return l * tLDDL;
}
// Computes the integral of the clamped cosine over the line segment.
// 'l1' and 'l2' define the integration interval.
// 'tangent' is the line's tangent direction.
// 'normal' is the direction orthogonal to the tangent. It is the shortest vector between
// the shaded point and the line, pointing away from the shaded point.
real LineIrradiance(real l1, real l2, real3 normal, real3 tangent)
{
real d = length(normal);
real l1rcpD = l1 * rcp(d);
real l2rcpD = l2 * rcp(d);
real tLDDL1 = l1rcpD / (d * d + l1 * l1);
real tLDDL2 = l2rcpD / (d * d + l2 * l2);
real intWt = LineFwt(tLDDL2, l2) - LineFwt(tLDDL1, l1);
real intP0 = LineFpo(tLDDL2, l2rcpD, rcp(d)) - LineFpo(tLDDL1, l1rcpD, rcp(d));
return intP0 * normal.z + intWt * tangent.z;
}
// Computes 1.0 / length(mul(ortho, transpose(inverse(invM)))).
real ComputeLineWidthFactor(real3x3 invM, real3 ortho)
{
// transpose(inverse(M)) = (1.0 / determinant(M)) * cofactor(M).
// Take into account that m12 = m21 = m23 = m32 = 0 and m33 = 1.
real det = invM._11 * invM._22 - invM._22 * invM._31 * invM._13;
real3x3 cof = {invM._22, 0.0, -invM._22 * invM._31,
0.0, invM._11 - invM._13 * invM._31, 0.0,
-invM._13 * invM._22, 0.0, invM._11 * invM._22};
// 1.0 / length(mul(V, (1.0 / s * M))) = abs(s) / length(mul(V, M)).
return abs(det) / length(mul(ortho, cof));
}
// For line lights.
real LTCEvaluate(real3 P1, real3 P2, real3 B, real3x3 invM)
{
real result = 0.0;
// Inverse-transform the endpoints.
P1 = mul(P1, invM);
P2 = mul(P2, invM);
// Terminate the algorithm if both points are below the horizon.
if (!(P1.z <= 0.0 && P2.z <= 0.0))
{
real width = ComputeLineWidthFactor(invM, B);
if (P1.z > P2.z)
{
// Convention: 'P2' is above 'P1', with the tangent pointing upwards.
Swap(P1, P2);
}
// Recompute the length and the tangent in the new coordinate system.
real len = length(P2 - P1);
real3 T = normalize(P2 - P1);
// Clip the part of the light below the horizon.
if (P1.z <= 0.0)
{
// P = P1 + t * T; P.z == 0.
real t = -P1.z / T.z;
P1 = real3(P1.xy + t * T.xy, 0.0);
// Set the length of the visible part of the light.
len -= t;
}
// Compute the normal direction to the line, s.t. it is the shortest vector
// between the shaded point and the line, pointing away from the shaded point.
// Can be interpreted as a point on the line, since the shaded point is at the origin.
real proj = dot(P1, T);
real3 P0 = P1 - proj * T;
// Compute the parameterization: distances from 'P1' and 'P2' to 'P0'.
real l1 = proj;
real l2 = l1 + len;
// Integrate the clamped cosine over the line segment.
real irradiance = LineIrradiance(l1, l2, P0, T);
// Guard against numerical precision issues.
result = max(INV_PI * width * irradiance, 0.0);
}
return result;
}
#endif // UNITY_AREA_LIGHTING_INCLUDED

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 2af09bb13e6547242913c40dfb0e50f9
timeCreated: 1476726533
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,175 @@
// Ref: https://github.com/knarkowicz/GPURealTimeBC6H/blob/master/bin/compress.hlsl
// Doc: https://msdn.microsoft.com/en-us/library/windows/desktop/hh308952(v=vs.85).aspx
// Measure compression error
float CalcMSLE(float3 a, float3 b)
{
float3 err = log2(( b + 1.0) / (a + 1.0 ));
err = err * err;
return err.x + err.y + err.z;
}
// Quantification Helpers
float3 Quantize7(float3 x)
{
return (f32tof16(x) * 128.0) / (0x7bff + 1.0);
}
float3 Quantize9(float3 x)
{
return (f32tof16(x) * 512.0) / (0x7bff + 1.0);
}
float3 Quantize10(float3 x)
{
return (f32tof16(x) * 1024.0) / (0x7bff + 1.0);
}
float3 Unquantize7(float3 x)
{
return (x * 65536.0 + 0x8000) / 128.0;
}
float3 Unquantize9(float3 x)
{
return (x * 65536.0 + 0x8000) / 512.0;
}
float3 Unquantize10(float3 x)
{
return (x * 65536.0 + 0x8000) / 1024.0;
}
// BC6H Helpers
// Compute index of a texel projected against endpoints
uint ComputeIndex3(float texelPos, float endPoint0Pos, float endPoint1Pos )
{
float r = ( texelPos - endPoint0Pos ) / ( endPoint1Pos - endPoint0Pos );
return (uint) clamp( r * 6.98182f + 0.00909f + 0.5f, 0.0, 7.0 );
}
uint ComputeIndex4(float texelPos, float endPoint0Pos, float endPoint1Pos )
{
float r = ( texelPos - endPoint0Pos ) / ( endPoint1Pos - endPoint0Pos );
return (uint) clamp( r * 14.93333f + 0.03333f + 0.5f, 0.0, 15.0 );
}
void SignExtend(inout float3 v1, uint mask, uint signFlag )
{
int3 v = (int3) v1;
v.x = ( v.x & mask ) | ( v.x < 0 ? signFlag : 0 );
v.y = ( v.y & mask ) | ( v.y < 0 ? signFlag : 0 );
v.z = ( v.z & mask ) | ( v.z < 0 ? signFlag : 0 );
v1 = v;
}
// 2nd step for unquantize
float3 FinishUnquantize( float3 endpoint0Unq, float3 endpoint1Unq, float weight )
{
float3 comp = ( endpoint0Unq * ( 64.0 - weight ) + endpoint1Unq * weight + 32.0 ) * ( 31.0 / 4096.0 );
return f16tof32( uint3( comp ) );
}
// BC6H Modes
void EncodeMode11( inout uint4 block, inout float blockMSLE, float3 texels[ 16 ] )
{
// compute endpoints (min/max RGB bbox)
float3 blockMin = texels[ 0 ];
float3 blockMax = texels[ 0 ];
uint i;
for (i = 1; i < 16; ++i )
{
blockMin = min( blockMin, texels[ i ] );
blockMax = max( blockMax, texels[ i ] );
}
// refine endpoints in log2 RGB space
float3 refinedBlockMin = blockMax;
float3 refinedBlockMax = blockMin;
for (i = 0; i < 16; ++i )
{
refinedBlockMin = min( refinedBlockMin, texels[ i ] == blockMin ? refinedBlockMin : texels[ i ] );
refinedBlockMax = max( refinedBlockMax, texels[ i ] == blockMax ? refinedBlockMax : texels[ i ] );
}
float3 logBlockMax = log2( blockMax + 1.0 );
float3 logBlockMin = log2( blockMin + 1.0 );
float3 logRefinedBlockMax = log2( refinedBlockMax + 1.0 );
float3 logRefinedBlockMin = log2( refinedBlockMin + 1.0 );
float3 logBlockMaxExt = ( logBlockMax - logBlockMin ) * ( 1.0 / 32.0 );
logBlockMin += min( logRefinedBlockMin - logBlockMin, logBlockMaxExt );
logBlockMax -= min( logBlockMax - logRefinedBlockMax, logBlockMaxExt );
blockMin = exp2( logBlockMin ) - 1.0;
blockMax = exp2( logBlockMax ) - 1.0;
float3 blockDir = blockMax - blockMin;
blockDir = blockDir / ( blockDir.x + blockDir.y + blockDir.z );
float3 endpoint0 = Quantize10( blockMin );
float3 endpoint1 = Quantize10( blockMax );
float endPoint0Pos = f32tof16( dot( blockMin, blockDir ) );
float endPoint1Pos = f32tof16( dot( blockMax, blockDir ) );
// check if endpoint swap is required
float fixupTexelPos = f32tof16( dot( texels[ 0 ], blockDir ) );
uint fixupIndex = ComputeIndex4( fixupTexelPos, endPoint0Pos, endPoint1Pos );
if ( fixupIndex > 7 )
{
Swap( endPoint0Pos, endPoint1Pos );
Swap( endpoint0, endpoint1 );
}
// compute indices
uint indices[ 16 ] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
for (i = 0; i < 16; ++i )
{
float texelPos = f32tof16( dot( texels[ i ], blockDir ) );
indices[ i ] = ComputeIndex4( texelPos, endPoint0Pos, endPoint1Pos );
}
// compute compression error (MSLE)
float3 endpoint0Unq = Unquantize10( endpoint0 );
float3 endpoint1Unq = Unquantize10( endpoint1 );
float msle = 0.0;
for (i = 0; i < 16; ++i )
{
float weight = floor( ( indices[ i ] * 64.0 ) / 15.0 + 0.5);
float3 texelUnc = FinishUnquantize( endpoint0Unq, endpoint1Unq, weight );
msle += CalcMSLE( texels[ i ], texelUnc );
}
// encode block for mode 11
blockMSLE = msle;
block.x = 0x03;
// endpoints
block.x |= (uint) endpoint0.x << 5;
block.x |= (uint) endpoint0.y << 15;
block.x |= (uint) endpoint0.z << 25;
block.y |= (uint) endpoint0.z >> 7;
block.y |= (uint) endpoint1.x << 3;
block.y |= (uint) endpoint1.y << 13;
block.y |= (uint) endpoint1.z << 23;
block.z |= (uint) endpoint1.z >> 9;
// indices
block.z |= indices[ 0 ] << 1;
block.z |= indices[ 1 ] << 4;
block.z |= indices[ 2 ] << 8;
block.z |= indices[ 3 ] << 12;
block.z |= indices[ 4 ] << 16;
block.z |= indices[ 5 ] << 20;
block.z |= indices[ 6 ] << 24;
block.z |= indices[ 7 ] << 28;
block.w |= indices[ 8 ] << 0;
block.w |= indices[ 9 ] << 4;
block.w |= indices[ 10 ] << 8;
block.w |= indices[ 11 ] << 12;
block.w |= indices[ 12 ] << 16;
block.w |= indices[ 13 ] << 20;
block.w |= indices[ 14 ] << 24;
block.w |= indices[ 15 ] << 28;
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 27d419a4917d0ea49978c236e058d464
timeCreated: 1507282342
licenseType: Pro
ShaderImporter:
externalObjects: {}
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,665 @@
#ifndef UNITY_BSDF_INCLUDED
#define UNITY_BSDF_INCLUDED
#if SHADER_API_MOBILE || SHADER_API_GLES || SHADER_API_GLES3
#pragma warning (disable : 3205) // conversion of larger type to smaller
#endif
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
// Note: All NDF and diffuse term have a version with and without divide by PI.
// Version with divide by PI are use for direct lighting.
// Version without divide by PI are use for image based lighting where often the PI cancel during importance sampling
//-----------------------------------------------------------------------------
// Help for BSDF evaluation
//-----------------------------------------------------------------------------
// Cosine-weighted BSDF (a BSDF taking the projected solid angle into account).
// If some of the values are monochromatic, the compiler will optimize accordingly.
struct CBSDF
{
float3 diffR; // Diffuse reflection (T -> MS -> T, same sides)
float3 specR; // Specular reflection (R, RR, TRT, etc)
float3 diffT; // Diffuse transmission (rough T or TT, opposite sides)
float3 specT; // Specular transmission (T, TT, TRRT, etc)
};
//-----------------------------------------------------------------------------
// Fresnel term
//-----------------------------------------------------------------------------
real F_Schlick(real f0, real f90, real u)
{
real x = 1.0 - u;
real x2 = x * x;
real x5 = x * x2 * x2;
return (f90 - f0) * x5 + f0; // sub mul mul mul sub mad
}
real F_Schlick(real f0, real u)
{
return F_Schlick(f0, 1.0, u); // sub mul mul mul sub mad
}
real3 F_Schlick(real3 f0, real f90, real u)
{
real x = 1.0 - u;
real x2 = x * x;
real x5 = x * x2 * x2;
return f0 * (1.0 - x5) + (f90 * x5); // sub mul mul mul sub mul mad*3
}
real3 F_Schlick(real3 f0, real u)
{
return F_Schlick(f0, 1.0, u); // sub mul mul mul sub mad*3
}
// Does not handle TIR.
real F_Transm_Schlick(real f0, real f90, real u)
{
real x = 1.0 - u;
real x2 = x * x;
real x5 = x * x2 * x2;
return (1.0 - f90 * x5) - f0 * (1.0 - x5); // sub mul mul mul mad sub mad
}
// Does not handle TIR.
real F_Transm_Schlick(real f0, real u)
{
return F_Transm_Schlick(f0, 1.0, u); // sub mul mul mad mad
}
// Does not handle TIR.
real3 F_Transm_Schlick(real3 f0, real f90, real u)
{
real x = 1.0 - u;
real x2 = x * x;
real x5 = x * x2 * x2;
return (1.0 - f90 * x5) - f0 * (1.0 - x5); // sub mul mul mul mad sub mad*3
}
// Does not handle TIR.
real3 F_Transm_Schlick(real3 f0, real u)
{
return F_Transm_Schlick(f0, 1.0, u); // sub mul mul mad mad*3
}
// Compute the cos of critical angle: cos(asin(eta)) == sqrt(1.0 - eta*eta)
// eta == IORMedium/IORSource
// If eta >= 1 the it's an AirMedium interation, otherwise it's MediumAir interation
real CosCriticalAngle(real eta)
{
return sqrt(max(1.0 - Sq(eta), 0.0));
// For 1 <= IOR <= 4: Max error: 0.0268594
//return eta >= 1.0 ? 0.0 : (((3.0 + eta) * sqrt(max(0.0, 1.0 - eta))) / (2.0 * sqrt(2.0)));
// For 1 <= IOR <= 4: Max error: 0.00533065
//return eta >= 1.0 ? 0.0 : (-((-23.0 - 10.0 * eta + Sq(eta)) * sqrt(max(0.0, 1.0 - eta))) / (16.0 * sqrt(2.0)));
// For 1 <= IOR <= 4: Max error: 0.00129402
//return eta >= 1.0 ? 0.0 : (((91.0 + 43.0 * eta - 7.0 * Sq(eta) + pow(eta, 3)) * sqrt(max(0.0, 1.0 - eta))) / (64. * sqrt(2.0)));
}
// Ref: https://seblagarde.wordpress.com/2013/04/29/memo-on-fresnel-equations/
// Fresnel dielectric / dielectric
real F_FresnelDielectric(real ior, real u)
{
real g = sqrt(Sq(ior) + Sq(u) - 1.0);
// The "1.0 - saturate(1.0 - result)" formulation allows to recover form cases where g is undefined, for IORs < 1
return 1.0 - saturate(1.0 - 0.5 * Sq((g - u) / (g + u)) * (1.0 + Sq(((g + u) * u - 1.0) / ((g - u) * u + 1.0))));
}
// Fresnel dieletric / conductor
// Note: etak2 = etak * etak (optimization for Artist Friendly Metallic Fresnel below)
// eta = eta_t / eta_i and etak = k_t / n_i
real3 F_FresnelConductor(real3 eta, real3 etak2, real cosTheta)
{
real cosTheta2 = cosTheta * cosTheta;
real sinTheta2 = 1.0 - cosTheta2;
real3 eta2 = eta * eta;
real3 t0 = eta2 - etak2 - sinTheta2;
real3 a2plusb2 = sqrt(t0 * t0 + 4.0 * eta2 * etak2);
real3 t1 = a2plusb2 + cosTheta2;
real3 a = sqrt(0.5 * (a2plusb2 + t0));
real3 t2 = 2.0 * a * cosTheta;
real3 Rs = (t1 - t2) / (t1 + t2);
real3 t3 = cosTheta2 * a2plusb2 + sinTheta2 * sinTheta2;
real3 t4 = t2 * sinTheta2;
real3 Rp = Rs * (t3 - t4) / (t3 + t4);
return 0.5 * (Rp + Rs);
}
// Conversion FO/IOR
TEMPLATE_2_REAL(IorToFresnel0, transmittedIor, incidentIor, return Sq((transmittedIor - incidentIor) / (transmittedIor + incidentIor)) )
// ior is a value between 1.0 and 3.0. 1.0 is air interface
real IorToFresnel0(real transmittedIor)
{
return IorToFresnel0(transmittedIor, 1.0);
}
// Assume air interface for top
// Note: We don't handle the case fresnel0 == 1
//real Fresnel0ToIor(real fresnel0)
//{
// real sqrtF0 = sqrt(fresnel0);
// return (1.0 + sqrtF0) / (1.0 - sqrtF0);
//}
TEMPLATE_1_REAL(Fresnel0ToIor, fresnel0, return ((1.0 + sqrt(fresnel0)) / (1.0 - sqrt(fresnel0))) )
// This function is a coarse approximation of computing fresnel0 for a different top than air (here clear coat of IOR 1.5) when we only have fresnel0 with air interface
// This function is equivalent to IorToFresnel0(Fresnel0ToIor(fresnel0), 1.5)
// mean
// real sqrtF0 = sqrt(fresnel0);
// return Sq(1.0 - 5.0 * sqrtF0) / Sq(5.0 - sqrtF0);
// Optimization: Fit of the function (3 mad) for range [0.04 (should return 0), 1 (should return 1)]
TEMPLATE_1_REAL(ConvertF0ForAirInterfaceToF0ForClearCoat15, fresnel0, return saturate(-0.0256868 + fresnel0 * (0.326846 + (0.978946 - 0.283835 * fresnel0) * fresnel0)))
// Even coarser approximation of ConvertF0ForAirInterfaceToF0ForClearCoat15 (above) for mobile (2 mad)
TEMPLATE_1_REAL(ConvertF0ForAirInterfaceToF0ForClearCoat15Fast, fresnel0, return saturate(fresnel0 * (fresnel0 * 0.526868 + 0.529324) - 0.0482256))
// Artist Friendly Metallic Fresnel Ref: http://jcgt.org/published/0003/04/03/paper.pdf
real3 GetIorN(real3 f0, real3 edgeTint)
{
real3 sqrtF0 = sqrt(f0);
return lerp((1.0 - f0) / (1.0 + f0), (1.0 + sqrtF0) / (1.0 - sqrt(f0)), edgeTint);
}
real3 getIorK2(real3 f0, real3 n)
{
real3 nf0 = Sq(n + 1.0) * f0 - Sq(f0 - 1.0);
return nf0 / (1.0 - f0);
}
// same as regular refract except there is not the test for total internal reflection + the vector is flipped for processing
real3 CoatRefract(real3 X, real3 N, real ieta)
{
real XdotN = saturate(dot(N, X));
return ieta * X + (sqrt(1 + ieta * ieta * (XdotN * XdotN - 1)) - ieta * XdotN) * N;
}
//-----------------------------------------------------------------------------
// Specular BRDF
//-----------------------------------------------------------------------------
float Lambda_GGX(float roughness, float3 V)
{
return 0.5 * (sqrt(1.0 + (Sq(roughness * V.x) + Sq(roughness * V.y)) / Sq(V.z)) - 1.0);
}
real D_GGXNoPI(real NdotH, real roughness)
{
real a2 = Sq(roughness);
real s = (NdotH * a2 - NdotH) * NdotH + 1.0;
// If roughness is 0, returns (NdotH == 1 ? 1 : 0).
// That is, it returns 1 for perfect mirror reflection, and 0 otherwise.
return SafeDiv(a2, s * s);
}
real D_GGX(real NdotH, real roughness)
{
return INV_PI * D_GGXNoPI(NdotH, roughness);
}
// Ref: Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs, p. 19, 29.
// p. 84 (37/60)
real G_MaskingSmithGGX(real NdotV, real roughness)
{
// G1(V, H) = HeavisideStep(VdotH) / (1 + Lambda(V)).
// Lambda(V) = -0.5 + 0.5 * sqrt(1 + 1 / a^2).
// a = 1 / (roughness * tan(theta)).
// 1 + Lambda(V) = 0.5 + 0.5 * sqrt(1 + roughness^2 * tan^2(theta)).
// tan^2(theta) = (1 - cos^2(theta)) / cos^2(theta) = 1 / cos^2(theta) - 1.
// Assume that (VdotH > 0), e.i. (acos(LdotV) < Pi).
return 1.0 / (0.5 + 0.5 * sqrt(1.0 + Sq(roughness) * (1.0 / Sq(NdotV) - 1.0)));
}
// Precompute part of lambdaV
real GetSmithJointGGXPartLambdaV(real NdotV, real roughness)
{
real a2 = Sq(roughness);
return sqrt((-NdotV * a2 + NdotV) * NdotV + a2);
}
// Note: V = G / (4 * NdotL * NdotV)
// Ref: http://jcgt.org/published/0003/02/03/paper.pdf
real V_SmithJointGGX(real NdotL, real NdotV, real roughness, real partLambdaV)
{
real a2 = Sq(roughness);
// Original formulation:
// lambda_v = (-1 + sqrt(a2 * (1 - NdotL2) / NdotL2 + 1)) * 0.5
// lambda_l = (-1 + sqrt(a2 * (1 - NdotV2) / NdotV2 + 1)) * 0.5
// G = 1 / (1 + lambda_v + lambda_l);
// Reorder code to be more optimal:
real lambdaV = NdotL * partLambdaV;
real lambdaL = NdotV * sqrt((-NdotL * a2 + NdotL) * NdotL + a2);
// Simplify visibility term: (2.0 * NdotL * NdotV) / ((4.0 * NdotL * NdotV) * (lambda_v + lambda_l))
return 0.5 / max(lambdaV + lambdaL, REAL_MIN);
}
real V_SmithJointGGX(real NdotL, real NdotV, real roughness)
{
real partLambdaV = GetSmithJointGGXPartLambdaV(NdotV, roughness);
return V_SmithJointGGX(NdotL, NdotV, roughness, partLambdaV);
}
// Inline D_GGX() * V_SmithJointGGX() together for better code generation.
real DV_SmithJointGGX(real NdotH, real NdotL, real NdotV, real roughness, real partLambdaV)
{
real a2 = Sq(roughness);
real s = (NdotH * a2 - NdotH) * NdotH + 1.0;
real lambdaV = NdotL * partLambdaV;
real lambdaL = NdotV * sqrt((-NdotL * a2 + NdotL) * NdotL + a2);
real2 D = real2(a2, s * s); // Fraction without the multiplier (1/Pi)
real2 G = real2(1, lambdaV + lambdaL); // Fraction without the multiplier (1/2)
// This function is only used for direct lighting.
// If roughness is 0, the probability of hitting a punctual or directional light is also 0.
// Therefore, we return 0. The most efficient way to do it is with a max().
return INV_PI * 0.5 * (D.x * G.x) / max(D.y * G.y, REAL_MIN);
}
real DV_SmithJointGGX(real NdotH, real NdotL, real NdotV, real roughness)
{
real partLambdaV = GetSmithJointGGXPartLambdaV(NdotV, roughness);
return DV_SmithJointGGX(NdotH, NdotL, NdotV, roughness, partLambdaV);
}
// Precompute a part of LambdaV.
// Note on this linear approximation.
// Exact for roughness values of 0 and 1. Also, exact when the cosine is 0 or 1.
// Otherwise, the worst case relative error is around 10%.
// https://www.desmos.com/calculator/wtp8lnjutx
real GetSmithJointGGXPartLambdaVApprox(real NdotV, real roughness)
{
real a = roughness;
return NdotV * (1 - a) + a;
}
real V_SmithJointGGXApprox(real NdotL, real NdotV, real roughness, real partLambdaV)
{
real a = roughness;
real lambdaV = NdotL * partLambdaV;
real lambdaL = NdotV * (NdotL * (1 - a) + a);
return 0.5 / (lambdaV + lambdaL);
}
real V_SmithJointGGXApprox(real NdotL, real NdotV, real roughness)
{
real partLambdaV = GetSmithJointGGXPartLambdaVApprox(NdotV, roughness);
return V_SmithJointGGXApprox(NdotL, NdotV, roughness, partLambdaV);
}
// roughnessT -> roughness in tangent direction
// roughnessB -> roughness in bitangent direction
real D_GGXAnisoNoPI(real TdotH, real BdotH, real NdotH, real roughnessT, real roughnessB)
{
real a2 = roughnessT * roughnessB;
real3 v = real3(roughnessB * TdotH, roughnessT * BdotH, a2 * NdotH);
real s = dot(v, v);
// If roughness is 0, returns (NdotH == 1 ? 1 : 0).
// That is, it returns 1 for perfect mirror reflection, and 0 otherwise.
return SafeDiv(a2 * a2 * a2, s * s);
}
real D_GGXAniso(real TdotH, real BdotH, real NdotH, real roughnessT, real roughnessB)
{
return INV_PI * D_GGXAnisoNoPI(TdotH, BdotH, NdotH, roughnessT, roughnessB);
}
real GetSmithJointGGXAnisoPartLambdaV(real TdotV, real BdotV, real NdotV, real roughnessT, real roughnessB)
{
return length(real3(roughnessT * TdotV, roughnessB * BdotV, NdotV));
}
// Note: V = G / (4 * NdotL * NdotV)
// Ref: https://cedec.cesa.or.jp/2015/session/ENG/14698.html The Rendering Materials of Far Cry 4
real V_SmithJointGGXAniso(real TdotV, real BdotV, real NdotV, real TdotL, real BdotL, real NdotL, real roughnessT, real roughnessB, real partLambdaV)
{
real lambdaV = NdotL * partLambdaV;
real lambdaL = NdotV * length(real3(roughnessT * TdotL, roughnessB * BdotL, NdotL));
return 0.5 / (lambdaV + lambdaL);
}
real V_SmithJointGGXAniso(real TdotV, real BdotV, real NdotV, real TdotL, real BdotL, real NdotL, real roughnessT, real roughnessB)
{
real partLambdaV = GetSmithJointGGXAnisoPartLambdaV(TdotV, BdotV, NdotV, roughnessT, roughnessB);
return V_SmithJointGGXAniso(TdotV, BdotV, NdotV, TdotL, BdotL, NdotL, roughnessT, roughnessB, partLambdaV);
}
// Inline D_GGXAniso() * V_SmithJointGGXAniso() together for better code generation.
real DV_SmithJointGGXAniso(real TdotH, real BdotH, real NdotH, real NdotV,
real TdotL, real BdotL, real NdotL,
real roughnessT, real roughnessB, real partLambdaV)
{
real a2 = roughnessT * roughnessB;
real3 v = real3(roughnessB * TdotH, roughnessT * BdotH, a2 * NdotH);
real s = dot(v, v);
real lambdaV = NdotL * partLambdaV;
real lambdaL = NdotV * length(real3(roughnessT * TdotL, roughnessB * BdotL, NdotL));
real2 D = real2(a2 * a2 * a2, s * s); // Fraction without the multiplier (1/Pi)
real2 G = real2(1, lambdaV + lambdaL); // Fraction without the multiplier (1/2)
// This function is only used for direct lighting.
// If roughness is 0, the probability of hitting a punctual or directional light is also 0.
// Therefore, we return 0. The most efficient way to do it is with a max().
return (INV_PI * 0.5) * (D.x * G.x) / max(D.y * G.y, REAL_MIN);
}
real DV_SmithJointGGXAniso(real TdotH, real BdotH, real NdotH,
real TdotV, real BdotV, real NdotV,
real TdotL, real BdotL, real NdotL,
real roughnessT, real roughnessB)
{
real partLambdaV = GetSmithJointGGXAnisoPartLambdaV(TdotV, BdotV, NdotV, roughnessT, roughnessB);
return DV_SmithJointGGXAniso(TdotH, BdotH, NdotH, NdotV,
TdotL, BdotL, NdotL,
roughnessT, roughnessB, partLambdaV);
}
// Get projected roughness for a certain normalized direction V in tangent space
// and an anisotropic roughness
// Ref: Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs, Heitz 2014, pp. 86, 88 - 39/60, 41/60
float GetProjectedRoughness(float TdotV, float BdotV, float NdotV, float roughnessT, float roughnessB)
{
float2 roughness = float2(roughnessT, roughnessB);
float sinTheta2 = max((1 - Sq(NdotV)), FLT_MIN);
// if sinTheta^2 = 0, NdotV = 1, TdotV = BdotV = 0 and roughness is arbitrary, no real azimuth
// as there's a breakdown of the spherical parameterization, so we clamp under by FLT_MIN in any case
// for safe division
// Note:
// sin(thetaV)^2 * cos(phiV)^2 = (TdotV)^2
// sin(thetaV)^2 * sin(phiV)^2 = (BdotV)^2
float2 vProj2 = Sq(float2(TdotV, BdotV)) * rcp(sinTheta2);
// vProj2 = (cos^2(phi), sin^2(phi))
float projRoughness = sqrt(dot(vProj2, roughness*roughness));
return projRoughness;
}
//-----------------------------------------------------------------------------
// Diffuse BRDF - diffuseColor is expected to be multiply by the caller
//-----------------------------------------------------------------------------
real LambertNoPI()
{
return 1.0;
}
real Lambert()
{
return INV_PI;
}
real DisneyDiffuseNoPI(real NdotV, real NdotL, real LdotV, real perceptualRoughness)
{
// (2 * LdotH * LdotH) = 1 + LdotV
// real fd90 = 0.5 + (2 * LdotH * LdotH) * perceptualRoughness;
real fd90 = 0.5 + (perceptualRoughness + perceptualRoughness * LdotV);
// Two schlick fresnel term
real lightScatter = F_Schlick(1.0, fd90, NdotL);
real viewScatter = F_Schlick(1.0, fd90, NdotV);
// Normalize the BRDF for polar view angles of up to (Pi/4).
// We use the worst case of (roughness = albedo = 1), and, for each view angle,
// integrate (brdf * cos(theta_light)) over all light directions.
// The resulting value is for (theta_view = 0), which is actually a little bit larger
// than the value of the integral for (theta_view = Pi/4).
// Hopefully, the compiler folds the constant together with (1/Pi).
return rcp(1.03571) * (lightScatter * viewScatter);
}
#ifndef BUILTIN_TARGET_API
real DisneyDiffuse(real NdotV, real NdotL, real LdotV, real perceptualRoughness)
{
return INV_PI * DisneyDiffuseNoPI(NdotV, NdotL, LdotV, perceptualRoughness);
}
#endif
// Ref: Diffuse Lighting for GGX + Smith Microsurfaces, p. 113.
real3 DiffuseGGXNoPI(real3 albedo, real NdotV, real NdotL, real NdotH, real LdotV, real roughness)
{
real facing = 0.5 + 0.5 * LdotV; // (LdotH)^2
real rough = facing * (0.9 - 0.4 * facing) * (0.5 / NdotH + 1);
real transmitL = F_Transm_Schlick(0, NdotL);
real transmitV = F_Transm_Schlick(0, NdotV);
real smooth = transmitL * transmitV * 1.05; // Normalize F_t over the hemisphere
real single = lerp(smooth, rough, roughness); // Rescaled by PI
real multiple = roughness * (0.1159 * PI); // Rescaled by PI
return single + albedo * multiple;
}
real3 DiffuseGGX(real3 albedo, real NdotV, real NdotL, real NdotH, real LdotV, real roughness)
{
// Note that we could save 2 cycles by inlining the multiplication by INV_PI.
return INV_PI * DiffuseGGXNoPI(albedo, NdotV, NdotL, NdotH, LdotV, roughness);
}
//-----------------------------------------------------------------------------
// Iridescence
//-----------------------------------------------------------------------------
// Ref: https://belcour.github.io/blog/research/2017/05/01/brdf-thin-film.html
// Evaluation XYZ sensitivity curves in Fourier space
real3 EvalSensitivity(real opd, real shift)
{
// Use Gaussian fits, given by 3 parameters: val, pos and var
real phase = 2.0 * PI * opd * 1e-6;
real3 val = real3(5.4856e-13, 4.4201e-13, 5.2481e-13);
real3 pos = real3(1.6810e+06, 1.7953e+06, 2.2084e+06);
real3 var = real3(4.3278e+09, 9.3046e+09, 6.6121e+09);
real3 xyz = val * sqrt(2.0 * PI * var) * cos(pos * phase + shift) * exp(-var * phase * phase);
xyz.x += 9.7470e-14 * sqrt(2.0 * PI * 4.5282e+09) * cos(2.2399e+06 * phase + shift) * exp(-4.5282e+09 * phase * phase);
xyz /= 1.0685e-7;
// Convert to linear sRGb color space here.
// EvalIridescence works in linear sRGB color space and does not switch...
real3 srgb = mul(XYZ_2_REC709_MAT, xyz);
return srgb;
}
// Evaluate the reflectance for a thin-film layer on top of a dielectric medum.
real3 EvalIridescence(real eta_1, real cosTheta1, real iridescenceThickness, real3 baseLayerFresnel0, real iorOverBaseLayer = 0.0)
{
real3 I;
// iridescenceThickness unit is micrometer for this equation here. Mean 0.5 is 500nm.
real Dinc = 3.0 * iridescenceThickness;
// Note: Unlike the code provide with the paper, here we use schlick approximation
// Schlick is a very poor approximation when dealing with iridescence to the Fresnel
// term and there is no "neutral" value in this unlike in the original paper.
// We use Iridescence mask here to allow to have neutral value
// Hack: In order to use only one parameter (DInc), we deduced the ior of iridescence from current Dinc iridescenceThickness
// and we use mask instead to fade out the effect
real eta_2 = lerp(2.0, 1.0, iridescenceThickness);
// Following line from original code is not needed for us, it create a discontinuity
// Force eta_2 -> eta_1 when Dinc -> 0.0
// real eta_2 = lerp(eta_1, eta_2, smoothstep(0.0, 0.03, Dinc));
// Evaluate the cosTheta on the base layer (Snell law)
real sinTheta2Sq = Sq(eta_1 / eta_2) * (1.0 - Sq(cosTheta1));
// Handle TIR:
// (Also note that with just testing sinTheta2Sq > 1.0, (1.0 - sinTheta2Sq) can be negative, as emitted instructions
// can eg be a mad giving a small negative for (1.0 - sinTheta2Sq), while sinTheta2Sq still testing equal to 1.0), so we actually
// test the operand [cosTheta2Sq := (1.0 - sinTheta2Sq)] < 0 directly:)
real cosTheta2Sq = (1.0 - sinTheta2Sq);
// Or use this "artistic hack" to get more continuity even though wrong (no TIR, continue the effect by mirroring it):
// if( cosTheta2Sq < 0.0 ) => { sinTheta2Sq = 2 - sinTheta2Sq; => so cosTheta2Sq = sinTheta2Sq - 1 }
// ie don't test and simply do
// real cosTheta2Sq = abs(1.0 - sinTheta2Sq);
if (cosTheta2Sq < 0.0)
I = real3(1.0, 1.0, 1.0);
else
{
real cosTheta2 = sqrt(cosTheta2Sq);
// First interface
real R0 = IorToFresnel0(eta_2, eta_1);
real R12 = F_Schlick(R0, cosTheta1);
real R21 = R12;
real T121 = 1.0 - R12;
real phi12 = 0.0;
real phi21 = PI - phi12;
// Second interface
// The f0 or the base should account for the new computed eta_2 on top.
// This is optionally done if we are given the needed current ior over the base layer that is accounted for
// in the baseLayerFresnel0 parameter:
if (iorOverBaseLayer > 0.0)
{
// Fresnel0ToIor will give us a ratio of baseIor/topIor, hence we * iorOverBaseLayer to get the baseIor
real3 baseIor = iorOverBaseLayer * Fresnel0ToIor(baseLayerFresnel0 + 0.0001); // guard against 1.0
baseLayerFresnel0 = IorToFresnel0(baseIor, eta_2);
}
real3 R23 = F_Schlick(baseLayerFresnel0, cosTheta2);
real phi23 = 0.0;
// Phase shift
real OPD = Dinc * cosTheta2;
real phi = phi21 + phi23;
// Compound terms
real3 R123 = clamp(R12 * R23, 1e-5, 0.9999);
real3 r123 = sqrt(R123);
real3 Rs = Sq(T121) * R23 / (real3(1.0, 1.0, 1.0) - R123);
// Reflectance term for m = 0 (DC term amplitude)
real3 C0 = R12 + Rs;
I = C0;
// Reflectance term for m > 0 (pairs of diracs)
real3 Cm = Rs - T121;
for (int m = 1; m <= 2; ++m)
{
Cm *= r123;
real3 Sm = 2.0 * EvalSensitivity(m * OPD, m * phi);
//vec3 SmP = 2.0 * evalSensitivity(m*OPD, m*phi2.y);
I += Cm * Sm;
}
// Since out of gamut colors might be produced, negative color values are clamped to 0.
I = max(I, float3(0.0, 0.0, 0.0));
}
return I;
}
//-----------------------------------------------------------------------------
// Fabric
//-----------------------------------------------------------------------------
// Ref: https://knarkowicz.wordpress.com/2018/01/04/cloth-shading/
real D_CharlieNoPI(real NdotH, real roughness)
{
float invR = rcp(roughness);
float cos2h = NdotH * NdotH;
float sin2h = 1.0 - cos2h;
// Note: We have sin^2 so multiply by 0.5 to cancel it
return (2.0 + invR) * PositivePow(sin2h, invR * 0.5) / 2.0;
}
real D_Charlie(real NdotH, real roughness)
{
return INV_PI * D_CharlieNoPI(NdotH, roughness);
}
real CharlieL(real x, real r)
{
r = saturate(r);
r = 1.0 - (1.0 - r) * (1.0 - r);
float a = lerp(25.3245, 21.5473, r);
float b = lerp(3.32435, 3.82987, r);
float c = lerp(0.16801, 0.19823, r);
float d = lerp(-1.27393, -1.97760, r);
float e = lerp(-4.85967, -4.32054, r);
return a / (1. + b * PositivePow(x, c)) + d * x + e;
}
// Note: This version don't include the softening of the paper: Production Friendly Microfacet Sheen BRDF
real V_Charlie(real NdotL, real NdotV, real roughness)
{
real lambdaV = NdotV < 0.5 ? exp(CharlieL(NdotV, roughness)) : exp(2.0 * CharlieL(0.5, roughness) - CharlieL(1.0 - NdotV, roughness));
real lambdaL = NdotL < 0.5 ? exp(CharlieL(NdotL, roughness)) : exp(2.0 * CharlieL(0.5, roughness) - CharlieL(1.0 - NdotL, roughness));
return 1.0 / ((1.0 + lambdaV + lambdaL) * (4.0 * NdotV * NdotL));
}
// We use V_Ashikhmin instead of V_Charlie in practice for game due to the cost of V_Charlie
real V_Ashikhmin(real NdotL, real NdotV)
{
// Use soft visibility term introduce in: Crafting a Next-Gen Material Pipeline for The Order : 1886
return 1.0 / (4.0 * (NdotL + NdotV - NdotL * NdotV));
}
// A diffuse term use with fabric done by tech artist - empirical
real FabricLambertNoPI(real roughness)
{
return lerp(1.0, 0.5, roughness);
}
real FabricLambert(real roughness)
{
return INV_PI * FabricLambertNoPI(roughness);
}
real G_CookTorrance(real NdotH, real NdotV, real NdotL, real HdotV)
{
return min(1.0, 2.0 * NdotH * min(NdotV, NdotL) / HdotV);
}
//-----------------------------------------------------------------------------
// Hair
//-----------------------------------------------------------------------------
//http://web.engr.oregonstate.edu/~mjb/cs519/Projects/Papers/HairRendering.pdf
real3 ShiftTangent(real3 T, real3 N, real shift)
{
return normalize(T + N * shift);
}
// Note: this is Blinn-Phong, the original paper uses Phong.
real3 D_KajiyaKay(real3 T, real3 H, real specularExponent)
{
real TdotH = dot(T, H);
real sinTHSq = saturate(1.0 - TdotH * TdotH);
real dirAttn = saturate(TdotH + 1.0); // Evgenii: this seems like a hack? Do we really need this?
// Note: Kajiya-Kay is not energy conserving.
// We attempt at least some energy conservation by approximately normalizing Blinn-Phong NDF.
// We use the formulation with the NdotL.
// See http://www.thetenthplanet.de/archives/255.
real n = specularExponent;
real norm = (n + 2) * rcp(2 * PI);
return dirAttn * norm * PositivePow(sinTHSq, 0.5 * n);
}
#if SHADER_API_MOBILE || SHADER_API_GLES || SHADER_API_GLES3
#pragma warning (enable : 3205) // conversion of larger type to smaller
#endif
#endif // UNITY_BSDF_INCLUDED

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5eb5e8e99ae281342bae5c7b296b3ae3
timeCreated: 1472140530
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,745 @@
#ifndef UNITY_COLOR_INCLUDED
#define UNITY_COLOR_INCLUDED
#if SHADER_API_MOBILE || SHADER_API_GLES || SHADER_API_GLES3
#pragma warning (disable : 3205) // conversion of larger type to smaller
#endif
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/ACES.hlsl"
//-----------------------------------------------------------------------------
// Gamma space - Assume positive values
//-----------------------------------------------------------------------------
// Gamma20
real Gamma20ToLinear(real c)
{
return c * c;
}
real3 Gamma20ToLinear(real3 c)
{
return c.rgb * c.rgb;
}
real4 Gamma20ToLinear(real4 c)
{
return real4(Gamma20ToLinear(c.rgb), c.a);
}
real LinearToGamma20(real c)
{
return sqrt(c);
}
real3 LinearToGamma20(real3 c)
{
return sqrt(c.rgb);
}
real4 LinearToGamma20(real4 c)
{
return real4(LinearToGamma20(c.rgb), c.a);
}
// Gamma22
real Gamma22ToLinear(real c)
{
return PositivePow(c, 2.2);
}
real3 Gamma22ToLinear(real3 c)
{
return PositivePow(c.rgb, real3(2.2, 2.2, 2.2));
}
real4 Gamma22ToLinear(real4 c)
{
return real4(Gamma22ToLinear(c.rgb), c.a);
}
real LinearToGamma22(real c)
{
return PositivePow(c, 0.454545454545455);
}
real3 LinearToGamma22(real3 c)
{
return PositivePow(c.rgb, real3(0.454545454545455, 0.454545454545455, 0.454545454545455));
}
real4 LinearToGamma22(real4 c)
{
return real4(LinearToGamma22(c.rgb), c.a);
}
// sRGB
real SRGBToLinear(real c)
{
#if defined(UNITY_COLORSPACE_GAMMA) && REAL_IS_HALF
c = min(c, 100.0); // Make sure not to exceed HALF_MAX after the pow() below
#endif
real linearRGBLo = c / 12.92;
real linearRGBHi = PositivePow((c + 0.055) / 1.055, 2.4);
real linearRGB = (c <= 0.04045) ? linearRGBLo : linearRGBHi;
return linearRGB;
}
real2 SRGBToLinear(real2 c)
{
#if defined(UNITY_COLORSPACE_GAMMA) && REAL_IS_HALF
c = min(c, 100.0); // Make sure not to exceed HALF_MAX after the pow() below
#endif
real2 linearRGBLo = c / 12.92;
real2 linearRGBHi = PositivePow((c + 0.055) / 1.055, real2(2.4, 2.4));
real2 linearRGB = (c <= 0.04045) ? linearRGBLo : linearRGBHi;
return linearRGB;
}
real3 SRGBToLinear(real3 c)
{
#if defined(UNITY_COLORSPACE_GAMMA) && REAL_IS_HALF
c = min(c, 100.0); // Make sure not to exceed HALF_MAX after the pow() below
#endif
real3 linearRGBLo = c / 12.92;
real3 linearRGBHi = PositivePow((c + 0.055) / 1.055, real3(2.4, 2.4, 2.4));
real3 linearRGB = (c <= 0.04045) ? linearRGBLo : linearRGBHi;
return linearRGB;
}
real4 SRGBToLinear(real4 c)
{
return real4(SRGBToLinear(c.rgb), c.a);
}
real LinearToSRGB(real c)
{
real sRGBLo = c * 12.92;
real sRGBHi = (PositivePow(c, 1.0/2.4) * 1.055) - 0.055;
real sRGB = (c <= 0.0031308) ? sRGBLo : sRGBHi;
return sRGB;
}
real2 LinearToSRGB(real2 c)
{
real2 sRGBLo = c * 12.92;
real2 sRGBHi = (PositivePow(c, real2(1.0/2.4, 1.0/2.4)) * 1.055) - 0.055;
real2 sRGB = (c <= 0.0031308) ? sRGBLo : sRGBHi;
return sRGB;
}
real3 LinearToSRGB(real3 c)
{
real3 sRGBLo = c * 12.92;
real3 sRGBHi = (PositivePow(c, real3(1.0/2.4, 1.0/2.4, 1.0/2.4)) * 1.055) - 0.055;
real3 sRGB = (c <= 0.0031308) ? sRGBLo : sRGBHi;
return sRGB;
}
real4 LinearToSRGB(real4 c)
{
return real4(LinearToSRGB(c.rgb), c.a);
}
// TODO: Seb - To verify and refit!
// Ref: http://chilliant.blogspot.com.au/2012/08/srgb-approximations-for-hlsl.html?m=1
real FastSRGBToLinear(real c)
{
return c * (c * (c * 0.305306011 + 0.682171111) + 0.012522878);
}
real2 FastSRGBToLinear(real2 c)
{
return c * (c * (c * 0.305306011 + 0.682171111) + 0.012522878);
}
real3 FastSRGBToLinear(real3 c)
{
return c * (c * (c * 0.305306011 + 0.682171111) + 0.012522878);
}
real4 FastSRGBToLinear(real4 c)
{
return real4(FastSRGBToLinear(c.rgb), c.a);
}
real FastLinearToSRGB(real c)
{
return saturate(1.055 * PositivePow(c, 0.416666667) - 0.055);
}
real2 FastLinearToSRGB(real2 c)
{
return saturate(1.055 * PositivePow(c, 0.416666667) - 0.055);
}
real3 FastLinearToSRGB(real3 c)
{
return saturate(1.055 * PositivePow(c, 0.416666667) - 0.055);
}
real4 FastLinearToSRGB(real4 c)
{
return real4(FastLinearToSRGB(c.rgb), c.a);
}
//-----------------------------------------------------------------------------
// Color space
//-----------------------------------------------------------------------------
// Convert rgb to luminance
// with rgb in linear space with sRGB primaries and D65 white point
#ifndef BUILTIN_TARGET_API
real Luminance(real3 linearRgb)
{
return dot(linearRgb, real3(0.2126729, 0.7151522, 0.0721750));
}
#endif
real Luminance(real4 linearRgba)
{
return Luminance(linearRgba.rgb);
}
real AcesLuminance(real3 linearRgb)
{
return dot(linearRgb, AP1_RGB2Y);
}
real AcesLuminance(real4 linearRgba)
{
return AcesLuminance(linearRgba.rgb);
}
// Scotopic luminance approximation - input is in XYZ space
// Note: the range of values returned is approximately [0;4]
// "A spatial postprocessing algorithm for images of night scenes"
// William B. Thompson, Peter Shirley, and James A. Ferwerda
real ScotopicLuminance(real3 xyzRgb)
{
float X = xyzRgb.x;
float Y = xyzRgb.y;
float Z = xyzRgb.z;
return Y * (1.33 * (1.0 + (Y + Z) / X) - 1.68);
}
real ScotopicLuminance(real4 xyzRgba)
{
return ScotopicLuminance(xyzRgba.rgb);
}
// This function take a rgb color (best is to provide color in sRGB space)
// and return a YCoCg color in [0..1] space for 8bit (An offset is apply in the function)
// Ref: http://www.nvidia.com/object/real-time-ycocg-dxt-compression.html
#define YCOCG_CHROMA_BIAS (128.0 / 255.0)
real3 RGBToYCoCg(real3 rgb)
{
real3 YCoCg;
YCoCg.x = dot(rgb, real3(0.25, 0.5, 0.25));
YCoCg.y = dot(rgb, real3(0.5, 0.0, -0.5)) + YCOCG_CHROMA_BIAS;
YCoCg.z = dot(rgb, real3(-0.25, 0.5, -0.25)) + YCOCG_CHROMA_BIAS;
return YCoCg;
}
real3 YCoCgToRGB(real3 YCoCg)
{
real Y = YCoCg.x;
real Co = YCoCg.y - YCOCG_CHROMA_BIAS;
real Cg = YCoCg.z - YCOCG_CHROMA_BIAS;
real3 rgb;
rgb.r = Y + Co - Cg;
rgb.g = Y + Cg;
rgb.b = Y - Co - Cg;
return rgb;
}
// Following function can be use to reconstruct chroma component for a checkboard YCoCg pattern
// Reference: The Compact YCoCg Frame Buffer
real YCoCgCheckBoardEdgeFilter(real centerLum, real2 a0, real2 a1, real2 a2, real2 a3)
{
real4 lum = real4(a0.x, a1.x, a2.x, a3.x);
// Optimize: real4 w = 1.0 - step(30.0 / 255.0, abs(lum - centerLum));
real4 w = 1.0 - saturate((abs(lum.xxxx - centerLum) - 30.0 / 255.0) * HALF_MAX);
real W = w.x + w.y + w.z + w.w;
// handle the special case where all the weights are zero.
return (W == 0.0) ? a0.y : (w.x * a0.y + w.y* a1.y + w.z* a2.y + w.w * a3.y) / W;
}
// Converts linear RGB to LMS
// Full float precision to avoid precision artefact when using ACES tonemapping
float3 LinearToLMS(float3 x)
{
const real3x3 LIN_2_LMS_MAT = {
3.90405e-1, 5.49941e-1, 8.92632e-3,
7.08416e-2, 9.63172e-1, 1.35775e-3,
2.31082e-2, 1.28021e-1, 9.36245e-1
};
return mul(LIN_2_LMS_MAT, x);
}
// Full float precision to avoid precision artefact when using ACES tonemapping
float3 LMSToLinear(float3 x)
{
const real3x3 LMS_2_LIN_MAT = {
2.85847e+0, -1.62879e+0, -2.48910e-2,
-2.10182e-1, 1.15820e+0, 3.24281e-4,
-4.18120e-2, -1.18169e-1, 1.06867e+0
};
return mul(LMS_2_LIN_MAT, x);
}
// Hue, Saturation, Value
// Ranges:
// Hue [0.0, 1.0]
// Sat [0.0, 1.0]
// Lum [0.0, HALF_MAX]
real3 RgbToHsv(real3 c)
{
const real4 K = real4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
real4 p = lerp(real4(c.bg, K.wz), real4(c.gb, K.xy), step(c.b, c.g));
real4 q = lerp(real4(p.xyw, c.r), real4(c.r, p.yzx), step(p.x, c.r));
real d = q.x - min(q.w, q.y);
const real e = 1.0e-4;
return real3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}
real3 HsvToRgb(real3 c)
{
const real4 K = real4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
real3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);
return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y);
}
real RotateHue(real value, real low, real hi)
{
return (value < low)
? value + hi
: (value > hi)
? value - hi
: value;
}
// CIE xyY to CIE 1931 XYZ
float3 xyYtoXYZ(float3 xyY)
{
float x = xyY.x;
float y = xyY.y;
float Y = xyY.z;
float X = (Y / y) * x;
float Z = (Y / y) * (1.0 - x - y);
return float3(X, Y, Z);
}
// CIE 1931 XYZ to CIE xy (Y component not returned)
float2 XYZtoxy(float3 XYZ)
{
return XYZ.xy / (dot(XYZ, 1));
}
// Soft-light blending mode use for split-toning. Works in HDR as long as `blend` is [0;1] which is
// fine for our use case.
float3 SoftLight(float3 base, float3 blend)
{
float3 r1 = 2.0 * base * blend + base * base * (1.0 - 2.0 * blend);
float3 r2 = sqrt(base) * (2.0 * blend - 1.0) + 2.0 * base * (1.0 - blend);
float3 t = step(0.5, blend);
return r2 * t + (1.0 - t) * r1;
}
// Alexa LogC converters (El 1000)
// See http://www.vocas.nl/webfm_send/964
// Max range is ~58.85666
// Set to 1 to use more precise but more expensive log/linear conversions. I haven't found a proper
// use case for the high precision version yet so I'm leaving this to 0.
#define USE_PRECISE_LOGC 0
struct ParamsLogC
{
real cut;
real a, b, c, d, e, f;
};
static const ParamsLogC LogC =
{
0.011361, // cut
5.555556, // a
0.047996, // b
0.244161, // c
0.386036, // d
5.301883, // e
0.092819 // f
};
real LinearToLogC_Precise(real x)
{
real o;
if (x > LogC.cut)
o = LogC.c * log10(max(LogC.a * x + LogC.b, 0.0)) + LogC.d;
else
o = LogC.e * x + LogC.f;
return o;
}
// Full float precision to avoid precision artefact when using ACES tonemapping
float3 LinearToLogC(float3 x)
{
#if USE_PRECISE_LOGC
return real3(
LinearToLogC_Precise(x.x),
LinearToLogC_Precise(x.y),
LinearToLogC_Precise(x.z)
);
#else
return LogC.c * log10(max(LogC.a * x + LogC.b, 0.0)) + LogC.d;
#endif
}
real LogCToLinear_Precise(real x)
{
real o;
if (x > LogC.e * LogC.cut + LogC.f)
o = (pow(10.0, (x - LogC.d) / LogC.c) - LogC.b) / LogC.a;
else
o = (x - LogC.f) / LogC.e;
return o;
}
// Full float precision to avoid precision artefact when using ACES tonemapping
float3 LogCToLinear(float3 x)
{
#if USE_PRECISE_LOGC
return real3(
LogCToLinear_Precise(x.x),
LogCToLinear_Precise(x.y),
LogCToLinear_Precise(x.z)
);
#else
return (pow(10.0, (x - LogC.d) / LogC.c) - LogC.b) / LogC.a;
#endif
}
//-----------------------------------------------------------------------------
// Utilities
//-----------------------------------------------------------------------------
real3 Desaturate(real3 value, real saturation)
{
// Saturation = Colorfulness / Brightness.
// https://munsell.com/color-blog/difference-chroma-saturation/
real mean = Avg3(value.r, value.g, value.b);
real3 dev = value - mean;
return mean + dev * saturation;
}
// Fast reversible tonemapper
// http://gpuopen.com/optimized-reversible-tonemapper-for-resolve/
real FastTonemapPerChannel(real c)
{
return c * rcp(c + 1.0);
}
real2 FastTonemapPerChannel(real2 c)
{
return c * rcp(c + 1.0);
}
real3 FastTonemap(real3 c)
{
return c * rcp(Max3(c.r, c.g, c.b) + 1.0);
}
real4 FastTonemap(real4 c)
{
return real4(FastTonemap(c.rgb), c.a);
}
real3 FastTonemap(real3 c, real w)
{
return c * (w * rcp(Max3(c.r, c.g, c.b) + 1.0));
}
real4 FastTonemap(real4 c, real w)
{
return real4(FastTonemap(c.rgb, w), c.a);
}
real FastTonemapPerChannelInvert(real c)
{
return c * rcp(1.0 - c);
}
real2 FastTonemapPerChannelInvert(real2 c)
{
return c * rcp(1.0 - c);
}
real3 FastTonemapInvert(real3 c)
{
return c * rcp(1.0 - Max3(c.r, c.g, c.b));
}
real4 FastTonemapInvert(real4 c)
{
return real4(FastTonemapInvert(c.rgb), c.a);
}
#ifndef SHADER_API_GLES
// 3D LUT grading
// scaleOffset = (1 / lut_size, lut_size - 1)
real3 ApplyLut3D(TEXTURE3D_PARAM(tex, samplerTex), float3 uvw, float2 scaleOffset)
{
uvw.xyz = uvw.xyz * scaleOffset.yyy * scaleOffset.xxx + scaleOffset.xxx * 0.5;
return SAMPLE_TEXTURE3D_LOD(tex, samplerTex, uvw, 0.0).rgb;
}
#endif
// 2D LUT grading
// scaleOffset = (1 / lut_width, 1 / lut_height, lut_height - 1)
real3 ApplyLut2D(TEXTURE2D_PARAM(tex, samplerTex), float3 uvw, float3 scaleOffset)
{
// Strip format where `height = sqrt(width)`
uvw.z *= scaleOffset.z;
float shift = floor(uvw.z);
uvw.xy = uvw.xy * scaleOffset.z * scaleOffset.xy + scaleOffset.xy * 0.5;
uvw.x += shift * scaleOffset.y;
uvw.xyz = lerp(
SAMPLE_TEXTURE2D_LOD(tex, samplerTex, uvw.xy, 0.0).rgb,
SAMPLE_TEXTURE2D_LOD(tex, samplerTex, uvw.xy + float2(scaleOffset.y, 0.0), 0.0).rgb,
uvw.z - shift
);
return uvw;
}
// Returns the default value for a given position on a 2D strip-format color lookup table
// params = (lut_height, 0.5 / lut_width, 0.5 / lut_height, lut_height / lut_height - 1)
real3 GetLutStripValue(float2 uv, float4 params)
{
uv -= params.yz;
real3 color;
color.r = frac(uv.x * params.x);
color.b = uv.x - color.r / params.x;
color.g = uv.y;
return color * params.w;
}
// Neutral tonemapping (Hable/Hejl/Frostbite)
// Input is linear RGB
// More accuracy to avoid NaN on extremely high values.
float3 NeutralCurve(float3 x, real a, real b, real c, real d, real e, real f)
{
return ((x * (a * x + c * b) + d * e) / (x * (a * x + b) + d * f)) - e / f;
}
#define TONEMAPPING_CLAMP_MAX 435.18712 //(-b + sqrt(b * b - 4 * a * (HALF_MAX - d * f))) / (2 * a * whiteScale)
//Extremely high values cause NaN output when using fp16, we clamp to avoid the performace hit of switching to fp32
//The overflow happens in (x * (a * x + b) + d * f) of the NeutralCurve, highest value that avoids fp16 precision errors is ~571.56873
//Since whiteScale is constant (~1.31338) max input is ~435.18712
real3 NeutralTonemap(real3 x)
{
// Tonemap
const real a = 0.2;
const real b = 0.29;
const real c = 0.24;
const real d = 0.272;
const real e = 0.02;
const real f = 0.3;
const real whiteLevel = 5.3;
const real whiteClip = 1.0;
#if defined(SHADER_API_MOBILE)
x = min(x, TONEMAPPING_CLAMP_MAX);
#endif
real3 whiteScale = (1.0).xxx / NeutralCurve(whiteLevel, a, b, c, d, e, f);
x = NeutralCurve(x * whiteScale, a, b, c, d, e, f);
x *= whiteScale;
// Post-curve white point adjustment
x /= whiteClip.xxx;
return x;
}
// Raw, unoptimized version of John Hable's artist-friendly tone curve
// Input is linear RGB
real EvalCustomSegment(real x, real4 segmentA, real2 segmentB)
{
const real kOffsetX = segmentA.x;
const real kOffsetY = segmentA.y;
const real kScaleX = segmentA.z;
const real kScaleY = segmentA.w;
const real kLnA = segmentB.x;
const real kB = segmentB.y;
real x0 = (x - kOffsetX) * kScaleX;
real y0 = (x0 > 0.0) ? exp(kLnA + kB * log(x0)) : 0.0;
return y0 * kScaleY + kOffsetY;
}
real EvalCustomCurve(real x, real3 curve, real4 toeSegmentA, real2 toeSegmentB, real4 midSegmentA, real2 midSegmentB, real4 shoSegmentA, real2 shoSegmentB)
{
real4 segmentA;
real2 segmentB;
if (x < curve.y)
{
segmentA = toeSegmentA;
segmentB = toeSegmentB;
}
else if (x < curve.z)
{
segmentA = midSegmentA;
segmentB = midSegmentB;
}
else
{
segmentA = shoSegmentA;
segmentB = shoSegmentB;
}
return EvalCustomSegment(x, segmentA, segmentB);
}
// curve: x: inverseWhitePoint, y: x0, z: x1
real3 CustomTonemap(real3 x, real3 curve, real4 toeSegmentA, real2 toeSegmentB, real4 midSegmentA, real2 midSegmentB, real4 shoSegmentA, real2 shoSegmentB)
{
real3 normX = x * curve.x;
real3 ret;
ret.x = EvalCustomCurve(normX.x, curve, toeSegmentA, toeSegmentB, midSegmentA, midSegmentB, shoSegmentA, shoSegmentB);
ret.y = EvalCustomCurve(normX.y, curve, toeSegmentA, toeSegmentB, midSegmentA, midSegmentB, shoSegmentA, shoSegmentB);
ret.z = EvalCustomCurve(normX.z, curve, toeSegmentA, toeSegmentB, midSegmentA, midSegmentB, shoSegmentA, shoSegmentB);
return ret;
}
// Coming from STP, to replace when STP lands.
#define SAT 8.0f
real3 InvertibleTonemap(real3 x)
{
real y = rcp(real(SAT) + Max3(x.r, x.g, x.b));
return saturate(x * real(y));
}
real3 InvertibleTonemapInverse(real3 x)
{
float y = rcp(max(real(1.0 / 32768.0), saturate(real(1.0 / SAT) - Max3(x.r, x.g, x.b) * real(1.0 / SAT))));
return x * y;
}
// Filmic tonemapping (ACES fitting, unless TONEMAPPING_USE_FULL_ACES is set to 1)
// Input is ACES2065-1 (AP0 w/ linear encoding)
#ifndef TONEMAPPING_USE_FULL_ACES
#define TONEMAPPING_USE_FULL_ACES 0
#endif
float3 AcesTonemap(float3 aces)
{
#if TONEMAPPING_USE_FULL_ACES
float3 oces = RRT(aces);
float3 odt = ODT_RGBmonitor_100nits_dim(oces);
return odt;
#else
// --- Glow module --- //
float saturation = rgb_2_saturation(aces);
float ycIn = rgb_2_yc(aces);
float s = sigmoid_shaper((saturation - 0.4) / 0.2);
float addedGlow = 1.0 + glow_fwd(ycIn, RRT_GLOW_GAIN * s, RRT_GLOW_MID);
aces *= addedGlow;
// --- Red modifier --- //
float hue = rgb_2_hue(aces);
float centeredHue = center_hue(hue, RRT_RED_HUE);
float hueWeight;
{
//hueWeight = cubic_basis_shaper(centeredHue, RRT_RED_WIDTH);
hueWeight = smoothstep(0.0, 1.0, 1.0 - abs(2.0 * centeredHue / RRT_RED_WIDTH));
hueWeight *= hueWeight;
}
aces.r += hueWeight * saturation * (RRT_RED_PIVOT - aces.r) * (1.0 - RRT_RED_SCALE);
// --- ACES to RGB rendering space --- //
float3 acescg = max(0.0, ACES_to_ACEScg(aces));
// --- Global desaturation --- //
//acescg = mul(RRT_SAT_MAT, acescg);
acescg = lerp(dot(acescg, AP1_RGB2Y).xxx, acescg, RRT_SAT_FACTOR.xxx);
// Apply RRT and ODT
// https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl
const float a = 0.0245786f;
const float b = 0.000090537f;
const float c = 0.983729f;
const float d = 0.4329510f;
const float e = 0.238081f;
#if defined(SHADER_API_SWITCH)
// To reduce the likelyhood of extremely large values, we avoid using the x^2 term and therefore
// divide numerator and denominator by it. This will lead to the constant factors of the
// quadratic in the numerator and denominator to be divided by x; we add a tiny epsilon to avoid divide by 0.
float3 rcpAcesCG = rcp(acescg + FLT_MIN);
float3 rgbPost = (acescg + a - b * rcpAcesCG) /
(acescg * c + d + e * rcpAcesCG);
#else
float3 rgbPost = (acescg * (acescg + a) - b) /
(acescg * (c * acescg + d) + e);
#endif
// Scale luminance to linear code value
// float3 linearCV = Y_2_linCV(rgbPost, CINEMA_WHITE, CINEMA_BLACK);
// Apply gamma adjustment to compensate for dim surround
float3 linearCV = darkSurround_to_dimSurround(rgbPost);
// Apply desaturation to compensate for luminance difference
//linearCV = mul(ODT_SAT_MAT, color);
linearCV = lerp(dot(linearCV, AP1_RGB2Y).xxx, linearCV, ODT_SAT_FACTOR.xxx);
// Convert to display primary encoding
// Rendering space RGB to XYZ
float3 XYZ = mul(AP1_2_XYZ_MAT, linearCV);
// Apply CAT from ACES white point to assumed observer adapted white point
XYZ = mul(D60_2_D65_CAT, XYZ);
// CIE XYZ to display primaries
linearCV = mul(XYZ_2_REC709_MAT, XYZ);
return linearCV;
#endif
}
// RGBM encode/decode
static const float kRGBMRange = 8.0;
half4 EncodeRGBM(half3 color)
{
color *= 1.0 / kRGBMRange;
half m = max(max(color.x, color.y), max(color.z, 1e-5));
m = ceil(m * 255) / 255;
return half4(color / m, m);
}
half3 DecodeRGBM(half4 rgbm)
{
return rgbm.xyz * rgbm.w * kRGBMRange;
}
#if SHADER_API_MOBILE || SHADER_API_GLES || SHADER_API_GLES3
#pragma warning (enable : 3205) // conversion of larger type to smaller
#endif
#endif // UNITY_COLOR_INCLUDED

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 23284bbc36146a94995a8a08e61f4e73
timeCreated: 1472140529
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a57f9f83ea626ae45b402953fe637268
timeCreated: 1472140530
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,18 @@
#ifndef UNITY_COMMON_DEPRECATED_INCLUDED
#define UNITY_COMMON_DEPRECATED_INCLUDED
// Function that are in this file shouldn't be use. they are obsolete and could be removed in the future
// they are here to keep compatibility with previous version
#if !defined(SHADER_API_GLES)
// Please use void LODDitheringTransition(uint2 fadeMaskSeed, float ditherFactor)
void LODDitheringTransition(uint3 fadeMaskSeed, float ditherFactor)
{
ditherFactor = ditherFactor < 0.0 ? 1 + ditherFactor : ditherFactor;
float p = GenerateHashedRandomFloat(fadeMaskSeed);
p = (ditherFactor >= 0.5) ? p : 1 - p;
clip(ditherFactor - p);
}
#endif
#endif

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: ca3a5025616550a40816a5272a4f7631
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,510 @@
#ifndef UNITY_COMMON_LIGHTING_INCLUDED
#define UNITY_COMMON_LIGHTING_INCLUDED
#if SHADER_API_MOBILE || SHADER_API_GLES || SHADER_API_GLES3
#pragma warning (disable : 3205) // conversion of larger type to smaller
#endif
// Ligthing convention
// Light direction is oriented backward (-Z). i.e in shader code, light direction is -lightData.forward
//-----------------------------------------------------------------------------
// Helper functions
//-----------------------------------------------------------------------------
// Performs the mapping of the vector 'v' centered within the axis-aligned cube
// of dimensions [-1, 1]^3 to a vector centered within the unit sphere.
// The function expects 'v' to be within the cube (possibly unexpected results otherwise).
// Ref: http://mathproofs.blogspot.com/2005/07/mapping-cube-to-sphere.html
real3 MapCubeToSphere(real3 v)
{
real3 v2 = v * v;
real2 vr3 = v2.xy * rcp(3.0);
return v * sqrt((real3)1.0 - 0.5 * v2.yzx - 0.5 * v2.zxy + vr3.yxx * v2.zzy);
}
// Computes the squared magnitude of the vector computed by MapCubeToSphere().
real ComputeCubeToSphereMapSqMagnitude(real3 v)
{
real3 v2 = v * v;
// Note: dot(v, v) is often computed before this function is called,
// so the compiler should optimize and use the precomputed result here.
return dot(v, v) - v2.x * v2.y - v2.y * v2.z - v2.z * v2.x + v2.x * v2.y * v2.z;
}
// texelArea = 4.0 / (resolution * resolution).
// Ref: http://bpeers.com/blog/?itemid=1017
// This version is less accurate, but much faster than this one:
// http://www.rorydriscoll.com/2012/01/15/cubemap-texel-solid-angle/
real ComputeCubemapTexelSolidAngle(real3 L, real texelArea)
{
// Stretch 'L' by (1/d) so that it points at a side of a [-1, 1]^2 cube.
real d = Max3(abs(L.x), abs(L.y), abs(L.z));
// Since 'L' is a unit vector, we can directly compute its
// new (inverse) length without dividing 'L' by 'd' first.
real invDist = d;
// dw = dA * cosTheta / (dist * dist), cosTheta = 1.0 / dist,
// where 'dA' is the area of the cube map texel.
return texelArea * invDist * invDist * invDist;
}
// Only makes sense for Monte-Carlo integration.
// Normalize by dividing by the total weight (or the number of samples) in the end.
// Integrate[6*(u^2+v^2+1)^(-3/2), {u,-1,1},{v,-1,1}] = 4 * Pi
// Ref: "Stupid Spherical Harmonics Tricks", p. 9.
real ComputeCubemapTexelSolidAngle(real2 uv)
{
real u = uv.x, v = uv.y;
return pow(1 + u * u + v * v, -1.5);
}
real ConvertEvToLuminance(real ev)
{
return exp2(ev - 3.0);
}
real ConvertLuminanceToEv(real luminance)
{
real k = 12.5f;
return log2((luminance * 100.0) / k);
}
//-----------------------------------------------------------------------------
// Attenuation functions
//-----------------------------------------------------------------------------
// Ref: Moving Frostbite to PBR.
// Non physically based hack to limit light influence to attenuationRadius.
// Square the result to smoothen the function.
real DistanceWindowing(real distSquare, real rangeAttenuationScale, real rangeAttenuationBias)
{
// If (range attenuation is enabled)
// rangeAttenuationScale = 1 / r^2
// rangeAttenuationBias = 1
// Else
// rangeAttenuationScale = 2^12 / r^2
// rangeAttenuationBias = 2^24
return saturate(rangeAttenuationBias - Sq(distSquare * rangeAttenuationScale));
}
real SmoothDistanceWindowing(real distSquare, real rangeAttenuationScale, real rangeAttenuationBias)
{
real factor = DistanceWindowing(distSquare, rangeAttenuationScale, rangeAttenuationBias);
return Sq(factor);
}
#define PUNCTUAL_LIGHT_THRESHOLD 0.01 // 1cm (in Unity 1 is 1m)
// Return physically based quadratic attenuation + influence limit to reach 0 at attenuationRadius
real SmoothWindowedDistanceAttenuation(real distSquare, real distRcp, real rangeAttenuationScale, real rangeAttenuationBias)
{
real attenuation = min(distRcp, 1.0 / PUNCTUAL_LIGHT_THRESHOLD);
attenuation *= DistanceWindowing(distSquare, rangeAttenuationScale, rangeAttenuationBias);
// Effectively results in (distRcp)^2 * SmoothDistanceWindowing(...).
return Sq(attenuation);
}
// Square the result to smoothen the function.
real AngleAttenuation(real cosFwd, real lightAngleScale, real lightAngleOffset)
{
return saturate(cosFwd * lightAngleScale + lightAngleOffset);
}
real SmoothAngleAttenuation(real cosFwd, real lightAngleScale, real lightAngleOffset)
{
real attenuation = AngleAttenuation(cosFwd, lightAngleScale, lightAngleOffset);
return Sq(attenuation);
}
// Combines SmoothWindowedDistanceAttenuation() and SmoothAngleAttenuation() in an efficient manner.
// distances = {d, d^2, 1/d, d_proj}, where d_proj = dot(lightToSample, lightData.forward).
real PunctualLightAttenuation(real4 distances, real rangeAttenuationScale, real rangeAttenuationBias,
real lightAngleScale, real lightAngleOffset)
{
real distSq = distances.y;
real distRcp = distances.z;
real distProj = distances.w;
real cosFwd = distProj * distRcp;
real attenuation = min(distRcp, 1.0 / PUNCTUAL_LIGHT_THRESHOLD);
attenuation *= DistanceWindowing(distSq, rangeAttenuationScale, rangeAttenuationBias);
attenuation *= AngleAttenuation(cosFwd, lightAngleScale, lightAngleOffset);
// Effectively results in SmoothWindowedDistanceAttenuation(...) * SmoothAngleAttenuation(...).
return Sq(attenuation);
}
// Applies SmoothDistanceWindowing() after transforming the attenuation ellipsoid into a sphere.
// If r = rsqrt(invSqRadius), then the ellipsoid is defined s.t. r1 = r / invAspectRatio, r2 = r3 = r.
// The transformation is performed along the major axis of the ellipsoid (corresponding to 'r1').
// Both the ellipsoid (e.i. 'axis') and 'unL' should be in the same coordinate system.
// 'unL' should be computed from the center of the ellipsoid.
real EllipsoidalDistanceAttenuation(real3 unL, real3 axis, real invAspectRatio,
real rangeAttenuationScale, real rangeAttenuationBias)
{
// Project the unnormalized light vector onto the axis.
real projL = dot(unL, axis);
// Transform the light vector so that we can work with
// with the ellipsoid as if it was a sphere with the radius of light's range.
real diff = projL - projL * invAspectRatio;
unL -= diff * axis;
real sqDist = dot(unL, unL);
return SmoothDistanceWindowing(sqDist, rangeAttenuationScale, rangeAttenuationBias);
}
// Applies SmoothDistanceWindowing() using the axis-aligned ellipsoid of the given dimensions.
// Both the ellipsoid and 'unL' should be in the same coordinate system.
// 'unL' should be computed from the center of the ellipsoid.
real EllipsoidalDistanceAttenuation(real3 unL, real3 invHalfDim,
real rangeAttenuationScale, real rangeAttenuationBias)
{
// Transform the light vector so that we can work with
// with the ellipsoid as if it was a unit sphere.
unL *= invHalfDim;
real sqDist = dot(unL, unL);
return SmoothDistanceWindowing(sqDist, rangeAttenuationScale, rangeAttenuationBias);
}
// Applies SmoothDistanceWindowing() after mapping the axis-aligned box to a sphere.
// If the diagonal of the box is 'd', invHalfDim = rcp(0.5 * d).
// Both the box and 'unL' should be in the same coordinate system.
// 'unL' should be computed from the center of the box.
real BoxDistanceAttenuation(real3 unL, real3 invHalfDim,
real rangeAttenuationScale, real rangeAttenuationBias)
{
real attenuation = 0.0;
// Transform the light vector so that we can work with
// with the box as if it was a [-1, 1]^2 cube.
unL *= invHalfDim;
// Our algorithm expects the input vector to be within the cube.
if (!(Max3(abs(unL.x), abs(unL.y), abs(unL.z)) > 1.0))
{
real sqDist = ComputeCubeToSphereMapSqMagnitude(unL);
attenuation = SmoothDistanceWindowing(sqDist, rangeAttenuationScale, rangeAttenuationBias);
}
return attenuation;
}
//-----------------------------------------------------------------------------
// IES Helper
//-----------------------------------------------------------------------------
real2 GetIESTextureCoordinate(real3x3 lightToWord, real3 L)
{
// IES need to be sample in light space
real3 dir = mul(lightToWord, -L); // Using matrix on left side do a transpose
// convert to spherical coordinate
real2 sphericalCoord; // .x is theta, .y is phi
// Texture is encoded with cos(phi), scale from -1..1 to 0..1
sphericalCoord.y = (dir.z * 0.5) + 0.5;
real theta = atan2(dir.y, dir.x);
sphericalCoord.x = theta * INV_TWO_PI;
return sphericalCoord;
}
//-----------------------------------------------------------------------------
// Lighting functions
//-----------------------------------------------------------------------------
// Ref: Horizon Occlusion for Normal Mapped Reflections: http://marmosetco.tumblr.com/post/81245981087
real GetHorizonOcclusion(real3 V, real3 normalWS, real3 vertexNormal, real horizonFade)
{
real3 R = reflect(-V, normalWS);
real specularOcclusion = saturate(1.0 + horizonFade * dot(R, vertexNormal));
// smooth it
return specularOcclusion * specularOcclusion;
}
// Ref: Moving Frostbite to PBR - Gotanda siggraph 2011
// Return specular occlusion based on ambient occlusion (usually get from SSAO) and view/roughness info
real GetSpecularOcclusionFromAmbientOcclusion(real NdotV, real ambientOcclusion, real roughness)
{
return saturate(PositivePow(NdotV + ambientOcclusion, exp2(-16.0 * roughness - 1.0)) - 1.0 + ambientOcclusion);
}
// ref: Practical Realtime Strategies for Accurate Indirect Occlusion
// Update ambient occlusion to colored ambient occlusion based on statitics of how light is bouncing in an object and with the albedo of the object
real3 GTAOMultiBounce(real visibility, real3 albedo)
{
real3 a = 2.0404 * albedo - 0.3324;
real3 b = -4.7951 * albedo + 0.6417;
real3 c = 2.7552 * albedo + 0.6903;
real x = visibility;
return max(x, ((x * a + b) * x + c) * x);
}
// Based on Oat and Sander's 2007 technique
// Area/solidAngle of intersection of two cone
real SphericalCapIntersectionSolidArea(real cosC1, real cosC2, real cosB)
{
real r1 = FastACos(cosC1);
real r2 = FastACos(cosC2);
real rd = FastACos(cosB);
real area = 0.0;
if (rd <= max(r1, r2) - min(r1, r2))
{
// One cap is completely inside the other
area = TWO_PI - TWO_PI * max(cosC1, cosC2);
}
else if (rd >= r1 + r2)
{
// No intersection exists
area = 0.0;
}
else
{
real diff = abs(r1 - r2);
real den = r1 + r2 - diff;
real x = 1.0 - saturate((rd - diff) / max(den, 0.0001));
area = smoothstep(0.0, 1.0, x);
area *= TWO_PI - TWO_PI * max(cosC1, cosC2);
}
return area;
}
// ref: Practical Realtime Strategies for Accurate Indirect Occlusion
// http://blog.selfshadow.com/publications/s2016-shading-course/#course_content
// Original Cone-Cone method with cosine weighted assumption (p129 s2016_pbs_activision_occlusion)
real GetSpecularOcclusionFromBentAO_ConeCone(real3 V, real3 bentNormalWS, real3 normalWS, real ambientOcclusion, real roughness)
{
// Retrieve cone angle
// Ambient occlusion is cosine weighted, thus use following equation. See slide 129
real cosAv = sqrt(1.0 - ambientOcclusion);
roughness = max(roughness, 0.01); // Clamp to 0.01 to avoid edge cases
real cosAs = exp2((-log(10.0) / log(2.0)) * Sq(roughness));
real cosB = dot(bentNormalWS, reflect(-V, normalWS));
return SphericalCapIntersectionSolidArea(cosAv, cosAs, cosB) / (TWO_PI * (1.0 - cosAs));
}
real GetSpecularOcclusionFromBentAO(real3 V, real3 bentNormalWS, real3 normalWS, real ambientOcclusion, real roughness)
{
// Pseudo code:
//SphericalGaussian NDF = WarpedGGXDistribution(normalWS, roughness, V);
//SphericalGaussian Visibility = VisibilityConeSG(bentNormalWS, ambientOcclusion);
//SphericalGaussian UpperHemisphere = UpperHemisphereSG(normalWS);
//return saturate( InnerProduct(NDF, Visibility) / InnerProduct(NDF, UpperHemisphere) );
// 1. Approximate visibility cone with a spherical gaussian of amplitude A=1
// For a cone angle X, we can determine sharpness so that all point inside the cone have a value > Y
// sharpness = (log(Y) - log(A)) / (cos(X) - 1)
// For AO cone, cos(X) = sqrt(1 - ambientOcclusion)
// -> for Y = 0.1, sharpness = -1.0 / (sqrt(1-ao) - 1)
float vs = -1.0f / min(sqrt(1.0f - ambientOcclusion) - 1.0f, -0.001f);
// 2. Approximate upper hemisphere with sharpness = 0.8 and amplitude = 1
float us = 0.8f;
// 3. Compute warped SG Axis of GGX distribution
// Ref: All-Frequency Rendering of Dynamic, Spatially-Varying Reflectance
// https://www.microsoft.com/en-us/research/wp-content/uploads/2009/12/sg.pdf
float NoV = dot(V, normalWS);
float3 NDFAxis = (2 * NoV * normalWS - V) * (0.5f / max(roughness * roughness * NoV, 0.001f));
float umLength1 = length(NDFAxis + vs * bentNormalWS);
float umLength2 = length(NDFAxis + us * normalWS);
float d1 = 1 - exp(-2 * umLength1);
float d2 = 1 - exp(-2 * umLength2);
float expFactor1 = exp(umLength1 - umLength2 + us - vs);
return saturate(expFactor1 * (d1 * umLength2) / (d2 * umLength1));
}
// Ref: Steve McAuley - Energy-Conserving Wrapped Diffuse
real ComputeWrappedDiffuseLighting(real NdotL, real w)
{
return saturate((NdotL + w) / ((1.0 + w) * (1.0 + w)));
}
// Ref: Stephen McAuley - Advances in Rendering: Graphics Research and Video Game Production
real3 ComputeWrappedNormal(real3 N, real3 L, real w)
{
real NdotL = dot(N, L);
real wrappedNdotL = saturate((NdotL + w) / (1 + w));
real sinPhi = lerp(w, 0.f, wrappedNdotL);
real cosPhi = sqrt(1.0f - sinPhi * sinPhi);
return normalize(cosPhi * N + sinPhi * cross(cross(N, L), N));
}
// Jimenez variant for eye
real ComputeWrappedPowerDiffuseLighting(real NdotL, real w, real p)
{
return pow(saturate((NdotL + w) / (1.0 + w)), p) * (p + 1) / (w * 2.0 + 2.0);
}
// Ref: The Technical Art of Uncharted 4 - Brinck and Maximov 2016
real ComputeMicroShadowing(real AO, real NdotL, real opacity)
{
real aperture = 2.0 * AO * AO;
real microshadow = saturate(NdotL + aperture - 1.0);
return lerp(1.0, microshadow, opacity);
}
real3 ComputeShadowColor(real shadow, real3 shadowTint, real penumbraFlag)
{
// The origin expression is
// lerp(real3(1.0, 1.0, 1.0) - ((1.0 - shadow) * (real3(1.0, 1.0, 1.0) - shadowTint))
// , shadow * lerp(shadowTint, lerp(shadowTint, real3(1.0, 1.0, 1.0), shadow), shadow)
// , penumbraFlag);
// it has been simplified to this
real3 invTint = real3(1.0, 1.0, 1.0) - shadowTint;
real shadow3 = shadow * shadow * shadow;
return lerp(real3(1.0, 1.0, 1.0) - ((1.0 - shadow) * invTint)
, shadow3 * invTint + shadow * shadowTint,
penumbraFlag);
}
// This is the same method as the one above. Simply the shadow is a real3 to support colored shadows.
real3 ComputeShadowColor(real3 shadow, real3 shadowTint, real penumbraFlag)
{
// The origin expression is
// lerp(real3(1.0, 1.0, 1.0) - ((1.0 - shadow) * (real3(1.0, 1.0, 1.0) - shadowTint))
// , shadow * lerp(shadowTint, lerp(shadowTint, real3(1.0, 1.0, 1.0), shadow), shadow)
// , penumbraFlag);
// it has been simplified to this
real3 invTint = real3(1.0, 1.0, 1.0) - shadowTint;
real3 shadow3 = shadow * shadow * shadow;
return lerp(real3(1.0, 1.0, 1.0) - ((1.0 - shadow) * invTint)
, shadow3 * invTint + shadow * shadowTint,
penumbraFlag);
}
//-----------------------------------------------------------------------------
// Helper functions
//--------------------------------------------------------------------------- --
// Ref: "Crafting a Next-Gen Material Pipeline for The Order: 1886".
real ClampNdotV(real NdotV)
{
return max(NdotV, 0.0001); // Approximately 0.0057 degree bias
}
// Helper function to return a set of common angle used when evaluating BSDF
// NdotL and NdotV are unclamped
void GetBSDFAngle(real3 V, real3 L, real NdotL, real NdotV,
out real LdotV, out real NdotH, out real LdotH, out real invLenLV)
{
// Optimized math. Ref: PBR Diffuse Lighting for GGX + Smith Microsurfaces (slide 114), assuming |L|=1 and |V|=1
LdotV = dot(L, V);
invLenLV = rsqrt(max(2.0 * LdotV + 2.0, FLT_EPS)); // invLenLV = rcp(length(L + V)), clamp to avoid rsqrt(0) = inf, inf * 0 = NaN
NdotH = saturate((NdotL + NdotV) * invLenLV);
LdotH = saturate(invLenLV * LdotV + invLenLV);
}
// Inputs: normalized normal and view vectors.
// Outputs: front-facing normal, and the new non-negative value of the cosine of the view angle.
// Important: call Orthonormalize() on the tangent and recompute the bitangent afterwards.
real3 GetViewReflectedNormal(real3 N, real3 V, out real NdotV)
{
// Fragments of front-facing geometry can have back-facing normals due to interpolation,
// normal mapping and decals. This can cause visible artifacts from both direct (negative or
// extremely high values) and indirect (incorrect lookup direction) lighting.
// There are several ways to avoid this problem. To list a few:
//
// 1. Setting { NdotV = max(<N,V>, SMALL_VALUE) }. This effectively removes normal mapping
// from the affected fragments, making the surface appear flat.
//
// 2. Setting { NdotV = abs(<N,V>) }. This effectively reverses the convexity of the surface.
// It also reduces light leaking from non-shadow-casting lights. Note that 'NdotV' can still
// be 0 in this case.
//
// It's important to understand that simply changing the value of the cosine is insufficient.
// For one, it does not solve the incorrect lookup direction problem, since the normal itself
// is not modified. There is a more insidious issue, however. 'NdotV' is a constituent element
// of the mathematical system describing the relationships between different vectors - and
// not just normal and view vectors, but also light vectors, half vectors, tangent vectors, etc.
// Changing only one angle (or its cosine) leaves the system in an inconsistent state, where
// certain relationships can take on different values depending on whether 'NdotV' is used
// in the calculation or not. Therefore, it is important to change the normal (or another
// vector) in order to leave the system in a consistent state.
//
// We choose to follow the conceptual approach (2) by reflecting the normal around the
// (<N,V> = 0) boundary if necessary, as it allows us to preserve some normal mapping details.
NdotV = dot(N, V);
// N = (NdotV >= 0.0) ? N : (N - 2.0 * NdotV * V);
N += (2.0 * saturate(-NdotV)) * V;
NdotV = abs(NdotV);
return N;
}
// Generates an orthonormal (row-major) basis from a unit vector. TODO: make it column-major.
// The resulting rotation matrix has the determinant of +1.
// Ref: 'ortho_basis_pixar_r2' from http://marc-b-reynolds.github.io/quaternions/2016/07/06/Orthonormal.html
real3x3 GetLocalFrame(real3 localZ)
{
real x = localZ.x;
real y = localZ.y;
real z = localZ.z;
real sz = FastSign(z);
real a = 1 / (sz + z);
real ya = y * a;
real b = x * ya;
real c = x * sz;
real3 localX = real3(c * x * a - 1, sz * b, c);
real3 localY = real3(b, y * ya - sz, y);
// Note: due to the quaternion formulation, the generated frame is rotated by 180 degrees,
// s.t. if localZ = {0, 0, 1}, then localX = {-1, 0, 0} and localY = {0, -1, 0}.
return real3x3(localX, localY, localZ);
}
// Generates an orthonormal (row-major) basis from a unit vector. TODO: make it column-major.
// The resulting rotation matrix has the determinant of +1.
real3x3 GetLocalFrame(real3 localZ, real3 localX)
{
real3 localY = cross(localZ, localX);
return real3x3(localX, localY, localZ);
}
// Construct a right-handed view-dependent orthogonal basis around the normal:
// b0-b2 is the view-normal aka reflection plane.
real3x3 GetOrthoBasisViewNormal(real3 V, real3 N, real unclampedNdotV, bool testSingularity = false)
{
real3x3 orthoBasisViewNormal;
if (testSingularity && (abs(1.0 - unclampedNdotV) <= FLT_EPS))
{
// In this case N == V, and azimuth orientation around N shouldn't matter for the caller,
// we can use any quaternion-based method, like Frisvad or Reynold's (Pixar):
orthoBasisViewNormal = GetLocalFrame(N);
}
else
{
orthoBasisViewNormal[0] = normalize(V - N * unclampedNdotV);
orthoBasisViewNormal[2] = N;
orthoBasisViewNormal[1] = cross(orthoBasisViewNormal[2], orthoBasisViewNormal[0]);
}
return orthoBasisViewNormal;
}
// Move this here since it's used by both LightLoop.hlsl and RaytracingLightLoop.hlsl
bool IsMatchingLightLayer(uint lightLayers, uint renderingLayers)
{
return (lightLayers & renderingLayers) != 0;
}
#if SHADER_API_MOBILE || SHADER_API_GLES || SHADER_API_GLES3
#pragma warning (enable : 3205) // conversion of larger type to smaller
#endif
#endif // UNITY_COMMON_LIGHTING_INCLUDED

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 93bbf250faa37d446990b9501e7fb7e8
timeCreated: 1474465931
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,370 @@
#ifndef UNITY_COMMON_MATERIAL_INCLUDED
#define UNITY_COMMON_MATERIAL_INCLUDED
#if SHADER_API_MOBILE || SHADER_API_GLES || SHADER_API_GLES3
#pragma warning (disable : 3205) // conversion of larger type to smaller
#endif
//-----------------------------------------------------------------------------
// Define constants
//-----------------------------------------------------------------------------
#define DEFAULT_SPECULAR_VALUE 0.04
// Following constant are used when we use clear coat properties that can't be store in the Gbuffer (with the Lit shader)
#define CLEAR_COAT_IOR 1.5
#define CLEAR_COAT_IETA (1.0 / CLEAR_COAT_IOR) // IETA is the inverse eta which is the ratio of IOR of two interface
#define CLEAR_COAT_F0 0.04 // IORToFresnel0(CLEAR_COAT_IOR)
#define CLEAR_COAT_ROUGHNESS 0.01
#define CLEAR_COAT_PERCEPTUAL_SMOOTHNESS RoughnessToPerceptualSmoothness(CLEAR_COAT_ROUGHNESS)
#define CLEAR_COAT_PERCEPTUAL_ROUGHNESS RoughnessToPerceptualRoughness(CLEAR_COAT_ROUGHNESS)
#define CLEAR_COAT_SSR_PERCEPTUAL_ROUGHNESS 0.0 // For screen space reflections and ray traced reflections, we want to have a purely smooth surface to map the envrionement light behavior
//-----------------------------------------------------------------------------
// Helper functions for roughness
//-----------------------------------------------------------------------------
#ifndef BUILTIN_TARGET_API
real PerceptualRoughnessToRoughness(real perceptualRoughness)
{
return perceptualRoughness * perceptualRoughness;
}
real RoughnessToPerceptualRoughness(real roughness)
{
return sqrt(roughness);
}
#endif
real RoughnessToPerceptualSmoothness(real roughness)
{
return 1.0 - sqrt(roughness);
}
real PerceptualSmoothnessToRoughness(real perceptualSmoothness)
{
return (1.0 - perceptualSmoothness) * (1.0 - perceptualSmoothness);
}
real PerceptualSmoothnessToPerceptualRoughness(real perceptualSmoothness)
{
return (1.0 - perceptualSmoothness);
}
// Beckmann to GGX roughness "conversions":
//
// As also noted for NormalVariance in this file, Beckmann microfacet models use a Gaussian distribution of slopes
// and the roughness parameter absorbs constants in the canonical Gaussian formula and is thus not exactly the variance.
// The relationship is:
//
// roughnessBeckmann^2 = 2 variance (where variance is usually denoted sigma^2 but some comp gfx papers use sigma for
// variance or even sigma for roughness itself.)
//
// Microfacet BRDF models with a GGX NDF implies a Cauchy distribution of slopes (also corresponds to the distribution
// of slopes on an ellipsoid). Cauchy distributions don't have second moments, which precludes having a variance,
// but chopping the far tails of GGX and keeping 94% of the mass yields a distribution with a defined variance where
// we can then relate the roughness of GGX to a variance (see Ray Tracing Gems p153 - the reference is wrong though,
// the Conty paper doesn't mention this at all, but it can be found in stats using quantiles):
//
// roughnessGGX^2 = variance / 2
//
// From the two previous, if we want roughly comparable variances of slopes between a Beckmann and a GGX NDF, we can
// equate the variances and get a conversion of their roughnesses:
//
// 2 * roughnessGGX^2 = roughnessBeckmann^2 / 2 <==>
// 4 * roughnessGGX^2 = roughnessBeckmann^2 <==>
// 2 * roughnessGGX = roughnessBeckmann
//
// (Note that the Ray Tracing Gems paper makes an error on p154 writing sqrt(2) * roughnessGGX = roughnessBeckmann;
// Their validation study using ray tracing and LEADR - which looks good - is for the *variance to GGX* roughness mapping,
// not the Beckmann to GGX roughness "conversion")
real BeckmannRoughnessToGGXRoughness(real roughnessBeckmann)
{
return 0.5 * roughnessBeckmann;
}
real PerceptualRoughnessBeckmannToGGX(real perceptualRoughnessBeckmann)
{
//sqrt(a_ggx) = sqrt(0.5) sqrt(a_beckmann)
return sqrt(0.5) * perceptualRoughnessBeckmann;
}
real GGXRoughnessToBeckmannRoughness(real roughnessGGX)
{
return 2.0 * roughnessGGX;
}
real PerceptualRoughnessToPerceptualSmoothness(real perceptualRoughness)
{
return (1.0 - perceptualRoughness);
}
// WARNING: this has been deprecated, and should not be used!
// Using roughness values of 0 leads to INFs and NANs. The only sensible place to use the roughness
// value of 0 is IBL, so we do not modify the perceptual roughness which is used to select the MIP map level.
// Note: making the constant too small results in aliasing.
real ClampRoughnessForAnalyticalLights(real roughness)
{
return max(roughness, 1.0 / 1024.0);
}
// Given that the GGX model is invalid for a roughness of 0.0. This values have been experimentally evaluated to be the limit for the roughness
// for integration.
real ClampRoughnessForRaytracing(real roughness)
{
return max(roughness, 0.001225);
}
real ClampPerceptualRoughnessForRaytracing(real perceptualRoughness)
{
return max(perceptualRoughness, 0.035);
}
void ConvertValueAnisotropyToValueTB(real value, real anisotropy, out real valueT, out real valueB)
{
// Use the parametrization of Sony Imageworks.
// Ref: Revisiting Physically Based Shading at Imageworks, p. 15.
valueT = value * (1 + anisotropy);
valueB = value * (1 - anisotropy);
}
void ConvertAnisotropyToRoughness(real perceptualRoughness, real anisotropy, out real roughnessT, out real roughnessB)
{
real roughness = PerceptualRoughnessToRoughness(perceptualRoughness);
ConvertValueAnisotropyToValueTB(roughness, anisotropy, roughnessT, roughnessB);
}
void ConvertRoughnessTAndAnisotropyToRoughness(real roughnessT, real anisotropy, out real roughness)
{
roughness = roughnessT / (1 + anisotropy);
}
real ConvertRoughnessTAndBToRoughness(real roughnessT, real roughnessB)
{
return 0.5 * (roughnessT + roughnessB);
}
void ConvertRoughnessToAnisotropy(real roughnessT, real roughnessB, out real anisotropy)
{
anisotropy = ((roughnessT - roughnessB) / max(roughnessT + roughnessB, 0.0001));
}
// WARNING: this has been deprecated, and should not be used!
// Same as ConvertAnisotropyToRoughness but
// roughnessT and roughnessB are clamped, and are meant to be used with punctual and directional lights.
void ConvertAnisotropyToClampRoughness(real perceptualRoughness, real anisotropy, out real roughnessT, out real roughnessB)
{
ConvertAnisotropyToRoughness(perceptualRoughness, anisotropy, roughnessT, roughnessB);
roughnessT = ClampRoughnessForAnalyticalLights(roughnessT);
roughnessB = ClampRoughnessForAnalyticalLights(roughnessB);
}
// Use with stack BRDF (clear coat / coat) - This only used same equation to convert from Blinn-Phong spec power to Beckmann roughness
real RoughnessToVariance(real roughness)
{
return 2.0 / Sq(roughness) - 2.0;
}
real VarianceToRoughness(real variance)
{
return sqrt(2.0 / (variance + 2.0));
}
// Normal Map Filtering - This must match HDRP\Editor\AssetProcessors\NormalMapFilteringTexturePostprocessor.cs - highestVarianceAllowed (TODO: Move in core)
#define NORMALMAP_HIGHEST_VARIANCE 0.03125
float DecodeVariance(float gradientW)
{
return gradientW * NORMALMAP_HIGHEST_VARIANCE;
}
// Return modified perceptualSmoothness based on provided variance (get from GeometricNormalVariance + TextureNormalVariance)
float NormalFiltering(float perceptualSmoothness, float variance, float threshold)
{
float roughness = PerceptualSmoothnessToRoughness(perceptualSmoothness);
// Ref: Geometry into Shading - http://graphics.pixar.com/library/BumpRoughness/paper.pdf - equation (3)
float squaredRoughness = saturate(roughness * roughness + min(2.0 * variance, threshold * threshold)); // threshold can be really low, square the value for easier control
return RoughnessToPerceptualSmoothness(sqrt(squaredRoughness));
}
float ProjectedSpaceNormalFiltering(float perceptualSmoothness, float variance, float threshold)
{
float roughness = PerceptualSmoothnessToRoughness(perceptualSmoothness);
// Ref: Stable Geometric Specular Antialiasing with Projected-Space NDF Filtering - https://yusuketokuyoshi.com/papers/2021/Tokuyoshi2021SAA.pdf
float squaredRoughness = roughness * roughness;
float projRoughness2 = squaredRoughness / (1.0 - squaredRoughness);
float filteredProjRoughness2 = saturate(projRoughness2 + min(2.0 * variance, threshold * threshold));
squaredRoughness = filteredProjRoughness2 / (filteredProjRoughness2 + 1.0f);
return RoughnessToPerceptualSmoothness(sqrt(squaredRoughness));
}
// Reference: Error Reduction and Simplification for Shading Anti-Aliasing
// Specular antialiasing for geometry-induced normal (and NDF) variations: Tokuyoshi / Kaplanyan et al.'s method.
// This is the deferred approximation, which works reasonably well so we keep it for forward too for now.
// screenSpaceVariance should be at most 0.5^2 = 0.25, as that corresponds to considering
// a gaussian pixel reconstruction kernel with a standard deviation of 0.5 of a pixel, thus 2 sigma covering the whole pixel.
float GeometricNormalVariance(float3 geometricNormalWS, float screenSpaceVariance)
{
float3 deltaU = ddx(geometricNormalWS);
float3 deltaV = ddy(geometricNormalWS);
return screenSpaceVariance * (dot(deltaU, deltaU) + dot(deltaV, deltaV));
}
// Return modified perceptualSmoothness
float GeometricNormalFiltering(float perceptualSmoothness, float3 geometricNormalWS, float screenSpaceVariance, float threshold)
{
float variance = GeometricNormalVariance(geometricNormalWS, screenSpaceVariance);
return NormalFiltering(perceptualSmoothness, variance, threshold);
}
float ProjectedSpaceGeometricNormalFiltering(float perceptualSmoothness, float3 geometricNormalWS, float screenSpaceVariance, float threshold)
{
float variance = GeometricNormalVariance(geometricNormalWS, screenSpaceVariance);
return ProjectedSpaceNormalFiltering(perceptualSmoothness, variance, threshold);
}
// Normal map filtering based on The Order : 1886 SIGGRAPH course notes implementation.
// Basically Toksvig with an intermediate single vMF lobe induced dispersion (Han et al. 2007)
//
// This returns 2 times the variance of the induced "mesoNDF" lobe (an NDF induced from a section of
// the normal map) from the level 0 mip normals covered by the "current texel".
//
// avgNormalLength gives the dispersion information for the covered normals.
//
// Note that hw filtering on the normal map should be trilinear to be conservative, while anisotropic
// risk underfiltering. Could also compute average normal on the fly with a proper normal map format,
// like Toksvig.
float TextureNormalVariance(float avgNormalLength)
{
float variance = 0.0;
if (avgNormalLength < 1.0)
{
float avgNormLen2 = avgNormalLength * avgNormalLength;
float kappa = (3.0 * avgNormalLength - avgNormalLength * avgNormLen2) / (1.0 - avgNormLen2);
// Ref: Frequency Domain Normal Map Filtering - http://www.cs.columbia.edu/cg/normalmap/normalmap.pdf (equation 21)
// Relationship between between the standard deviation of a Gaussian distribution and the roughness parameter of a Beckmann distribution.
// is roughness^2 = 2 variance (note: variance is sigma^2)
// (Ref: Filtering Distributions of Normals for Shading Antialiasing - Equation just after (14))
// Relationship between gaussian lobe and vMF lobe is 2 * variance = 1 / (2 * kappa) = roughness^2
// (Equation 36 of Normal map filtering based on The Order : 1886 SIGGRAPH course notes implementation).
// So to get variance we must use variance = 1 / (4 * kappa)
variance = 0.25 / kappa;
}
return variance;
}
float TextureNormalFiltering(float perceptualSmoothness, float avgNormalLength, float threshold)
{
float variance = TextureNormalVariance(avgNormalLength);
return NormalFiltering(perceptualSmoothness, variance, threshold);
}
// ----------------------------------------------------------------------------
// Helper for Disney parametrization
// ----------------------------------------------------------------------------
float3 ComputeDiffuseColor(float3 baseColor, float metallic)
{
return baseColor * (1.0 - metallic);
}
float3 ComputeFresnel0(float3 baseColor, float metallic, float dielectricF0)
{
return lerp(dielectricF0.xxx, baseColor, metallic);
}
// ----------------------------------------------------------------------------
// Helper for normal blending
// ----------------------------------------------------------------------------
// ref https://www.gamedev.net/topic/678043-how-to-blend-world-space-normals/#entry5287707
// assume compositing in world space
// Note: Using vtxNormal = real3(0, 0, 1) give the BlendNormalRNM formulation.
// TODO: Untested
real3 BlendNormalWorldspaceRNM(real3 n1, real3 n2, real3 vtxNormal)
{
// Build the shortest-arc quaternion
real4 q = real4(cross(vtxNormal, n2), dot(vtxNormal, n2) + 1.0) / sqrt(2.0 * (dot(vtxNormal, n2) + 1));
// Rotate the normal
return n1 * (q.w * q.w - dot(q.xyz, q.xyz)) + 2 * q.xyz * dot(q.xyz, n1) + 2 * q.w * cross(q.xyz, n1);
}
// ref http://blog.selfshadow.com/publications/blending-in-detail/
// ref https://gist.github.com/selfshadow/8048308
// Reoriented Normal Mapping
// Blending when n1 and n2 are already 'unpacked' and normalised
// assume compositing in tangent space
real3 BlendNormalRNM(real3 n1, real3 n2)
{
real3 t = n1.xyz + real3(0.0, 0.0, 1.0);
real3 u = n2.xyz * real3(-1.0, -1.0, 1.0);
real3 r = (t / t.z) * dot(t, u) - u;
return r;
}
// assume compositing in tangent space
real3 BlendNormal(real3 n1, real3 n2)
{
return normalize(real3(n1.xy * n2.z + n2.xy * n1.z, n1.z * n2.z));
}
// ----------------------------------------------------------------------------
// Helper for triplanar
// ----------------------------------------------------------------------------
// Ref: http://http.developer.nvidia.com/GPUGems3/gpugems3_ch01.html / http://www.slideshare.net/icastano/cascades-demo-secrets
real3 ComputeTriplanarWeights(real3 normal)
{
// Determine the blend weights for the 3 planar projections.
real3 blendWeights = abs(normal);
// Tighten up the blending zone
blendWeights = (blendWeights - 0.2);
blendWeights = blendWeights * blendWeights * blendWeights; // pow(blendWeights, 3);
// Force weights to sum to 1.0 (very important!)
blendWeights = max(blendWeights, real3(0.0, 0.0, 0.0));
blendWeights /= dot(blendWeights, 1.0);
return blendWeights;
}
// Planar/Triplanar convention for Unity in world space
void GetTriplanarCoordinate(float3 position, out float2 uvXZ, out float2 uvXY, out float2 uvZY)
{
// Caution: This must follow the same rule as what is use for SurfaceGradient triplanar
// TODO: Currently the normal mapping looks wrong without SURFACE_GRADIENT option because we don't handle corretly the tangent space
uvXZ = float2(position.x, position.z);
uvXY = float2(position.x, position.y);
uvZY = float2(position.z, position.y);
}
// ----------------------------------------------------------------------------
// Helper for detail map operation
// ----------------------------------------------------------------------------
real LerpWhiteTo(real b, real t)
{
real oneMinusT = 1.0 - t;
return oneMinusT + b * t;
}
#ifndef BUILTIN_TARGET_API
real3 LerpWhiteTo(real3 b, real t)
{
real oneMinusT = 1.0 - t;
return real3(oneMinusT, oneMinusT, oneMinusT) + b * t;
}
#endif
#if SHADER_API_MOBILE || SHADER_API_GLES || SHADER_API_GLES3
#pragma warning (enable : 3205) // conversion of larger type to smaller
#endif
#endif // UNITY_COMMON_MATERIAL_INCLUDED

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 540178d5ddc29e74da771e38536aee22
timeCreated: 1477404191
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,14 @@
#ifndef UNITY_COMMON_SHADOW_INCLUDED
#define UNITY_COMMON_SHADOW_INCLUDED
// Ref: https://mynameismjp.wordpress.com/2015/02/18/shadow-sample-update/
// Calculates the offset to use for sampling the shadow map, based on the surface normal
real3 GetShadowPosOffset(real NdotL, real3 normalWS, real2 invShadowMapSize)
{
real texelSize = 2.0 * invShadowMapSize.x;
real offsetScaleNormalize = saturate(1.0 - NdotL);
// return texelSize * OffsetScale * offsetScaleNormalize * normalWS;
return texelSize * offsetScaleNormalize * normalWS;
}
#endif // UNITY_COMMON_SHADOW_INCLUDED

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: a85db80be6def144e938df4cbf0d1aa6
timeCreated: 1477397630
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,549 @@
#ifndef UNITY_DEBUG_INCLUDED
#define UNITY_DEBUG_INCLUDED
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
// UX-verified colorblind-optimized debug colors, listed in order of increasing perceived "hotness"
#define DEBUG_COLORS_COUNT 12
#define kDebugColorBlack float4(0.0 / 255.0, 0.0 / 255.0, 0.0 / 255.0, 1.0) // #000000
#define kDebugColorLightPurple float4(166.0 / 255.0, 70.0 / 255.0, 242.0 / 255.0, 1.0) // #A646F2
#define kDebugColorDeepBlue float4(0.0 / 255.0, 26.0 / 255.0, 221.0 / 255.0, 1.0) // #001ADD
#define kDebugColorSkyBlue float4(65.0 / 255.0, 152.0 / 255.0, 224.0 / 255.0, 1.0) // #4198E0
#define kDebugColorLightBlue float4(158.0 / 255.0, 228.0 / 255.0, 251.0 / 255.0, 1.0) // #1A1D21
#define kDebugColorTeal float4(56.0 / 255.0, 243.0 / 255.0, 176.0 / 255.0, 1.0) // #38F3B0
#define kDebugColorBrightGreen float4(168.0 / 255.0, 238.0 / 255.0, 46.0 / 255.0, 1.0) // #A8EE2E
#define kDebugColorBrightYellow float4(255.0 / 255.0, 253.0 / 255.0, 76.0 / 255.0, 1.0) // #FFFD4C
#define kDebugColorDarkYellow float4(255.0 / 255.0, 214.0 / 255.0, 0.0 / 255.0, 1.0) // #FFD600
#define kDebugColorOrange float4(253.0 / 255.0, 152.0 / 255.0, 0.0 / 255.0, 1.0) // #FD9800
#define kDebugColorBrightRed float4(255.0 / 255.0, 67.0 / 255.0, 51.0 / 255.0, 1.0) // #FF4333
#define kDebugColorDarkRed float4(132.0 / 255.0, 10.0 / 255.0, 54.0 / 255.0, 1.0) // #840A36
// Shadow cascade debug colors. Keep in sync with the ones in ShadowCascadeGUI.cs.
// Note: These colors are not 1:1 match to editor UI, in order to provide better contrast in the viewport.
#define kDebugColorShadowCascade0 float4(0.4, 0.4, 0.9, 1.0)
#define kDebugColorShadowCascade1 float4(0.4, 0.9, 0.4, 1.0)
#define kDebugColorShadowCascade2 float4(0.9, 0.9, 0.4, 1.0)
#define kDebugColorShadowCascade3 float4(0.9, 0.4, 0.4, 1.0)
// UX-verified colorblind-optimized "heat color gradient"
static const float4 kDebugColorGradient[DEBUG_COLORS_COUNT] = { kDebugColorBlack, kDebugColorLightPurple, kDebugColorDeepBlue,
kDebugColorSkyBlue, kDebugColorLightBlue, kDebugColorTeal, kDebugColorBrightGreen, kDebugColorBrightYellow,
kDebugColorDarkYellow, kDebugColorOrange, kDebugColorBrightRed, kDebugColorDarkRed };
#define TRANSPARENCY_OVERDRAW_COST 1.0
#define TRANSPARENCY_OVERDRAW_A 1.0
// Given an enum (represented by an int here), return a color.
// Use for DebugView of enum
real3 GetIndexColor(int index)
{
real3 outColor = real3(1.0, 0.0, 0.0);
if (index == 0)
outColor = real3(1.0, 0.5, 0.5);
else if (index == 1)
outColor = real3(0.5, 1.0, 0.5);
else if (index == 2)
outColor = real3(0.5, 0.5, 1.0);
else if (index == 3)
outColor = real3(1.0, 1.0, 0.5);
else if (index == 4)
outColor = real3(1.0, 0.5, 1.0);
else if (index == 5)
outColor = real3(0.5, 1.0, 1.0);
else if (index == 6)
outColor = real3(0.25, 0.75, 1.0);
else if (index == 7)
outColor = real3(1.0, 0.75, 0.25);
else if (index == 8)
outColor = real3(0.75, 1.0, 0.25);
else if (index == 9)
outColor = real3(0.75, 0.25, 1.0);
else if (index == 10)
outColor = real3(0.25, 1.0, 0.75);
else if (index == 11)
outColor = real3(0.75, 0.75, 0.25);
else if (index == 12)
outColor = real3(0.75, 0.25, 0.75);
else if (index == 13)
outColor = real3(0.25, 0.75, 0.75);
else if (index == 14)
outColor = real3(0.25, 0.25, 0.75);
else if (index == 15)
outColor = real3(0.75, 0.25, 0.25);
return outColor;
}
bool SampleDebugFont(int2 pixCoord, uint digit)
{
if (pixCoord.x < 0 || pixCoord.y < 0 || pixCoord.x >= 5 || pixCoord.y >= 9 || digit > 9)
return false;
#define PACK_BITS25(_x0,_x1,_x2,_x3,_x4,_x5,_x6,_x7,_x8,_x9,_x10,_x11,_x12,_x13,_x14,_x15,_x16,_x17,_x18,_x19,_x20,_x21,_x22,_x23,_x24) (_x0|(_x1<<1)|(_x2<<2)|(_x3<<3)|(_x4<<4)|(_x5<<5)|(_x6<<6)|(_x7<<7)|(_x8<<8)|(_x9<<9)|(_x10<<10)|(_x11<<11)|(_x12<<12)|(_x13<<13)|(_x14<<14)|(_x15<<15)|(_x16<<16)|(_x17<<17)|(_x18<<18)|(_x19<<19)|(_x20<<20)|(_x21<<21)|(_x22<<22)|(_x23<<23)|(_x24<<24))
#define _ 0
#define x 1
uint fontData[9][2] = {
{ PACK_BITS25(_,_,x,_,_, _,_,x,_,_, _,x,x,x,_, x,x,x,x,x, _,_,_,x,_), PACK_BITS25(x,x,x,x,x, _,x,x,x,_, x,x,x,x,x, _,x,x,x,_, _,x,x,x,_) },
{ PACK_BITS25(_,x,_,x,_, _,x,x,_,_, x,_,_,_,x, _,_,_,_,x, _,_,_,x,_), PACK_BITS25(x,_,_,_,_, x,_,_,_,x, _,_,_,_,x, x,_,_,_,x, x,_,_,_,x) },
{ PACK_BITS25(x,_,_,_,x, x,_,x,_,_, x,_,_,_,x, _,_,_,x,_, _,_,x,x,_), PACK_BITS25(x,_,_,_,_, x,_,_,_,_, _,_,_,x,_, x,_,_,_,x, x,_,_,_,x) },
{ PACK_BITS25(x,_,_,_,x, _,_,x,_,_, _,_,_,_,x, _,_,x,_,_, _,x,_,x,_), PACK_BITS25(x,_,x,x,_, x,_,_,_,_, _,_,_,x,_, x,_,_,_,x, x,_,_,_,x) },
{ PACK_BITS25(x,_,_,_,x, _,_,x,_,_, _,_,_,x,_, _,x,x,x,_, _,x,_,x,_), PACK_BITS25(x,x,_,_,x, x,x,x,x,_, _,_,x,_,_, _,x,x,x,_, _,x,x,x,x) },
{ PACK_BITS25(x,_,_,_,x, _,_,x,_,_, _,_,x,_,_, _,_,_,_,x, x,_,_,x,_), PACK_BITS25(_,_,_,_,x, x,_,_,_,x, _,_,x,_,_, x,_,_,_,x, _,_,_,_,x) },
{ PACK_BITS25(x,_,_,_,x, _,_,x,_,_, _,x,_,_,_, _,_,_,_,x, x,x,x,x,x), PACK_BITS25(_,_,_,_,x, x,_,_,_,x, _,x,_,_,_, x,_,_,_,x, _,_,_,_,x) },
{ PACK_BITS25(_,x,_,x,_, _,_,x,_,_, x,_,_,_,_, x,_,_,_,x, _,_,_,x,_), PACK_BITS25(x,_,_,_,x, x,_,_,_,x, _,x,_,_,_, x,_,_,_,x, x,_,_,_,x) },
{ PACK_BITS25(_,_,x,_,_, x,x,x,x,x, x,x,x,x,x, _,x,x,x,_, _,_,_,x,_), PACK_BITS25(_,x,x,x,_, _,x,x,x,_, _,x,_,_,_, _,x,x,x,_, _,x,x,x,_) }
};
#undef _
#undef x
#undef PACK_BITS25
return (fontData[8 - pixCoord.y][digit >= 5] >> ((digit % 5) * 5 + pixCoord.x)) & 1;
}
/*
* Sample up to 2 digits of a number. (Excluding leading zeroes)
*
* Note: Digit have a size of 5x8 pixels and spaced by 1 pixel
* See SampleDebugFontNumberAllDigits to sample all digits.
*
* @param pixCoord: pixel coordinate of the number sample
* @param number: number to sample
* @return true when the pixel is a pixel of a digit.
*/
bool SampleDebugFontNumber2Digits(int2 pixCoord, uint number)
{
pixCoord.y -= 4;
if (number <= 9)
{
return SampleDebugFont(pixCoord - int2(6, 0), number);
}
else
{
return (SampleDebugFont(pixCoord, number / 10) | SampleDebugFont(pixCoord - int2(6, 0), number % 10));
}
}
/*
* Sample up to 3 digits of a number. (Excluding leading zeroes)
*
* Note: Digit have a size of 5x8 pixels and spaced by 1 pixel
* See SampleDebugFontNumberAllDigits to sample all digits.
*
* @param pixCoord: pixel coordinate of the number sample
* @param number: number to sample
* @return true when the pixel is a pixel of a digit.
*/
bool SampleDebugFontNumber3Digits(int2 pixCoord, uint number)
{
pixCoord.y -= 4;
if (number <= 9)
{
return SampleDebugFont(pixCoord - int2(6, 0), number);
}
else if (number <= 99)
{
return (SampleDebugFont(pixCoord, (number / 10) % 10) | SampleDebugFont(pixCoord - int2(6, 0), number % 10));
}
else
{
return (SampleDebugFont(pixCoord, (number / 100)) | SampleDebugFont(pixCoord - int2(4, 0),(number / 10) % 10) | SampleDebugFont(pixCoord - int2(8, 0),(number / 10) % 10) );
}
}
/*
* Sample all digits of a number. (Excluding leading zeroes)
*
* Note: Digit have a size of 5x8 pixels and spaced by 1 pixel
* See SampleDebugFontNumber2Digits for a faster version supporting only 2 digits.
*
* @param pixCoord: pixel coordinate of the number sample
* @param number: number to sample
* @return true when the pixel is a pixel of a digit.
*/
bool SampleDebugFontNumberAllDigits(int2 pixCoord, uint number)
{
const int digitCount = (int)max(1u, uint(log10(number)) + 1u);
pixCoord.y -= 4;
int2 offset = int2(6 * digitCount, 0);
uint current = number;
for (int i = 0; i < digitCount; ++i)
{
if (SampleDebugFont(pixCoord - offset, current % 10))
return true;
current /= 10;
offset -= int2(6, 0);
}
return false;
}
// Draws a heatmap with numbered tiles, with increasingly "hot" background colors depending on n,
// where values at or above maxN receive strong red background color.
float4 OverlayHeatMap(uint2 pixCoord, uint2 tileSize, uint n, uint maxN, float opacity)
{
int colorIndex = 1 + (int)floor(10 * (log2((float)n + 0.1f) / log2(float(maxN))));
colorIndex = clamp(colorIndex, 0, DEBUG_COLORS_COUNT-1);
float4 col = kDebugColorGradient[colorIndex];
int2 coord = (pixCoord & (tileSize - 1)) - int2(tileSize.x/4+1, tileSize.y/3-3);
float4 color = float4(PositivePow(col.rgb, 2.2), opacity * col.a);
if (n >= 0)
{
if (SampleDebugFontNumber3Digits(coord, n)) // Shadow
color = float4(0, 0, 0, 1);
if (SampleDebugFontNumber3Digits(coord + 1, n)) // Text
color = float4(1, 1, 1, 1);
}
return color;
}
float4 GetStreamingMipColor(uint mipCount, float4 mipInfo)
{
// alpha is amount to blend with source color (0.0 = use original, 1.0 = use new color)
// mipInfo :
// x = quality setings minStreamingMipLevel
// y = original mip count for texture
// z = desired on screen mip level
// w = 0
uint originalTextureMipCount = uint(mipInfo.y);
// If material/shader mip info (original mip level) has not been set its not a streamed texture
if (originalTextureMipCount == 0)
return float4(1.0, 1.0, 1.0, 0.0);
uint desiredMipLevel = uint(mipInfo.z);
uint mipCountDesired = uint(originalTextureMipCount)-uint(desiredMipLevel);
if (mipCount == 0)
{
// Magenta if mip count invalid
return float4(1.0, 0.0, 1.0, 1.0);
}
else if (mipCount < mipCountDesired)
{
// red tones when not at the desired mip level (reduction due to budget). Brighter is further from original, alpha 0 when at desired
float ratioToDesired = float(mipCount) / float(mipCountDesired);
return float4(1.0, 0.0, 0.0, 1.0 - ratioToDesired);
}
else if (mipCount >= originalTextureMipCount)
{
// original color when at (or beyond) original mip count
return float4(1.0, 1.0, 1.0, 0.0);
}
else
{
// green tones when not at the original mip level. Brighter is closer to original, alpha 0 when at original
float ratioToOriginal = float(mipCount) / float(originalTextureMipCount);
return float4(0.0, 1.0, 0.0, 1.0 - ratioToOriginal);
}
}
float4 GetSimpleMipCountColor(uint mipCount)
{
// Grey scale for mip counts where mip count of 14 = white
float mipCountColor = float(mipCount) / 14.0;
float4 color = float4(mipCountColor, mipCountColor, mipCountColor, 1.0f);
// alpha is amount to blend with source color (0.0 = use original, 1.0 = use new color)
// Magenta is no valid mip count
// Red if greater than 14
return mipCount==0 ? float4(1.0, 0.0, 1.0, 1.0) : (mipCount > 14 ? float4(1.0, 0.0, 0.0, 1.0) : color );
}
float4 GetMipLevelColor(float2 uv, float4 texelSize)
{
// Push down into colors list to "optimal level" in following table.
// .zw is texture width,height so *2 is down one mip, *4 is down two mips
texelSize.zw *= 4.0;
float mipLevel = ComputeTextureLOD(uv, texelSize.wz);
mipLevel = clamp(mipLevel, 0.0, 5.0 - 0.0001);
float4 colors[6] = {
float4(0.0, 0.0, 1.0, 0.8), // 0 BLUE = too little texture detail
float4(0.0, 0.5, 1.0, 0.4), // 1
float4(1.0, 1.0, 1.0, 0.0), // 2 = optimal level
float4(1.0, 0.7, 0.0, 0.2), // 3 (YELLOW tint)
float4(1.0, 0.3, 0.0, 0.6), // 4 (clamped mipLevel 4.9999)
float4(1.0, 0.0, 0.0, 0.8) // 5 RED = too much texture detail (max blended value)
};
int mipLevelInt = floor(mipLevel);
float t = frac(mipLevel);
float4 a = colors[mipLevelInt];
float4 b = colors[mipLevelInt + 1];
float4 color = lerp(a, b, t);
return color;
}
float3 GetDebugMipColor(float3 originalColor, float4 texelSize, float2 uv)
{
// https://aras-p.info/blog/2011/05/03/a-way-to-visualize-mip-levels/
float4 mipColor = GetMipLevelColor(uv, texelSize);
return lerp(originalColor, mipColor.rgb, mipColor.a);
}
float3 GetDebugMipCountColor(float3 originalColor, uint mipCount)
{
float4 mipColor = GetSimpleMipCountColor(mipCount);
return lerp(originalColor, mipColor.rgb, mipColor.a);
}
float3 GetDebugStreamingMipColor(uint mipCount, float4 mipInfo)
{
return GetStreamingMipColor(mipCount, mipInfo).xyz;
}
float3 GetDebugStreamingMipColorBlended(float3 originalColor, uint mipCount, float4 mipInfo)
{
float4 mipColor = GetStreamingMipColor(mipCount, mipInfo);
return lerp(originalColor, mipColor.rgb, mipColor.a);
}
float3 GetDebugMipColorIncludingMipReduction(float3 originalColor, uint mipCount, float4 texelSize, float2 uv, float4 mipInfo)
{
uint originalTextureMipCount = uint(mipInfo.y);
if (originalTextureMipCount != 0)
{
// mipInfo :
// x = quality setings minStreamingMipLevel
// y = original mip count for texture
// z = desired on screen mip level
// w = 0
// Mip count has been reduced but the texelSize was not updated to take that into account
uint mipReductionLevel = originalTextureMipCount - mipCount;
uint mipReductionFactor = 1U << mipReductionLevel;
if (mipReductionFactor)
{
float oneOverMipReductionFactor = 1.0 / mipReductionFactor;
// texelSize.xy *= mipReductionRatio; // Unused in GetDebugMipColor so lets not re-calculate it
texelSize.zw *= oneOverMipReductionFactor;
}
}
return GetDebugMipColor(originalColor, texelSize, uv);
}
// mipInfo :
// x = quality setings minStreamingMipLevel
// y = original mip count for texture
// z = desired on screen mip level
// w = 0
float3 GetDebugMipReductionColor(uint mipCount, float4 mipInfo)
{
float3 outColor = float3(1.0, 0.0, 1.0); // Can't calculate without original mip count - return magenta
uint originalTextureMipCount = uint(mipInfo.y);
if (originalTextureMipCount != 0)
{
// Mip count has been reduced but the texelSize was not updated to take that into account
uint mipReductionLevel = originalTextureMipCount - mipCount;
float mipCol = float(mipReductionLevel) / 14.0;
outColor = float3(0, mipCol, 0);
}
return outColor;
}
// Convert an arbitrary range to color base on threshold provide to the function, threshold must be in growing order
real3 GetColorCodeFunction(real value, real4 threshold)
{
const real3 red = { 1.0, 0.0, 0.0 };
const real3 lightGreen = { 0.5, 1.0, 0.5 };
const real3 darkGreen = { 0.1, 1.0, 0.1 };
const real3 yellow = { 1.0, 1.0, 0.0 };
real3 outColor = red;
if (value < threshold[0])
{
outColor = red;
}
else if (value >= threshold[0] && value < threshold[1])
{
real scale = (value - threshold[0]) / (threshold[1] - threshold[0]);
outColor = lerp(red, darkGreen, scale);
}
else if (value >= threshold[1] && value < threshold[2])
{
real scale = (value - threshold[1]) / (threshold[2] - threshold[1]);
outColor = lerp(darkGreen, lightGreen, scale);
}
else if (value >= threshold[2] && value < threshold[3])
{
real scale = (value - threshold[2]) / (threshold[2] - threshold[2]);
outColor = lerp(lightGreen, yellow, scale);
}
else
{
outColor = yellow;
}
return outColor;
}
/// Return the color of the overdraw debug.
///
/// The color will go from
/// (cheap) dark blue -> red -> violet -> white (expensive)
///
/// * overdrawCount: the number of overdraw
/// * maxOverdrawCount: the maximum number of overdraw.
/// if the overdrawCount is above, the most expensive color is returned.
real3 GetOverdrawColor(real overdrawCount, real maxOverdrawCount)
{
if (overdrawCount < 0.01)
return real3(0, 0, 0);
// cheapest hue
const float initialHue = 240;
// most expensive hue is initialHue - deltaHue
const float deltaHue = 20;
// the value in % of budget where we start to remove saturation
const float xLight = 0.95;
// minimum hue
const float minHue = deltaHue - 360 + initialHue;
// budget value of a single draw
const float xCostOne = 1.0 / maxOverdrawCount;
// current budget value
const float x = saturate(overdrawCount / maxOverdrawCount);
float hue = fmod(max(min((x - xCostOne) * (deltaHue - 360) * (1.0 / (xLight - xCostOne)) + initialHue, initialHue), minHue), 360)/360.0;
float saturation = min(max((-1.0/(1 - xLight)) * (x - xLight), 0), 1);
return HsvToRgb(real3(hue, saturation, 1.0));
}
uint OverdrawLegendBucketInterval(uint maxOverdrawCount)
{
if (maxOverdrawCount <= 10)
return 1;
if (maxOverdrawCount <= 50)
return 5;
if (maxOverdrawCount <= 100)
return 10;
const uint digitCount = floor(log10(maxOverdrawCount));
const uint digitMultiplier = pow(10, digitCount);
const uint biggestDigit = floor(maxOverdrawCount/digitMultiplier);
if (biggestDigit < 5)
return pow(10, digitCount - 1) * 5;
return digitMultiplier;
}
/// Return the color of the overdraw debug legend.
///
/// It will draw a bar with all the color buckets of the overdraw debug
///
/// * texcoord: the texture coordinate of the pixel to draw
/// * maxOverdrawCount: the maximum number of overdraw.
/// * screenSize: screen size (w, h, 1/w, 1/h).
/// * defaultColor: the default color used for other areas
void DrawOverdrawLegend(real2 texCoord, real maxOverdrawCount, real4 screenSize, inout real3 color)
{
// Band parameters
// Position of the band (fixed x, fixed y, rel x, rel y)
const real4 bandPosition = real4(20, 20, 0, 0);
// Position of the band labels (fixed x, fixed y, rel x, rel y)
const real4 bandLabelPosition = real4(20, 50, 0, 0);
// Size of the band (fixed x, fixed y, rel x, rel y)
const real4 bandSize = real4(-bandPosition.x * 2, 20, 1, 0);
// Thickness of the band (fixed x, fixed y, rel x, rel y)
const real4 bandBorderThickness = real4(4, 4, 0, 0);
// Compute UVs
const real2 bandPositionUV = bandPosition.xy * screenSize.zw + bandPosition.zw;
const real2 bandLabelPositionUV = bandLabelPosition.xy * screenSize.zw + bandLabelPosition.zw;
const real2 bandSizeUV = bandSize.xy * screenSize.zw + bandSize.zw;
const real4 bandBorderPosition = bandPosition - bandBorderThickness;
const real4 bandBorderSize = bandSize + 2 * bandBorderThickness;
const real2 bandBorderPositionUV = bandBorderPosition.xy * screenSize.zw + bandBorderPosition.zw;
const real2 bandBorderSizeUV = bandBorderSize.xy * screenSize.zw + bandBorderSize.zw;
// Transform coordinate
const real2 bandBorderCoord = (texCoord - bandBorderPositionUV) / bandBorderSizeUV;
const real2 bandCoord = (texCoord - bandPositionUV) / bandSizeUV;
// Compute bucket index
const real bucket = ceil(bandCoord.x * maxOverdrawCount);
// Assign color when relevant
// Band border
if (all(bandBorderCoord >= 0) && all(bandBorderCoord <= 1))
color = real3(0.1, 0.1, 0.1);
// Band color
if (all(bandCoord >= 0) && all(bandCoord <= 1))
color = GetOverdrawColor(bucket, maxOverdrawCount);
// Bucket label
if (0 < bucket && bucket <= maxOverdrawCount)
{
const uint bucketInterval = OverdrawLegendBucketInterval(maxOverdrawCount);
const uint bucketLabelIndex = (uint(bucket) / bucketInterval) * bucketInterval;
const real2 labelStartCoord = real2(
bandLabelPositionUV.x + (bucketLabelIndex - 1) * (bandSizeUV.x / maxOverdrawCount),
bandLabelPositionUV.y
);
const uint2 pixCoord = uint2((texCoord - labelStartCoord) * screenSize.xy);
if (SampleDebugFontNumberAllDigits(pixCoord, bucketLabelIndex))
color = real3(1, 1, 1);
}
}
// Returns the barycentric coordinates of a point p in a triangle defined by the vertices a, b, and c
float3 GetBarycentricCoord(float2 p, float2 a, float2 b, float2 c)
{
float2 v0 = b - a;
float2 v1 = c - a;
float2 v2 = p - a;
float d00 = dot(v0, v0);
float d01 = dot(v0, v1);
float d11 = dot(v1, v1);
float d20 = dot(v2, v0);
float d21 = dot(v2, v1);
float denom = d00 * d11 - d01 * d01;
float3 bary = 0;
bary.y = (d11 * d20 - d01 * d21) / denom;
bary.z = (d00 * d21 - d01 * d20) / denom;
bary.x = 1.0f - bary.y - bary.z;
return bary;
}
// Returns whether a point p is part of a triangle defined by the vertices a, b, and c
bool IsPointInTriangle(float2 p, float2 a, float2 b, float2 c)
{
float3 bar = GetBarycentricCoord(p, a, b, c);
return (bar.x >= 0 && bar.x <= 1 && bar.y >= 0 && bar.y <= 1 && (bar.x + bar.y) <= 1);
}
/// Return the color of the segment.
///
/// It will draw a line between the given points with the given appearance (thickness and color).
///
/// * texcoord: the texture coordinate of the pixel to draw
/// * p1: coordinates of the line start
/// * p2: coordinates of the line end
/// * thickness: how thick the line should be
/// * color: color of the line
float4 DrawSegment(float2 texcoord, float2 p1, float2 p2, float thickness, float3 color)
{
float a = abs(distance(p1, texcoord));
float b = abs(distance(p2, texcoord));
float c = abs(distance(p1, p2));
if (a >= c || b >= c) return 0;
float p = (a + b + c) * 0.5;
float h = 2 / c * sqrt(p * (p - a) * (p - b) * (p - c));
float lineAlpha = lerp(1.0, 0.0, smoothstep(0.5 * thickness, 1.5 * thickness, h));
return float4(color * lineAlpha, lineAlpha);
}
#endif // UNITY_DEBUG_INCLUDED

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 90f3145f58b7eb44cb4252ac2a3ab258
timeCreated: 1476051069
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,4 @@
// This file is only to force Unity to load the ShaderLibrary's hlsl files in visual studio project via asmdef file, so they can be browse.
class DummyShaderLibrary
{
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0e625d3de4b77c14b9a31bc7b56dfde7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,288 @@
#ifndef UNITY_ENTITY_LIGHTING_INCLUDED
#define UNITY_ENTITY_LIGHTING_INCLUDED
#if SHADER_API_MOBILE || SHADER_API_GLES || SHADER_API_GLES3
#pragma warning (disable : 3205) // conversion of larger type to smaller
#endif
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/SphericalHarmonics.hlsl"
#define LIGHTMAP_RGBM_MAX_GAMMA real(5.0) // NB: Must match value in RGBMRanges.h
#define LIGHTMAP_RGBM_MAX_LINEAR real(34.493242) // LIGHTMAP_RGBM_MAX_GAMMA ^ 2.2
#ifdef UNITY_LIGHTMAP_RGBM_ENCODING
#ifdef UNITY_COLORSPACE_GAMMA
#define LIGHTMAP_HDR_MULTIPLIER LIGHTMAP_RGBM_MAX_GAMMA
#define LIGHTMAP_HDR_EXPONENT real(1.0) // Not used in gamma color space
#else
#define LIGHTMAP_HDR_MULTIPLIER LIGHTMAP_RGBM_MAX_LINEAR
#define LIGHTMAP_HDR_EXPONENT real(2.2)
#endif
#elif defined(UNITY_LIGHTMAP_DLDR_ENCODING)
#ifdef UNITY_COLORSPACE_GAMMA
#define LIGHTMAP_HDR_MULTIPLIER real(2.0)
#else
#define LIGHTMAP_HDR_MULTIPLIER real(4.59) // 2.0 ^ 2.2
#endif
#define LIGHTMAP_HDR_EXPONENT real(0.0)
#else // (UNITY_LIGHTMAP_FULL_HDR)
#define LIGHTMAP_HDR_MULTIPLIER real(1.0)
#define LIGHTMAP_HDR_EXPONENT real(1.0)
#endif
// texture3dLod is not supported on gles2.
#if !defined(SHADER_API_GLES)
// This sample a 3D volume storing SH
// Volume is store as 3D texture with 4 R, G, B, Occ set of 4 coefficient store atlas in same 3D texture. Occ is use for occlusion.
// TODO: the packing here is inefficient as we will fetch values far away from each other and they may not fit into the cache - Suggest we pack RGB continuously
// TODO: The calcul of texcoord could be perform with a single matrix multicplication calcualted on C++ side that will fold probeVolumeMin and probeVolumeSizeInv into it and handle the identity case, no reasons to do it in C++ (ask Ionut about it)
// It should also handle the camera relative path (if the render pipeline use it)
// bakeDiffuseLighting and backBakeDiffuseLighting must be initialize outside the function
void SampleProbeVolumeSH4(TEXTURE3D_PARAM(SHVolumeTexture, SHVolumeSampler), float3 positionWS, float3 normalWS, float3 backNormalWS, float4x4 WorldToTexture,
float transformToLocal, float texelSizeX, float3 probeVolumeMin, float3 probeVolumeSizeInv,
inout float3 bakeDiffuseLighting, inout float3 backBakeDiffuseLighting)
{
float3 position = (transformToLocal == 1.0) ? mul(WorldToTexture, float4(positionWS, 1.0)).xyz : positionWS;
float3 texCoord = (position - probeVolumeMin) * probeVolumeSizeInv.xyz;
// Each component is store in the same texture 3D. Each use one quater on the x axis
// Here we get R component then increase by step size (0.25) to get other component. This assume 4 component
// but last one is not used.
// Clamp to edge of the "internal" texture, as R is from half texel to size of R texture minus half texel.
// This avoid leaking
texCoord.x = clamp(texCoord.x * 0.25, 0.5 * texelSizeX, 0.25 - 0.5 * texelSizeX);
float4 shAr = SAMPLE_TEXTURE3D_LOD(SHVolumeTexture, SHVolumeSampler, texCoord, 0);
texCoord.x += 0.25;
float4 shAg = SAMPLE_TEXTURE3D_LOD(SHVolumeTexture, SHVolumeSampler, texCoord, 0);
texCoord.x += 0.25;
float4 shAb = SAMPLE_TEXTURE3D_LOD(SHVolumeTexture, SHVolumeSampler, texCoord, 0);
bakeDiffuseLighting += SHEvalLinearL0L1(normalWS, shAr, shAg, shAb);
backBakeDiffuseLighting += SHEvalLinearL0L1(backNormalWS, shAr, shAg, shAb);
}
// Just a shortcut that call function above
float3 SampleProbeVolumeSH4(TEXTURE3D_PARAM(SHVolumeTexture, SHVolumeSampler), float3 positionWS, float3 normalWS, float4x4 WorldToTexture,
float transformToLocal, float texelSizeX, float3 probeVolumeMin, float3 probeVolumeSizeInv)
{
float3 backNormalWSUnused = 0.0;
float3 bakeDiffuseLighting = 0.0;
float3 backBakeDiffuseLightingUnused = 0.0;
SampleProbeVolumeSH4(TEXTURE3D_ARGS(SHVolumeTexture, SHVolumeSampler), positionWS, normalWS, backNormalWSUnused, WorldToTexture,
transformToLocal, texelSizeX, probeVolumeMin, probeVolumeSizeInv,
bakeDiffuseLighting, backBakeDiffuseLightingUnused);
return bakeDiffuseLighting;
}
// The SphericalHarmonicsL2 coefficients are packed into 7 coefficients per color channel instead of 9.
// The packing from 9 to 7 is done from engine code and will use the alpha component of the pixel to store an additional SH coefficient.
// The 3D atlas texture will contain 7 SH coefficient parts.
// bakeDiffuseLighting and backBakeDiffuseLighting must be initialize outside the function
void SampleProbeVolumeSH9(TEXTURE3D_PARAM(SHVolumeTexture, SHVolumeSampler), float3 positionWS, float3 normalWS, float3 backNormalWS, float4x4 WorldToTexture,
float transformToLocal, float texelSizeX, float3 probeVolumeMin, float3 probeVolumeSizeInv,
inout float3 bakeDiffuseLighting, inout float3 backBakeDiffuseLighting)
{
float3 position = (transformToLocal == 1.0f) ? mul(WorldToTexture, float4(positionWS, 1.0)).xyz : positionWS;
float3 texCoord = (position - probeVolumeMin) * probeVolumeSizeInv;
const uint shCoeffCount = 7;
const float invShCoeffCount = 1.0f / float(shCoeffCount);
// We need to compute proper X coordinate to sample into the atlas.
texCoord.x = texCoord.x / shCoeffCount;
// Clamp the x coordinate otherwise we'll have leaking between RGB coefficients.
float texCoordX = clamp(texCoord.x, 0.5f * texelSizeX, invShCoeffCount - 0.5f * texelSizeX);
float4 SHCoefficients[7];
for (uint i = 0; i < shCoeffCount; i++)
{
texCoord.x = texCoordX + i * invShCoeffCount;
SHCoefficients[i] = SAMPLE_TEXTURE3D_LOD(SHVolumeTexture, SHVolumeSampler, texCoord, 0);
}
bakeDiffuseLighting += SampleSH9(SHCoefficients, normalize(normalWS));
backBakeDiffuseLighting += SampleSH9(SHCoefficients, normalize(backNormalWS));
}
// Just a shortcut that call function above
float3 SampleProbeVolumeSH9(TEXTURE3D_PARAM(SHVolumeTexture, SHVolumeSampler), float3 positionWS, float3 normalWS, float4x4 WorldToTexture,
float transformToLocal, float texelSizeX, float3 probeVolumeMin, float3 probeVolumeSizeInv)
{
float3 backNormalWSUnused = 0.0;
float3 bakeDiffuseLighting = 0.0;
float3 backBakeDiffuseLightingUnused = 0.0;
SampleProbeVolumeSH9(TEXTURE3D_ARGS(SHVolumeTexture, SHVolumeSampler), positionWS, normalWS, backNormalWSUnused, WorldToTexture,
transformToLocal, texelSizeX, probeVolumeMin, probeVolumeSizeInv,
bakeDiffuseLighting, backBakeDiffuseLightingUnused);
return bakeDiffuseLighting;
}
#endif
float4 SampleProbeOcclusion(TEXTURE3D_PARAM(SHVolumeTexture, SHVolumeSampler), float3 positionWS, float4x4 WorldToTexture,
float transformToLocal, float texelSizeX, float3 probeVolumeMin, float3 probeVolumeSizeInv)
{
float3 position = (transformToLocal == 1.0) ? mul(WorldToTexture, float4(positionWS, 1.0)).xyz : positionWS;
float3 texCoord = (position - probeVolumeMin) * probeVolumeSizeInv.xyz;
// Sample fourth texture in the atlas
// We need to compute proper U coordinate to sample.
// Clamp the coordinate otherwize we'll have leaking between ShB coefficients and Probe Occlusion(Occ) info
texCoord.x = max(texCoord.x * 0.25 + 0.75, 0.75 + 0.5 * texelSizeX);
return SAMPLE_TEXTURE3D(SHVolumeTexture, SHVolumeSampler, texCoord);
}
// Following functions are to sample enlighten lightmaps (or lightmaps encoded the same way as our
// enlighten implementation). They assume use of RGB9E5 for dynamic illuminance map and RGBM for baked ones.
// It is required for other platform that aren't supporting this format to implement variant of these functions
// (But these kind of platform should use regular render loop and not news shaders).
// TODO: This is the max value allowed for emissive (bad name - but keep for now to retrieve it) (It is 8^2.2 (gamma) and 8 is the limit of punctual light slider...), comme from UnityCg.cginc. Fix it!
// Ask Jesper if this can be change for HDRenderPipeline
#define EMISSIVE_RGBM_SCALE 97.0
// RGBM stuff is temporary. For now baked lightmap are in RGBM and the RGBM range for lightmaps is specific so we can't use the generic method.
// In the end baked lightmaps are going to be BC6H so the code will be the same as dynamic lightmaps.
// Same goes for emissive packed as an input for Enlighten with another hard coded multiplier.
// TODO: This function is used with the LightTransport pass to encode lightmap or emissive
real4 PackEmissiveRGBM(real3 rgb)
{
real kOneOverRGBMMaxRange = 1.0 / EMISSIVE_RGBM_SCALE;
const real kMinMultiplier = 2.0 * 1e-2;
real4 rgbm = real4(rgb * kOneOverRGBMMaxRange, 1.0);
rgbm.a = max(max(rgbm.r, rgbm.g), max(rgbm.b, kMinMultiplier));
rgbm.a = ceil(rgbm.a * 255.0) / 255.0;
// Division-by-zero warning from d3d9, so make compiler happy.
rgbm.a = max(rgbm.a, kMinMultiplier);
rgbm.rgb /= rgbm.a;
return rgbm;
}
real3 UnpackLightmapRGBM(real4 rgbmInput, real4 decodeInstructions)
{
#ifdef UNITY_COLORSPACE_GAMMA
return rgbmInput.rgb * (rgbmInput.a * decodeInstructions.x);
#else
return rgbmInput.rgb * (PositivePow(rgbmInput.a, decodeInstructions.y) * decodeInstructions.x);
#endif
}
real3 UnpackLightmapDoubleLDR(real4 encodedColor, real4 decodeInstructions)
{
return encodedColor.rgb * decodeInstructions.x;
}
#ifndef BUILTIN_TARGET_API
real3 DecodeLightmap(real4 encodedIlluminance, real4 decodeInstructions)
{
#if defined(UNITY_LIGHTMAP_RGBM_ENCODING)
return UnpackLightmapRGBM(encodedIlluminance, decodeInstructions);
#elif defined(UNITY_LIGHTMAP_DLDR_ENCODING)
return UnpackLightmapDoubleLDR(encodedIlluminance, decodeInstructions);
#else // (UNITY_LIGHTMAP_FULL_HDR)
return encodedIlluminance.rgb;
#endif
}
#endif
real3 DecodeHDREnvironment(real4 encodedIrradiance, real4 decodeInstructions)
{
// Take into account texture alpha if decodeInstructions.w is true(the alpha value affects the RGB channels)
real alpha = max(decodeInstructions.w * (encodedIrradiance.a - 1.0) + 1.0, 0.0);
// If Linear mode is not supported we can skip exponent part
return (decodeInstructions.x * PositivePow(alpha, decodeInstructions.y)) * encodedIrradiance.rgb;
}
#if defined(UNITY_DOTS_INSTANCING_ENABLED)
#define TEXTURE2D_LIGHTMAP_PARAM TEXTURE2D_ARRAY_PARAM
#define TEXTURE2D_LIGHTMAP_ARGS TEXTURE2D_ARRAY_ARGS
#define SAMPLE_TEXTURE2D_LIGHTMAP SAMPLE_TEXTURE2D_ARRAY
#define LIGHTMAP_EXTRA_ARGS float2 uv, float slice
#define LIGHTMAP_EXTRA_ARGS_USE uv, slice
#else
#define TEXTURE2D_LIGHTMAP_PARAM TEXTURE2D_PARAM
#define TEXTURE2D_LIGHTMAP_ARGS TEXTURE2D_ARGS
#define SAMPLE_TEXTURE2D_LIGHTMAP SAMPLE_TEXTURE2D
#define LIGHTMAP_EXTRA_ARGS float2 uv
#define LIGHTMAP_EXTRA_ARGS_USE uv
#endif
real3 SampleSingleLightmap(TEXTURE2D_LIGHTMAP_PARAM(lightmapTex, lightmapSampler), LIGHTMAP_EXTRA_ARGS, float4 transform, bool encodedLightmap, real4 decodeInstructions)
{
// transform is scale and bias
uv = uv * transform.xy + transform.zw;
real3 illuminance = real3(0.0, 0.0, 0.0);
// Remark: baked lightmap is RGBM for now, dynamic lightmap is RGB9E5
if (encodedLightmap)
{
real4 encodedIlluminance = SAMPLE_TEXTURE2D_LIGHTMAP(lightmapTex, lightmapSampler, LIGHTMAP_EXTRA_ARGS_USE).rgba;
illuminance = DecodeLightmap(encodedIlluminance, decodeInstructions);
}
else
{
illuminance = SAMPLE_TEXTURE2D_LIGHTMAP(lightmapTex, lightmapSampler, LIGHTMAP_EXTRA_ARGS_USE).rgb;
}
return illuminance;
}
void SampleDirectionalLightmap(TEXTURE2D_LIGHTMAP_PARAM(lightmapTex, lightmapSampler), TEXTURE2D_LIGHTMAP_PARAM(lightmapDirTex, lightmapDirSampler), LIGHTMAP_EXTRA_ARGS, float4 transform,
float3 normalWS, float3 backNormalWS, bool encodedLightmap, real4 decodeInstructions, inout real3 bakeDiffuseLighting, inout real3 backBakeDiffuseLighting)
{
// In directional mode Enlighten bakes dominant light direction
// in a way, that using it for half Lambert and then dividing by a "rebalancing coefficient"
// gives a result close to plain diffuse response lightmaps, but normalmapped.
// Note that dir is not unit length on purpose. Its length is "directionality", like
// for the directional specular lightmaps.
// transform is scale and bias
uv = uv * transform.xy + transform.zw;
real4 direction = SAMPLE_TEXTURE2D_LIGHTMAP(lightmapDirTex, lightmapDirSampler, LIGHTMAP_EXTRA_ARGS_USE);
// Remark: baked lightmap is RGBM for now, dynamic lightmap is RGB9E5
real3 illuminance = real3(0.0, 0.0, 0.0);
if (encodedLightmap)
{
real4 encodedIlluminance = SAMPLE_TEXTURE2D_LIGHTMAP(lightmapTex, lightmapSampler, LIGHTMAP_EXTRA_ARGS_USE).rgba;
illuminance = DecodeLightmap(encodedIlluminance, decodeInstructions);
}
else
{
illuminance = SAMPLE_TEXTURE2D_LIGHTMAP(lightmapTex, lightmapSampler, LIGHTMAP_EXTRA_ARGS_USE).rgb;
}
real halfLambert = dot(normalWS, direction.xyz - 0.5) + 0.5;
bakeDiffuseLighting += illuminance * halfLambert / max(1e-4, direction.w);
real backHalfLambert = dot(backNormalWS, direction.xyz - 0.5) + 0.5;
backBakeDiffuseLighting += illuminance * backHalfLambert / max(1e-4, direction.w);
}
// Just a shortcut that call function above
real3 SampleDirectionalLightmap(TEXTURE2D_LIGHTMAP_PARAM(lightmapTex, lightmapSampler), TEXTURE2D_LIGHTMAP_PARAM(lightmapDirTex, lightmapDirSampler), LIGHTMAP_EXTRA_ARGS, float4 transform,
float3 normalWS, bool encodedLightmap, real4 decodeInstructions)
{
float3 backNormalWSUnused = 0.0;
real3 bakeDiffuseLighting = 0.0;
real3 backBakeDiffuseLightingUnused = 0.0;
SampleDirectionalLightmap(TEXTURE2D_LIGHTMAP_ARGS(lightmapTex, lightmapSampler), TEXTURE2D_LIGHTMAP_ARGS(lightmapDirTex, lightmapDirSampler), LIGHTMAP_EXTRA_ARGS_USE, transform,
normalWS, backNormalWSUnused, encodedLightmap, decodeInstructions, bakeDiffuseLighting, backBakeDiffuseLightingUnused);
return bakeDiffuseLighting;
}
#if SHADER_API_MOBILE || SHADER_API_GLES || SHADER_API_GLES3
#pragma warning (enable : 3205) // conversion of larger type to smaller
#endif
#endif // UNITY_ENTITY_LIGHTING_INCLUDED

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 0303be75670325342b4bf5697686e77b
timeCreated: 1477930471
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,176 @@
#ifndef UNITY_FILTERING_INCLUDED
#define UNITY_FILTERING_INCLUDED
// Basic B-Spline of the 2nd degree (3rd order, support = 4).
// The fractional coordinate of each part is assumed to be in the [0, 1] range.
// https://www.desmos.com/calculator/479pgatwlt
//
// Sample use-case:
// float2 xy = uv * resolution.xy;
// float2 ic = floor(xy); // Note-centered (primal grid)
// float2 fc = 1 - frac(xy); // Inverse-translate the filter centered around 0.5
// Then pass x = fc.
//
real2 BSpline2Left(real2 x)
{
return 0.5 * x * x;
}
real2 BSpline2Middle(real2 x)
{
return (1 - x) * x + 0.5;
}
real2 BSpline2Right(real2 x)
{
return (0.5 * x - 1) * x + 0.5;
}
// Basic B-Spline of the 3nd degree (4th order, support = 4).
// The fractional coordinate of each part is assumed to be in the [0, 1] range.
// https://www.desmos.com/calculator/479pgatwlt
//
// Sample use-case:
// float2 xy = uv * resolution.xy;
// float2 ic = round(xy) + 0.5; // Cell-centered (dual grid)
// float2 fc = ic - xy; // Inverse-translate the the filter around 0.5 with a wrap
// Then pass x = fc.
//
real2 BSpline3Leftmost(real2 x)
{
return 0.16666667 * x * x * x;
}
real2 BSpline3MiddleLeft(real2 x)
{
return 0.16666667 + x * (0.5 + x * (0.5 - x * 0.5));
}
real2 BSpline3MiddleRight(real2 x)
{
return 0.66666667 + x * (-1.0 + 0.5 * x) * x;
}
real2 BSpline3Rightmost(real2 x)
{
return 0.16666667 + x * (-0.5 + x * (0.5 - x * 0.16666667));
}
// Compute weights & offsets for 4x bilinear taps for the bicubic B-Spline filter.
// The fractional coordinate should be in the [0, 1] range (centered on 0.5).
// Inspired by: http://vec3.ca/bicubic-filtering-in-fewer-taps/
void BicubicFilter(float2 fracCoord, out float2 weights[2], out float2 offsets[2])
{
float2 r = BSpline3Rightmost(fracCoord);
float2 mr = BSpline3MiddleRight(fracCoord);
float2 ml = BSpline3MiddleLeft(fracCoord);
float2 l = 1.0 - mr - ml - r;
weights[0] = r + mr;
weights[1] = ml + l;
offsets[0] = -1.0 + mr * rcp(weights[0]);
offsets[1] = 1.0 + l * rcp(weights[1]);
}
// Compute weights & offsets for 4x bilinear taps for the biquadratic B-Spline filter.
// The fractional coordinate should be in the [0, 1] range (centered on 0.5).
// Inspired by: http://vec3.ca/bicubic-filtering-in-fewer-taps/
void BiquadraticFilter(float2 fracCoord, out float2 weights[2], out float2 offsets[2])
{
float2 l = BSpline2Left(fracCoord);
float2 m = BSpline2Middle(fracCoord);
float2 r = 1.0 - l - m;
// Compute offsets for 4x bilinear taps for the quadratic B-Spline reconstruction kernel.
// 0: lerp between left and middle
// 1: lerp between middle and right
weights[0] = l + 0.5 * m;
weights[1] = r + 0.5 * m;
offsets[0] = -0.5 + 0.5 * m * rcp(weights[0]);
offsets[1] = 0.5 + r * rcp(weights[1]);
}
// texSize = (width, height, 1/width, 1/height)
float4 SampleTexture2DBiquadratic(TEXTURE2D_PARAM(tex, smp), float2 coord, float4 texSize)
{
float2 xy = coord * texSize.xy;
float2 ic = floor(xy);
float2 fc = frac(xy);
float2 weights[2], offsets[2];
BiquadraticFilter(1.0 - fc, weights, offsets); // Inverse-translate the filter centered around 0.5
// Apply the viewport scale right at the end.
return weights[0].x * weights[0].y * SAMPLE_TEXTURE2D_LOD(tex, smp, min((ic + float2(offsets[0].x, offsets[0].y)) * (texSize.zw * 1.0), 1.0), 0.0) // Top left
+ weights[1].x * weights[0].y * SAMPLE_TEXTURE2D_LOD(tex, smp, min((ic + float2(offsets[1].x, offsets[0].y)) * (texSize.zw * 1.0), 1.0), 0.0) // Top right
+ weights[0].x * weights[1].y * SAMPLE_TEXTURE2D_LOD(tex, smp, min((ic + float2(offsets[0].x, offsets[1].y)) * (texSize.zw * 1.0), 1.0), 0.0) // Bottom left
+ weights[1].x * weights[1].y * SAMPLE_TEXTURE2D_LOD(tex, smp, min((ic + float2(offsets[1].x, offsets[1].y)) * (texSize.zw * 1.0), 1.0), 0.0); // Bottom right
}
// texSize = (width, height, 1/width, 1/height)
float4 SampleTexture2DBicubic(TEXTURE2D_PARAM(tex, smp), float2 coord, float4 texSize, float2 maxCoord, uint unused /* needed to match signature of texarray version below */)
{
float2 xy = coord * texSize.xy + 0.5;
float2 ic = floor(xy);
float2 fc = frac(xy);
float2 weights[2], offsets[2];
BicubicFilter(fc, weights, offsets);
return weights[0].y * (weights[0].x * SAMPLE_TEXTURE2D_LOD(tex, smp, min((ic + float2(offsets[0].x, offsets[0].y) - 0.5) * texSize.zw, maxCoord), 0.0) +
weights[1].x * SAMPLE_TEXTURE2D_LOD(tex, smp, min((ic + float2(offsets[1].x, offsets[0].y) - 0.5) * texSize.zw, maxCoord), 0.0)) +
weights[1].y * (weights[0].x * SAMPLE_TEXTURE2D_LOD(tex, smp, min((ic + float2(offsets[0].x, offsets[1].y) - 0.5) * texSize.zw, maxCoord), 0.0) +
weights[1].x * SAMPLE_TEXTURE2D_LOD(tex, smp, min((ic + float2(offsets[1].x, offsets[1].y) - 0.5) * texSize.zw, maxCoord), 0.0));
}
float4 SampleTexture2DArrayBicubic(TEXTURE2D_ARRAY_PARAM(tex, smp), float2 coord, float slice, float4 texSize)
{
float2 xy = coord * texSize.xy + 0.5;
float2 ic = floor(xy);
float2 fc = frac(xy);
float2 weights[2], offsets[2];
BicubicFilter(fc, weights, offsets);
return weights[0].y * (weights[0].x * SAMPLE_TEXTURE2D_ARRAY(tex, smp, (ic + float2(offsets[0].x, offsets[0].y) - 0.5) * texSize.zw, slice).rgba +
weights[1].x * SAMPLE_TEXTURE2D_ARRAY(tex, smp, (ic + float2(offsets[1].x, offsets[0].y) - 0.5) * texSize.zw, slice).rgba) +
weights[1].y * (weights[0].x * SAMPLE_TEXTURE2D_ARRAY(tex, smp, (ic + float2(offsets[0].x, offsets[1].y) - 0.5) * texSize.zw, slice).rgba +
weights[1].x * SAMPLE_TEXTURE2D_ARRAY(tex, smp, (ic + float2(offsets[1].x, offsets[1].y) - 0.5) * texSize.zw, slice).rgba);
}
float4 SampleTexture2DArrayBicubicLOD(TEXTURE2D_ARRAY_PARAM(tex, smp), float2 coord, float slice, float4 texSize, int lod)
{
float2 xy = coord * texSize.xy + 0.5;
float2 ic = floor(xy);
float2 fc = frac(xy);
float2 weights[2], offsets[2];
BicubicFilter(fc, weights, offsets);
return weights[0].y * (weights[0].x * SAMPLE_TEXTURE2D_ARRAY_LOD(tex, smp, (ic + float2(offsets[0].x, offsets[0].y) - 0.5) * texSize.zw, slice, lod).rgba +
weights[1].x * SAMPLE_TEXTURE2D_ARRAY_LOD(tex, smp, (ic + float2(offsets[1].x, offsets[0].y) - 0.5) * texSize.zw, slice, lod).rgba) +
weights[1].y * (weights[0].x * SAMPLE_TEXTURE2D_ARRAY_LOD(tex, smp, (ic + float2(offsets[0].x, offsets[1].y) - 0.5) * texSize.zw, slice, lod).rgba +
weights[1].x * SAMPLE_TEXTURE2D_ARRAY_LOD(tex, smp, (ic + float2(offsets[1].x, offsets[1].y) - 0.5) * texSize.zw, slice, lod).rgba);
}
#if !defined(SHADER_API_GLES)
// texSize = (width, height, 1/width, 1/height)
// texture array version for XR single-pass
float4 SampleTexture2DBicubic(TEXTURE2D_ARRAY_PARAM(tex, smp), float2 coord, float4 texSize, float2 maxCoord, uint slice)
{
float2 xy = coord * texSize.xy + 0.5;
float2 ic = floor(xy);
float2 fc = frac(xy);
float2 weights[2], offsets[2];
BicubicFilter(fc, weights, offsets);
return weights[0].y * (weights[0].x * SAMPLE_TEXTURE2D_ARRAY_LOD(tex, smp, min((ic + float2(offsets[0].x, offsets[0].y) - 0.5) * texSize.zw, maxCoord), slice, 0.0) +
weights[1].x * SAMPLE_TEXTURE2D_ARRAY_LOD(tex, smp, min((ic + float2(offsets[1].x, offsets[0].y) - 0.5) * texSize.zw, maxCoord), slice, 0.0)) +
weights[1].y * (weights[0].x * SAMPLE_TEXTURE2D_ARRAY_LOD(tex, smp, min((ic + float2(offsets[0].x, offsets[1].y) - 0.5) * texSize.zw, maxCoord), slice, 0.0) +
weights[1].x * SAMPLE_TEXTURE2D_ARRAY_LOD(tex, smp, min((ic + float2(offsets[1].x, offsets[1].y) - 0.5) * texSize.zw, maxCoord), slice, 0.0));
}
#else
#define SampleTexture2DBicubic ERROR_ON_UNSUPPORTED_FUNCTION(SampleTexture2DBicubic)
#endif
#endif // UNITY_FILTERING_INCLUDED

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 54ca0b3b7814f804aac1450b38477c74
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,12 @@
#ifndef UNITY_FOVEATED_RENDERING_INCLUDED
#define UNITY_FOVEATED_RENDERING_INCLUDED
#if defined(SHADER_API_PS5) && defined(_FOVEATED_RENDERING_NON_UNIFORM_RASTER)
#include "Packages/com.unity.render-pipelines.ps5/ShaderLibrary/API/FoveatedRendering_PSSL.hlsl"
#endif
#if defined(SHADER_API_METAL) && defined(_FOVEATED_RENDERING_NON_UNIFORM_RASTER)
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/API/FoveatedRendering_Metal.hlsl"
#endif
#endif // UNITY_FOVEATED_RENDERING_INCLUDED

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: f36f5598be293c04db2a21f9e7463518
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,310 @@
#ifndef UNITY_GEOMETRICTOOLS_INCLUDED
#define UNITY_GEOMETRICTOOLS_INCLUDED
//-----------------------------------------------------------------------------
// Transform functions
//-----------------------------------------------------------------------------
// Rotate around a pivot point and an axis
float3 Rotate(float3 pivot, float3 position, float3 rotationAxis, float angle)
{
rotationAxis = normalize(rotationAxis);
float3 cpa = pivot + rotationAxis * dot(rotationAxis, position - pivot);
return cpa + ((position - cpa) * cos(angle) + cross(rotationAxis, (position - cpa)) * sin(angle));
}
float3x3 RotationFromAxisAngle(float3 A, float sinAngle, float cosAngle)
{
float c = cosAngle;
float s = sinAngle;
return float3x3(A.x * A.x * (1 - c) + c, A.x * A.y * (1 - c) - A.z * s, A.x * A.z * (1 - c) + A.y * s,
A.x * A.y * (1 - c) + A.z * s, A.y * A.y * (1 - c) + c, A.y * A.z * (1 - c) - A.x * s,
A.x * A.z * (1 - c) - A.y * s, A.y * A.z * (1 - c) + A.x * s, A.z * A.z * (1 - c) + c);
}
//-----------------------------------------------------------------------------
// Solver
//-----------------------------------------------------------------------------
// Solves the quadratic equation of the form: a*t^2 + b*t + c = 0.
// Returns 'false' if there are no real roots, 'true' otherwise.
// Ensures that roots.x <= roots.y.
bool SolveQuadraticEquation(float a, float b, float c, out float2 roots)
{
float det = Sq(b) - 4.0 * a * c;
float sqrtDet = sqrt(det);
roots.x = (-b - sign(a) * sqrtDet) / (2.0 * a);
roots.y = (-b + sign(a) * sqrtDet) / (2.0 * a);
return (det >= 0.0);
}
//-----------------------------------------------------------------------------
// Intersection functions
//-----------------------------------------------------------------------------
bool IntersectRayAABB(float3 rayOrigin, float3 rayDirection,
float3 boxMin, float3 boxMax,
float tMin, float tMax,
out float tEntr, out float tExit)
{
// Could be precomputed. Clamp to avoid INF. clamp() is a single ALU on GCN.
// rcp(FLT_EPS) = 16,777,216, which is large enough for our purposes,
// yet doesn't cause a lot of numerical issues associated with FLT_MAX.
float3 rayDirInv = clamp(rcp(rayDirection), -rcp(FLT_EPS), rcp(FLT_EPS));
// Perform ray-slab intersection (component-wise).
float3 t0 = boxMin * rayDirInv - (rayOrigin * rayDirInv);
float3 t1 = boxMax * rayDirInv - (rayOrigin * rayDirInv);
// Find the closest/farthest distance (component-wise).
float3 tSlabEntr = min(t0, t1);
float3 tSlabExit = max(t0, t1);
// Find the farthest entry and the nearest exit.
tEntr = Max3(tSlabEntr.x, tSlabEntr.y, tSlabEntr.z);
tExit = Min3(tSlabExit.x, tSlabExit.y, tSlabExit.z);
// Clamp to the range.
tEntr = max(tEntr, tMin);
tExit = min(tExit, tMax);
return tEntr < tExit;
}
// This simplified version assume that we care about the result only when we are inside the box
float IntersectRayAABBSimple(float3 start, float3 dir, float3 boxMin, float3 boxMax)
{
float3 invDir = rcp(dir);
// Find the ray intersection with box plane
float3 rbmin = (boxMin - start) * invDir;
float3 rbmax = (boxMax - start) * invDir;
float3 rbminmax = (dir > 0.0) ? rbmax : rbmin;
return min(min(rbminmax.x, rbminmax.y), rbminmax.z);
}
// Assume Sphere is at the origin (i.e start = position - spherePosition)
bool IntersectRaySphere(float3 start, float3 dir, float radius, out float2 intersections)
{
float a = dot(dir, dir);
float b = dot(dir, start) * 2.0;
float c = dot(start, start) - radius * radius;
return SolveQuadraticEquation(a, b, c, intersections);
}
// This simplified version assume that we care about the result only when we are inside the sphere
// Assume Sphere is at the origin (i.e start = position - spherePosition) and dir is normalized
// Ref: http://http.developer.nvidia.com/GPUGems/gpugems_ch19.html
float IntersectRaySphereSimple(float3 start, float3 dir, float radius)
{
float b = dot(dir, start) * 2.0;
float c = dot(start, start) - radius * radius;
float discriminant = b * b - 4.0 * c;
return abs(sqrt(discriminant) - b) * 0.5;
}
float3 IntersectRayPlane(float3 rayOrigin, float3 rayDirection, float3 planeOrigin, float3 planeNormal)
{
float dist = dot(planeNormal, planeOrigin - rayOrigin) / dot(planeNormal, rayDirection);
return rayOrigin + rayDirection * dist;
}
// Same as above but return intersection distance and true / false if the ray hit/miss
bool IntersectRayPlane(float3 rayOrigin, float3 rayDirection, float3 planePosition, float3 planeNormal, out float t)
{
bool res = false;
t = -1.0;
float denom = dot(planeNormal, rayDirection);
if (abs(denom) > 1e-5)
{
float3 d = planePosition - rayOrigin;
t = dot(d, planeNormal) / denom;
res = (t >= 0);
}
return res;
}
bool RayPlaneSegmentIntersect(in float3 rayOrigin, in float3 rayDirection, float3 planeNormal, float planeDistance, inout float3 intersectionPoint)
{
float denom = dot(rayDirection, planeNormal);
float lambda = (denom != 0.0) ? (planeDistance - dot(rayOrigin, planeNormal)) / denom : -1.0;
if ((lambda >= 0.0) && (lambda <= 1.0))
{
intersectionPoint = rayOrigin + lambda * rayDirection;
return true;
}
else
return false;
}
// Can support cones with an elliptic base: pre-scale 'coneAxisX' and 'coneAxisY' by (h/r_x) and (h/r_y).
// Returns parametric distances 'tEntr' and 'tExit' along the ray,
// subject to constraints 'tMin' and 'tMax'.
bool IntersectRayCone(float3 rayOrigin, float3 rayDirection,
float3 coneOrigin, float3 coneDirection,
float3 coneAxisX, float3 coneAxisY,
float tMin, float tMax,
out float tEntr, out float tExit)
{
// Inverse transform the ray into a coordinate system with the cone at the origin facing along the Z axis.
float3x3 rotMat = float3x3(coneAxisX, coneAxisY, coneDirection);
float3 o = mul(rotMat, rayOrigin - coneOrigin);
float3 d = mul(rotMat, rayDirection);
// Cone equation (facing along Z): (h/r*x)^2 + (h/r*y)^2 - z^2 = 0.
// Cone axes are premultiplied with (h/r).
// Set up the quadratic equation: a*t^2 + b*t + c = 0.
float a = d.x * d.x + d.y * d.y - d.z * d.z;
float b = o.x * d.x + o.y * d.y - o.z * d.z;
float c = o.x * o.x + o.y * o.y - o.z * o.z;
float2 roots;
// Check whether we have at least 1 root.
bool hit = SolveQuadraticEquation(a, 2 * b, c, roots);
tEntr = roots.x;
tExit = roots.y;
float3 pEntr = o + tEntr * d;
float3 pExit = o + tExit * d;
// Clip the negative cone.
bool pEntrNeg = pEntr.z < 0;
bool pExitNeg = pExit.z < 0;
if (pEntrNeg && pExitNeg) { hit = false; }
if (pEntrNeg) { tEntr = tExit; tExit = tMax; }
if (pExitNeg) { tExit = tEntr; tEntr = tMin; }
// Clamp using the values passed into the function.
tEntr = clamp(tEntr, tMin, tMax);
tExit = clamp(tExit, tMin, tMax);
// Check for grazing intersections.
if (tEntr == tExit) { hit = false; }
return hit;
}
bool IntersectSphereAABB(float3 position, float radius, float3 aabbMin, float3 aabbMax)
{
float x = max(aabbMin.x, min(position.x, aabbMax.x));
float y = max(aabbMin.y, min(position.y, aabbMax.y));
float z = max(aabbMin.z, min(position.z, aabbMax.z));
float distance2 = ((x - position.x) * (x - position.x) + (y - position.y) * (y - position.y) + (z - position.z) * (z - position.z));
return distance2 < radius * radius;
}
//-----------------------------------------------------------------------------
// Miscellaneous functions
//-----------------------------------------------------------------------------
// Box is AABB
float DistancePointBox(float3 position, float3 boxMin, float3 boxMax)
{
return length(max(max(position - boxMax, boxMin - position), float3(0.0, 0.0, 0.0)));
}
float3 ProjectPointOnPlane(float3 position, float3 planePosition, float3 planeNormal)
{
return position - (dot(position - planePosition, planeNormal) * planeNormal);
}
// Plane equation: {(a, b, c) = N, d = -dot(N, P)}.
// Returns the distance from the plane to the point 'p' along the normal.
// Positive -> in front (above), negative -> behind (below).
float DistanceFromPlane(float3 p, float4 plane)
{
return dot(float4(p, 1.0), plane);
}
// Returns 'true' if the triangle is outside of the frustum.
// 'epsilon' is the (negative) distance to (outside of) the frustum below which we cull the triangle.
bool CullTriangleFrustum(float3 p0, float3 p1, float3 p2, float epsilon, float4 frustumPlanes[6], int numPlanes)
{
bool outside = false;
for (int i = 0; i < numPlanes; i++)
{
// If all 3 points are behind any of the planes, we cull.
outside = outside || Max3(DistanceFromPlane(p0, frustumPlanes[i]),
DistanceFromPlane(p1, frustumPlanes[i]),
DistanceFromPlane(p2, frustumPlanes[i])) < epsilon;
}
return outside;
}
// Returns 'true' if the edge of the triangle is outside of the frustum.
// The edges are defined s.t. they are on the opposite side of the point with the given index.
// 'epsilon' is the (negative) distance to (outside of) the frustum below which we cull the triangle.
//output packing:
// x,y,z - one component per triangle edge, true if outside, false otherwise
// w - true if entire triangle is outside of at least 1 plane of the frustum, false otherwise
bool4 CullFullTriangleAndEdgesFrustum(float3 p0, float3 p1, float3 p2, float epsilon, float4 frustumPlanes[6], int numPlanes)
{
bool4 edgesOutsideXYZ_triangleOutsideW = false;
for (int i = 0; i < numPlanes; i++)
{
bool3 pointsOutside = bool3(DistanceFromPlane(p0, frustumPlanes[i]) < epsilon,
DistanceFromPlane(p1, frustumPlanes[i]) < epsilon,
DistanceFromPlane(p2, frustumPlanes[i]) < epsilon);
bool3 edgesOutside;
// If both points of the edge are behind any of the planes, we cull.
edgesOutside.x = pointsOutside.y && pointsOutside.z;
edgesOutside.y = pointsOutside.x && pointsOutside.z;
edgesOutside.z = pointsOutside.x && pointsOutside.y;
edgesOutsideXYZ_triangleOutsideW = edgesOutsideXYZ_triangleOutsideW || bool4(edgesOutside.xyz, all(pointsOutside));
}
return edgesOutsideXYZ_triangleOutsideW;
}
// Returns 'true' if the edge of the triangle is outside of the frustum.
// The edges are defined s.t. they are on the opposite side of the point with the given index.
// 'epsilon' is the (negative) distance to (outside of) the frustum below which we cull the triangle.
//output packing:
// x,y,z - one component per triangle edge, true if outside, false otherwise
bool3 CullTriangleEdgesFrustum(float3 p0, float3 p1, float3 p2, float epsilon, float4 frustumPlanes[6], int numPlanes)
{
return CullFullTriangleAndEdgesFrustum(p0, p1, p2, epsilon, frustumPlanes, numPlanes).xyz;
}
bool CullTriangleBackFaceView(float3 p0, float3 p1, float3 p2, float epsilon, float3 V, float winding)
{
float3 edge1 = p1 - p0;
float3 edge2 = p2 - p0;
float3 N = cross(edge1, edge2);
float NdotV = dot(N, V) * winding;
// Optimize:
// NdotV / (length(N) * length(V)) < Epsilon
// NdotV < Epsilon * length(N) * length(V)
// NdotV < Epsilon * sqrt(dot(N, N)) * sqrt(dot(V, V))
// NdotV < Epsilon * sqrt(dot(N, N) * dot(V, V))
return NdotV < epsilon * sqrt(dot(N, N) * dot(V, V));
}
// Returns 'true' if a triangle defined by 3 vertices is back-facing.
// 'epsilon' is the (negative) value of dot(N, V) below which we cull the triangle.
// 'winding' can be used to change the order: pass 1 for (p0 -> p1 -> p2), or -1 for (p0 -> p2 -> p1).
bool CullTriangleBackFace(float3 p0, float3 p1, float3 p2, float epsilon, float3 viewPos, float winding)
{
float3 V = viewPos - p0;
return CullTriangleBackFaceView(p0, p1, p2, epsilon, V, winding);
}
#endif // UNITY_GEOMETRICTOOLS_INCLUDED

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: eebfba22df48acf4b978d98000cb10e6
timeCreated: 1472140530
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,12 @@
#ifndef UNITY_CORE_SAMPLERS_INCLUDED
#define UNITY_CORE_SAMPLERS_INCLUDED
// Common inline samplers.
// Separated into its own file for robust including from any other file.
// Helps with sharing samplers between intermediate and/or procedural textures (D3D11 has a active sampler limit of 16).
SamplerState sampler_PointClamp;
SamplerState sampler_LinearClamp;
SamplerState sampler_PointRepeat;
SamplerState sampler_LinearRepeat;
#endif //UNITY_CORE_SAMPLERS_INCLUDED

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 47ecc1e1971024be4a44aa322690660e
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,864 @@
#ifndef GRA_HLSL_3
#define GRA_HLSL_3 0
#endif
#ifndef GRA_HLSL_4
#define GRA_HLSL_4 0
#endif
#ifndef GRA_HLSL_5
#define GRA_HLSL_5 0
#endif
#ifndef GRA_GLSL_120
#define GRA_GLSL_120 0
#endif
#ifndef GRA_GLSL_130
#define GRA_GLSL_130 0
#endif
#ifndef GRA_GLSL_330
#define GRA_GLSL_330 0
#endif
#ifndef GRA_VERTEX_SHADER
#define GRA_VERTEX_SHADER 0
#endif
#ifndef GRA_PIXEL_SHADER
#define GRA_PIXEL_SHADER 0
#endif
#ifndef GRA_HQ_CUBEMAPPING
#define GRA_HQ_CUBEMAPPING 0
#endif
#ifndef GRA_DEBUG_TILES
#define GRA_DEBUG_TILES 0
#endif
#ifndef GRA_BGRA
#define GRA_BGRA 0
#endif
#ifndef GRA_ROW_MAJOR
#define GRA_ROW_MAJOR 1
#endif
#ifndef GRA_DEBUG
#define GRA_DEBUG 1
#endif
#ifndef GRA_64BIT_RESOLVER
#define GRA_64BIT_RESOLVER 0
#endif
#ifndef GRA_RWTEXTURE2D_SCALE
#define GRA_RWTEXTURE2D_SCALE 16
#endif
#ifndef GRA_DISABLE_TEX_LOAD
#define GRA_DISABLE_TEX_LOAD 0
#endif
#ifndef GRA_PACK_RESOLVE_OUTPUT
#define GRA_PACK_RESOLVE_OUTPUT 1
#endif
// Temp workaround for some platforms's lack of unorm.
#ifdef GRA_NO_UNORM
#define GRA_UNORM
#else
#define GRA_UNORM unorm
#endif
#ifndef GRA_TEXTURE_ARRAY_SUPPORT
#if (GRA_HLSL_5 == 1) || (GRA_HLSL_4 == 1) || (GRA_GLSL_330 == 1)
#define GRA_TEXTURE_ARRAY_SUPPORT 1
#else
#define GRA_TEXTURE_ARRAY_SUPPORT 0
#endif
#endif
#define GRA_HLSL_FAMILY ((GRA_HLSL_3 == 1) || (GRA_HLSL_5 == 1) || (GRA_HLSL_4 == 1))
#define GRA_GLSL_FAMILY ((GRA_GLSL_120 == 1) || (GRA_GLSL_130 == 1) || (GRA_GLSL_330 == 1))
#if GRA_HLSL_FAMILY
#define gra_Float2 float2
#define gra_Float3 float3
#define gra_Float4 float4
#define gra_Int3 int3
#define gra_Float4x4 float4x4
#define gra_Unroll [unroll]
#define gra_Branch [branch]
#elif GRA_GLSL_FAMILY
#if (GRA_VERTEX_SHADER == 0) && (GRA_PIXEL_SHADER ==0)
#error GLSL requires knowledge of the shader stage! Neither GRA_VERTEX_SHADER or GRA_PIXEL_SHADER are defined!
#else
#define gra_Float2 vec2
#define gra_Float3 vec3
#define gra_Float4 vec4
#define gra_Int3 ivec3
#define gra_Float4x4 mat4
#define gra_Unroll
#define gra_Branch
#if (GRA_VERTEX_SHADER == 1)
#define ddx
#define ddy
#elif (GRA_PIXEL_SHADER == 1)
#define ddx dFdx
#define ddy dFdy
#endif
#define frac fract
#define lerp mix
/** This is not correct (http://stackoverflow.com/questions/7610631/glsl-mod-vs-hlsl-fmod) but it is for our case */
#define fmod mod
#endif
#else
#error unknown shader architecture
#endif
#if (GRA_DISABLE_TEX_LOAD!=1)
#if (GRA_HLSL_5 == 1) || (GRA_HLSL_4 == 1) || (GRA_GLSL_130 == 1) || (GRA_GLSL_330 == 1)
#define GRA_LOAD_INSTR 1
#else
#define GRA_LOAD_INSTR 0
#endif
#else
#define GRA_LOAD_INSTR 0
#endif
/**
a cross API texture handle
*/
#if (GRA_HLSL_5 == 1) || (GRA_HLSL_4 == 1)
struct GraniteTranslationTexture
{
SamplerState Sampler;
Texture2D Texture;
};
struct GraniteCacheTexture
{
SamplerState Sampler;
#if GRA_TEXTURE_ARRAY_SUPPORT
Texture2DArray TextureArray;
#else
Texture2D Texture;
#endif
};
#elif (GRA_HLSL_3 == 1) || (GRA_GLSL_120 == 1) || (GRA_GLSL_130 == 1) || (GRA_GLSL_330 == 1)
#define GraniteTranslationTexture sampler2D
#if GRA_TEXTURE_ARRAY_SUPPORT
#define GraniteCacheTexture sampler2DArray
#else
#define GraniteCacheTexture sampler2D
#endif
#else
#error unknow shader archtecture
#endif
/**
Struct defining the constant buffer for each streaming texture.
Use IStreamingTexture::GetConstantBuffer to fill this struct.
*/
struct GraniteStreamingTextureConstantBuffer
{
#define _grStreamingTextureCBSize 2
gra_Float4 data[_grStreamingTextureCBSize];
};
/**
Struct defining the constant buffer for each cube streaming texture.
Use multiple calls to IStreamingTexture::GetConstantBuffer this struct (one call for each face).
*/
struct GraniteStreamingTextureCubeConstantBuffer
{
#define _grStreamingTextureCubeCBSize 6
GraniteStreamingTextureConstantBuffer data[_grStreamingTextureCubeCBSize];
};
/**
Struct defining the constant buffer for each tileset.
Use ITileSet::GetConstantBuffer to fill this struct.
*/
struct GraniteTilesetConstantBuffer
{
#define _grTilesetCBSize 2
gra_Float4x4 data[_grTilesetCBSize];
};
/**
Utility struct used by the shaderlib to wrap up all required constant buffers needed to perform a VT lookup/sample.
*/
struct GraniteConstantBuffers
{
GraniteTilesetConstantBuffer tilesetBuffer;
GraniteStreamingTextureConstantBuffer streamingTextureBuffer;
};
/**
Utility struct used by the shaderlib to wrap up all required constant buffers needed to perform a Cube VT lookup/sample.
*/
struct GraniteCubeConstantBuffers
{
GraniteTilesetConstantBuffer tilesetBuffer;
GraniteStreamingTextureCubeConstantBuffer streamingTextureCubeBuffer;
};
/**
The Granite lookup data for the different sampling functions.
*/
// Granite lookup data for automatic mip level selecting sampling
struct GraniteLookupData
{
gra_Float4 translationTableData;
gra_Float2 textureCoordinates;
gra_Float2 dX;
gra_Float2 dY;
};
// Granite lookup data for explicit level-of-detail sampling
struct GraniteLODLookupData
{
gra_Float4 translationTableData;
gra_Float2 textureCoordinates;
float cacheLevel;
};
//@IGNORE_END
// public interface
/*
END OF PUBLIC INTERFACE
Everything below this point should be treated as private to GraniteShaderLib.h
*/
//@INSERT_DEFINES
#define gra_TilesetBuffer grCB.tilesetBuffer
#define gra_TilesetBufferInternal tsCB.data[0]
#define gra_TilesetCacheBuffer tsCB.data[1]
#define gra_StreamingTextureCB grCB.streamingTextureBuffer
#define gra_StreamingTextureCubeCB grCB.streamingTextureCubeBuffer
#define gra_Transform grCB.streamingTextureBuffer.data[0]
#define gra_CubeTransform grCB.streamingTextureCubeBuffer.data
#define gra_StreamingTextureTransform grSTCB.data[0]
#define gra_StreamingTextureInfo grSTCB.data[1]
#define gra_NumLevels gra_StreamingTextureInfo.x
#define gra_AssetWidthRcp gra_StreamingTextureInfo.y
#define gra_AssetHeightRcp gra_StreamingTextureInfo.z
#if GRA_ROW_MAJOR == 1
#define gra_TranslationTableBias gra_TilesetBufferInternal[0][0]
#define gra_MaxAnisotropyLog2 gra_TilesetBufferInternal[1][0]
#define gra_CalcMiplevelDeltaScale gra_Float2(gra_TilesetBufferInternal[2][0], gra_TilesetBufferInternal[3][0])
#define gra_CalcMiplevelDeltaScaleX gra_TilesetBufferInternal[2][0]
#define gra_CalcMiplevelDeltaScaleY gra_TilesetBufferInternal[3][0]
#define gra_LodBiasPow2 gra_TilesetBufferInternal[0][1]
#define gra_TrilinearOffset gra_TilesetBufferInternal[0][2]
#define gra_TileContentInTiles gra_Float2(gra_TilesetBufferInternal[0][2], gra_TilesetBufferInternal[1][2])
#define gra_Level0NumTilesX gra_TilesetBufferInternal[0][3]
#define gra_NumTilesYScale gra_TilesetBufferInternal[1][3]
#define gra_TextureMagic gra_TilesetBufferInternal[2][3]
#define gra_TextureId gra_TilesetBufferInternal[3][3]
#define gra_RcpCacheInTiles(l) gra_Float2(gra_TilesetCacheBuffer[0][l], gra_TilesetCacheBuffer[1][l])
#define gra_BorderPixelsRcpCache(l) gra_Float2(gra_TilesetCacheBuffer[2][l], gra_TilesetCacheBuffer[3][l])
#else
#define gra_TranslationTableBias gra_TilesetBufferInternal[0][0]
#define gra_MaxAnisotropyLog2 gra_TilesetBufferInternal[0][1]
#define gra_CalcMiplevelDeltaScale gra_Float2(gra_TilesetBufferInternal[0][2], gra_TilesetBufferInternal[0][3])
#define gra_CalcMiplevelDeltaScaleX gra_TilesetBufferInternal[0][2]
#define gra_CalcMiplevelDeltaScaleY gra_TilesetBufferInternal[0][3]
#define gra_LodBiasPow2 gra_TilesetBufferInternal[1][0]
#define gra_TrilinearOffset gra_TilesetBufferInternal[2][0]
#define gra_TileContentInTiles gra_Float2(gra_TilesetBufferInternal[2][0], gra_TilesetBufferInternal[2][1])
#define gra_Level0NumTilesX gra_TilesetBufferInternal[3][0]
#define gra_NumTilesYScale gra_TilesetBufferInternal[3][1]
#define gra_TextureMagic gra_TilesetBufferInternal[3][2]
#define gra_TextureId gra_TilesetBufferInternal[3][3]
#define gra_RcpCacheInTiles(l) gra_Float2(gra_TilesetCacheBuffer[l][0], gra_TilesetCacheBuffer[l][1])
#define gra_BorderPixelsRcpCache(l) gra_Float2(gra_TilesetCacheBuffer[l][2], gra_TilesetCacheBuffer[l][3])
#endif
#if (GRA_GLSL_120==1)
// Extension needed for texture2DLod
//extension GL_ARB_shader_texture_lod : enable
// Extensions needed fot texture2DGrad
//extension GL_EXT_gpu_shader4 : enable
// Extensions needed for bit manipulation
//extension GL_ARB_shader_bit_encoding : enable
#endif
#if (GRA_TEXTURE_ARRAY_SUPPORT==1)
gra_Float4 GranitePrivate_SampleArray(in GraniteCacheTexture tex, in gra_Float3 texCoord)
{
#if (GRA_HLSL_5 == 1) || (GRA_HLSL_4 == 1)
return tex.TextureArray.Sample(tex.Sampler, texCoord);
#elif (GRA_GLSL_330 == 1)
return texture(tex, texCoord);
#else
#error using unsupported function
#endif
}
gra_Float4 GranitePrivate_SampleGradArray(in GraniteCacheTexture tex, in gra_Float3 texCoord, in gra_Float2 dX, in gra_Float2 dY)
{
#if (GRA_HLSL_5 == 1) || (GRA_HLSL_4 == 1)
return tex.TextureArray.SampleGrad(tex.Sampler,texCoord,dX,dY);
#elif (GRA_GLSL_330 == 1)
return textureGrad(tex, texCoord, dX, dY);
#else
#error using unsupported function
#endif
}
gra_Float4 GranitePrivate_SampleLevelArray(in GraniteCacheTexture tex, in gra_Float3 texCoord, in float level)
{
#if (GRA_HLSL_5 == 1) || (GRA_HLSL_4 == 1)
return tex.TextureArray.SampleLevel(tex.Sampler, texCoord, level);
#elif (GRA_GLSL_330 == 1)
return textureLod(tex, texCoord, level);
#else
#error using unsupported function
#endif
}
#else
gra_Float4 GranitePrivate_Sample(in GraniteCacheTexture tex, in gra_Float2 texCoord)
{
#if (GRA_HLSL_5 == 1) || (GRA_HLSL_4 == 1)
return tex.Texture.Sample(tex.Sampler,texCoord);
#elif (GRA_HLSL_3 == 1)
return tex2D(tex,texCoord);
#elif (GRA_GLSL_120 == 1) || (GRA_GLSL_130 == 1)
return texture2D(tex, texCoord);
#elif (GRA_GLSL_330 == 1)
return texture(tex, texCoord);
#endif
}
gra_Float4 GranitePrivate_SampleLevel(in GraniteCacheTexture tex, in gra_Float2 texCoord, in float level)
{
#if (GRA_HLSL_5 == 1) || (GRA_HLSL_4 == 1)
return tex.Texture.SampleLevel(tex.Sampler, texCoord, level);
#elif (GRA_HLSL_3 == 1)
return tex2Dlod(tex,gra_Float4(texCoord,0.0,level));
#elif (GRA_GLSL_120 == 1)
return texture2DLod(tex, texCoord, level);
#elif (GRA_GLSL_130 == 1) || (GRA_GLSL_330 == 1)
return textureLod(tex, texCoord, level);
#endif
}
gra_Float4 GranitePrivate_SampleGrad(in GraniteCacheTexture tex, in gra_Float2 texCoord, in gra_Float2 dX, in gra_Float2 dY)
{
#if (GRA_HLSL_5 == 1) || (GRA_HLSL_4 == 1)
return tex.Texture.SampleGrad(tex.Sampler,texCoord,dX,dY);
#elif (GRA_HLSL_3 == 1)
return tex2D(tex,texCoord,dX,dY);
#elif (GRA_GLSL_120 == 1)
return texture2DGrad(tex, texCoord, dX, dY);
#elif (GRA_GLSL_130 == 1) || (GRA_GLSL_330 == 1)
return textureGrad(tex, texCoord, dX, dY);
#endif
}
#endif //#if (GRA_TEXTURE_ARRAY_SUPPORT==1)
#if (GRA_LOAD_INSTR==1)
gra_Float4 GranitePrivate_Load(in GraniteTranslationTexture tex, in gra_Int3 location)
{
#if (GRA_HLSL_5 == 1) || (GRA_HLSL_4 == 1)
return tex.Texture.Load(location);
#elif (GRA_GLSL_130 == 1) || (GRA_GLSL_330 == 1)
return texelFetch(tex, location.xy, location.z);
#elif (GRA_HLSL_3 == 1) || (GRA_GLSL_120 == 1)
#error using unsupported function
#endif
}
#endif
//work-around shader compiler bug
//compiler gets confused with GranitePrivate_SampleLevel taking a GraniteCacheTexture as argument when array support is disabled
//Without array support, GraniteCacheTexture and GraniteTranslationTexture are the same (but still different types!)
//compiler is confused (ERR_AMBIGUOUS_FUNCTION_CALL). Looks like somebody is over enthusiastic optimizing...
gra_Float4 GranitePrivate_SampleLevel_Translation(in GraniteTranslationTexture tex, in gra_Float2 texCoord, in float level)
{
#if (GRA_HLSL_5 == 1) || (GRA_HLSL_4 == 1)
return tex.Texture.SampleLevel(tex.Sampler, texCoord, level);
#elif (GRA_HLSL_3 == 1)
return tex2Dlod(tex,gra_Float4(texCoord,0.0,level));
#elif (GRA_GLSL_120 == 1)
return texture2DLod(tex, texCoord, level);
#elif (GRA_GLSL_130 == 1) || (GRA_GLSL_330 == 1)
return textureLod(tex, texCoord, level);
#endif
}
float GranitePrivate_Saturate(in float value)
{
#if GRA_HLSL_FAMILY
return saturate(value);
#elif GRA_GLSL_FAMILY
return clamp(value, 0.0f, 1.0f);
#endif
}
#if (GRA_HLSL_5 == 1) || (GRA_HLSL_4 == 1) || (GRA_GLSL_330 == 1)
uint GranitePrivate_FloatAsUint(float value)
{
#if (GRA_HLSL_5 == 1) || (GRA_HLSL_4 == 1)
return asuint(value);
#elif (GRA_GLSL_330 == 1)
return floatBitsToUint(value);
#endif
}
#endif
float GranitePrivate_Pow2(uint exponent)
{
#if GRA_HLSL_FAMILY
return pow(2.0, exponent);
#else
return pow(2.0, float(exponent));
#endif
}
gra_Float2 GranitePrivate_RepeatUV(in gra_Float2 uv, in GraniteStreamingTextureConstantBuffer grSTCB)
{
return frac(uv);
}
gra_Float2 GranitePrivate_UdimUV(in gra_Float2 uv, in GraniteStreamingTextureConstantBuffer grSTCB)
{
return uv;
}
gra_Float2 GranitePrivate_ClampUV(in gra_Float2 uv, in GraniteStreamingTextureConstantBuffer grSTCB)
{
gra_Float2 epsilon2 = gra_Float2(gra_AssetWidthRcp, gra_AssetHeightRcp);
return clamp(uv, epsilon2, gra_Float2(1,1) - epsilon2);
}
gra_Float2 GranitePrivate_MirrorUV(in gra_Float2 uv, in GraniteStreamingTextureConstantBuffer grSTCB)
{
gra_Float2 t = frac(uv*0.5)*2.0;
gra_Float2 l = gra_Float2(1.0,1.0);
return l-abs(t-l);
}
// function definitons for private functions
gra_Float4 GranitePrivate_PackTileId(in gra_Float2 tileXY, in float level, in float textureID);
gra_Float4 Granite_DebugPackedTileId64(in gra_Float4 PackedTile)
{
#if GRA_64BIT_RESOLVER
gra_Float4 output;
const float scale = 1.0f / 65535.0f;
gra_Float4 temp = PackedTile / scale;
output.x = fmod(temp.x, 256.0f);
output.y = floor(temp.x / 256.0f) + fmod(temp.y, 16.0f) * 16.0f;
output.z = floor(temp.y / 16.0f);
output.w = temp.z + temp.a * 16.0f;
return gra_Float4
(
(float)output.x / 255.0f,
(float)output.y / 255.0f,
(float)output.z / 255.0f,
(float)output.w / 255.0f
);
#else
return PackedTile;
#endif
}
gra_Float3 Granite_UnpackNormal(in gra_Float4 PackedNormal, float scale)
{
gra_Float2 reconstructed = gra_Float2(PackedNormal.x * PackedNormal.a, PackedNormal.y) * 2.0f - 1.0f;
reconstructed *= scale;
float z = sqrt(1.0f - GranitePrivate_Saturate(dot(reconstructed, reconstructed)));
return gra_Float3(reconstructed, z);
}
gra_Float3 Granite_UnpackNormal(in gra_Float4 PackedNormal)
{
return Granite_UnpackNormal(PackedNormal, 1.0);
}
#if GRA_HLSL_FAMILY
GraniteTilesetConstantBuffer Granite_ApplyResolutionOffset(in GraniteTilesetConstantBuffer INtsCB, in float resolutionOffsetPow2)
{
GraniteTilesetConstantBuffer tsCB = INtsCB;
gra_LodBiasPow2 *= resolutionOffsetPow2;
//resolutionOffsetPow2 *= resolutionOffsetPow2; //Square it before multiplying it in below
gra_CalcMiplevelDeltaScaleX *= resolutionOffsetPow2;
gra_CalcMiplevelDeltaScaleY *= resolutionOffsetPow2;
return tsCB;
}
GraniteTilesetConstantBuffer Granite_SetMaxAnisotropy(in GraniteTilesetConstantBuffer INtsCB, in float maxAnisotropyLog2)
{
GraniteTilesetConstantBuffer tsCB = INtsCB;
gra_MaxAnisotropyLog2 = min(gra_MaxAnisotropyLog2, maxAnisotropyLog2);
return tsCB;
}
#else
void Granite_ApplyResolutionOffset(inout GraniteTilesetConstantBuffer tsCB, in float resolutionOffsetPow2)
{
gra_LodBiasPow2 *= resolutionOffsetPow2;
//resolutionOffsetPow2 *= resolutionOffsetPow2; //Square it before multiplying it in below
gra_CalcMiplevelDeltaScaleX *= resolutionOffsetPow2;
gra_CalcMiplevelDeltaScaleY *= resolutionOffsetPow2;
}
void Granite_SetMaxAnisotropy(inout GraniteTilesetConstantBuffer tsCB, in float maxAnisotropyLog2)
{
gra_MaxAnisotropyLog2 = min(gra_MaxAnisotropyLog2, maxAnisotropyLog2);
}
#endif
gra_Float2 Granite_Transform(in GraniteStreamingTextureConstantBuffer grSTCB, in gra_Float2 textureCoord)
{
return textureCoord * gra_StreamingTextureTransform.zw + gra_StreamingTextureTransform.xy;
}
gra_Float4 Granite_MergeResolveOutputs(in gra_Float4 resolve0, in gra_Float4 resolve1, in gra_Float2 pixelLocation)
{
gra_Float2 screenPos = frac(pixelLocation * 0.5f);
bool dither = (screenPos.x != screenPos.y);
return (dither) ? resolve0 : resolve1;
}
gra_Float4 Granite_PackTileId(in gra_Float4 unpackedTileID)
{
return GranitePrivate_PackTileId(unpackedTileID.xy, unpackedTileID.z, unpackedTileID.w);
}
#if (GRA_HLSL_5 == 1)
void Granite_DitherResolveOutput(in gra_Float4 resolve, in RWTexture2D<GRA_UNORM gra_Float4> resolveTexture, in gra_Float2 screenPos, in float alpha)
{
const uint2 pixelPos = int2(screenPos);
const uint2 pixelLocation = pixelPos % GRA_RWTEXTURE2D_SCALE;
bool dither = (pixelLocation.x == 0) && (pixelLocation.y == 0);
uint2 writePos = pixelPos / GRA_RWTEXTURE2D_SCALE;
if ( alpha == 0 )
{
dither = false;
}
else if (alpha != 1.0)
{
// Do a 4x4 dither patern so alternating pixels resolve to the first or the second texture
gra_Float2 pixelLocationAlpha = frac(screenPos * 0.25f); // We don't scale after the frac so this will give coords 0, 0.25, 0.5, 0.75
int pixelId = (int)(pixelLocationAlpha.y * 16 + pixelLocationAlpha.x * 4); //faster as a dot2 ?
// Clamp
// This ensures that for example alpha=0.95 still resolves some tiles of the surfaces behind it
// and alpha=0.05 still resolves some tiles of this surface
alpha = min(max(alpha, 0.0625), 0.9375);
// Modern hardware supports array indexing with per pixel varying indexes
// on old hardware this will be expanded to a conditional tree by the compiler
const float thresholdMaxtrix[16] = { 1.0f / 17.0f, 9.0f / 17.0f, 3.0f / 17.0f, 11.0f / 17.0f,
13.0f / 17.0f, 5.0f / 17.0f, 15.0f / 17.0f, 7.0f / 17.0f,
4.0f / 17.0f, 12.0f / 17.0f, 2.0f / 17.0f, 10.0f / 17.0f,
16.0f / 17.0f, 8.0f / 17.0f, 14.0f / 17.0f, 6.0f / 17.0f};
float threshold = thresholdMaxtrix[pixelId];
if (alpha < threshold)
{
dither = false;
}
}
gra_Branch if (dither)
{
#if (GRA_PACK_RESOLVE_OUTPUT==0)
resolveTexture[writePos] = Granite_PackTileId(resolve);
#else
resolveTexture[writePos] = resolve;
#endif
}
}
#endif
float GranitePrivate_CalcMiplevelAnisotropic(in GraniteTilesetConstantBuffer tsCB, in GraniteStreamingTextureConstantBuffer grSTCB, in gra_Float2 ddxTc, in gra_Float2 ddyTc)
{
// Calculate the required mipmap level, this uses a similar
// formula as the GL spec.
// To reduce sqrt's and log2's we do some stuff in squared space here and further below in log space
// i.e. we wait with the sqrt untill we can do it for 'free' later during the log2
ddxTc *= gra_CalcMiplevelDeltaScale;
ddyTc *= gra_CalcMiplevelDeltaScale;
float lenDxSqr = dot(ddxTc, ddxTc);
float lenDySqr = dot(ddyTc, ddyTc);
float dMaxSqr = max(lenDxSqr, lenDySqr);
float dMinSqr = min(lenDxSqr, lenDySqr);
// Calculate mipmap levels directly from sqared distances. This uses log2(sqrt(x)) = 0.5 * log2(x) to save some sqrt's
float maxLevel = 0.5 * log2( dMaxSqr );
float minLevel = 0.5 * log2( dMinSqr );
// Calculate the log2 of the anisotropy and clamp it by the max supported. This uses log2(a/b) = log2(a)-log2(b) and min(log(a),log(b)) = log(min(a,b))
float anisoLog2 = maxLevel - minLevel;
anisoLog2 = min( anisoLog2, gra_MaxAnisotropyLog2 );
// Adjust for anisotropy & clamp to level 0
float result = max(maxLevel - anisoLog2 - 0.5f, 0.0f); //Subtract 0.5 to compensate for trilinear mipmapping
// Added clamping to avoid "hot pink" on small tilesets that try to sample past the 1x1 tile miplevel
// This happens if you for example import a relatively small texture and zoom out
return min(result, gra_NumLevels);
}
float GranitePrivate_CalcMiplevelLinear(in GraniteTilesetConstantBuffer tsCB, in GraniteStreamingTextureConstantBuffer grSTCB, in gra_Float2 ddxTc, in gra_Float2 ddyTc)
{
// Calculate the required mipmap level, this uses a similar
// formula as the GL spec.
// To reduce sqrt's and log2's we do some stuff in squared space here and further below in log space
// i.e. we wait with the sqrt untill we can do it for 'free' later during the log2
ddxTc *= gra_CalcMiplevelDeltaScale;
ddyTc *= gra_CalcMiplevelDeltaScale;
float lenDxSqr = dot(ddxTc, ddxTc);
float lenDySqr = dot(ddyTc, ddyTc);
float dMaxSqr = max(lenDxSqr, lenDySqr);
// Calculate mipmap levels directly from squared distances. This uses log2(sqrt(x)) = 0.5 * log2(x) to save some sqrt's
float maxLevel = 0.5 * log2(dMaxSqr) - 0.5f; //Subtract 0.5 to compensate for trilinear mipmapping
return clamp(maxLevel, 0.0f, gra_NumLevels);
}
gra_Float4 GranitePrivate_PackTileId(in gra_Float2 tileXY, in float level, in float textureID)
{
#if GRA_64BIT_RESOLVER == 0
gra_Float4 resultBits;
resultBits.x = fmod(tileXY.x, 256.0f);
resultBits.y = floor(tileXY.x / 256.0f) + fmod(tileXY.y, 32.0f) * 8.0f;
resultBits.z = floor(tileXY.y / 32.0f) + fmod(level, 4.0f) * 64.0f;
resultBits.w = floor(level / 4.0f) + textureID * 4.0f;
const float scale = 1.0f / 255.0f;
#if GRA_BGRA == 0
return scale * gra_Float4
(
float(resultBits.x),
float(resultBits.y),
float(resultBits.z),
float(resultBits.w)
);
#else
return scale * gra_Float4
(
float(resultBits.z),
float(resultBits.y),
float(resultBits.x),
float(resultBits.w)
);
#endif
#else
const float scale = 1.0f / 65535.0f;
return gra_Float4(tileXY.x, tileXY.y, level, textureID) * scale;
#endif
}
gra_Float4 GranitePrivate_UnpackTileId(in gra_Float4 packedTile)
{
gra_Float4 swiz;
#if GRA_BGRA == 0
swiz = packedTile;
#else
swiz = packedTile.zyxw;
#endif
swiz *= 255.0f;
float tileX = swiz.x + fmod(swiz.y, 16.0f) * 256.0f;
float tileY = floor(swiz.y / 16.0f) + swiz.z * 16.0f;
float level = fmod(swiz.w, 16.0f);
float tex = floor(swiz.w / 16.0f);
return gra_Float4(tileX, tileY, level, tex);
}
gra_Float3 GranitePrivate_TranslateCoord(in GraniteTilesetConstantBuffer tsCB, in gra_Float2 inputTexCoord, in gra_Float4 translationData, in int layer, out gra_Float2 numPagesOnLevel)
{
// The translation table contains uint32_t values so we have to get to the individual bits of the float data
uint data = GranitePrivate_FloatAsUint(translationData[layer]);
// Slice Index: 7 bits, Cache X: 10 bits, Cache Y: 10 bits, Tile Level: 4 bits
uint slice = (data >> 24u) & 0x7Fu;
uint cacheX = (data >> 14u) & 0x3FFu;
uint cacheY = (data >> 4u) & 0x3FFu;
uint revLevel = data & 0xFu;
gra_Float2 numTilesOnLevel;
numTilesOnLevel.x = GranitePrivate_Pow2(revLevel);
numTilesOnLevel.y = numTilesOnLevel.x * gra_NumTilesYScale;
gra_Float2 tileTexCoord = frac(inputTexCoord * numTilesOnLevel);
gra_Float2 tileTexCoordCache = tileTexCoord * gra_TileContentInTiles + gra_Float2(cacheX, cacheY);
gra_Float3 final = gra_Float3(tileTexCoordCache * gra_RcpCacheInTiles(layer) + gra_BorderPixelsRcpCache(layer), slice);
numPagesOnLevel = numTilesOnLevel * gra_TileContentInTiles * gra_RcpCacheInTiles(layer);
return final;
}
gra_Float4 GranitePrivate_DrawDebugTiles(in gra_Float4 sourceColor, in gra_Float2 textureCoord, in gra_Float2 numPagesOnLevel)
{
// Calculate the border values
gra_Float2 cacheOffs = frac(textureCoord * numPagesOnLevel);
float borderTemp = max(cacheOffs.x, 1.0-cacheOffs.x);
borderTemp = max(max(cacheOffs.y, 1.0-cacheOffs.y), borderTemp);
float border = smoothstep(0.98, 0.99, borderTemp);
// White
gra_Float4 borderColor = gra_Float4(1,1,1,1);
//Lerp it over the source color
return lerp(sourceColor, borderColor, border);
}
gra_Float4 GranitePrivate_MakeResolveOutput(in GraniteTilesetConstantBuffer tsCB, in gra_Float2 tileXY, in float level)
{
#if GRA_PACK_RESOLVE_OUTPUT
return GranitePrivate_PackTileId(tileXY, level, gra_TextureId);
#else
return gra_Float4(tileXY, level, gra_TextureId);
#endif
}
gra_Float4 GranitePrivate_ResolverPixel(in GraniteTilesetConstantBuffer tsCB, in gra_Float2 inputTexCoord, in float LOD)
{
float level = floor(LOD + 0.5f);
// Number of tiles on level zero
gra_Float2 level0NumTiles;
level0NumTiles.x = gra_Level0NumTilesX;
level0NumTiles.y = gra_Level0NumTilesX * gra_NumTilesYScale;
// Calculate xy of the tiles to load
gra_Float2 virtualTilesUv = floor(inputTexCoord * level0NumTiles * pow(0.5, level));
return GranitePrivate_MakeResolveOutput(tsCB, virtualTilesUv, level);
}
void GranitePrivate_CalculateCubemapCoordinates(in gra_Float3 inputTexCoord, in gra_Float3 dVx, in gra_Float3 dVy, in GraniteStreamingTextureCubeConstantBuffer transforms, out int faceIdx, out gra_Float2 texCoord, out gra_Float2 dX, out gra_Float2 dY)
{
gra_Float2 contTexCoord;
gra_Float3 derivX;
gra_Float3 derivY;
float majorAxis;
if (abs(inputTexCoord.z) >= abs(inputTexCoord.x) && abs(inputTexCoord.z) >= abs(inputTexCoord.y))
{
// Z major axis
if(inputTexCoord.z < 0.0)
{
faceIdx = 5;
texCoord.x = -inputTexCoord.x;
}
else
{
faceIdx = 4;
texCoord.x = inputTexCoord.x;
}
texCoord.y = -inputTexCoord.y;
majorAxis = inputTexCoord.z;
contTexCoord = gra_Float2(inputTexCoord.x, inputTexCoord.y);
derivX = gra_Float3(dVx.x, dVx.y, dVx.z);
derivY = gra_Float3(dVy.x, dVy.y, dVy.z);
}
else if (abs(inputTexCoord.y) >= abs(inputTexCoord.x))
{
// Y major axis
if(inputTexCoord.y < 0.0)
{
faceIdx = 3;
texCoord.y = -inputTexCoord.z;
}
else
{
faceIdx = 2;
texCoord.y = inputTexCoord.z;
}
texCoord.x = inputTexCoord.x;
majorAxis = inputTexCoord.y;
contTexCoord = gra_Float2(inputTexCoord.x, inputTexCoord.z);
derivX = gra_Float3(dVx.x, dVx.z, dVx.y);
derivY = gra_Float3(dVy.x, dVy.z, dVy.y);
}
else
{
// X major axis
if(inputTexCoord.x < 0.0)
{
faceIdx = 1;
texCoord.x = inputTexCoord.z;
}
else
{
faceIdx = 0;
texCoord.x = -inputTexCoord.z;
}
texCoord.y = -inputTexCoord.y;
majorAxis = inputTexCoord.x;
contTexCoord = gra_Float2(inputTexCoord.z, inputTexCoord.y);
derivX = gra_Float3(dVx.z, dVx.y, dVx.x);
derivY = gra_Float3(dVy.z, dVy.y, dVy.x);
}
texCoord = (texCoord + majorAxis) / (2.0 * abs(majorAxis));
#if GRA_HQ_CUBEMAPPING
dX = /*contTexCoord **/ ((contTexCoord + derivX.xy) / ( 2.0 * (majorAxis + derivX.z)) - (contTexCoord / (2.0 * majorAxis)));
dY = /*contTexCoord **/ ((contTexCoord + derivY.xy) / ( 2.0 * (majorAxis + derivY.z)) - (contTexCoord / (2.0 * majorAxis)));
#else
dX = ((/*contTexCoord **/ derivX.xy) / (2.0 * abs(majorAxis)));
dY = ((/*contTexCoord **/ derivY.xy) / (2.0 * abs(majorAxis)));
#endif
// Now scale the derivatives with the texture transform scale
dX *= transforms.data[faceIdx].data[0].zw;
dY *= transforms.data[faceIdx].data[0].zw;
}
// Auto-level
void GranitePrivate_CalculateCubemapCoordinates(in gra_Float3 inputTexCoord, in GraniteStreamingTextureCubeConstantBuffer transforms, out int faceIdx, out gra_Float2 texCoord, out gra_Float2 dX, out gra_Float2 dY)
{
gra_Float3 dVx = ddx(inputTexCoord);
gra_Float3 dVy = ddy(inputTexCoord);
GranitePrivate_CalculateCubemapCoordinates(inputTexCoord, dVx, dVy, transforms, faceIdx, texCoord, dX, dY);
}
gra_Float2 Granite_GetTextureDimensions(in GraniteStreamingTextureConstantBuffer grSTCB)
{
return gra_Float2(1.0 / gra_AssetWidthRcp, 1.0 / gra_AssetHeightRcp); //TODO(ddebaets) use HLSL rcp here
}

View File

@@ -0,0 +1,27 @@
fileFormatVersion: 2
guid: c5520328ccc5d6c4e8a923677cbb21cf
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,714 @@
// Important! This file assumes Color.hlsl and ACES.hlsl has been already included.
#ifndef HDROUTPUT_INCLUDED
#define HDROUTPUT_INCLUDED
#include "Packages/com.unity.render-pipelines.core/Runtime/PostProcessing/HDROutputDefines.cs.hlsl"
#if defined(HDR_COLORSPACE_CONVERSION_AND_ENCODING)
#define HDR_COLORSPACE_CONVERSION
#define HDR_ENCODING
#endif
int _HDRColorspace;
int _HDREncoding;
// A bit of nomenclature that will be used in the file:
// Gamut: It is the subset of colors that is possible to reproduce by using three specific primary colors.
// Rec709 (ITU-R Recommendation BT709) is a HDTV standard, in our context, we mostly care about its color gamut (https://en.wikipedia.org/wiki/Rec._709). The Rec709 gamut is the same as BT1886 and sRGB.
// Rec2020 (ITU-R Recommendation BT2020) is an UHDTV standard. As above, we mostly reference it w.r.t. the color gamut. (https://en.wikipedia.org/wiki/Rec._2020). Nice property is that all primaries are on the locus.
// DCI-P3 (or just P3): is a gamut used in cinema grading and used by iPhone for example.
// ACEScg: A gamut that is larger than Rec2020.
// ACES2065-1: A gamut that covers the full XYZ space, part of the ACES specs. Mostly used for storage since it is harder to work with than ACEScg.
// WCG: Wide color gamut. This is defined as a color gamut that is wider than the Rec709 one.
// LMS: A color space represented by the response of the three cones of human eye (responsivity peaks Long, Medium, Short)
// OETF (Optical Eelectro Transfer Function): This is a function to goes from optical (linear light) to electro (signal transmitted to the display).
// EOTF (Eelectro Optical Transfer Function): The inverse of the OETF, used by the TV/Monitor.
// EETF (Eelectro-Electro Transfer Function): This is generally just a remapping function, we use the BT2390 EETF to perform range reduction based on the actual display.
// PQ (Perceptual Quantizer): the EOTF used for HDR10 TVs. It works in the range [0, 10000] nits. Important to keep in mind that this represents an absolute intensity and not relative as for SDR. Sometimes this can be referenced as ST2084. As OETF we'll use the inverse of the PQ curve.
// scRGB: a wide color gamut that uses same color space and white point as sRGB, but with much wider coordinates. Used on windows when 16 bit depth is selected. Most of the color space is imaginary colors. Works differently than with PQ (encoding is linear).
// --------------------------------
// Perceptual Quantizer (PQ) / ST 2084
// --------------------------------
#define MAX_PQ_VALUE 10000 // 10k nits is the maximum supported by the standard.
#define PQ_N (2610.0f / 4096.0f / 4.0f)
#define PQ_M (2523.0f / 4096.0f * 128.0f)
#define PQ_C1 (3424.0f / 4096.0f)
#define PQ_C2 (2413.0f / 4096.0f * 32.0f)
#define PQ_C3 (2392.0f / 4096.0f * 32.0f)
float LinearToPQ(float value, float maxPQValue)
{
value /= maxPQValue;
float Ym1 = PositivePow(value, PQ_N);
float n = (PQ_C1 + PQ_C2 * Ym1);
float d = (1.0f + PQ_C3 * Ym1);
return PositivePow(n / d, PQ_M);
}
float LinearToPQ(float value)
{
return LinearToPQ(value, MAX_PQ_VALUE);
}
float3 LinearToPQ(float3 value, float maxPQValue)
{
float3 outPQ;
outPQ.x = LinearToPQ(value.x, maxPQValue);
outPQ.y = LinearToPQ(value.y, maxPQValue);
outPQ.z = LinearToPQ(value.z, maxPQValue);
return outPQ;
}
float3 LinearToPQ(float3 value)
{
return LinearToPQ(value, MAX_PQ_VALUE);
}
float PQToLinear(float value)
{
float Em2 = PositivePow(value, 1.0f / PQ_M);
float X = (max(0.0, Em2 - PQ_C1)) / (PQ_C2 - PQ_C3 * Em2);
return PositivePow(X, 1.0f / PQ_N);
}
float PQToLinear(float value, float maxPQValue)
{
return PQToLinear(value) * maxPQValue;
}
float3 PQToLinear(float3 value, float maxPQValue)
{
float3 outLinear;
outLinear.x = PQToLinear(value.x, maxPQValue);
outLinear.y = PQToLinear(value.y, maxPQValue);
outLinear.z = PQToLinear(value.z, maxPQValue);
return outLinear;
}
float3 PQToLinear(float3 value)
{
float3 outLinear;
outLinear.x = PQToLinear(value.x);
outLinear.y = PQToLinear(value.y);
outLinear.z = PQToLinear(value.z);
return outLinear;
}
// --------------------------------------------------------------------------------------------
// --------------------------------
// Color Space transforms
// --------------------------------
// As any other space transform, changing color space involves a change of basis and therefore a matrix multiplication.
// Note that Rec2020 and Rec2100 share the same color space.
float3 RotateRec709ToRec2020(float3 Rec709Input)
{
static const float3x3 Rec709ToRec2020Mat = float3x3(
0.627402, 0.329292, 0.043306,
0.069095, 0.919544, 0.011360,
0.016394, 0.088028, 0.895578
);
return mul(Rec709ToRec2020Mat, Rec709Input);
}
float3 RotateRec2020ToRec709(float3 Rec2020Input)
{
static const float3x3 Rec2020ToRec709Mat = float3x3(
1.660496, -0.587656, -0.072840,
-0.124547, 1.132895, -0.008348,
-0.018154, -0.100597, 1.118751
);
return mul(Rec2020ToRec709Mat, Rec2020Input);
}
float3 RotateRec709ToOutputSpace(float3 Rec709Input)
{
if (_HDRColorspace == HDRCOLORSPACE_REC2020)
{
return RotateRec709ToRec2020(Rec709Input);
}
else // HDRCOLORSPACE_REC709
{
return Rec709Input;
}
}
float3 RotateRec2020ToOutputSpace(float3 Rec2020Input)
{
if (_HDRColorspace == HDRCOLORSPACE_REC2020)
{
return Rec2020Input;
}
else // HDRCOLORSPACE_REC709
{
return RotateRec2020ToRec709(Rec2020Input);
}
}
float3 RotateRec2020ToLMS(float3 Rec2020Input)
{
static const float3x3 Rec2020ToLMSMat =
{
0.412109375, 0.52392578125, 0.06396484375,
0.166748046875, 0.720458984375, 0.11279296875,
0.024169921875, 0.075439453125, 0.900390625
};
return mul(Rec2020ToLMSMat, Rec2020Input);
}
float3 Rotate709ToLMS(float3 Rec709Input)
{
static const float3x3 Rec709ToLMSMat =
{
0.412109375, 0.52392578125, 0.06396484375,
0.166748046875, 0.720458984375, 0.11279296875,
0.024169921875, 0.075439453125, 0.900390625
};
return mul(Rec709ToLMSMat, Rec709Input);
}
// Ref: ICtCp Dolby white paper (https://www.dolby.com/us/en/technologies/dolby-vision/ictcp-white-paper.pdf)
float3 RotatePQLMSToICtCp(float3 LMSInput)
{
static const float3x3 PQLMSToICtCpMat = float3x3(
0.5f, 0.5f, 0.0f,
1.613769f, -3.323486f, 1.709716f,
4.378174f, -4.245605f, -0.1325683f
);
return mul(PQLMSToICtCpMat, LMSInput);
}
float3 RotateLMSToICtCp(float3 lms)
{
float3 PQLMS = LinearToPQ(max(0.0f, lms));
return RotatePQLMSToICtCp(PQLMS);
}
float3 RotateRec2020ToICtCp(float3 Rec2020)
{
float3 lms = RotateRec2020ToLMS(Rec2020);
float3 PQLMS = LinearToPQ(max(0.0f, lms));
return RotatePQLMSToICtCp(PQLMS);
}
float3 RotateOutputSpaceToICtCp(float3 inputColor)
{
// TODO: Do the conversion directly from Rec709 (bake matrix Rec709 -> XYZ -> LMS)
if (_HDRColorspace == HDRCOLORSPACE_REC709)
{
inputColor = RotateRec709ToRec2020(inputColor);
}
return RotateRec2020ToICtCp(inputColor);
}
float3 RotateLMSToXYZ(float3 LMSInput)
{
static const float3x3 LMSToXYZMat = float3x3(
2.07018005669561320f, -1.32645687610302100f, 0.206616006847855170f,
0.36498825003265756f, 0.68046736285223520f, -0.045421753075853236f,
-0.04959554223893212f, -0.04942116118675749f, 1.187995941732803400f
);
return mul(LMSToXYZMat, LMSInput);
}
float3 RotateXYZToRec2020(float3 XYZ)
{
static const float3x3 XYZToRec2020Mat = float3x3(
1.71235168f, -0.35487896f, -0.25034135f,
-0.66728621f, 1.61794055f, 0.01495380f,
0.01763985f, -0.04277060f, 0.94210320f
);
return mul(XYZToRec2020Mat, XYZ);
}
float3 RotateXYZToRec709(float3 XYZ)
{
return mul(XYZ_2_REC709_MAT, XYZ);
}
float3 RotateXYZToOutputSpace(float3 xyz)
{
if (_HDRColorspace == HDRCOLORSPACE_REC2020)
{
return RotateXYZToRec2020(xyz);
}
// else if (_HDRColorspace == HDRCOLORSPACE_P3D65)
// {
// return RotateXYZToP3D65(xyz);
// }
else // HDRCOLORSPACE_REC709
{
return RotateXYZToRec709(xyz);
}
}
float3 RotateRec709ToXYZ(float3 rgb)
{
static const float3x3 Rec709ToXYZMat = float3x3(
0.412391f, 0.357584f, 0.180481,
0.212639, 0.715169, 0.0721923,
0.0193308, 0.119195, 0.950532
);
return mul(Rec709ToXYZMat, rgb);
}
float3 RotateRec2020ToXYZ(float3 rgb)
{
static const float3x3 Rec2020ToXYZMat = float3x3(
0.638574, 0.144617, 0.167265,
0.263367, 0.677998, 0.0586353,
0.0f, 0.0280727, 1.06099
);
return mul(Rec2020ToXYZMat, rgb);
}
float3 RotateOutputSpaceToXYZ(float3 rgb)
{
if (_HDRColorspace == HDRCOLORSPACE_REC2020)
{
return RotateRec2020ToXYZ(rgb);
}
// else if (_HDRColorspace == HDRCOLORSPACE_P3D65)
// {
// return RotateP3D65ToXYZ(rgb);
// }
else // HDRCOLORSPACE_REC709
{
return RotateRec709ToXYZ(rgb);
}
}
float3 RotateICtCpToPQLMS(float3 ICtCp)
{
static const float3x3 ICtCpToPQLMSMat = float3x3(
1.0f, 0.0086051456939815f, 0.1110356044754732f,
1.0f, -0.0086051456939815f, -0.1110356044754732f,
1.0f, 0.5600488595626390f, -0.3206374702321221f
);
return mul(ICtCpToPQLMSMat, ICtCp);
}
float3 RotateICtCpToXYZ(float3 ICtCp)
{
float3 PQLMS = RotateICtCpToPQLMS(ICtCp);
float3 LMS = PQToLinear(PQLMS, MAX_PQ_VALUE);
return RotateLMSToXYZ(LMS);
}
float3 RotateICtCpToRec2020(float3 ICtCp)
{
return RotateXYZToRec2020(RotateICtCpToXYZ(ICtCp));
}
float3 RotateICtCpToRec709(float3 ICtCp)
{
return RotateXYZToRec709(RotateICtCpToXYZ(ICtCp));
}
float3 RotateICtCpToOutputSpace(float3 ICtCp)
{
if (_HDRColorspace == HDRCOLORSPACE_REC2020)
{
return RotateICtCpToRec2020(ICtCp);
}
else // HDRCOLORSPACE_REC709
{
return RotateICtCpToRec709(ICtCp);
}
}
// --------------------------------------------------------------------------------------------
// --------------------------------
// OETFs
// --------------------------------
// The functions here are OETF, technically for applying the opposite of the PQ curve, we are mapping
// from linear to PQ space as this is what the display expects.
// See this desmos for comparisons https://www.desmos.com/calculator/5jdfc4pgtk
#define PRECISE_PQ 0
#define ISS_APPROX_PQ 1
#define GTS_APPROX_PQ 2
#define OETF_CHOICE GTS_APPROX_PQ
// What the platforms expects as SDR max brightness (different from paper white brightness) in linear encoding
#if defined(SHADER_API_METAL)
#define SDR_REF_WHITE 100
#else
#define SDR_REF_WHITE 80
#endif
// Ref: [Patry 2017] HDR Display Support in Infamous Second Son and Infamous First Light
// Fastest option, but also the least accurate. Behaves well for values up to 1400 nits but then starts diverging.
// IMPORTANT! It requires the input to be scaled from [0 ... 10000] to [0...100]!
float3 PatryApproxLinToPQ(float3 x)
{
return (x * (x * (x * (x * (x * 533095.76 + 47438306.2) + 29063622.1) + 575216.76) + 383.09104) + 0.000487781) /
(x * (x * (x * (x * 66391357.4 + 81884528.2) + 4182885.1) + 10668.404) + 1.0);
}
// Ref: [Uchimura and Suzuki 2018] Practical HDR and Wide Color Techniques in Gran Turismo Sport
// Slower than Infamous approx, but more precise ( https://www.desmos.com/calculator/up4wwozghk ) in the full [0... 10 000] range, but still faster than reference
// IMPORTANT! It requires the input to be scaled from [0 ... 10000] to [0...100]!
float3 GTSApproxLinToPQ(float3 inputCol)
{
float3 k = PositivePow((inputCol * 0.01), PQ_N);
return (3.61972*(1e-8) + k * (0.00102859 + k * (-0.101284 + 2.05784 * k))) /
(0.0495245 + k * (0.135214 + k * (0.772669 + k)));
}
// IMPORTANT! This wants the input in [0...10000] range, if the method requires scaling, it is done inside this function.
float3 OETF(float3 inputCol)
{
if (_HDREncoding == HDRENCODING_LINEAR)
{
// IMPORTANT! This assumes that the maximum nits is always higher or same as the reference white. Seems like a sensible choice, but revisit if we find weird use cases (just min with the the max nits).
// We need to map the value 1 to [reference white] nits.
return inputCol / SDR_REF_WHITE;
}
else if (_HDREncoding == HDRENCODING_PQ)
{
#if OETF_CHOICE == PRECISE_PQ
return LinearToPQ(inputCol);
#elif OETF_CHOICE == ISS_APPROX_PQ
return PatryApproxLinToPQ(inputCol * 0.01f);
#elif OETF_CHOICE == GTS_APPROX_PQ
return GTSApproxLinToPQ(inputCol * 0.01f);
#endif
}
else
{
return inputCol;
}
}
#define LIN_TO_PQ_FOR_LUT GTS_APPROX_PQ // GTS is close enough https://www.desmos.com/calculator/up4wwozghk
float3 LinearToPQForLUT(float3 inputCol)
{
#if LIN_TO_PQ_FOR_LUT == PRECISE_PQ
return LinearToPQ(inputCol);
#elif LIN_TO_PQ_FOR_LUT == ISS_APPROX_PQ
return PatryApproxLinToPQ(inputCol * 0.01f);
#elif LIN_TO_PQ_FOR_LUT == GTS_APPROX_PQ
return GTSApproxLinToPQ(inputCol * 0.01f);
#endif
}
// --------------------------------------------------------------------------------------------
// --------------------------------
// Range reduction
// --------------------------------
// This section of the file concerns the way we map from full range to whatever range the display supports.
// Also note, we always tonemap luminance component only, so we need to reach this point after we converted
// to a format such as ICtCp or YCbCr
// See https://www.desmos.com/calculator/pqc3raolms for plots
#define RANGE_REDUCTION HDRRANGEREDUCTION_BT2390LUMA_ONLY
// Note this takes x being in [0...10k nits]
float ReinhardTonemap(float x, float peakValue)
{
float m = MAX_PQ_VALUE * peakValue / (MAX_PQ_VALUE - peakValue);
return x * m / (x + m);
}
/// BT2390 EETF Helper functions
float T(float A, float Ks)
{
return (A - Ks) / (1.0f - Ks);
}
float P(float B, float Ks, float L_max)
{
float TB2 = T(B, Ks) * T(B, Ks);
float TB3 = TB2 * T(B, Ks);
return lerp((TB3 - 2 * TB2 + T(B, Ks)), (2.0f * TB3 - 3.0f * TB2 + 1.0f), Ks) + (-2.0f * TB3 + 3.0f*TB2)*L_max;
}
// Ref: https://www.itu.int/dms_pub/itu-r/opb/rep/R-REP-BT.2390-4-2018-PDF-E.pdf page 21
// This takes values in [0...10k nits] and it outputs in the same space. PQ conversion outside.
// If we chose this, it can be optimized (a few identity happen with moving between linear and PQ)
float BT2390EETF(float x, float minLimit, float maxLimit)
{
float E_0 = LinearToPQ(x);
// For the following formulas we are assuming L_B = 0 and L_W = 10000 -- see original paper for full formulation
float E_1 = E_0;
float L_min = LinearToPQ(minLimit);
float L_max = LinearToPQ(maxLimit);
float Ks = 1.5f * L_max - 0.5f; // Knee start
float b = L_min;
float E_2 = E_1 < Ks ? E_1 : P(E_1, Ks, L_max);
float E3Part = (1.0f - E_2);
float E3Part2 = E3Part * E3Part;
float E_3 = E_2 + b * (E3Part2 * E3Part2);
float E_4 = E_3; // Is like this because PQ(L_W)= 1 and PQ(L_B) = 0
return PQToLinear(E_4, MAX_PQ_VALUE);
}
float3 PerformRangeReduction(float3 input, float minNits, float maxNits)
{
float3 ICtCp = RotateOutputSpaceToICtCp(input); // This is in PQ space.
float linearLuma = PQToLinear(ICtCp.x, MAX_PQ_VALUE);
#if RANGE_REDUCTION == HDRRANGEREDUCTION_REINHARD_LUMA_ONLY
linearLuma = ReinhardTonemap(linearLuma, maxNits);
#elif RANGE_REDUCTION == HDRRANGEREDUCTION_BT2390LUMA_ONLY
linearLuma = BT2390EETF(linearLuma, minNits, maxNits);
#endif
ICtCp.x = LinearToPQ(linearLuma);
return RotateICtCpToOutputSpace(ICtCp); // This moves back to linear too!
}
// TODO: This is very ad-hoc and eyeballed on a limited set. Would be nice to find a standard.
float3 DesaturateReducedICtCp(float3 ICtCp, float lumaPre, float maxNits)
{
float saturationAmount = min(1.0f, ICtCp.x / max(lumaPre, 1e-6f)); // BT2390, but only when getting darker.
//saturationAmount = min(lumaPre / ICtCp.x, ICtCp.x / lumaPre); // Actual BT2390 suggestion
saturationAmount *= saturationAmount;
//saturationAmount = pow(smoothstep(1.0f, 0.4f, ICtCp.x), 0.9f); // A smoothstepp-y function.
ICtCp.yz *= saturationAmount;
return ICtCp;
}
float LumaRangeReduction(float input, float minNits, float maxNits, int mode)
{
float output = input;
if (mode == HDRRANGEREDUCTION_REINHARD)
{
output = ReinhardTonemap(input, maxNits);
}
else if (mode == HDRRANGEREDUCTION_BT2390)
{
output = BT2390EETF(input, minNits, maxNits);
}
return output;
}
float3 HuePreservingRangeReduction(float3 input, float minNits, float maxNits, int mode)
{
float3 ICtCp = RotateOutputSpaceToICtCp(input);
float lumaPreRed = ICtCp.x;
float linearLuma = PQToLinear(ICtCp.x, MAX_PQ_VALUE);
linearLuma = LumaRangeReduction(linearLuma, minNits, maxNits, mode);
ICtCp.x = LinearToPQ(linearLuma);
ICtCp = DesaturateReducedICtCp(ICtCp, lumaPreRed, maxNits);
return RotateICtCpToOutputSpace(ICtCp);
}
float3 HueShiftingRangeReduction(float3 input, float minNits, float maxNits, int mode)
{
float3 hueShiftedResult = input;
if (mode == HDRRANGEREDUCTION_REINHARD)
{
hueShiftedResult.x = ReinhardTonemap(input.x, maxNits);
hueShiftedResult.y = ReinhardTonemap(input.y, maxNits);
hueShiftedResult.z = ReinhardTonemap(input.z, maxNits);
}
else if(mode == HDRRANGEREDUCTION_BT2390)
{
hueShiftedResult.x = BT2390EETF(input.x, minNits, maxNits);
hueShiftedResult.y = BT2390EETF(input.y, minNits, maxNits);
hueShiftedResult.z = BT2390EETF(input.z, minNits, maxNits);
}
return hueShiftedResult;
}
// Ref "High Dynamic Range color grading and display in Frostbite" [Fry 2017]
float3 FryHuePreserving(float3 input, float minNits, float maxNits, float hueShift, int mode)
{
float3 ictcp = RotateOutputSpaceToICtCp(input);
// Hue-preserving range compression requires desaturation in order to achieve a natural look. We adaptively desaturate the input based on its luminance.
float saturationAmount = pow(smoothstep(1.0, 0.3, ictcp.x), 1.3);
float3 col = RotateICtCpToOutputSpace(ictcp * float3(1, saturationAmount.xx));
// Only compress luminance starting at a certain point. Dimmer inputs are passed through without modification.
float linearSegmentEnd = 0.25f;
// Hue-preserving mapping
float maxCol = max(col.x, max(col.y, col.z));
float mappedMax = maxCol;
if (maxCol > linearSegmentEnd)
{
mappedMax = LumaRangeReduction(maxCol, minNits, maxNits, mode);
}
float3 compressedHuePreserving = col * mappedMax / maxCol;
// Non-hue preserving mapping
float3 perChannelCompressed = 0;
perChannelCompressed.x = col.x > linearSegmentEnd ? LumaRangeReduction(col.x, minNits, maxNits, mode) : col.x;
perChannelCompressed.y = col.y > linearSegmentEnd ? LumaRangeReduction(col.y, minNits, maxNits, mode) : col.y;
perChannelCompressed.z = col.z > linearSegmentEnd ? LumaRangeReduction(col.z, minNits, maxNits, mode) : col.z;
// Combine hue-preserving and non-hue-preserving colors. Absolute hue preservation looks unnatural, as bright colors *appear* to have been hue shifted.
// Actually doing some amount of hue shifting looks more pleasing
col = lerp(perChannelCompressed, compressedHuePreserving, 1-hueShift);
float3 ictcpMapped = RotateOutputSpaceToICtCp(col);
// Smoothly ramp off saturation as brightness increases, but keep some even for very bright input
float postCompressionSaturationBoost = 0.3 * smoothstep(1.0, 0.5, ictcp.x);
// Re-introduce some hue from the pre-compression color. Something similar could be accomplished by delaying the luma-dependent desaturation before range compression.
// Doing it here however does a better job of preserving perceptual luminance of highly saturated colors. Because in the hue-preserving path we only range-compress the max channel,
// saturated colors lose luminance. By desaturating them more aggressively first, compressing, and then re-adding some saturation, we can preserve their brightness to a greater extent.
ictcpMapped.yz = lerp(ictcpMapped.yz, ictcp.yz * ictcpMapped.x / max(1e-3, ictcp.x), postCompressionSaturationBoost);
col = RotateICtCpToOutputSpace(ictcpMapped);
return col;
}
float3 PerformRangeReduction(float3 input, float minNits, float maxNits, int mode, float hueShift)
{
float3 outputValue = input;
bool reduceLuma = hueShift < 1.0f;
bool needHueShiftVersion = hueShift > 0.0f;
if (mode == HDRRANGEREDUCTION_NONE)
{
outputValue = input;
}
else
{
float3 huePreserving = reduceLuma ? HuePreservingRangeReduction(input, minNits, maxNits, mode) : 0;
float3 hueShifted = needHueShiftVersion ? HueShiftingRangeReduction(input, minNits, maxNits, mode) : 0;
if (reduceLuma && !needHueShiftVersion)
{
outputValue = huePreserving;
}
else if (!reduceLuma && needHueShiftVersion)
{
outputValue = hueShifted;
}
else
{
// We need to combine the two cases
outputValue = lerp(huePreserving, hueShifted, hueShift);
}
}
return outputValue;
}
// --------------------------------------------------------------------------------------------
// --------------------------------
// Public facing functions
// --------------------------------
// These functions are aggregate of most of what we have above. You can think of this as the public API of the HDR Output library.
// Note that throughout HDRP we are assuming that when it comes to the final pass adjustements, our tonemapper has *NOT*
// performed range reduction and everything is assumed to be displayed on a reference 10k nits display and everything post-tonemapping
// is in either the Rec 2020 or Rec709 color space. The Rec709 version just rotate to Rec2020 before going forward if required by the output device.
float3 HDRMappingFromRec2020(float3 Rec2020Input, float paperWhite, float minNits, float maxNits, int reductionMode, float hueShift, bool skipOETF = false)
{
float3 outputSpaceInput = RotateRec2020ToOutputSpace(Rec2020Input);
float3 reducedHDR = PerformRangeReduction(outputSpaceInput * paperWhite, minNits, maxNits, reductionMode, hueShift);
if (skipOETF) return reducedHDR;
return OETF(reducedHDR);
}
float3 HDRMappingFromRec709(float3 Rec709Input, float paperWhite, float minNits, float maxNits, int reductionMode, float hueShift, bool skipOETF = false)
{
float3 outputSpaceInput = RotateRec709ToOutputSpace(Rec709Input);
float3 reducedHDR = PerformRangeReduction(outputSpaceInput * paperWhite, minNits, maxNits, reductionMode, hueShift);
if (skipOETF) return reducedHDR;
return OETF(reducedHDR);
}
float3 HDRMappingACES(float3 aces, float hdrBoost, int reductionMode, bool skipOETF = false)
{
aces = (aces * hdrBoost * 0.01f);
float3 oces = RRT(aces);
float3 AP1ODT = 0;
// This is a static branch.
if (reductionMode == HDRRANGEREDUCTION_ACES1000NITS)
{
AP1ODT = ODT_1000nits_ToAP1(oces);
}
else if (reductionMode == HDRRANGEREDUCTION_ACES2000NITS)
{
AP1ODT = ODT_2000nits_ToAP1(oces);
}
else if (reductionMode == HDRRANGEREDUCTION_ACES4000NITS)
{
AP1ODT = ODT_4000nits_ToAP1(oces);
}
float3 linearODT = 0;
if (_HDRColorspace == HDRCOLORSPACE_REC2020)
{
const float3x3 AP1_2_Rec2020 = mul(XYZ_2_REC2020_MAT, mul(D60_2_D65_CAT, AP1_2_XYZ_MAT));
linearODT = mul(AP1_2_Rec2020, AP1ODT);
}
else // HDRCOLORSPACE_REC709
{
const float3x3 AP1_2_Rec709 = mul(XYZ_2_REC709_MAT, mul(D60_2_D65_CAT, AP1_2_XYZ_MAT));
linearODT = mul(AP1_2_Rec709, AP1ODT);
}
if (skipOETF) return linearODT;
return OETF(linearODT);
}
// --------------------------------------------------------------------------------------------
// --------------------------------
// UI Related functions
// --------------------------------
float3 ProcessUIForHDR(float3 uiSample, float paperWhite, float maxNits)
{
uiSample.rgb = RotateRec709ToOutputSpace(uiSample.rgb);
uiSample.rgb *= paperWhite;
return uiSample.rgb;
}
float3 SceneUIComposition(float4 uiSample, float3 sceneColor, float paperWhite, float maxNits)
{
// Undo the pre multiply.
uiSample.rgb = uiSample.rgb / (uiSample.a == 0.0f ? 1.0 : uiSample.a);
uiSample.rgb = ProcessUIForHDR(uiSample.rgb, paperWhite, maxNits);
return uiSample.rgb * uiSample.a + sceneColor.rgb * (1.0f - uiSample.a);
}
// --------------------------------------------------------------------------------------------
#endif

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: b06473c622f844540bd141fc0efae169
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,227 @@
void Hash_Tchou_2_1_uint(uint2 v, out uint o)
{
// ~6 alu (2 mul)
v.y ^= 1103515245U;
v.x += v.y;
v.x *= v.y;
v.x ^= v.x >> 5u;
v.x *= 0x27d4eb2du;
o = v.x;
}
void Hash_Tchou_2_1_float(float2 i, out float o)
{
uint r;
uint2 v = (uint2) (int2) round(i);
Hash_Tchou_2_1_uint(v, r);
o = r * (1.0 / float(0xffffffff));
}
void Hash_Tchou_2_1_half(half2 i, out half o)
{
uint r;
uint2 v = (uint2) (int2) round(i);
Hash_Tchou_2_1_uint(v, r);
o = r * (1.0 / float(0xffffffff));
}
void Hash_Tchou_2_3_uint(uint2 q, out uint3 o)
{
// ~10 alu (2 mul)
uint3 v;
v.xy = q;
v.y ^= 1103515245U;
v.x += v.y;
v.x *= v.y;
v.x ^= v.x >> 5u;
v.x *= 0x27d4eb2du;
v.y ^= (v.x << 3u);
v.z = v.x ^ (v.y << 5u);
o = v;
}
void Hash_Tchou_2_3_float(float2 i, out float3 o)
{
uint3 r;
uint2 v = (uint2) (int2) round(i);
Hash_Tchou_2_3_uint(v, r);
o = r * (1.0 / float(0xffffffff));
}
void Hash_Tchou_2_3_half(half2 i, out half3 o)
{
uint3 r;
uint2 v = (uint2) (int2) round(i);
Hash_Tchou_2_3_uint(v, r);
o = r * (1.0 / float(0xffffffff));
}
void Hash_Tchou_2_2_uint(uint2 v, out uint2 o)
{
// ~8 alu (2 mul)
v.y ^= 1103515245U;
v.x += v.y;
v.x *= v.y;
v.x ^= v.x >> 5u;
v.x *= 0x27d4eb2du;
v.y ^= (v.x << 3u);
o = v;
}
void Hash_Tchou_2_2_float(float2 i, out float2 o)
{
uint2 r;
uint2 v = (uint2) (int2) round(i);
Hash_Tchou_2_2_uint(v, r);
o = r * (1.0 / float(0xffffffff));
}
void Hash_Tchou_2_2_half(half2 i, out half2 o)
{
uint2 r;
uint2 v = (uint2) (int2) round(i);
Hash_Tchou_2_2_uint(v, r);
o = r * (1.0 / float(0xffffffff));
}
void Hash_Tchou_3_1_uint(uint3 v, out uint o)
{
// ~15 alu (3 mul)
v.x ^= 1103515245U;
v.y ^= v.x + v.z;
v.y = v.y * 134775813;
v.z += v.x ^ v.y;
v.y += v.x ^ v.z;
v.x += v.y * v.z;
v.x = v.x * 0x27d4eb2du;
o = v.x;
}
void Hash_Tchou_3_1_float(float3 i, out float o)
{
uint r;
uint3 v = (uint3) (int3) round(i);
Hash_Tchou_3_1_uint(v, r);
o = r * (1.0 / float(0xffffffff));
}
void Hash_Tchou_3_1_half(half3 i, out half o)
{
uint r;
uint3 v = (uint3) (int3) round(i);
Hash_Tchou_3_1_uint(v, r);
o = r * (1.0 / float(0xffffffff));
}
void Hash_Tchou_3_3_uint(uint3 v, out uint3 o)
{
// ~15 alu (3 mul)
v.x ^= 1103515245U;
v.y ^= v.x + v.z;
v.y = v.y * 134775813;
v.z += v.x ^ v.y;
v.y += v.x ^ v.z;
v.x += v.y * v.z;
v.x = v.x * 0x27d4eb2du;
v.z ^= v.x << 3;
v.y += v.z << 3;
o = v;
}
void Hash_Tchou_3_3_float(float3 i, out float3 o)
{
uint3 r, v = (uint3) (int3) round(i);
Hash_Tchou_3_3_uint(v, r);
o = r * (1.0 / float(0xffffffff));
}
void Hash_Tchou_3_3_half(half3 i, out half3 o)
{
uint3 r, v = (uint3) (int3) round(i);
Hash_Tchou_3_3_uint(v, r);
o = r * (1.0 / float(0xffffffff));
}
void Hash_LegacySine_2_1_float(float2 i, out float o)
{
float angle = dot(i, float2(12.9898, 78.233));
#if defined(SHADER_API_MOBILE) && (defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) || defined(SHADER_API_VULKAN))
// 'sin()' has bad precision on Mali GPUs for inputs > 10000
angle = fmod(angle, TWO_PI); // Avoid large inputs to sin()
#endif
o = frac(sin(angle)*43758.5453);
}
void Hash_LegacySine_2_1_half(half2 i, out half o)
{
half angle = dot(i, half2(12.9898, 78.233));
#if defined(SHADER_API_MOBILE) && (defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) || defined(SHADER_API_VULKAN))
// 'sin()' has bad precision on Mali GPUs for inputs > 10000
angle = fmod(angle, TWO_PI); // Avoid large inputs to sin()
#endif
o = frac(sin(angle)*43758.5453);
}
void Hash_BetterSine_2_1_float(float2 i, out float o)
{
float angle = dot(i, float2(12.9898, 78.233) / 1000.0f);
#if defined(SHADER_API_MOBILE) && (defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) || defined(SHADER_API_VULKAN))
// 'sin()' has bad precision on Mali GPUs for inputs > 10000
angle = fmod(angle, TWO_PI); // Avoid large inputs to sin()
#endif
o = frac(sin(angle)*43758.5453);
}
void Hash_BetterSine_2_1_half(half2 i, out half o)
{
float angle = dot(i, half2(12.9898, 78.233) / 1000.0f);
#if defined(SHADER_API_MOBILE) && (defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) || defined(SHADER_API_VULKAN))
// 'sin()' has bad precision on Mali GPUs for inputs > 10000
angle = fmod(angle, TWO_PI); // Avoid large inputs to sin()
#endif
o = frac(sin(angle)*43758.5453);
}
void Hash_LegacySine_2_2_float(float2 i, out float2 o)
{
float2x2 m = float2x2(15.27, 47.63, 99.41, 89.98);
float2 angles = mul(i, m);
#if defined(SHADER_API_MOBILE) && (defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) || defined(SHADER_API_VULKAN))
// 'sin()' has bad precision on Mali GPUs for inputs > 10000
angles = fmod(angles, TWO_PI); // Avoid large inputs to sin()
#endif
o = frac(sin(angles));
}
void Hash_LegacySine_2_2_half(half2 i, out half2 o)
{
half2x2 m = half2x2(15.27, 47.63, 99.41, 89.98);
half2 angles = mul(i, m);
#if defined(SHADER_API_MOBILE) && (defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) || defined(SHADER_API_VULKAN))
// 'sin()' has bad precision on Mali GPUs for inputs > 10000
angles = fmod(angles, TWO_PI); // Avoid large inputs to sin()
#endif
o = frac(sin(angles));
}
void Hash_LegacyMod_2_1_float(float2 i, out float o)
{
// Permutation and hashing used in webgl-nosie goo.gl/pX7HtC
i = i % 289;
// need full precision, otherwise half overflows when p > 1
float x = float(34 * i.x + 1) * i.x % 289 + i.y;
x = (34 * x + 1) * x % 289;
x = frac(x / 41) * 2 - 1;
o = x;
}
void Hash_LegacyMod_2_1_half(half2 i, out half o)
{
// Permutation and hashing used in webgl-nosie goo.gl/pX7HtC
i = i % 289;
// need full precision, otherwise half overflows when p > 1
float x = float(34 * i.x + 1) * i.x % 289 + i.y;
x = (34 * x + 1) * x % 289;
x = frac(x / 41) * 2 - 1;
o = x;
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 0bf6c7395c05c624d92ebdff0dcc1a61
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,713 @@
#ifndef UNITY_IMAGE_BASED_LIGHTING_HLSL_INCLUDED
#define UNITY_IMAGE_BASED_LIGHTING_HLSL_INCLUDED
#if SHADER_API_MOBILE || SHADER_API_GLES || SHADER_API_GLES3
#pragma warning (disable : 3205) // conversion of larger type to smaller
#endif
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonLighting.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/BSDF.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Random.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Sampling/Sampling.hlsl"
#ifndef UNITY_SPECCUBE_LOD_STEPS
// This is actuall the last mip index, we generate 7 mips of convolution
#define UNITY_SPECCUBE_LOD_STEPS 6
#endif
//-----------------------------------------------------------------------------
// Util image based lighting
//-----------------------------------------------------------------------------
// The *approximated* version of the non-linear remapping. It works by
// approximating the cone of the specular lobe, and then computing the MIP map level
// which (approximately) covers the footprint of the lobe with a single texel.
// Improves the perceptual roughness distribution.
real PerceptualRoughnessToMipmapLevel(real perceptualRoughness, uint maxMipLevel)
{
perceptualRoughness = perceptualRoughness * (1.7 - 0.7 * perceptualRoughness);
return perceptualRoughness * maxMipLevel;
}
real PerceptualRoughnessToMipmapLevel(real perceptualRoughness)
{
return PerceptualRoughnessToMipmapLevel(perceptualRoughness, UNITY_SPECCUBE_LOD_STEPS);
}
// The *accurate* version of the non-linear remapping. It works by
// approximating the cone of the specular lobe, and then computing the MIP map level
// which (approximately) covers the footprint of the lobe with a single texel.
// Improves the perceptual roughness distribution and adds reflection (contact) hardening.
// TODO: optimize!
real PerceptualRoughnessToMipmapLevel(real perceptualRoughness, real NdotR)
{
real m = PerceptualRoughnessToRoughness(perceptualRoughness);
// Remap to spec power. See eq. 21 in --> https://dl.dropboxusercontent.com/u/55891920/papers/mm_brdf.pdf
real n = (2.0 / max(REAL_EPS, m * m)) - 2.0;
// Remap from n_dot_h formulation to n_dot_r. See section "Pre-convolved Cube Maps vs Path Tracers" --> https://s3.amazonaws.com/docs.knaldtech.com/knald/1.0.0/lys_power_drops.html
n /= (4.0 * max(NdotR, REAL_EPS));
// remap back to square root of real roughness (0.25 include both the sqrt root of the conversion and sqrt for going from roughness to perceptualRoughness)
perceptualRoughness = pow(2.0 / (n + 2.0), 0.25);
return perceptualRoughness * UNITY_SPECCUBE_LOD_STEPS;
}
// The inverse of the *approximated* version of perceptualRoughnessToMipmapLevel().
real MipmapLevelToPerceptualRoughness(real mipmapLevel)
{
real perceptualRoughness = saturate(mipmapLevel / UNITY_SPECCUBE_LOD_STEPS);
return saturate(1.7 / 1.4 - sqrt(2.89 / 1.96 - (2.8 / 1.96) * perceptualRoughness));
}
//-----------------------------------------------------------------------------
// Anisotropic image based lighting
//-----------------------------------------------------------------------------
// T is the fiber axis (hair strand direction, root to tip).
float3 ComputeViewFacingNormal(float3 V, float3 T)
{
return Orthonormalize(V, T);
}
// Fake anisotropy by distorting the normal (non-negative anisotropy values only).
// The grain direction (e.g. hair or brush direction) is assumed to be orthogonal to N.
// Anisotropic ratio (0->no isotropic; 1->full anisotropy in tangent direction)
real3 GetAnisotropicModifiedNormal(real3 grainDir, real3 N, real3 V, real anisotropy)
{
real3 grainNormal = ComputeViewFacingNormal(V, grainDir);
return normalize(lerp(N, grainNormal, anisotropy));
}
// For GGX aniso and IBL we have done an empirical (eye balled) approximation compare to the reference.
// We use a single fetch, and we stretch the normal to use based on various criteria.
// result are far away from the reference but better than nothing
// Anisotropic ratio (0->no isotropic; 1->full anisotropy in tangent direction) - positive use bitangentWS - negative use tangentWS
// Note: returned iblPerceptualRoughness shouldn't be use for sampling FGD texture in a pre-integration
void GetGGXAnisotropicModifiedNormalAndRoughness(real3 bitangentWS, real3 tangentWS, real3 N, real3 V, real anisotropy, real perceptualRoughness, out real3 iblN, out real iblPerceptualRoughness)
{
// For positive anisotropy values: tangent = highlight stretch (anisotropy) direction, bitangent = grain (brush) direction.
float3 grainDirWS = (anisotropy >= 0.0) ? bitangentWS : tangentWS;
// Reduce stretching depends on the perceptual roughness
float stretch = abs(anisotropy) * saturate(1.5 * sqrt(perceptualRoughness));
// NOTE: If we follow the theory we should use the modified normal for the different calculation implying a normal (like NdotV)
// However modified normal is just a hack. The goal is just to stretch a cubemap, no accuracy here. Let's save performance instead.
iblN = GetAnisotropicModifiedNormal(grainDirWS, N, V, stretch);
iblPerceptualRoughness = perceptualRoughness * saturate(1.2 - abs(anisotropy));
}
// Ref: "Moving Frostbite to PBR", p. 69.
real3 GetSpecularDominantDir(real3 N, real3 R, real perceptualRoughness, real NdotV)
{
real p = perceptualRoughness;
real a = 1.0 - p * p;
real s = sqrt(a);
#ifdef USE_FB_DSD
// This is the original formulation.
real lerpFactor = (s + p * p) * a;
#else
// TODO: tweak this further to achieve a closer match to the reference.
real lerpFactor = (s + p * p) * saturate(a * a + lerp(0.0, a, NdotV * NdotV));
#endif
// The result is not normalized as we fetch in a cubemap
return lerp(N, R, lerpFactor);
}
// ----------------------------------------------------------------------------
// Importance sampling BSDF functions
// ----------------------------------------------------------------------------
void SampleGGXDir(real2 u,
real3 V,
real3x3 localToWorld,
real roughness,
out real3 L,
out real NdotL,
out real NdotH,
out real VdotH,
bool VeqN = false)
{
// GGX NDF sampling
real cosTheta = sqrt(SafeDiv(1.0 - u.x, 1.0 + (roughness * roughness - 1.0) * u.x));
real phi = TWO_PI * u.y;
real3 localH = SphericalToCartesian(phi, cosTheta);
NdotH = cosTheta;
real3 localV;
if (VeqN)
{
// localV == localN
localV = real3(0.0, 0.0, 1.0);
VdotH = NdotH;
}
else
{
localV = mul(V, transpose(localToWorld));
VdotH = saturate(dot(localV, localH));
}
// Compute { localL = reflect(-localV, localH) }
real3 localL = -localV + 2.0 * VdotH * localH;
NdotL = localL.z;
L = mul(localL, localToWorld);
}
// ref: http://blog.selfshadow.com/publications/s2012-shading-course/burley/s2012_pbs_disney_brdf_notes_v3.pdf p26
void SampleAnisoGGXDir(real2 u,
real3 V,
real3 N,
real3 tangentX,
real3 tangentY,
real roughnessT,
real roughnessB,
out real3 H,
out real3 L)
{
// AnisoGGX NDF sampling
H = sqrt(u.x / (1.0 - u.x)) * (roughnessT * cos(TWO_PI * u.y) * tangentX + roughnessB * sin(TWO_PI * u.y) * tangentY) + N;
H = normalize(H);
// Convert sample from half angle to incident angle
L = 2.0 * saturate(dot(V, H)) * H - V;
}
// Adapted from: "Sampling the GGX Distribution of Visible Normals", by E. Heitz
// http://jcgt.org/published/0007/04/01/paper.pdf
void SampleAnisoGGXVisibleNormal(float2 u,
float3 V,
float3x3 localToWorld,
float roughnessX,
float roughnessY,
out float3 localV,
out float3 localH,
out float VdotH)
{
localV = mul(V, transpose(localToWorld));
// Construct an orthonormal basis around the stretched view direction
float3x3 viewToLocal;
viewToLocal[2] = normalize(float3(roughnessX * localV.x, roughnessY * localV.y, localV.z));
viewToLocal[0] = (viewToLocal[2].z < 0.9999) ? normalize(cross(float3(0, 0, 1), viewToLocal[2])) : float3(1, 0, 0);
viewToLocal[1] = cross(viewToLocal[2], viewToLocal[0]);
// Compute a sample point with polar coordinates (r, phi)
float r = sqrt(u.x);
float phi = 2.0 * PI * u.y;
float t1 = r * cos(phi);
float t2 = r * sin(phi);
float s = 0.5 * (1.0 + viewToLocal[2].z);
t2 = (1.0 - s) * sqrt(1.0 - t1 * t1) + s * t2;
// Reproject onto hemisphere
localH = t1 * viewToLocal[0] + t2 * viewToLocal[1] + sqrt(max(0.0, 1.0 - t1 * t1 - t2 * t2)) * viewToLocal[2];
// Transform the normal back to the ellipsoid configuration
localH = normalize(float3(roughnessX * localH.x, roughnessY * localH.y, max(0.0, localH.z)));
VdotH = saturate(dot(localV, localH));
}
// GGX vsible normal sampling, isotropic variant
void SampleGGXVisibleNormal(float2 u,
float3 V,
float3x3 localToWorld,
float roughness,
out float3 localV,
out float3 localH,
out float VdotH)
{
SampleAnisoGGXVisibleNormal(u, V, localToWorld, roughness, roughness, localV, localH, VdotH);
}
// weightOverPdf return the weight (without the diffuseAlbedo term) over pdf. diffuseAlbedo term must be apply by the caller.
void ImportanceSampleLambert(real2 u,
real3x3 localToWorld,
out real3 L,
out real NdotL,
out real weightOverPdf)
{
#if 0
real3 localL = SampleHemisphereCosine(u.x, u.y);
NdotL = localL.z;
L = mul(localL, localToWorld);
#else
real3 N = localToWorld[2];
L = SampleHemisphereCosine(u.x, u.y, N);
NdotL = saturate(dot(N, L));
#endif
// Importance sampling weight for each sample
// pdf = N.L / PI
// weight = fr * (N.L) with fr = diffuseAlbedo / PI
// weight over pdf is:
// weightOverPdf = (diffuseAlbedo / PI) * (N.L) / (N.L / PI)
// weightOverPdf = diffuseAlbedo
// diffuseAlbedo is apply outside the function
weightOverPdf = 1.0;
}
// weightOverPdf return the weight (without the Fresnel term) over pdf. Fresnel term must be apply by the caller.
void ImportanceSampleGGX(real2 u,
real3 V,
real3x3 localToWorld,
real roughness,
real NdotV,
out real3 L,
out real VdotH,
out real NdotL,
out real weightOverPdf)
{
real NdotH;
SampleGGXDir(u, V, localToWorld, roughness, L, NdotL, NdotH, VdotH);
// Importance sampling weight for each sample
// pdf = D(H) * (N.H) / (4 * (L.H))
// weight = fr * (N.L) with fr = F(H) * G(V, L) * D(H) / (4 * (N.L) * (N.V))
// weight over pdf is:
// weightOverPdf = F(H) * G(V, L) * (L.H) / ((N.H) * (N.V))
// weightOverPdf = F(H) * 4 * (N.L) * V(V, L) * (L.H) / (N.H) with V(V, L) = G(V, L) / (4 * (N.L) * (N.V))
// Remind (L.H) == (V.H)
// F is apply outside the function
real Vis = V_SmithJointGGX(NdotL, NdotV, roughness);
weightOverPdf = 4.0 * Vis * NdotL * VdotH / NdotH;
}
// weightOverPdf return the weight (without the Fresnel term) over pdf. Fresnel term must be apply by the caller.
void ImportanceSampleAnisoGGX(real2 u,
real3 V,
real3x3 localToWorld,
real roughnessT,
real roughnessB,
real NdotV,
out real3 L,
out real VdotH,
out real NdotL,
out real weightOverPdf)
{
real3 tangentX = localToWorld[0];
real3 tangentY = localToWorld[1];
real3 N = localToWorld[2];
real3 H;
SampleAnisoGGXDir(u, V, N, tangentX, tangentY, roughnessT, roughnessB, H, L);
real NdotH = saturate(dot(N, H));
// Note: since L and V are symmetric around H, LdotH == VdotH
VdotH = saturate(dot(V, H));
NdotL = saturate(dot(N, L));
// Importance sampling weight for each sample
// pdf = D(H) * (N.H) / (4 * (L.H))
// weight = fr * (N.L) with fr = F(H) * G(V, L) * D(H) / (4 * (N.L) * (N.V))
// weight over pdf is:
// weightOverPdf = F(H) * G(V, L) * (L.H) / ((N.H) * (N.V))
// weightOverPdf = F(H) * 4 * (N.L) * V(V, L) * (L.H) / (N.H) with V(V, L) = G(V, L) / (4 * (N.L) * (N.V))
// Remind (L.H) == (V.H)
// F is apply outside the function
// For anisotropy we must not saturate these values
real TdotV = dot(tangentX, V);
real BdotV = dot(tangentY, V);
real TdotL = dot(tangentX, L);
real BdotL = dot(tangentY, L);
real Vis = V_SmithJointGGXAniso(TdotV, BdotV, NdotV, TdotL, BdotL, NdotL, roughnessT, roughnessB);
weightOverPdf = 4.0 * Vis * NdotL * VdotH / NdotH;
}
// ----------------------------------------------------------------------------
// Pre-integration
// ----------------------------------------------------------------------------
#if !defined SHADER_API_GLES
// Ref: Listing 18 in "Moving Frostbite to PBR" + https://knarkowicz.wordpress.com/2014/12/27/analytical-dfg-term-for-ibl/
real4 IntegrateGGXAndDisneyDiffuseFGD(real NdotV, real roughness, uint sampleCount = 4096)
{
// Note that our LUT covers the full [0, 1] range.
// Therefore, we don't really want to clamp NdotV here (else the lerp slope is wrong).
// However, if NdotV is 0, the integral is 0, so that's not what we want, either.
// Our runtime NdotV bias is quite large, so we use a smaller one here instead.
NdotV = max(NdotV, REAL_EPS);
real3 V = real3(sqrt(1 - NdotV * NdotV), 0, NdotV);
real4 acc = real4(0.0, 0.0, 0.0, 0.0);
real3x3 localToWorld = k_identity3x3;
for (uint i = 0; i < sampleCount; ++i)
{
real2 u = Hammersley2d(i, sampleCount);
real VdotH;
real NdotL;
real weightOverPdf;
real3 L; // Unused
ImportanceSampleGGX(u, V, localToWorld, roughness, NdotV,
L, VdotH, NdotL, weightOverPdf);
if (NdotL > 0.0)
{
// Integral{BSDF * <N,L> dw} =
// Integral{(F0 + (1 - F0) * (1 - <V,H>)^5) * (BSDF / F) * <N,L> dw} =
// (1 - F0) * Integral{(1 - <V,H>)^5 * (BSDF / F) * <N,L> dw} + F0 * Integral{(BSDF / F) * <N,L> dw}=
// (1 - F0) * x + F0 * y = lerp(x, y, F0)
acc.x += weightOverPdf * pow(1 - VdotH, 5);
acc.y += weightOverPdf;
}
// for Disney we still use a Cosine importance sampling, true Disney importance sampling imply a look up table
ImportanceSampleLambert(u, localToWorld, L, NdotL, weightOverPdf);
if (NdotL > 0.0)
{
real LdotV = dot(L, V);
real disneyDiffuse = DisneyDiffuseNoPI(NdotV, NdotL, LdotV, RoughnessToPerceptualRoughness(roughness));
acc.z += disneyDiffuse * weightOverPdf;
}
}
acc /= sampleCount;
// Remap from the [0.5, 1.5] to the [0, 1] range.
acc.z -= 0.5;
return acc;
}
#else
// Not supported due to lack of random library in GLES 2
#define IntegrateGGXAndDisneyDiffuseFGD ERROR_ON_UNSUPPORTED_FUNCTION(IntegrateGGXAndDisneyDiffuseFGD)
#endif
uint GetIBLRuntimeFilterSampleCount(uint mipLevel)
{
uint sampleCount = 0;
switch (mipLevel)
{
case 1: sampleCount = 21; break;
case 2: sampleCount = 34; break;
#if defined(SHADER_API_MOBILE) || defined(SHADER_API_SWITCH)
case 3: sampleCount = 34; break;
case 4: sampleCount = 34; break;
case 5: sampleCount = 34; break;
case 6: sampleCount = 34; break; // UNITY_SPECCUBE_LOD_STEPS
#else
case 3: sampleCount = 55; break;
case 4: sampleCount = 89; break;
case 5: sampleCount = 89; break;
case 6: sampleCount = 89; break; // UNITY_SPECCUBE_LOD_STEPS
#endif
}
return sampleCount;
}
// Ref: Listing 19 in "Moving Frostbite to PBR"
real4 IntegrateLD(TEXTURECUBE_PARAM(tex, sampl),
TEXTURE2D(ggxIblSamples),
real3 V,
real3 N,
real roughness,
real index, // Current MIP level minus one
real invOmegaP,
uint sampleCount, // Must be a Fibonacci number
bool prefilter,
bool usePrecomputedSamples)
{
real3x3 localToWorld = GetLocalFrame(N);
#ifndef USE_KARIS_APPROXIMATION
real NdotV = 1; // N == V
real partLambdaV = GetSmithJointGGXPartLambdaV(NdotV, roughness);
#endif
real3 lightInt = real3(0.0, 0.0, 0.0);
real cbsdfInt = 0.0;
for (uint i = 0; i < sampleCount; ++i)
{
real3 L;
real NdotL, NdotH, LdotH;
if (usePrecomputedSamples)
{
// Performance warning: using a texture LUT will generate a vector load,
// which increases both the VGPR pressure and the workload of the
// texture unit. A better solution here is to load from a Constant, Raw
// or Structured buffer, or perhaps even declare all the constants in an
// HLSL header to allow the compiler to inline everything.
real3 localL = LOAD_TEXTURE2D(ggxIblSamples, uint2(i, index)).xyz;
L = mul(localL, localToWorld);
NdotL = localL.z;
LdotH = sqrt(0.5 + 0.5 * NdotL);
}
else
{
real2 u = Fibonacci2d(i, sampleCount);
// Note: if (N == V), all of the microsurface normals are visible.
SampleGGXDir(u, V, localToWorld, roughness, L, NdotL, NdotH, LdotH, true);
if (NdotL <= 0) continue; // Note that some samples will have 0 contribution
}
real mipLevel;
if (!prefilter) // BRDF importance sampling
{
mipLevel = 0;
}
else // Prefiltered BRDF importance sampling
{
// Use lower MIP-map levels for fetching samples with low probabilities
// in order to reduce the variance.
// Ref: http://http.developer.nvidia.com/GPUGems3/gpugems3_ch20.html
//
// - OmegaS: Solid angle associated with the sample
// - OmegaP: Solid angle associated with the texel of the cubemap
real omegaS;
if (usePrecomputedSamples)
{
omegaS = LOAD_TEXTURE2D(ggxIblSamples, uint2(i, index)).w;
}
else
{
// real PDF = D * NdotH * Jacobian, where Jacobian = 1 / (4 * LdotH).
// Since (N == V), NdotH == LdotH.
real pdf = 0.25 * D_GGX(NdotH, roughness);
// TODO: improve the accuracy of the sample's solid angle fit for GGX.
omegaS = rcp(sampleCount) * rcp(pdf);
}
// 'invOmegaP' is precomputed on CPU and provided as a parameter to the function.
// real omegaP = FOUR_PI / (6.0 * cubemapWidth * cubemapWidth);
const real mipBias = roughness;
mipLevel = 0.5 * log2(omegaS * invOmegaP) + mipBias;
}
// TODO: use a Gaussian-like filter to generate the MIP pyramid.
real3 val = SAMPLE_TEXTURECUBE_LOD(tex, sampl, L, mipLevel).rgb;
// The goal of this function is to use Monte-Carlo integration to find
// X = Integral{Radiance(L) * CBSDF(L, N, V) dL} / Integral{CBSDF(L, N, V) dL}.
// Note: Integral{CBSDF(L, N, V) dL} is given by the FDG texture.
// CBSDF = F * D * G * NdotL / (4 * NdotL * NdotV) = F * D * G / (4 * NdotV).
// PDF = D * NdotH / (4 * LdotH).
// Weight = CBSDF / PDF = F * G * LdotH / (NdotV * NdotH).
// Since we perform filtering with the assumption that (V == N),
// (LdotH == NdotH) && (NdotV == 1) && (Weight == F * G).
// Therefore, after the Monte Carlo expansion of the integrals,
// X = Sum(Radiance(L) * Weight) / Sum(Weight) = Sum(Radiance(L) * F * G) / Sum(F * G).
#ifndef USE_KARIS_APPROXIMATION
// The choice of the Fresnel factor does not appear to affect the result.
real F = 1; // F_Schlick(F0, LdotH);
real G = V_SmithJointGGX(NdotL, NdotV, roughness, partLambdaV) * NdotL * NdotV; // 4 cancels out
lightInt += F * G * val;
cbsdfInt += F * G;
#else
// Use the approximation from "Real Shading in Unreal Engine 4": Weight ~ NdotL.
lightInt += NdotL * val;
cbsdfInt += NdotL;
#endif
}
return real4(lightInt / cbsdfInt, 1.0);
}
real4 IntegrateLDCharlie(TEXTURECUBE_PARAM(tex, sampl),
real3 N,
real roughness,
uint sampleCount,
real invFaceCenterTexelSolidAngle)
{
// ensure proper values
roughness = max(roughness, 0.001f);
sampleCount = max(1, sampleCount);
// filtered uniform sampling of the hemisphere
real3x3 localToWorld = GetLocalFrame(N);
real3 totalLight = real3(0.0, 0.0, 0.0);
real totalWeight = 0.0;
real rcpNumSamples = rcp(sampleCount);
real pdf = 1 / (2.0f * PI);
real lodBias = roughness;
real lodBase = 0.5f * log2((rcpNumSamples * 1.0f / pdf) * invFaceCenterTexelSolidAngle) + lodBias;
for (uint i = 0; i < sampleCount; ++i)
{
// generate sample on the normal oriented hemisphere (uniform sampling)
real3 localL = SampleConeStrata(i, rcpNumSamples, 0.0f);
real NdotL = localL.z;
real3 L = mul(localL, localToWorld);
// evaluate BRDF for the sample (assume V=N)
real NdotV = 1.0;
real LdotV, NdotH, LdotH, invLenLV;
GetBSDFAngle(N, L, NdotL, NdotV, LdotV, NdotH, LdotH, invLenLV);
real D = D_Charlie(NdotH, roughness);
// calculate texture LOD: 0.5*log2(omegaS/omegaP) as descriped in GPU Gems 3 "GPU-Based Importance Sampling" chapter 20.4:
// https://developer.nvidia.com/gpugems/gpugems3/part-iii-rendering/chapter-20-gpu-based-importance-sampling
// omegaS = solid angle of the sample (i.e. 2pi/sampleCount for uniform hemisphere sampling)
// omegaP = solid angle of the texel in the sample direction. This is calculated by multiplying solid angle
// of the face center texel with texel cos(theta), where theta is angle between sample direction
// and center of the face, to account diminishing texel solid angles towards the edges of the cube.
real3 cubeCoord = L / max(abs(L.x), max(abs(L.y), abs(L.z))); // project sample direction to the cube face
real invDu2 = dot(cubeCoord, cubeCoord); // invDu2=1/cos^2(theta) of the sample texel
real lod = 0.5f * 0.5f * log2(invDu2) + lodBase; // extra 0.5f for sqrt(invDu2)=1/cos(theta)
real3 val = SAMPLE_TEXTURECUBE_LOD(tex, sampl, L, lod).rgb;
// accumulate lighting & weights
real w = D * NdotL;
totalLight += val * w;
totalWeight += w;
}
return real4(totalLight / totalWeight, 1.0);
}
// Searches the row 'j' containing 'n' elements of 'haystack' and
// returns the index of the first element greater or equal to 'needle'.
uint BinarySearchRow(uint j, real needle, TEXTURE2D(haystack), uint n)
{
uint i = n - 1;
real v = LOAD_TEXTURE2D(haystack, uint2(i, j)).r;
if (needle < v)
{
i = 0;
for (uint b = 1U << firstbithigh(n - 1); b != 0; b >>= 1)
{
uint p = i | b;
v = LOAD_TEXTURE2D(haystack, uint2(p, j)).r;
if (v <= needle) { i = p; } // Move to the right.
}
}
return i;
}
#if !defined SHADER_API_GLES
real4 IntegrateLD_MIS(TEXTURECUBE_PARAM(envMap, sampler_envMap),
TEXTURE2D(marginalRowDensities),
TEXTURE2D(conditionalDensities),
real3 V,
real3 N,
real roughness,
real invOmegaP,
uint width,
uint height,
uint sampleCount,
bool prefilter)
{
real3x3 localToWorld = GetLocalFrame(N);
real3 lightInt = real3(0.0, 0.0, 0.0);
real cbsdfInt = 0.0;
/*
// Dedicate 50% of samples to light sampling at 1.0 roughness.
// Only perform BSDF sampling when roughness is below 0.5.
const int lightSampleCount = lerp(0, sampleCount / 2, saturate(2.0 * roughness - 1.0));
const int bsdfSampleCount = sampleCount - lightSampleCount;
*/
// The value of the integral of intensity values of the environment map (as a 2D step function).
real envMapInt2dStep = LOAD_TEXTURE2D(marginalRowDensities, uint2(height, 0)).r;
// Since we are using equiareal mapping, we need to divide by the area of the sphere.
real envMapIntSphere = envMapInt2dStep * INV_FOUR_PI;
// Perform light importance sampling.
for (uint i = 0; i < sampleCount; i++)
{
real2 s = Hammersley2d(i, sampleCount);
// Sample a row from the marginal distribution.
uint y = BinarySearchRow(0, s.x, marginalRowDensities, height - 1);
// Sample a column from the conditional distribution.
uint x = BinarySearchRow(y, s.y, conditionalDensities, width - 1);
// Compute the coordinates of the sample.
// Note: we take the sample in between two texels, and also apply the half-texel offset.
// We could compute fractional coordinates at the cost of 4 extra texel samples.
real u = saturate((real)x / width + 1.0 / width);
real v = saturate((real)y / height + 1.0 / height);
real3 L = ConvertEquiarealToCubemap(u, v);
real NdotL = saturate(dot(N, L));
if (NdotL > 0.0)
{
real3 val = SAMPLE_TEXTURECUBE_LOD(envMap, sampler_envMap, L, 0).rgb;
real pdf = (val.r + val.g + val.b) / envMapIntSphere;
if (pdf > 0.0)
{
// (N == V) && (acos(VdotL) == 2 * acos(NdotH)).
real NdotH = sqrt(NdotL * 0.5 + 0.5);
// *********************************************************************************
// Our goal is to use Monte-Carlo integration with importance sampling to evaluate
// X(V) = Integral{Radiance(L) * CBSDF(L, N, V) dL} / Integral{CBSDF(L, N, V) dL}.
// CBSDF = F * D * G * NdotL / (4 * NdotL * NdotV) = F * D * G / (4 * NdotV).
// Weight = CBSDF / PDF.
// We use two approximations of Brian Karis from "Real Shading in Unreal Engine 4":
// (F * G ~ NdotL) && (NdotV == 1).
// Weight = D * NdotL / (4 * PDF).
// *********************************************************************************
real weight = D_GGX(NdotH, roughness) * NdotL / (4.0 * pdf);
lightInt += weight * val;
cbsdfInt += weight;
}
}
}
// Prevent NaNs arising from the division of 0 by 0.
cbsdfInt = max(cbsdfInt, REAL_EPS);
return real4(lightInt / cbsdfInt, 1.0);
}
#else
// Not supported due to lack of random library in GLES 2
#define IntegrateLD_MIS ERROR_ON_UNSUPPORTED_FUNCTION(IntegrateLD_MIS)
#endif
// Little helper to share code between sphere and box reflection probe.
// This function will fade the mask of a reflection volume based on normal orientation compare to direction define by the center of the reflection volume.
float InfluenceFadeNormalWeight(float3 normal, float3 centerToPos)
{
// Start weight from 0.6f (1 fully transparent) to 0.2f (fully opaque).
return saturate((-1.0f / 0.4f) * dot(normal, centerToPos) + (0.6f / 0.4f));
}
#if SHADER_API_MOBILE || SHADER_API_GLES || SHADER_API_GLES3
#pragma warning (enable : 3205) // conversion of larger type to smaller
#endif
#endif // UNITY_IMAGE_BASED_LIGHTING_HLSL_INCLUDED

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: ae4dc0bfd9fc0b544a109513ba841d30
timeCreated: 1476117021
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,241 @@
#ifndef UNITY_MACROS_INCLUDED
#define UNITY_MACROS_INCLUDED
// Some shader compiler don't support to do multiple ## for concatenation inside the same macro, it require an indirection.
// This is the purpose of this macro
#define MERGE_NAME(X, Y) X##Y
#define CALL_MERGE_NAME(X, Y) MERGE_NAME(X, Y)
// These define are use to abstract the way we sample into a cubemap array.
// Some platform don't support cubemap array so we fallback on 2D latlong
#ifdef UNITY_NO_CUBEMAP_ARRAY
#define TEXTURECUBE_ARRAY_ABSTRACT TEXTURE2D_ARRAY
#define TEXTURECUBE_ARRAY_PARAM_ABSTRACT TEXTURE2D_ARRAY_PARAM
#define TEXTURECUBE_ARRAY_ARGS_ABSTRACT TEXTURE2D_ARRAY_ARGS
#define SAMPLE_TEXTURECUBE_ARRAY_LOD_ABSTRACT(textureName, samplerName, coord3, index, lod) SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, DirectionToLatLongCoordinate(coord3), index, lod)
#else
#define TEXTURECUBE_ARRAY_ABSTRACT TEXTURECUBE_ARRAY
#define TEXTURECUBE_ARRAY_PARAM_ABSTRACT TEXTURECUBE_ARRAY_PARAM
#define TEXTURECUBE_ARRAY_ARGS_ABSTRACT TEXTURECUBE_ARRAY_ARGS
#define SAMPLE_TEXTURECUBE_ARRAY_LOD_ABSTRACT(textureName, samplerName, coord3, index, lod) SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod)
#endif
#define PI 3.14159265358979323846
#define TWO_PI 6.28318530717958647693
#define FOUR_PI 12.5663706143591729538
#define INV_PI 0.31830988618379067154
#define INV_TWO_PI 0.15915494309189533577
#define INV_FOUR_PI 0.07957747154594766788
#define HALF_PI 1.57079632679489661923
#define INV_HALF_PI 0.63661977236758134308
#define LOG2_E 1.44269504088896340736
#define INV_SQRT2 0.70710678118654752440
#define PI_DIV_FOUR 0.78539816339744830961
#define MILLIMETERS_PER_METER 1000
#define METERS_PER_MILLIMETER rcp(MILLIMETERS_PER_METER)
#define CENTIMETERS_PER_METER 100
#define METERS_PER_CENTIMETER rcp(CENTIMETERS_PER_METER)
#define FLT_INF asfloat(0x7F800000)
#define FLT_EPS 5.960464478e-8 // 2^-24, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)
#define FLT_MIN 1.175494351e-38 // Minimum normalized positive floating-point number
#define FLT_MAX 3.402823466e+38 // Maximum representable floating-point number
#define HALF_EPS 4.8828125e-4 // 2^-11, machine epsilon: 1 + EPS = 1 (half of the ULP for 1.0f)
#define HALF_MIN 6.103515625e-5 // 2^-14, the same value for 10, 11 and 16-bit: https://www.khronos.org/opengl/wiki/Small_Float_Formats
#define HALF_MIN_SQRT 0.0078125 // 2^-7 == sqrt(HALF_MIN), useful for ensuring HALF_MIN after x^2
#define HALF_MAX 65504.0
#define UINT_MAX 0xFFFFFFFFu
#define INT_MAX 0x7FFFFFFF
#ifdef SHADER_API_GLES
#define GENERATE_INT_FLOAT_1_ARG(FunctionName, Parameter1, FunctionBody) \
float FunctionName(float Parameter1) { FunctionBody; } \
int FunctionName(int Parameter1) { FunctionBody; }
#else
#define GENERATE_INT_FLOAT_1_ARG(FunctionName, Parameter1, FunctionBody) \
float FunctionName(float Parameter1) { FunctionBody; } \
uint FunctionName(uint Parameter1) { FunctionBody; } \
int FunctionName(int Parameter1) { FunctionBody; }
#endif
#define TEMPLATE_1_FLT(FunctionName, Parameter1, FunctionBody) \
float FunctionName(float Parameter1) { FunctionBody; } \
float2 FunctionName(float2 Parameter1) { FunctionBody; } \
float3 FunctionName(float3 Parameter1) { FunctionBody; } \
float4 FunctionName(float4 Parameter1) { FunctionBody; }
#define TEMPLATE_1_HALF(FunctionName, Parameter1, FunctionBody) \
half FunctionName(half Parameter1) { FunctionBody; } \
half2 FunctionName(half2 Parameter1) { FunctionBody; } \
half3 FunctionName(half3 Parameter1) { FunctionBody; } \
half4 FunctionName(half4 Parameter1) { FunctionBody; } \
float FunctionName(float Parameter1) { FunctionBody; } \
float2 FunctionName(float2 Parameter1) { FunctionBody; } \
float3 FunctionName(float3 Parameter1) { FunctionBody; } \
float4 FunctionName(float4 Parameter1) { FunctionBody; }
#ifdef SHADER_API_GLES
#define TEMPLATE_1_INT(FunctionName, Parameter1, FunctionBody) \
int FunctionName(int Parameter1) { FunctionBody; } \
int2 FunctionName(int2 Parameter1) { FunctionBody; } \
int3 FunctionName(int3 Parameter1) { FunctionBody; } \
int4 FunctionName(int4 Parameter1) { FunctionBody; }
#else
#define TEMPLATE_1_INT(FunctionName, Parameter1, FunctionBody) \
int FunctionName(int Parameter1) { FunctionBody; } \
int2 FunctionName(int2 Parameter1) { FunctionBody; } \
int3 FunctionName(int3 Parameter1) { FunctionBody; } \
int4 FunctionName(int4 Parameter1) { FunctionBody; } \
uint FunctionName(uint Parameter1) { FunctionBody; } \
uint2 FunctionName(uint2 Parameter1) { FunctionBody; } \
uint3 FunctionName(uint3 Parameter1) { FunctionBody; } \
uint4 FunctionName(uint4 Parameter1) { FunctionBody; }
#endif
#define TEMPLATE_2_FLT(FunctionName, Parameter1, Parameter2, FunctionBody) \
float FunctionName(float Parameter1, float Parameter2) { FunctionBody; } \
float2 FunctionName(float2 Parameter1, float2 Parameter2) { FunctionBody; } \
float3 FunctionName(float3 Parameter1, float3 Parameter2) { FunctionBody; } \
float4 FunctionName(float4 Parameter1, float4 Parameter2) { FunctionBody; }
#define TEMPLATE_2_HALF(FunctionName, Parameter1, Parameter2, FunctionBody) \
half FunctionName(half Parameter1, half Parameter2) { FunctionBody; } \
half2 FunctionName(half2 Parameter1, half2 Parameter2) { FunctionBody; } \
half3 FunctionName(half3 Parameter1, half3 Parameter2) { FunctionBody; } \
half4 FunctionName(half4 Parameter1, half4 Parameter2) { FunctionBody; } \
float FunctionName(float Parameter1, float Parameter2) { FunctionBody; } \
float2 FunctionName(float2 Parameter1, float2 Parameter2) { FunctionBody; } \
float3 FunctionName(float3 Parameter1, float3 Parameter2) { FunctionBody; } \
float4 FunctionName(float4 Parameter1, float4 Parameter2) { FunctionBody; }
#ifdef SHADER_API_GLES
#define TEMPLATE_2_INT(FunctionName, Parameter1, Parameter2, FunctionBody) \
int FunctionName(int Parameter1, int Parameter2) { FunctionBody; } \
int2 FunctionName(int2 Parameter1, int2 Parameter2) { FunctionBody; } \
int3 FunctionName(int3 Parameter1, int3 Parameter2) { FunctionBody; } \
int4 FunctionName(int4 Parameter1, int4 Parameter2) { FunctionBody; }
#else
#define TEMPLATE_2_INT(FunctionName, Parameter1, Parameter2, FunctionBody) \
int FunctionName(int Parameter1, int Parameter2) { FunctionBody; } \
int2 FunctionName(int2 Parameter1, int2 Parameter2) { FunctionBody; } \
int3 FunctionName(int3 Parameter1, int3 Parameter2) { FunctionBody; } \
int4 FunctionName(int4 Parameter1, int4 Parameter2) { FunctionBody; } \
uint FunctionName(uint Parameter1, uint Parameter2) { FunctionBody; } \
uint2 FunctionName(uint2 Parameter1, uint2 Parameter2) { FunctionBody; } \
uint3 FunctionName(uint3 Parameter1, uint3 Parameter2) { FunctionBody; } \
uint4 FunctionName(uint4 Parameter1, uint4 Parameter2) { FunctionBody; }
#endif
#define TEMPLATE_3_FLT(FunctionName, Parameter1, Parameter2, Parameter3, FunctionBody) \
float FunctionName(float Parameter1, float Parameter2, float Parameter3) { FunctionBody; } \
float2 FunctionName(float2 Parameter1, float2 Parameter2, float2 Parameter3) { FunctionBody; } \
float3 FunctionName(float3 Parameter1, float3 Parameter2, float3 Parameter3) { FunctionBody; } \
float4 FunctionName(float4 Parameter1, float4 Parameter2, float4 Parameter3) { FunctionBody; }
#define TEMPLATE_3_HALF(FunctionName, Parameter1, Parameter2, Parameter3, FunctionBody) \
half FunctionName(half Parameter1, half Parameter2, half Parameter3) { FunctionBody; } \
half2 FunctionName(half2 Parameter1, half2 Parameter2, half2 Parameter3) { FunctionBody; } \
half3 FunctionName(half3 Parameter1, half3 Parameter2, half3 Parameter3) { FunctionBody; } \
half4 FunctionName(half4 Parameter1, half4 Parameter2, half4 Parameter3) { FunctionBody; } \
float FunctionName(float Parameter1, float Parameter2, float Parameter3) { FunctionBody; } \
float2 FunctionName(float2 Parameter1, float2 Parameter2, float2 Parameter3) { FunctionBody; } \
float3 FunctionName(float3 Parameter1, float3 Parameter2, float3 Parameter3) { FunctionBody; } \
float4 FunctionName(float4 Parameter1, float4 Parameter2, float4 Parameter3) { FunctionBody; }
#ifdef SHADER_API_GLES
#define TEMPLATE_3_INT(FunctionName, Parameter1, Parameter2, Parameter3, FunctionBody) \
int FunctionName(int Parameter1, int Parameter2, int Parameter3) { FunctionBody; } \
int2 FunctionName(int2 Parameter1, int2 Parameter2, int2 Parameter3) { FunctionBody; } \
int3 FunctionName(int3 Parameter1, int3 Parameter2, int3 Parameter3) { FunctionBody; } \
int4 FunctionName(int4 Parameter1, int4 Parameter2, int4 Parameter3) { FunctionBody; }
#else
#define TEMPLATE_3_INT(FunctionName, Parameter1, Parameter2, Parameter3, FunctionBody) \
int FunctionName(int Parameter1, int Parameter2, int Parameter3) { FunctionBody; } \
int2 FunctionName(int2 Parameter1, int2 Parameter2, int2 Parameter3) { FunctionBody; } \
int3 FunctionName(int3 Parameter1, int3 Parameter2, int3 Parameter3) { FunctionBody; } \
int4 FunctionName(int4 Parameter1, int4 Parameter2, int4 Parameter3) { FunctionBody; } \
uint FunctionName(uint Parameter1, uint Parameter2, uint Parameter3) { FunctionBody; } \
uint2 FunctionName(uint2 Parameter1, uint2 Parameter2, uint2 Parameter3) { FunctionBody; } \
uint3 FunctionName(uint3 Parameter1, uint3 Parameter2, uint3 Parameter3) { FunctionBody; } \
uint4 FunctionName(uint4 Parameter1, uint4 Parameter2, uint4 Parameter3) { FunctionBody; }
#endif
#ifdef SHADER_API_GLES
#define TEMPLATE_SWAP(FunctionName) \
void FunctionName(inout real a, inout real b) { real t = a; a = b; b = t; } \
void FunctionName(inout real2 a, inout real2 b) { real2 t = a; a = b; b = t; } \
void FunctionName(inout real3 a, inout real3 b) { real3 t = a; a = b; b = t; } \
void FunctionName(inout real4 a, inout real4 b) { real4 t = a; a = b; b = t; } \
void FunctionName(inout int a, inout int b) { int t = a; a = b; b = t; } \
void FunctionName(inout int2 a, inout int2 b) { int2 t = a; a = b; b = t; } \
void FunctionName(inout int3 a, inout int3 b) { int3 t = a; a = b; b = t; } \
void FunctionName(inout int4 a, inout int4 b) { int4 t = a; a = b; b = t; } \
void FunctionName(inout bool a, inout bool b) { bool t = a; a = b; b = t; } \
void FunctionName(inout bool2 a, inout bool2 b) { bool2 t = a; a = b; b = t; } \
void FunctionName(inout bool3 a, inout bool3 b) { bool3 t = a; a = b; b = t; } \
void FunctionName(inout bool4 a, inout bool4 b) { bool4 t = a; a = b; b = t; }
#else
#if REAL_IS_HALF
#define TEMPLATE_SWAP(FunctionName) \
void FunctionName(inout real a, inout real b) { real t = a; a = b; b = t; } \
void FunctionName(inout real2 a, inout real2 b) { real2 t = a; a = b; b = t; } \
void FunctionName(inout real3 a, inout real3 b) { real3 t = a; a = b; b = t; } \
void FunctionName(inout real4 a, inout real4 b) { real4 t = a; a = b; b = t; } \
void FunctionName(inout float a, inout float b) { float t = a; a = b; b = t; } \
void FunctionName(inout float2 a, inout float2 b) { float2 t = a; a = b; b = t; } \
void FunctionName(inout float3 a, inout float3 b) { float3 t = a; a = b; b = t; } \
void FunctionName(inout float4 a, inout float4 b) { float4 t = a; a = b; b = t; } \
void FunctionName(inout int a, inout int b) { int t = a; a = b; b = t; } \
void FunctionName(inout int2 a, inout int2 b) { int2 t = a; a = b; b = t; } \
void FunctionName(inout int3 a, inout int3 b) { int3 t = a; a = b; b = t; } \
void FunctionName(inout int4 a, inout int4 b) { int4 t = a; a = b; b = t; } \
void FunctionName(inout uint a, inout uint b) { uint t = a; a = b; b = t; } \
void FunctionName(inout uint2 a, inout uint2 b) { uint2 t = a; a = b; b = t; } \
void FunctionName(inout uint3 a, inout uint3 b) { uint3 t = a; a = b; b = t; } \
void FunctionName(inout uint4 a, inout uint4 b) { uint4 t = a; a = b; b = t; } \
void FunctionName(inout bool a, inout bool b) { bool t = a; a = b; b = t; } \
void FunctionName(inout bool2 a, inout bool2 b) { bool2 t = a; a = b; b = t; } \
void FunctionName(inout bool3 a, inout bool3 b) { bool3 t = a; a = b; b = t; } \
void FunctionName(inout bool4 a, inout bool4 b) { bool4 t = a; a = b; b = t; }
#else
#define TEMPLATE_SWAP(FunctionName) \
void FunctionName(inout real a, inout real b) { real t = a; a = b; b = t; } \
void FunctionName(inout real2 a, inout real2 b) { real2 t = a; a = b; b = t; } \
void FunctionName(inout real3 a, inout real3 b) { real3 t = a; a = b; b = t; } \
void FunctionName(inout real4 a, inout real4 b) { real4 t = a; a = b; b = t; } \
void FunctionName(inout int a, inout int b) { int t = a; a = b; b = t; } \
void FunctionName(inout int2 a, inout int2 b) { int2 t = a; a = b; b = t; } \
void FunctionName(inout int3 a, inout int3 b) { int3 t = a; a = b; b = t; } \
void FunctionName(inout int4 a, inout int4 b) { int4 t = a; a = b; b = t; } \
void FunctionName(inout uint a, inout uint b) { uint t = a; a = b; b = t; } \
void FunctionName(inout uint2 a, inout uint2 b) { uint2 t = a; a = b; b = t; } \
void FunctionName(inout uint3 a, inout uint3 b) { uint3 t = a; a = b; b = t; } \
void FunctionName(inout uint4 a, inout uint4 b) { uint4 t = a; a = b; b = t; } \
void FunctionName(inout bool a, inout bool b) { bool t = a; a = b; b = t; } \
void FunctionName(inout bool2 a, inout bool2 b) { bool2 t = a; a = b; b = t; } \
void FunctionName(inout bool3 a, inout bool3 b) { bool3 t = a; a = b; b = t; } \
void FunctionName(inout bool4 a, inout bool4 b) { bool4 t = a; a = b; b = t; }
#endif
#endif
// MACRO from Legacy Untiy
// Transforms 2D UV by scale/bias property
#define TRANSFORM_TEX(tex, name) ((tex.xy) * name##_ST.xy + name##_ST.zw)
#define GET_TEXELSIZE_NAME(name) (name##_TexelSize)
#if UNITY_REVERSED_Z
# define COMPARE_DEVICE_DEPTH_CLOSER(shadowMapDepth, zDevice) (shadowMapDepth > zDevice)
# define COMPARE_DEVICE_DEPTH_CLOSEREQUAL(shadowMapDepth, zDevice) (shadowMapDepth >= zDevice)
#else
# define COMPARE_DEVICE_DEPTH_CLOSER(shadowMapDepth, zDevice) (shadowMapDepth < zDevice)
# define COMPARE_DEVICE_DEPTH_CLOSEREQUAL(shadowMapDepth, zDevice) (shadowMapDepth <= zDevice)
#endif
#endif // UNITY_MACROS_INCLUDED

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 6300b0e79f5d15e499b9d6b5d23ca01b
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,188 @@
#ifndef UNITY_META_PASS_INCLUDED
#define UNITY_META_PASS_INCLUDED
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/EntityLighting.hlsl"
CBUFFER_START(UnityMetaPass)
// x = use uv1 as raster position
// y = use uv2 as raster position
bool4 unity_MetaVertexControl;
// x = return albedo
// y = return normal
bool4 unity_MetaFragmentControl;
// Control which VisualizationMode we will
// display in the editor
int unity_VisualizationMode;
CBUFFER_END
struct UnityMetaInput
{
half3 Albedo;
half3 Emission;
#ifdef EDITOR_VISUALIZATION
float2 VizUV;
float4 LightCoord;
#endif
};
#ifdef EDITOR_VISUALIZATION
// Visualization defines
// Should be kept in sync with the EditorVisualizationMode enum in EditorCameraDrawing.cpp
// First two are unused.
#define EDITORVIZ_PBR_VALIDATION_ALBEDO 0
#define EDITORVIZ_PBR_VALIDATION_METALSPECULAR 1
#define EDITORVIZ_TEXTURE 2
#define EDITORVIZ_SHOWLIGHTMASK 3
uniform sampler2D unity_EditorViz_Texture;
uniform half4 unity_EditorViz_Texture_ST;
uniform int unity_EditorViz_UVIndex;
uniform half4 unity_EditorViz_Decode_HDR;
uniform bool unity_EditorViz_ConvertToLinearSpace;
uniform half4 unity_EditorViz_ColorMul;
uniform half4 unity_EditorViz_ColorAdd;
uniform half unity_EditorViz_Exposure;
uniform sampler2D unity_EditorViz_LightTexture;
uniform sampler2D unity_EditorViz_LightTextureB;
#define unity_EditorViz_ChannelSelect unity_EditorViz_ColorMul
#define unity_EditorViz_Color unity_EditorViz_ColorAdd
#define unity_EditorViz_LightType unity_EditorViz_UVIndex
uniform float4x4 unity_EditorViz_WorldToLight;
#endif // EDITOR_VISUALIZATION
float2 UnityMetaVizUV(int uvIndex, float2 uv0, float2 uv1, float2 uv2, float4 st)
{
if (uvIndex == 0)
return uv0 * st.xy + st.zw;
else if (uvIndex == 1)
return uv1 * st.xy + st.zw;
else
return uv2 * st.xy + st.zw;
}
void UnityEditorVizData(float3 positionOS, float2 uv0, float2 uv1, float2 uv2, float4 st, out float2 VizUV, out float4 LightCoord)
{
#ifdef EDITOR_VISUALIZATION
if (unity_VisualizationMode == EDITORVIZ_TEXTURE)
VizUV = UnityMetaVizUV(unity_EditorViz_UVIndex, uv0, uv1, uv2, unity_EditorViz_Texture_ST);
else if (unity_VisualizationMode == EDITORVIZ_SHOWLIGHTMASK)
{
VizUV = uv1 * st.xy + st.zw;
LightCoord = mul(unity_EditorViz_WorldToLight, float4(TransformObjectToWorld(positionOS), 1));
}
#endif
}
void UnityEditorVizData(float3 positionOS, float2 uv0, float2 uv1, float2 uv2, out float2 VizUV, out float4 LightCoord)
{
float4 st = unity_LightmapST;
if (unity_MetaVertexControl.y)
st = unity_DynamicLightmapST;
UnityEditorVizData(positionOS, uv0, uv1, uv2, st, VizUV, LightCoord);
}
float4 UnityMetaVertexPosition(float3 vertex, float2 uv1, float2 uv2, float4 lightmapST, float4 dynlightmapST)
{
#ifndef EDITOR_VISUALIZATION
if (unity_MetaVertexControl.x)
{
vertex.xy = uv1 * lightmapST.xy + lightmapST.zw;
// OpenGL right now needs to actually use incoming vertex position,
// so use it in a very dummy way
vertex.z = vertex.z > 0 ? REAL_MIN : 0.0f;
}
if (unity_MetaVertexControl.y)
{
vertex.xy = uv2 * dynlightmapST.xy + dynlightmapST.zw;
// OpenGL right now needs to actually use incoming vertex position,
// so use it in a very dummy way
vertex.z = vertex.z > 0 ? REAL_MIN : 0.0f;
}
return TransformWorldToHClip(vertex);
#else
return TransformObjectToHClip(vertex);
#endif
}
float4 UnityMetaVertexPosition(float3 vertex, float2 uv1, float2 uv2)
{
return UnityMetaVertexPosition(vertex, uv1, uv2, unity_LightmapST, unity_DynamicLightmapST);
}
float unity_OneOverOutputBoost;
float unity_MaxOutputValue;
float unity_UseLinearSpace;
half4 UnityMetaFragment (UnityMetaInput IN)
{
half4 res = 0;
#ifndef EDITOR_VISUALIZATION
if (unity_MetaFragmentControl.x)
{
res = half4(IN.Albedo,1);
// Apply Albedo Boost from LightmapSettings.
res.rgb = clamp(pow(abs(res.rgb), saturate(unity_OneOverOutputBoost)), 0, unity_MaxOutputValue);
}
if (unity_MetaFragmentControl.y)
{
half3 emission;
if (unity_UseLinearSpace)
emission = IN.Emission;
else
emission = Gamma20ToLinear(IN.Emission);
res = half4(emission, 1.0);
}
#else
// SRPs don't support EDITORVIZ_PBR_VALIDATION_ALBEDO or EDITORVIZ_PBR_VALIDATION_METALSPECULAR
if (unity_VisualizationMode == EDITORVIZ_TEXTURE)
{
res = tex2D(unity_EditorViz_Texture, IN.VizUV);
if (unity_EditorViz_Decode_HDR.x > 0)
res = half4(DecodeHDREnvironment(res, unity_EditorViz_Decode_HDR), 1);
if (unity_EditorViz_ConvertToLinearSpace)
res.rgb = LinearToGamma20(res.rgb);
res *= unity_EditorViz_ColorMul;
res += unity_EditorViz_ColorAdd;
res *= exp2(unity_EditorViz_Exposure);
}
else if (unity_VisualizationMode == EDITORVIZ_SHOWLIGHTMASK)
{
float result = dot(unity_EditorViz_ChannelSelect, tex2D(unity_EditorViz_Texture, IN.VizUV).rgba);
if (result == 0)
discard;
float atten = 1;
if (unity_EditorViz_LightType == 0)
{
// directional: no attenuation
}
else if (unity_EditorViz_LightType == 1)
{
// point
atten = tex2D(unity_EditorViz_LightTexture, dot(IN.LightCoord.xyz, IN.LightCoord.xyz).xx).r;
}
else if (unity_EditorViz_LightType == 2)
{
// spot
atten = tex2D(unity_EditorViz_LightTexture, dot(IN.LightCoord.xyz, IN.LightCoord.xyz).xx).r;
float cookie = tex2D(unity_EditorViz_LightTextureB, IN.LightCoord.xy / max(IN.LightCoord.w, 0.0001) + 0.5).w;
atten *= (IN.LightCoord.z > 0) * cookie;
}
clip(atten - 0.001f);
res = float4(unity_EditorViz_Color.xyz * result, unity_EditorViz_Color.w);
}
#endif // EDITOR_VISUALIZATION
return res;
}
#endif // UNITY_META_PASS_INCLUDED

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: d7414e735eb09cd40855d8142a1c2e18
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,76 @@
#ifndef UNITY_AREA_MRP_INCLUDED
#define UNITY_AREA_MRP_INCLUDED
// Ref: Moving Frostbite to PBR (Listing 11).
// Returns the solid angle of a rectangle at the point.
float SolidAngleRectangle(float3 positionWS, float4x3 lightVerts)
{
float3 v0 = lightVerts[0] - positionWS;
float3 v1 = lightVerts[1] - positionWS;
float3 v2 = lightVerts[2] - positionWS;
float3 v3 = lightVerts[3] - positionWS;
float3 n0 = normalize(cross(v0, v1));
float3 n1 = normalize(cross(v1, v2));
float3 n2 = normalize(cross(v2, v3));
float3 n3 = normalize(cross(v3, v0));
float g0 = FastACos(dot(-n0, n1));
float g1 = FastACos(dot(-n1, n2));
float g2 = FastACos(dot(-n2, n3));
float g3 = FastACos(dot(-n3, n0));
return g0 + g1 + g2 + g3 - TWO_PI;
}
// Optimized (and approximate) solid angle routine. Doesn't handle the horizon.
float SolidAngleRightPyramid(float positionWS, float lightPositionWS, float halfWidth, float halfHeight)
{
const float a = halfWidth;
const float b = halfHeight;
const float h = length(positionWS - lightPositionWS);
return 4.0 * FastASin(a * b / sqrt (( a * a + h * h) * (b * b + h * h) ));
}
float FlatAngleSegment(float3 positionWS, float3 lightP1, float3 lightP2)
{
float3 v0 = normalize(lightP1 - positionWS);
float3 v1 = normalize(lightP2 - positionWS);
return FastACos(dot(v0,v1));
}
// Ref: Moving Frostbite to PBR (Appendix E, Listing E.2)
// Returns the closest point to a rectangular shape defined by right and up (and the rect extents).
float3 ClosestPointRectangle(float3 positionWS, float3 planeOrigin, float3 left, float3 up, float halfWidth, float halfHeight)
{
float3 dir = positionWS - planeOrigin;
// Project into the 2D light plane.
float2 dist2D = float2(dot(dir, left), dot(dir, up));
// Clamp within the rectangle.
const float2 halfSize = float2(halfWidth, halfHeight);
dist2D = clamp(dist2D, -halfSize, halfSize);
// Compute the new world position.
return planeOrigin + dist2D.x * left + dist2D.y * up;
}
// Ref: Moving Frostbite to PBR (Listing 13)
float3 ClosestPointLine(float3 a, float3 b, float3 c)
{
float3 ab = b - a;
float t = dot(c - a, ab) / dot(ab, ab);
return a + t * ab;
}
float3 ClosestPointSegment(float3 a, float3 b, float3 c)
{
float3 ab = b - a;
float t = dot(c - a, ab) / dot(ab, ab);
return a + saturate(t) * ab;
}
#endif // UNITY_AREA_MRP_INCLUDED

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 73b08ea164ce48f382a510231156102f
timeCreated: 1652089082

View File

@@ -0,0 +1,100 @@
// this produces an orthonormal basis of the tangent and bitangent WITHOUT vertex level tangent/bitangent for any UV including procedurally generated
// method released with the demo for publication of "bump mapping unparametrized surfaces on the GPU"
// http://mmikkelsen3d.blogspot.com/2011/07/derivative-maps.html
void SurfaceGradientGenBasisTB(float3 nrmVertexNormal, float3 sigmaX, float3 sigmaY, float flipSign, float2 texST, out float3 vT, out float3 vB)
{
float2 dSTdx = ddx_fine(texST), dSTdy = ddy_fine(texST);
float det = dot(dSTdx, float2(dSTdy.y, -dSTdy.x));
float sign_det = det < 0 ? -1 : 1;
// invC0 represents (dXds, dYds); but we don't divide by determinant (scale by sign instead)
float2 invC0 = sign_det * float2(dSTdy.y, -dSTdx.y);
vT = sigmaX * invC0.x + sigmaY * invC0.y;
if (abs(det) > 0.0)
vT = normalize(vT);
vB = (sign_det * flipSign) * cross(nrmVertexNormal, vT);
}
// surface gradient from an on the fly TBN (deriv obtained using tspaceNormalToDerivative()) or from conventional vertex level TBN (mikktspace compliant and deriv obtained using tspaceNormalToDerivative())
real3 SurfaceGradientFromTBN(real2 deriv, real3 vT, real3 vB)
{
return deriv.x * vT + deriv.y * vB;
}
// surface gradient from an already generated "normal" such as from an object or world space normal map
// CAUTION: nrmVertexNormal and v must be in the same space. i.e world or object
// this allows us to mix the contribution together with a series of other contributions including tangent space normals
// v does not need to be unit length as long as it establishes the direction.
real3 SurfaceGradientFromPerturbedNormal(real3 nrmVertexNormal, real3 v)
{
real3 n = nrmVertexNormal;
real s = 1.0 / max(REAL_EPS, abs(dot(n, v)));
return s * (dot(n, v) * n - v);
}
// used to produce a surface gradient from the gradient of a volume bump function such as a volume of perlin noise.
// equation 2. in "bump mapping unparametrized surfaces on the GPU".
// Observe the difference in figure 2. between using the gradient vs. the surface gradient to do bump mapping (the original method is proved wrong in the paper!).
real3 SurfaceGradientFromVolumeGradient(real3 nrmVertexNormal, real3 grad)
{
return grad - dot(nrmVertexNormal, grad) * nrmVertexNormal;
}
// triplanar projection considered special case of volume bump map
// described here: http://mmikkelsen3d.blogspot.com/2013/10/volume-height-maps-and-triplanar-bump.html
// derivs obtained using tspaceNormalToDerivative() and weights using computeTriplanarWeights().
real3 SurfaceGradientFromTriplanarProjection(real3 nrmVertexNormal, real3 triplanarWeights, real2 deriv_xplane, real2 deriv_yplane, real2 deriv_zplane)
{
const real w0 = triplanarWeights.x, w1 = triplanarWeights.y, w2 = triplanarWeights.z;
// Assume derivXplane, derivYPlane and derivZPlane sampled using (z,y), (x,z) and (x,y) respectively
// (ie using Morten's convention http://jcgt.org/published/0009/03/04/ p80-81 for left handed worldspace)
// positive scales of the look-up coordinate will work as well but for negative scales the derivative components will need to be negated accordingly.
real3 volumeGrad = real3(w2 * deriv_zplane.x + w1 * deriv_yplane.x, w2 * deriv_zplane.y + w0 * deriv_xplane.y, w0 * deriv_xplane.x + w1 * deriv_yplane.y);
return SurfaceGradientFromVolumeGradient(nrmVertexNormal, volumeGrad);
}
real3 SurfaceGradientResolveNormal(real3 nrmVertexNormal, real3 surfGrad)
{
return SafeNormalize(nrmVertexNormal - surfGrad);
}
real2 ConvertTangentSpaceNormalToHeightMapGradient(real2 normalXY, real rcpNormalZ, real scale)
{
// scale * (-normal.xy / normal.z)
return normalXY * (-rcpNormalZ * scale);
}
real3 SurfaceGradientFromTangentSpaceNormalAndFromTBN(real3 normalTS, real3 vT, real3 vB, real scale = 1.0)
{
float2 deriv = ConvertTangentSpaceNormalToHeightMapGradient(normalTS.xy, rcp(max(normalTS.z, REAL_EPS)), scale);
return SurfaceGradientFromTBN(deriv, vT, vB);
}
// Converts tangent space normal to slopes (height map gradient).
real2 UnpackDerivativeNormalRGB(real4 packedNormal, real scale = 1.0)
{
real3 vT = packedNormal.rgb * 2.0 - 1.0; // Unsigned to signed
real rcpZ = rcp(max(vT.z, REAL_EPS)); // Clamp to avoid INF
return ConvertTangentSpaceNormalToHeightMapGradient(vT.xy, rcpZ, scale);
}
// Converts tangent space normal to slopes (height map gradient).
real2 UnpackDerivativeNormalAG(real4 packedNormal, real scale = 1.0)
{
real2 vT = packedNormal.ag * 2.0 - 1.0; // Unsigned to signed
real rcpZ = rsqrt(max(1 - Sq(vT.x) - Sq(vT.y), HALF_MIN_SQRT)); // Clamp to avoid INF
return ConvertTangentSpaceNormalToHeightMapGradient(vT.xy, rcpZ, scale);
}
// Unpack normal as DXT5nm (1, y, 0, x) or BC5 (x, y, 0, 1)
real2 UnpackDerivativeNormalRGorAG(real4 packedNormal, real scale = 1.0)
{
// Convert to (?, y, 0, x)
packedNormal.a *= packedNormal.r;
return UnpackDerivativeNormalAG(packedNormal, scale);
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: b6ff088bebec9f941ae19a0086e4f097
timeCreated: 1487475828
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,606 @@
#ifndef UNITY_PACKING_INCLUDED
#define UNITY_PACKING_INCLUDED
#if SHADER_API_MOBILE || SHADER_API_GLES || SHADER_API_GLES3
#pragma warning (disable : 3205) // conversion of larger type to smaller
#endif
//-----------------------------------------------------------------------------
// Normal packing
//-----------------------------------------------------------------------------
real3 PackNormalMaxComponent(real3 n)
{
return (n / Max3(abs(n.x), abs(n.y), abs(n.z))) * 0.5 + 0.5;
}
real3 UnpackNormalMaxComponent(real3 n)
{
return normalize(n * 2.0 - 1.0);
}
// Ref: http://www.vis.uni-stuttgart.de/~engelhts/paper/vmvOctaMaps.pdf "Octahedron Environment Maps"
// Encode with Oct, this function work with any size of output
// return real between [-1, 1]
real2 PackNormalOctRectEncode(real3 n)
{
// Perform planar projection.
real3 p = n * rcp(dot(abs(n), 1.0));
real x = p.x, y = p.y, z = p.z;
// Unfold the octahedron.
// Also correct the aspect ratio from 2:1 to 1:1.
real r = saturate(0.5 - 0.5 * x + 0.5 * y);
real g = x + y;
// Negative hemisphere on the left, positive on the right.
return real2(CopySign(r, z), g);
}
real3 UnpackNormalOctRectEncode(real2 f)
{
real r = f.r, g = f.g;
// Solve for {x, y, z} given {r, g}.
real x = 0.5 + 0.5 * g - abs(r);
real y = g - x;
real z = max(1.0 - abs(x) - abs(y), REAL_EPS); // EPS is absolutely crucial for anisotropy
real3 p = real3(x, y, CopySign(z, r));
return normalize(p);
}
// Ref: http://jcgt.org/published/0003/02/01/paper.pdf "A Survey of Efficient Representations for Independent Unit Vectors"
// Encode with Oct, this function work with any size of output
// return float between [-1, 1]
float2 PackNormalOctQuadEncode(float3 n)
{
//float l1norm = dot(abs(n), 1.0);
//float2 res0 = n.xy * (1.0 / l1norm);
//float2 val = 1.0 - abs(res0.yx);
//return (n.zz < float2(0.0, 0.0) ? (res0 >= 0.0 ? val : -val) : res0);
// Optimized version of above code:
n *= rcp(max(dot(abs(n), 1.0), 1e-6));
float t = saturate(-n.z);
return n.xy + (n.xy >= 0.0 ? t : -t);
}
float3 UnpackNormalOctQuadEncode(float2 f)
{
float3 n = float3(f.x, f.y, 1.0 - abs(f.x) - abs(f.y));
//float2 val = 1.0 - abs(n.yx);
//n.xy = (n.zz < float2(0.0, 0.0) ? (n.xy >= 0.0 ? val : -val) : n.xy);
// Optimized version of above code:
float t = max(-n.z, 0.0);
n.xy += n.xy >= 0.0 ? -t.xx : t.xx;
return normalize(n);
}
real2 PackNormalHemiOctEncode(real3 n)
{
real l1norm = dot(abs(n), 1.0);
real2 res = n.xy * (1.0 / l1norm);
return real2(res.x + res.y, res.x - res.y);
}
real3 UnpackNormalHemiOctEncode(real2 f)
{
real2 val = real2(f.x + f.y, f.x - f.y) * 0.5;
real3 n = real3(val, 1.0 - dot(abs(val), 1.0));
return normalize(n);
}
// Tetrahedral encoding - Looks like Tetra encoding 10:10 + 2 is similar to oct 11:11, as oct is cheaper prefer it
// To generate the basisNormal below we use these 4 vertex of a regular tetrahedron
// v0 = float3(1.0, 0.0, -1.0 / sqrt(2.0));
// v1 = float3(-1.0, 0.0, -1.0 / sqrt(2.0));
// v2 = float3(0.0, 1.0, 1.0 / sqrt(2.0));
// v3 = float3(0.0, -1.0, 1.0 / sqrt(2.0));
// Then we normalize the average of each face's vertices
// normalize(v0 + v1 + v2), etc...
static const real3 tetraBasisNormal[4] =
{
real3(0., 0.816497, -0.57735),
real3(-0.816497, 0., 0.57735),
real3(0.816497, 0., 0.57735),
real3(0., -0.816497, -0.57735)
};
// Then to get the local matrix (with z axis rotate to basisNormal) use GetLocalFrame(basisNormal[xxx])
static const real3x3 tetraBasisArray[4] =
{
real3x3(-1., 0., 0.,0., 0.57735, 0.816497,0., 0.816497, -0.57735),
real3x3(0., -1., 0.,0.57735, 0., 0.816497,-0.816497, 0., 0.57735),
real3x3(0., 1., 0.,-0.57735, 0., 0.816497,0.816497, 0., 0.57735),
real3x3(1., 0., 0.,0., -0.57735, 0.816497,0., -0.816497, -0.57735)
};
// Return [-1..1] vector2 oriented in plane of the faceIndex of a regular tetrahedron
real2 PackNormalTetraEncode(float3 n, out uint faceIndex)
{
// Retrieve the tetrahedra's face for the normal direction
// It is the one with the greatest dot value with face normal
real dot0 = dot(n, tetraBasisNormal[0]);
real dot1 = dot(n, tetraBasisNormal[1]);
real dot2 = dot(n, tetraBasisNormal[2]);
real dot3 = dot(n, tetraBasisNormal[3]);
real maxi0 = max(dot0, dot1);
real maxi1 = max(dot2, dot3);
real maxi = max(maxi0, maxi1);
// Get the index from the greatest dot
if (maxi == dot0)
faceIndex = 0;
else if (maxi == dot1)
faceIndex = 1;
else if (maxi == dot2)
faceIndex = 2;
else //(maxi == dot3)
faceIndex = 3;
// Rotate n into this local basis
n = mul(tetraBasisArray[faceIndex], n);
// Project n onto the local plane
return n.xy;
}
// Assume f [-1..1]
real3 UnpackNormalTetraEncode(real2 f, uint faceIndex)
{
// Recover n from local plane
real3 n = real3(f.xy, sqrt(1.0 - dot(f.xy, f.xy)));
// Inverse of transform PackNormalTetraEncode (just swap order in mul as we have a rotation)
return mul(n, tetraBasisArray[faceIndex]);
}
// Unpack from normal map
real3 UnpackNormalRGB(real4 packedNormal, real scale = 1.0)
{
real3 normal;
normal.xyz = packedNormal.rgb * 2.0 - 1.0;
normal.xy *= scale;
return normal;
}
real3 UnpackNormalRGBNoScale(real4 packedNormal)
{
return packedNormal.rgb * 2.0 - 1.0;
}
real3 UnpackNormalAG(real4 packedNormal, real scale = 1.0)
{
real3 normal;
normal.xy = packedNormal.ag * 2.0 - 1.0;
normal.z = max(1.0e-16, sqrt(1.0 - saturate(dot(normal.xy, normal.xy))));
// must scale after reconstruction of normal.z which also
// mirrors UnpackNormalRGB(). This does imply normal is not returned
// as a unit length vector but doesn't need it since it will get normalized after TBN transformation.
// If we ever need to blend contributions with built-in shaders for URP
// then we should consider using UnpackDerivativeNormalAG() instead like
// HDRP does since derivatives do not use renormalization and unlike tangent space
// normals allow you to blend, accumulate and scale contributions correctly.
normal.xy *= scale;
return normal;
}
// Unpack normal as DXT5nm (1, y, 0, x) or BC5 (x, y, 0, 1)
real3 UnpackNormalmapRGorAG(real4 packedNormal, real scale = 1.0)
{
// Convert to (?, y, 0, x)
packedNormal.a *= packedNormal.r;
return UnpackNormalAG(packedNormal, scale);
}
#ifndef BUILTIN_TARGET_API
real3 UnpackNormal(real4 packedNormal)
{
#if defined(UNITY_ASTC_NORMALMAP_ENCODING)
return UnpackNormalAG(packedNormal, 1.0);
#elif defined(UNITY_NO_DXT5nm)
return UnpackNormalRGBNoScale(packedNormal);
#else
// Compiler will optimize the scale away
return UnpackNormalmapRGorAG(packedNormal, 1.0);
#endif
}
#endif
real3 UnpackNormalScale(real4 packedNormal, real bumpScale)
{
#if defined(UNITY_ASTC_NORMALMAP_ENCODING)
return UnpackNormalAG(packedNormal, bumpScale);
#elif defined(UNITY_NO_DXT5nm)
return UnpackNormalRGB(packedNormal, bumpScale);
#else
return UnpackNormalmapRGorAG(packedNormal, bumpScale);
#endif
}
//-----------------------------------------------------------------------------
// HDR packing
//-----------------------------------------------------------------------------
// HDR Packing not defined in GLES2
#if !defined(SHADER_API_GLES)
// Ref: http://realtimecollisiondetection.net/blog/?p=15
real4 PackToLogLuv(real3 vRGB)
{
// M matrix, for encoding
const real3x3 M = real3x3(
0.2209, 0.3390, 0.4184,
0.1138, 0.6780, 0.7319,
0.0102, 0.1130, 0.2969);
real4 vResult;
real3 Xp_Y_XYZp = mul(vRGB, M);
Xp_Y_XYZp = max(Xp_Y_XYZp, real3(1e-6, 1e-6, 1e-6));
vResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;
real Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;
vResult.w = frac(Le);
vResult.z = (Le - (floor(vResult.w * 255.0)) / 255.0) / 255.0;
return vResult;
}
real3 UnpackFromLogLuv(real4 vLogLuv)
{
// Inverse M matrix, for decoding
const real3x3 InverseM = real3x3(
6.0014, -2.7008, -1.7996,
-1.3320, 3.1029, -5.7721,
0.3008, -1.0882, 5.6268);
real Le = vLogLuv.z * 255.0 + vLogLuv.w;
real3 Xp_Y_XYZp;
Xp_Y_XYZp.y = exp2((Le - 127.0) / 2.0);
Xp_Y_XYZp.z = Xp_Y_XYZp.y / vLogLuv.y;
Xp_Y_XYZp.x = vLogLuv.x * Xp_Y_XYZp.z;
real3 vRGB = mul(Xp_Y_XYZp, InverseM);
return max(vRGB, real3(0.0, 0.0, 0.0));
}
// The standard 32-bit HDR color format
uint PackToR11G11B10f(float3 rgb)
{
uint r = (f32tof16(rgb.x) << 17) & 0xFFE00000;
uint g = (f32tof16(rgb.y) << 6) & 0x001FFC00;
uint b = (f32tof16(rgb.z) >> 5) & 0x000003FF;
return r | g | b;
}
float3 UnpackFromR11G11B10f(uint rgb)
{
float r = f16tof32((rgb >> 17) & 0x7FF0);
float g = f16tof32((rgb >> 6) & 0x7FF0);
float b = f16tof32((rgb << 5) & 0x7FE0);
return float3(r, g, b);
}
#endif // SHADER_API_GLES
//-----------------------------------------------------------------------------
// Color packing
//-----------------------------------------------------------------------------
float4 UnpackFromR8G8B8A8(uint rgba)
{
return float4(rgba & 255, (rgba >> 8) & 255, (rgba >> 16) & 255, (rgba >> 24) & 255) * (1.0 / 255);
}
//-----------------------------------------------------------------------------
// Quaternion packing
//-----------------------------------------------------------------------------
// Ref: https://cedec.cesa.or.jp/2015/session/ENG/14698.html The Rendering Materials of Far Cry 4
/*
// This is GCN intrinsic
uint FindBiggestComponent(real4 q)
{
uint xyzIndex = CubeMapFaceID(q.x, q.y, q.z) * 0.5f;
uint wIndex = 3;
bool wBiggest = abs(q.w) > max3(abs(q.x), qbs(q.y), qbs(q.z));
return wBiggest ? wIndex : xyzIndex;
}
// Pack a quaternion into a 10:10:10:2
real4 PackQuat(real4 quat)
{
uint index = FindBiggestComponent(quat);
if (index == 0) quat = quat.yzwx;
if (index == 1) quat = quat.xzwy;
if (index == 2) quat = quat.xywz;
real4 packedQuat;
packedQuat.xyz = quat.xyz * FastSign(quat.w) * sqrt(0.5) + 0.5;
packedQuat.w = index / 3.0;
return packedQuat;
}
*/
// Unpack a quaternion from a 10:10:10:2
real4 UnpackQuat(real4 packedQuat)
{
uint index = (uint)(packedQuat.w * 3.0);
real4 quat;
quat.xyz = packedQuat.xyz * sqrt(2.0) - (1.0 / sqrt(2.0));
quat.w = sqrt(1.0 - saturate(dot(quat.xyz, quat.xyz)));
if (index == 0) quat = quat.wxyz;
if (index == 1) quat = quat.xwyz;
if (index == 2) quat = quat.xywz;
return quat;
}
// Integer and Float packing not defined in GLES2
#if !defined(SHADER_API_GLES)
//-----------------------------------------------------------------------------
// Integer packing
//-----------------------------------------------------------------------------
// Packs an integer stored using at most 'numBits' into a [0..1] real.
real PackInt(uint i, uint numBits)
{
uint maxInt = (1u << numBits) - 1u;
return saturate(i * rcp(maxInt));
}
// Unpacks a [0..1] real into an integer of size 'numBits'.
uint UnpackInt(real f, uint numBits)
{
uint maxInt = (1u << numBits) - 1u;
return (uint)(f * maxInt + 0.5); // Round instead of truncating
}
// Packs a [0..255] integer into a [0..1] real.
real PackByte(uint i)
{
return PackInt(i, 8);
}
// Unpacks a [0..1] real into a [0..255] integer.
uint UnpackByte(real f)
{
return UnpackInt(f, 8);
}
// Packs a [0..65535] integer into a [0..1] real.
real PackShort(uint i)
{
return PackInt(i, 16);
}
// Unpacks a [0..1] real into a [0..65535] integer.
uint UnpackShort(real f)
{
return UnpackInt(f, 16);
}
// Packs 8 lowermost bits of a [0..65535] integer into a [0..1] real.
real PackShortLo(uint i)
{
uint lo = BitFieldExtract(i, 0u, 8u);
return PackInt(lo, 8);
}
// Packs 8 uppermost bits of a [0..65535] integer into a [0..1] real.
real PackShortHi(uint i)
{
uint hi = BitFieldExtract(i, 8u, 8u);
return PackInt(hi, 8);
}
real Pack2Byte(real2 inputs)
{
real2 temp = inputs * real2(255.0, 255.0);
temp.x *= 256.0;
temp = round(temp);
real combined = temp.x + temp.y;
return combined * (1.0 / 65535.0);
}
real2 Unpack2Byte(real inputs)
{
real temp = round(inputs * 65535.0);
real ipart;
real fpart = modf(temp / 256.0, ipart);
real2 result = real2(ipart, round(256.0 * fpart));
return result * (1.0 / real2(255.0, 255.0));
}
// Encode a real in [0..1] and an int in [0..maxi - 1] as a real [0..1] to be store in log2(precision) bit
// maxi must be a power of two and define the number of bit dedicated 0..1 to the int part (log2(maxi))
// Example: precision is 256.0, maxi is 2, i is [0..1] encode on 1 bit. f is [0..1] encode on 7 bit.
// Example: precision is 256.0, maxi is 4, i is [0..3] encode on 2 bit. f is [0..1] encode on 6 bit.
// Example: precision is 256.0, maxi is 8, i is [0..7] encode on 3 bit. f is [0..1] encode on 5 bit.
// ...
// Example: precision is 1024.0, maxi is 8, i is [0..7] encode on 3 bit. f is [0..1] encode on 7 bit.
//...
real PackFloatInt(real f, uint i, real maxi, real precision)
{
// Constant
real precisionMinusOne = precision - 1.0;
real t1 = ((precision / maxi) - 1.0) / precisionMinusOne;
real t2 = (precision / maxi) / precisionMinusOne;
return t1 * f + t2 * real(i);
}
void UnpackFloatInt(real val, real maxi, real precision, out real f, out uint i)
{
// Constant
real precisionMinusOne = precision - 1.0;
real t1 = ((precision / maxi) - 1.0) / precisionMinusOne;
real t2 = (precision / maxi) / precisionMinusOne;
// extract integer part
i = int((val / t2) + rcp(precisionMinusOne)); // + rcp(precisionMinusOne) to deal with precision issue (can't use round() as val contain the floating number
// Now that we have i, solve formula in PackFloatInt for f
//f = (val - t2 * real(i)) / t1 => convert in mads form
f = saturate((-t2 * real(i) + val) / t1); // Saturate in case of precision issue
}
// Define various variante for ease of read
real PackFloatInt8bit(real f, uint i, real maxi)
{
return PackFloatInt(f, i, maxi, 256.0);
}
void UnpackFloatInt8bit(real val, real maxi, out real f, out uint i)
{
UnpackFloatInt(val, maxi, 256.0, f, i);
}
real PackFloatInt10bit(real f, uint i, real maxi)
{
return PackFloatInt(f, i, maxi, 1024.0);
}
void UnpackFloatInt10bit(real val, real maxi, out real f, out uint i)
{
UnpackFloatInt(val, maxi, 1024.0, f, i);
}
real PackFloatInt16bit(real f, uint i, real maxi)
{
return PackFloatInt(f, i, maxi, 65536.0);
}
void UnpackFloatInt16bit(real val, real maxi, out real f, out uint i)
{
UnpackFloatInt(val, maxi, 65536.0, f, i);
}
//-----------------------------------------------------------------------------
// Float packing
//-----------------------------------------------------------------------------
// src must be between 0.0 and 1.0
uint PackFloatToUInt(real src, uint offset, uint numBits)
{
return UnpackInt(src, numBits) << offset;
}
real UnpackUIntToFloat(uint src, uint offset, uint numBits)
{
uint maxInt = (1u << numBits) - 1u;
return real(BitFieldExtract(src, offset, numBits)) * rcp(maxInt);
}
uint PackToR10G10B10A2(real4 rgba)
{
return (PackFloatToUInt(rgba.x, 0, 10) |
PackFloatToUInt(rgba.y, 10, 10) |
PackFloatToUInt(rgba.z, 20, 10) |
PackFloatToUInt(rgba.w, 30, 2));
}
real4 UnpackFromR10G10B10A2(uint rgba)
{
real4 output;
output.x = UnpackUIntToFloat(rgba, 0, 10);
output.y = UnpackUIntToFloat(rgba, 10, 10);
output.z = UnpackUIntToFloat(rgba, 20, 10);
output.w = UnpackUIntToFloat(rgba, 30, 2);
return output;
}
// Both the input and the output are in the [0, 1] range.
real2 PackFloatToR8G8(real f)
{
uint i = UnpackShort(f);
return real2(PackShortLo(i), PackShortHi(i));
}
// Both the input and the output are in the [0, 1] range.
real UnpackFloatFromR8G8(real2 f)
{
uint lo = UnpackByte(f.x);
uint hi = UnpackByte(f.y);
uint cb = (hi << 8) + lo;
return PackShort(cb);
}
// Pack float2 (each of 12 bit) in 888
uint3 PackFloat2To888UInt(float2 f)
{
uint2 i = (uint2)(f * 4095.5);
uint2 hi = i >> 8;
uint2 lo = i & 255;
// 8 bit in lo, 4 bit in hi
uint3 cb = uint3(lo, hi.x | (hi.y << 4));
return cb;
}
// Pack float2 (each of 12 bit) in 888
float3 PackFloat2To888(float2 f)
{
return PackFloat2To888UInt(f) / 255.0;
}
// Unpack 2 float of 12bit packed into a 888
float2 Unpack888UIntToFloat2(uint3 x)
{
// 8 bit in lo, 4 bit in hi
uint hi = x.z >> 4;
uint lo = x.z & 15;
uint2 cb = x.xy | uint2(lo << 8, hi << 8);
return cb / 4095.0;
}
// Unpack 2 float of 12bit packed into a 888
float2 Unpack888ToFloat2(float3 x)
{
uint3 i = (uint3)(x * 255.5); // +0.5 to fix precision error on iOS
return Unpack888UIntToFloat2(i);
}
#endif // SHADER_API_GLES
// Pack 2 float values from the [0, 1] range, to an 8 bits float from the [0, 1] range
float PackFloat2To8(float2 f)
{
float x_expanded = f.x * 15.0; // f.x encoded over 4 bits, can have 2^4 = 16 distinct values mapped to [0, 1, ..., 15]
float y_expanded = f.y * 15.0; // f.y encoded over 4 bits, can have 2^4 = 16 distinct values mapped to [0, 1, ..., 15]
float x_y_expanded = x_expanded * 16.0 + y_expanded; // f.x encoded over higher bits, f.y encoded over the lower bits - x_y values in range [0, 1, ..., 255]
return x_y_expanded / 255.0;
// above 4 lines equivalent to:
//return (16.0 * f.x + f.y) / 17.0;
}
// Unpack 2 float values from the [0, 1] range, packed in an 8 bits float from the [0, 1] range
float2 Unpack8ToFloat2(float f)
{
float x_y_expanded = 255.0 * f;
float x_expanded = floor(x_y_expanded / 16.0);
float y_expanded = x_y_expanded - 16.0 * x_expanded;
float x = x_expanded / 15.0;
float y = y_expanded / 15.0;
return float2(x, y);
}
#if SHADER_API_MOBILE || SHADER_API_GLES || SHADER_API_GLES3
#pragma warning (enable : 3205) // conversion of larger type to smaller
#endif
#endif // UNITY_PACKING_INCLUDED

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ad629edbad34c1c45afea3021c1553c8
timeCreated: 1472140530
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,52 @@
#ifndef UNIVERSAL_PARALLAX_MAPPING_INCLUDED
#define UNIVERSAL_PARALLAX_MAPPING_INCLUDED
// Return view direction in tangent space, make sure tangentWS.w is already multiplied by GetOddNegativeScale()
half3 GetViewDirectionTangentSpace(half4 tangentWS, half3 normalWS, half3 viewDirWS)
{
// must use interpolated tangent, bitangent and normal before they are normalized in the pixel shader.
half3 unnormalizedNormalWS = normalWS;
const half renormFactor = 1.0 / length(unnormalizedNormalWS);
// use bitangent on the fly like in hdrp
// IMPORTANT! If we ever support Flip on double sided materials ensure bitangent and tangent are NOT flipped.
half crossSign = (tangentWS.w > 0.0 ? 1.0 : -1.0); // we do not need to multiple GetOddNegativeScale() here, as it is done in vertex shader
half3 bitang = crossSign * cross(normalWS.xyz, tangentWS.xyz);
half3 WorldSpaceNormal = renormFactor * normalWS.xyz; // we want a unit length Normal Vector node in shader graph
// to preserve mikktspace compliance we use same scale renormFactor as was used on the normal.
// This is explained in section 2.2 in "surface gradient based bump mapping framework"
half3 WorldSpaceTangent = renormFactor * tangentWS.xyz;
half3 WorldSpaceBiTangent = renormFactor * bitang;
half3x3 tangentSpaceTransform = half3x3(WorldSpaceTangent, WorldSpaceBiTangent, WorldSpaceNormal);
half3 viewDirTS = mul(tangentSpaceTransform, viewDirWS);
return viewDirTS;
}
#ifndef BUILTIN_TARGET_API
half2 ParallaxOffset1Step(half height, half amplitude, half3 viewDirTS)
{
height = height * amplitude - amplitude / 2.0;
half3 v = normalize(viewDirTS);
v.z += 0.42;
return height * (v.xy / v.z);
}
#endif
float2 ParallaxMapping(TEXTURE2D_PARAM(heightMap, sampler_heightMap), half3 viewDirTS, half scale, float2 uv)
{
half h = SAMPLE_TEXTURE2D(heightMap, sampler_heightMap, uv).g;
float2 offset = ParallaxOffset1Step(h, scale, viewDirTS);
return offset;
}
float2 ParallaxMappingChannel(TEXTURE2D_PARAM(heightMap, sampler_heightMap), half3 viewDirTS, half scale, float2 uv, int channel)
{
half h = SAMPLE_TEXTURE2D(heightMap, sampler_heightMap, uv)[channel];
float2 offset = ParallaxOffset1Step(h, scale, viewDirTS);
return offset;
}
#endif // UNIVERSAL_PARALLAX_MAPPING_INCLUDED

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: c6976b17260ed7d4ca3810ae8488f67f
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,128 @@
// 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
// ref: https://www.gamedev.net/resources/_/technical/graphics-programming-and-theory/a-closer-look-at-parallax-occlusion-mapping-r3262
#ifndef POM_USER_DATA_PARAMETERS
#define POM_USER_DATA_PARAMETERS
#endif
#ifndef POM_USER_DATA_ARGUMENTS
#define POM_USER_DATA_ARGUMENTS
#endif
real2
#ifdef POM_NAME_ID
MERGE_NAME(ParallaxOcclusionMapping,POM_NAME_ID)
#else
ParallaxOcclusionMapping
#endif
(real lod, real lodThreshold, int numSteps, real3 viewDirTS, PerPixelHeightDisplacementParam ppdParam, out real outHeight POM_USER_DATA_PARAMETERS)
{
// Convention: 1.0 is top, 0.0 is bottom - POM is always inward, no extrusion
real stepSize = 1.0 / (real)numSteps;
// View vector is from the point to the camera, but we want to raymarch from camera to point, so reverse the sign
// The length of viewDirTS vector determines the furthest amount of displacement:
// real parallaxLimit = -length(viewDirTS.xy) / viewDirTS.z;
// real2 parallaxDir = normalize(Out.viewDirTS.xy);
// real2 parallaxMaxOffsetTS = parallaxDir * parallaxLimit;
// Above code simplify to
real2 parallaxMaxOffsetTS = (viewDirTS.xy / -viewDirTS.z);
real2 texOffsetPerStep = stepSize * parallaxMaxOffsetTS;
// Do a first step before the loop to init all value correctly
real2 texOffsetCurrent = real2(0.0, 0.0);
real prevHeight = ComputePerPixelHeightDisplacement(texOffsetCurrent, lod, ppdParam POM_USER_DATA_ARGUMENTS);
texOffsetCurrent += texOffsetPerStep;
real currHeight = ComputePerPixelHeightDisplacement(texOffsetCurrent, lod, ppdParam POM_USER_DATA_ARGUMENTS);
real rayHeight = 1.0 - stepSize; // Start at top less one sample
// Linear search
for (int stepIndex = 0; stepIndex < numSteps; ++stepIndex)
{
// Have we found a height below our ray height ? then we have an intersection
if (currHeight > rayHeight)
break; // end the loop
prevHeight = currHeight;
rayHeight -= stepSize;
texOffsetCurrent += texOffsetPerStep;
// Sample height map which in this case is stored in the alpha channel of the normal map:
currHeight = ComputePerPixelHeightDisplacement(texOffsetCurrent, lod, ppdParam POM_USER_DATA_ARGUMENTS);
}
// Found below and above points, now perform line interesection (ray) with piecewise linear heightfield approximation
// Refine the search with secant method
#define POM_SECANT_METHOD 1
#if POM_SECANT_METHOD
real pt0 = rayHeight + stepSize;
real pt1 = rayHeight;
real delta0 = pt0 - prevHeight;
real delta1 = pt1 - currHeight;
real delta;
real2 offset;
// Secant method to affine the search
// Ref: Faster Relief Mapping Using the Secant Method - Eric Risser
for (int i = 0; i < 3; ++i)
{
// intersectionHeight is the height [0..1] for the intersection between view ray and heightfield line
real intersectionHeight = (pt0 * delta1 - pt1 * delta0) / (delta1 - delta0);
// Retrieve offset require to find this intersectionHeight
offset = (1 - intersectionHeight) * texOffsetPerStep * numSteps;
currHeight = ComputePerPixelHeightDisplacement(offset, lod, ppdParam POM_USER_DATA_ARGUMENTS);
delta = intersectionHeight - currHeight;
if (abs(delta) <= 0.01)
break;
// intersectionHeight < currHeight => new lower bounds
if (delta < 0.0)
{
delta1 = delta;
pt1 = intersectionHeight;
}
else
{
delta0 = delta;
pt0 = intersectionHeight;
}
}
#else // regular POM intersection
//real pt0 = rayHeight + stepSize;
//real pt1 = rayHeight;
//real delta0 = pt0 - prevHeight;
//real delta1 = pt1 - currHeight;
//real intersectionHeight = (pt0 * delta1 - pt1 * delta0) / (delta1 - delta0);
//real2 offset = (1 - intersectionHeight) * texOffsetPerStep * numSteps;
// A bit more optimize
real delta0 = currHeight - rayHeight;
real delta1 = (rayHeight + stepSize) - prevHeight;
real ratio = delta0 / (delta0 + delta1);
real2 offset = texOffsetCurrent - ratio * texOffsetPerStep;
currHeight = ComputePerPixelHeightDisplacement(offset, lod, ppdParam POM_USER_DATA_ARGUMENTS);
#endif
outHeight = currHeight;
// Fade the effect with lod (allow to avoid pop when switching to a discrete LOD mesh)
offset *= (1.0 - saturate(lod - lodThreshold));
return offset;
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 0a40799d368cbbd4982d2f423cdd8595
timeCreated: 1486045136
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,75 @@
#ifndef UNITY_PHYSICAL_CAMERA_INCLUDED
#define UNITY_PHYSICAL_CAMERA_INCLUDED
// Has to be kept in sync with ColorUtils.cs
// References:
// "Moving Frostbite to PBR" (Sebastien Lagarde & Charles de Rousiers)
// https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf
// "Implementing a Physically Based Camera" (Padraic Hennessy)
// https://placeholderart.wordpress.com/2014/11/16/implementing-a-physically-based-camera-understanding-exposure/
float ComputeEV100(float aperture, float shutterSpeed, float ISO)
{
// EV number is defined as:
// 2^ EV_s = N^2 / t and EV_s = EV_100 + log2 (S /100)
// This gives
// EV_s = log2 (N^2 / t)
// EV_100 + log2 (S /100) = log2 (N^2 / t)
// EV_100 = log2 (N^2 / t) - log2 (S /100)
// EV_100 = log2 (N^2 / t . 100 / S)
return log2((aperture * aperture) / shutterSpeed * 100.0 / ISO);
}
float ComputeEV100FromAvgLuminance(float avgLuminance, float calibrationConstant)
{
const float K = calibrationConstant;
return log2(avgLuminance * 100.0 / K);
}
float ComputeEV100FromAvgLuminance(float avgLuminance)
{
// We later use the middle gray at 12.7% in order to have
// a middle gray at 18% with a sqrt(2) room for specular highlights
// But here we deal with the spot meter measuring the middle gray
// which is fixed at 12.5 for matching standard camera
// constructor settings (i.e. calibration constant K = 12.5)
// Reference: http://en.wikipedia.org/wiki/Film_speed
const float K = 12.5; // Reflected-light meter calibration constant
return ComputeEV100FromAvgLuminance(avgLuminance, K);
}
float ConvertEV100ToExposure(float EV100, float exposureScale)
{
// Compute the maximum luminance possible with H_sbs sensitivity
// maxLum = 78 / ( S * q ) * N^2 / t
// = 78 / ( S * q ) * 2^ EV_100
// = 78 / (100 * s_LensAttenuation) * 2^ EV_100
// = exposureScale * 2^ EV
// Reference: http://en.wikipedia.org/wiki/Film_speed
float maxLuminance = exposureScale * pow(2.0, EV100);
return 1.0 / maxLuminance;
}
float ConvertEV100ToExposure(float EV100)
{
const float exposureScale = 1.2;
return ConvertEV100ToExposure(EV100, exposureScale);
}
float ComputeISO(float aperture, float shutterSpeed, float targetEV100)
{
// Compute the required ISO to reach the target EV100
return ((aperture * aperture) * 100.0) / (shutterSpeed * pow(2.0, targetEV100));
}
float ComputeLuminanceAdaptation(float previousLuminance, float currentLuminance, float speedDarkToLight, float speedLightToDark, float deltaTime)
{
float delta = currentLuminance - previousLuminance;
float speed = delta > 0.0 ? speedDarkToLight : speedLightToDark;
// Exponential decay
return previousLuminance + delta * (1.0 - exp2(-deltaTime * speed));
}
#endif // UNITY_PHYSICAL_CAMERA_INCLUDED

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 259e4e1d42f9302459819d218966a11c
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,114 @@
#ifndef UNITY_RANDOM_INCLUDED
#define UNITY_RANDOM_INCLUDED
// Safe for GLES2: HLSLcc will emulate the missing operator ^, >> and rcp
float Hash(uint s)
{
s = s ^ 2747636419u;
s = s * 2654435769u;
s = s ^ (s >> 16);
s = s * 2654435769u;
s = s ^ (s >> 16);
s = s * 2654435769u;
return float(s) * rcp(4294967296.0); // 2^-32
}
#if !defined(SHADER_API_GLES)
// A single iteration of Bob Jenkins' One-At-A-Time hashing algorithm.
uint JenkinsHash(uint x)
{
x += (x << 10u);
x ^= (x >> 6u);
x += (x << 3u);
x ^= (x >> 11u);
x += (x << 15u);
return x;
}
// Compound versions of the hashing algorithm.
uint JenkinsHash(uint2 v)
{
return JenkinsHash(v.x ^ JenkinsHash(v.y));
}
uint JenkinsHash(uint3 v)
{
return JenkinsHash(v.x ^ JenkinsHash(v.yz));
}
uint JenkinsHash(uint4 v)
{
return JenkinsHash(v.x ^ JenkinsHash(v.yzw));
}
// Construct a float with half-open range [0, 1) using low 23 bits.
// All zeros yields 0, all ones yields the next smallest representable value below 1.
float ConstructFloat(int m) {
const int ieeeMantissa = 0x007FFFFF; // Binary FP32 mantissa bitmask
const int ieeeOne = 0x3F800000; // 1.0 in FP32 IEEE
m &= ieeeMantissa; // Keep only mantissa bits (fractional part)
m |= ieeeOne; // Add fractional part to 1.0
float f = asfloat(m); // Range [1, 2)
return f - 1; // Range [0, 1)
}
float ConstructFloat(uint m)
{
return ConstructFloat(asint(m));
}
// Pseudo-random value in half-open range [0, 1). The distribution is reasonably uniform.
// Ref: https://stackoverflow.com/a/17479300
float GenerateHashedRandomFloat(uint x)
{
return ConstructFloat(JenkinsHash(x));
}
float GenerateHashedRandomFloat(uint2 v)
{
return ConstructFloat(JenkinsHash(v));
}
float GenerateHashedRandomFloat(uint3 v)
{
return ConstructFloat(JenkinsHash(v));
}
float GenerateHashedRandomFloat(uint4 v)
{
return ConstructFloat(JenkinsHash(v));
}
float2 InitRandom(float2 input)
{
float2 r;
r.x = Hash(uint(input.x * UINT_MAX));
r.y = Hash(uint(input.y * UINT_MAX));
return r;
}
#endif // SHADER_API_GLES
//From Next Generation Post Processing in Call of Duty: Advanced Warfare [Jimenez 2014]
// http://advances.realtimerendering.com/s2014/index.html
float InterleavedGradientNoise(float2 pixCoord, int frameCount)
{
const float3 magic = float3(0.06711056f, 0.00583715f, 52.9829189f);
float2 frameMagicScale = float2(2.083f, 4.867f);
pixCoord += frameCount * frameMagicScale;
return frac(magic.z * frac(dot(pixCoord, magic.xy)));
}
// 32-bit Xorshift random number generator
uint XorShift(inout uint rngState)
{
rngState ^= rngState << 13;
rngState ^= rngState >> 17;
rngState ^= rngState << 5;
return rngState;
}
#endif // UNITY_RANDOM_INCLUDED

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 11914c30949383848ab39385375eff34
timeCreated: 1504012042
licenseType: Pro
ShaderImporter:
externalObjects: {}
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,70 @@
#ifndef UNITY_REFRACTION_INCLUDED
#define UNITY_REFRACTION_INCLUDED
//-----------------------------------------------------------------------------
// Util refraction
//-----------------------------------------------------------------------------
struct RefractionModelResult
{
real dist; // length of the transmission during refraction through the shape
float3 positionWS; // out ray position
real3 rayWS; // out ray direction
};
RefractionModelResult RefractionModelSphere(real3 V, float3 positionWS, real3 normalWS, real ior, real thickness)
{
// Sphere shape model:
// We approximate locally the shape of the object as sphere, that is tangent to the shape.
// The sphere has a diameter of {thickness}
// The center of the sphere is at {positionWS} - {normalWS} * {thickness} * 0.5
//
// So the light is refracted twice: in and out of the tangent sphere
// First refraction (tangent sphere in)
// Refracted ray
real3 R1 = refract(-V, normalWS, 1.0 / ior);
// Center of the tangent sphere
real3 C = positionWS - normalWS * thickness * 0.5;
// Second refraction (tangent sphere out)
real NoR1 = dot(normalWS, R1);
// Optical depth within the sphere
real dist = -NoR1 * thickness;
// Out hit point in the tangent sphere
real3 P1 = positionWS + R1 * dist;
// Out normal
real3 N1 = SafeNormalize(C - P1);
// Out refracted ray
real3 R2 = refract(R1, N1, ior);
real N1oR2 = dot(N1, R2);
real VoR1 = dot(V, R1);
RefractionModelResult result;
result.dist = dist;
result.positionWS = P1;
result.rayWS = R2;
return result;
}
RefractionModelResult RefractionModelBox(real3 V, float3 positionWS, real3 normalWS, real ior, real thickness)
{
// Plane shape model:
// We approximate locally the shape of the object as a plane with normal {normalWS} at {positionWS}
// with a thickness {thickness}
// Refracted ray
real3 R = refract(-V, normalWS, 1.0 / ior);
// Optical depth within the thin plane
real dist = thickness / max(dot(R, -normalWS), 1e-5f);
RefractionModelResult result;
result.dist = dist;
result.positionWS = positionWS + R * dist;
result.rayWS = -V;
return result;
}
#endif

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 61125f624d229884d8cff04fc0fceab7
timeCreated: 1509090550
licenseType: Pro
ShaderImporter:
externalObjects: {}
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,28 @@
#ifndef UNITY_SDF2D_INCLUDED
#define UNITY_SDF2D_INCLUDED
// Ref: https://www.iquilezles.org/www/articles/distfunctions2d/distfunctions2d.htm
float CircleSDF(float2 position, float radius)
{
return length(position) - radius;
}
float RectangleSDF(float2 position, float2 bound)
{
float2 d = abs(position) - bound;
return length(max(d, float2(0, 0))) + min(max(d.x, d.y), 0.0);
}
float EllipseSDF(float2 position, float2 r)
{
float2 p = position;
float2 r2 = r*r;
float k0 = length(p/r);
float k1 = length(p/r2);
return k0*(k0 - 1.0)/k1;
}
#endif // UNITY_SDF2D_INCLUDED

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 325b1a823e35d84478e89669f808ecb9
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 14115a7568c4882499f59039a0585e3b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,306 @@
#ifndef UNITY_FIBONACCI_INCLUDED
#define UNITY_FIBONACCI_INCLUDED
#if SHADER_API_MOBILE || SHADER_API_GLES || SHADER_API_GLES3
#pragma warning (disable : 3205) // conversion of larger type to smaller
#endif
// Computes a point using the Fibonacci sequence of length N.
// Input: Fib[N - 1], Fib[N - 2], and the index 'i' of the point.
// Ref: Efficient Quadrature Rules for Illumination Integrals
real2 Fibonacci2dSeq(real fibN1, real fibN2, uint i)
{
// 3 cycles on GCN if 'fibN1' and 'fibN2' are known at compile time.
// N.b.: According to Swinbank and Pusser [SP06], the uniformity of the distribution
// can be slightly improved by introducing an offset of 1/N to the Z (or R) coordinates.
return real2(i / fibN1 + (0.5 / fibN1), frac(i * (fibN2 / fibN1)));
}
#define GOLDEN_RATIO 1.618033988749895
#define GOLDEN_ANGLE 2.399963229728653
// Replaces the Fibonacci sequence in Fibonacci2dSeq() with the Golden ratio.
real2 Golden2dSeq(uint i, real n)
{
// GoldenAngle = 2 * Pi * (1 - 1 / GoldenRatio).
// We can drop the "1 -" part since all it does is reverse the orientation.
return real2(i / n + (0.5 / n), frac(i * rcp(GOLDEN_RATIO)));
}
static const uint k_FibonacciSeq[] = {
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181
};
static const real2 k_Fibonacci2dSeq21[] = {
real2(0.02380952, 0.00000000),
real2(0.07142857, 0.61904764),
real2(0.11904762, 0.23809528),
real2(0.16666667, 0.85714293),
real2(0.21428572, 0.47619057),
real2(0.26190478, 0.09523821),
real2(0.30952382, 0.71428585),
real2(0.35714287, 0.33333349),
real2(0.40476191, 0.95238113),
real2(0.45238096, 0.57142878),
real2(0.50000000, 0.19047642),
real2(0.54761904, 0.80952406),
real2(0.59523809, 0.42857170),
real2(0.64285713, 0.04761887),
real2(0.69047618, 0.66666698),
real2(0.73809522, 0.28571510),
real2(0.78571427, 0.90476227),
real2(0.83333331, 0.52380943),
real2(0.88095236, 0.14285755),
real2(0.92857140, 0.76190567),
real2(0.97619045, 0.38095284)
};
static const real2 k_Fibonacci2dSeq34[] = {
real2(0.01470588, 0.00000000),
real2(0.04411765, 0.61764705),
real2(0.07352941, 0.23529410),
real2(0.10294118, 0.85294116),
real2(0.13235295, 0.47058821),
real2(0.16176471, 0.08823538),
real2(0.19117647, 0.70588231),
real2(0.22058824, 0.32352924),
real2(0.25000000, 0.94117641),
real2(0.27941176, 0.55882359),
real2(0.30882353, 0.17647076),
real2(0.33823529, 0.79411745),
real2(0.36764705, 0.41176462),
real2(0.39705881, 0.02941132),
real2(0.42647058, 0.64705849),
real2(0.45588234, 0.26470566),
real2(0.48529410, 0.88235283),
real2(0.51470590, 0.50000000),
real2(0.54411763, 0.11764717),
real2(0.57352942, 0.73529434),
real2(0.60294116, 0.35294151),
real2(0.63235295, 0.97058773),
real2(0.66176468, 0.58823490),
real2(0.69117647, 0.20588207),
real2(0.72058821, 0.82352924),
real2(0.75000000, 0.44117641),
real2(0.77941179, 0.05882263),
real2(0.80882353, 0.67646980),
real2(0.83823532, 0.29411697),
real2(0.86764705, 0.91176414),
real2(0.89705884, 0.52941132),
real2(0.92647058, 0.14705849),
real2(0.95588237, 0.76470566),
real2(0.98529410, 0.38235283)
};
static const real2 k_Fibonacci2dSeq55[] = {
real2(0.00909091, 0.00000000),
real2(0.02727273, 0.61818182),
real2(0.04545455, 0.23636365),
real2(0.06363636, 0.85454547),
real2(0.08181818, 0.47272730),
real2(0.10000000, 0.09090900),
real2(0.11818182, 0.70909095),
real2(0.13636364, 0.32727289),
real2(0.15454546, 0.94545460),
real2(0.17272727, 0.56363630),
real2(0.19090909, 0.18181801),
real2(0.20909090, 0.80000019),
real2(0.22727273, 0.41818190),
real2(0.24545455, 0.03636360),
real2(0.26363635, 0.65454578),
real2(0.28181818, 0.27272701),
real2(0.30000001, 0.89090919),
real2(0.31818181, 0.50909138),
real2(0.33636364, 0.12727261),
real2(0.35454544, 0.74545479),
real2(0.37272727, 0.36363602),
real2(0.39090911, 0.98181820),
real2(0.40909091, 0.60000038),
real2(0.42727274, 0.21818161),
real2(0.44545454, 0.83636379),
real2(0.46363637, 0.45454597),
real2(0.48181817, 0.07272720),
real2(0.50000000, 0.69090843),
real2(0.51818180, 0.30909157),
real2(0.53636366, 0.92727280),
real2(0.55454546, 0.54545403),
real2(0.57272726, 0.16363716),
real2(0.59090906, 0.78181839),
real2(0.60909092, 0.39999962),
real2(0.62727273, 0.01818275),
real2(0.64545453, 0.63636398),
real2(0.66363639, 0.25454521),
real2(0.68181819, 0.87272835),
real2(0.69999999, 0.49090958),
real2(0.71818179, 0.10909081),
real2(0.73636365, 0.72727203),
real2(0.75454545, 0.34545517),
real2(0.77272725, 0.96363640),
real2(0.79090911, 0.58181763),
real2(0.80909091, 0.20000076),
real2(0.82727271, 0.81818199),
real2(0.84545457, 0.43636322),
real2(0.86363637, 0.05454636),
real2(0.88181818, 0.67272758),
real2(0.89999998, 0.29090881),
real2(0.91818184, 0.90909195),
real2(0.93636364, 0.52727318),
real2(0.95454544, 0.14545441),
real2(0.97272730, 0.76363754),
real2(0.99090910, 0.38181686)
};
static const real2 k_Fibonacci2dSeq89[] = {
real2(0.00561798, 0.00000000),
real2(0.01685393, 0.61797750),
real2(0.02808989, 0.23595500),
real2(0.03932584, 0.85393250),
real2(0.05056180, 0.47191000),
real2(0.06179775, 0.08988762),
real2(0.07303371, 0.70786500),
real2(0.08426967, 0.32584238),
real2(0.09550562, 0.94382000),
real2(0.10674157, 0.56179762),
real2(0.11797753, 0.17977524),
real2(0.12921348, 0.79775238),
real2(0.14044943, 0.41573000),
real2(0.15168539, 0.03370762),
real2(0.16292135, 0.65168476),
real2(0.17415731, 0.26966286),
real2(0.18539326, 0.88764000),
real2(0.19662921, 0.50561714),
real2(0.20786516, 0.12359524),
real2(0.21910113, 0.74157238),
real2(0.23033708, 0.35955048),
real2(0.24157304, 0.97752762),
real2(0.25280899, 0.59550476),
real2(0.26404494, 0.21348286),
real2(0.27528089, 0.83146000),
real2(0.28651685, 0.44943714),
real2(0.29775280, 0.06741524),
real2(0.30898875, 0.68539238),
real2(0.32022473, 0.30336952),
real2(0.33146068, 0.92134666),
real2(0.34269664, 0.53932571),
real2(0.35393259, 0.15730286),
real2(0.36516854, 0.77528000),
real2(0.37640449, 0.39325714),
real2(0.38764045, 0.01123428),
real2(0.39887640, 0.62921333),
real2(0.41011235, 0.24719048),
real2(0.42134830, 0.86516762),
real2(0.43258426, 0.48314476),
real2(0.44382024, 0.10112190),
real2(0.45505619, 0.71910095),
real2(0.46629214, 0.33707809),
real2(0.47752810, 0.95505524),
real2(0.48876405, 0.57303238),
real2(0.50000000, 0.19100952),
real2(0.51123595, 0.80898666),
real2(0.52247190, 0.42696571),
real2(0.53370786, 0.04494286),
real2(0.54494381, 0.66292000),
real2(0.55617976, 0.28089714),
real2(0.56741571, 0.89887428),
real2(0.57865167, 0.51685333),
real2(0.58988762, 0.13483047),
real2(0.60112357, 0.75280762),
real2(0.61235952, 0.37078476),
real2(0.62359548, 0.98876190),
real2(0.63483149, 0.60673904),
real2(0.64606744, 0.22471619),
real2(0.65730339, 0.84269333),
real2(0.66853935, 0.46067429),
real2(0.67977530, 0.07865143),
real2(0.69101125, 0.69662857),
real2(0.70224720, 0.31460571),
real2(0.71348315, 0.93258286),
real2(0.72471911, 0.55056000),
real2(0.73595506, 0.16853714),
real2(0.74719101, 0.78651428),
real2(0.75842696, 0.40449142),
real2(0.76966292, 0.02246857),
real2(0.78089887, 0.64044571),
real2(0.79213482, 0.25842667),
real2(0.80337077, 0.87640381),
real2(0.81460673, 0.49438095),
real2(0.82584268, 0.11235809),
real2(0.83707863, 0.73033524),
real2(0.84831458, 0.34831238),
real2(0.85955054, 0.96628952),
real2(0.87078649, 0.58426666),
real2(0.88202250, 0.20224380),
real2(0.89325845, 0.82022095),
real2(0.90449440, 0.43820190),
real2(0.91573036, 0.05617905),
real2(0.92696631, 0.67415619),
real2(0.93820226, 0.29213333),
real2(0.94943821, 0.91011047),
real2(0.96067417, 0.52808762),
real2(0.97191012, 0.14606476),
real2(0.98314607, 0.76404190),
real2(0.99438202, 0.38201904)
};
// Loads elements from one of the precomputed tables for sample counts of 21, 34, 55, and 89.
// Computes sample positions at runtime otherwise.
// Sample count must be a Fibonacci number (see 'k_FibonacciSeq').
real2 Fibonacci2d(uint i, uint sampleCount)
{
switch (sampleCount)
{
case 21: return k_Fibonacci2dSeq21[i];
case 34: return k_Fibonacci2dSeq34[i];
case 55: return k_Fibonacci2dSeq55[i];
case 89: return k_Fibonacci2dSeq89[i];
default:
{
uint fibN1 = sampleCount;
uint fibN2 = sampleCount;
// These are all constants, so this loop will be optimized away.
for (uint j = 1; j < 20; j++)
{
if (k_FibonacciSeq[j] == fibN1)
{
fibN2 = k_FibonacciSeq[j - 1];
}
}
return Fibonacci2dSeq(fibN1, fibN2, i);
}
}
}
real2 SampleDiskGolden(uint i, uint sampleCount)
{
real2 f = Golden2dSeq(i, sampleCount);
return real2(sqrt(f.x), TWO_PI * f.y);
}
// Returns the radius as the X coordinate, and the angle as the Y coordinate.
real2 SampleDiskFibonacci(uint i, uint sampleCount)
{
real2 f = Fibonacci2d(i, sampleCount);
return real2(sqrt(f.x), TWO_PI * f.y);
}
// Returns the zenith as the X coordinate, and the azimuthal angle as the Y coordinate.
real2 SampleHemisphereFibonacci(uint i, uint sampleCount)
{
real2 f = Fibonacci2d(i, sampleCount);
return real2(1 - f.x, TWO_PI * f.y);
}
// Returns the zenith as the X coordinate, and the azimuthal angle as the Y coordinate.
real2 SampleSphereFibonacci(uint i, uint sampleCount)
{
real2 f = Fibonacci2d(i, sampleCount);
return real2(1 - 2 * f.x, TWO_PI * f.y);
}
#if SHADER_API_MOBILE || SHADER_API_GLES || SHADER_API_GLES3
#pragma warning (enable : 3205) // conversion of larger type to smaller
#endif
#endif // UNITY_FIBONACCI_INCLUDED

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 63275e6ba7e477f43a376217dc2e147f
timeCreated: 1482325231
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,444 @@
#ifndef UNITY_HAMMERSLEY_INCLUDED
#define UNITY_HAMMERSLEY_INCLUDED
#if SHADER_API_MOBILE || SHADER_API_GLES || SHADER_API_GLES3
#pragma warning (disable : 3205) // conversion of larger type to smaller
#endif
// Ref: http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
uint ReverseBits32(uint bits)
{
#if (SHADER_TARGET >= 45)
return reversebits(bits);
#else
bits = (bits << 16) | (bits >> 16);
bits = ((bits & 0x00ff00ff) << 8) | ((bits & 0xff00ff00) >> 8);
bits = ((bits & 0x0f0f0f0f) << 4) | ((bits & 0xf0f0f0f0) >> 4);
bits = ((bits & 0x33333333) << 2) | ((bits & 0xcccccccc) >> 2);
bits = ((bits & 0x55555555) << 1) | ((bits & 0xaaaaaaaa) >> 1);
return bits;
#endif
}
real VanDerCorputBase2(uint i)
{
return ReverseBits32(i) * rcp(4294967296.0); // 2^-32
}
real2 Hammersley2dSeq(uint i, uint sequenceLength)
{
return real2(real(i) / real(sequenceLength), VanDerCorputBase2(i));
}
#ifdef HAMMERSLEY_USE_CB
#include "Packages/com.unity.render-pipelines.core/Runtime/ShaderLibrary/Sampling/Hammersley.cs.hlsl"
#else
static const real2 k_Hammersley2dSeq16[] = {
real2(0.00000000, 0.00000000),
real2(0.06250000, 0.50000000),
real2(0.12500000, 0.25000000),
real2(0.18750000, 0.75000000),
real2(0.25000000, 0.12500000),
real2(0.31250000, 0.62500000),
real2(0.37500000, 0.37500000),
real2(0.43750000, 0.87500000),
real2(0.50000000, 0.06250000),
real2(0.56250000, 0.56250000),
real2(0.62500000, 0.31250000),
real2(0.68750000, 0.81250000),
real2(0.75000000, 0.18750000),
real2(0.81250000, 0.68750000),
real2(0.87500000, 0.43750000),
real2(0.93750000, 0.93750000)
};
static const real2 k_Hammersley2dSeq32[] = {
real2(0.00000000, 0.00000000),
real2(0.03125000, 0.50000000),
real2(0.06250000, 0.25000000),
real2(0.09375000, 0.75000000),
real2(0.12500000, 0.12500000),
real2(0.15625000, 0.62500000),
real2(0.18750000, 0.37500000),
real2(0.21875000, 0.87500000),
real2(0.25000000, 0.06250000),
real2(0.28125000, 0.56250000),
real2(0.31250000, 0.31250000),
real2(0.34375000, 0.81250000),
real2(0.37500000, 0.18750000),
real2(0.40625000, 0.68750000),
real2(0.43750000, 0.43750000),
real2(0.46875000, 0.93750000),
real2(0.50000000, 0.03125000),
real2(0.53125000, 0.53125000),
real2(0.56250000, 0.28125000),
real2(0.59375000, 0.78125000),
real2(0.62500000, 0.15625000),
real2(0.65625000, 0.65625000),
real2(0.68750000, 0.40625000),
real2(0.71875000, 0.90625000),
real2(0.75000000, 0.09375000),
real2(0.78125000, 0.59375000),
real2(0.81250000, 0.34375000),
real2(0.84375000, 0.84375000),
real2(0.87500000, 0.21875000),
real2(0.90625000, 0.71875000),
real2(0.93750000, 0.46875000),
real2(0.96875000, 0.96875000)
};
static const real2 k_Hammersley2dSeq64[] = {
real2(0.00000000, 0.00000000),
real2(0.01562500, 0.50000000),
real2(0.03125000, 0.25000000),
real2(0.04687500, 0.75000000),
real2(0.06250000, 0.12500000),
real2(0.07812500, 0.62500000),
real2(0.09375000, 0.37500000),
real2(0.10937500, 0.87500000),
real2(0.12500000, 0.06250000),
real2(0.14062500, 0.56250000),
real2(0.15625000, 0.31250000),
real2(0.17187500, 0.81250000),
real2(0.18750000, 0.18750000),
real2(0.20312500, 0.68750000),
real2(0.21875000, 0.43750000),
real2(0.23437500, 0.93750000),
real2(0.25000000, 0.03125000),
real2(0.26562500, 0.53125000),
real2(0.28125000, 0.28125000),
real2(0.29687500, 0.78125000),
real2(0.31250000, 0.15625000),
real2(0.32812500, 0.65625000),
real2(0.34375000, 0.40625000),
real2(0.35937500, 0.90625000),
real2(0.37500000, 0.09375000),
real2(0.39062500, 0.59375000),
real2(0.40625000, 0.34375000),
real2(0.42187500, 0.84375000),
real2(0.43750000, 0.21875000),
real2(0.45312500, 0.71875000),
real2(0.46875000, 0.46875000),
real2(0.48437500, 0.96875000),
real2(0.50000000, 0.01562500),
real2(0.51562500, 0.51562500),
real2(0.53125000, 0.26562500),
real2(0.54687500, 0.76562500),
real2(0.56250000, 0.14062500),
real2(0.57812500, 0.64062500),
real2(0.59375000, 0.39062500),
real2(0.60937500, 0.89062500),
real2(0.62500000, 0.07812500),
real2(0.64062500, 0.57812500),
real2(0.65625000, 0.32812500),
real2(0.67187500, 0.82812500),
real2(0.68750000, 0.20312500),
real2(0.70312500, 0.70312500),
real2(0.71875000, 0.45312500),
real2(0.73437500, 0.95312500),
real2(0.75000000, 0.04687500),
real2(0.76562500, 0.54687500),
real2(0.78125000, 0.29687500),
real2(0.79687500, 0.79687500),
real2(0.81250000, 0.17187500),
real2(0.82812500, 0.67187500),
real2(0.84375000, 0.42187500),
real2(0.85937500, 0.92187500),
real2(0.87500000, 0.10937500),
real2(0.89062500, 0.60937500),
real2(0.90625000, 0.35937500),
real2(0.92187500, 0.85937500),
real2(0.93750000, 0.23437500),
real2(0.95312500, 0.73437500),
real2(0.96875000, 0.48437500),
real2(0.98437500, 0.98437500)
};
static const real2 k_Hammersley2dSeq256[] = {
real2(0.00000000, 0.00000000),
real2(0.00390625, 0.50000000),
real2(0.00781250, 0.25000000),
real2(0.01171875, 0.75000000),
real2(0.01562500, 0.12500000),
real2(0.01953125, 0.62500000),
real2(0.02343750, 0.37500000),
real2(0.02734375, 0.87500000),
real2(0.03125000, 0.06250000),
real2(0.03515625, 0.56250000),
real2(0.03906250, 0.31250000),
real2(0.04296875, 0.81250000),
real2(0.04687500, 0.18750000),
real2(0.05078125, 0.68750000),
real2(0.05468750, 0.43750000),
real2(0.05859375, 0.93750000),
real2(0.06250000, 0.03125000),
real2(0.06640625, 0.53125000),
real2(0.07031250, 0.28125000),
real2(0.07421875, 0.78125000),
real2(0.07812500, 0.15625000),
real2(0.08203125, 0.65625000),
real2(0.08593750, 0.40625000),
real2(0.08984375, 0.90625000),
real2(0.09375000, 0.09375000),
real2(0.09765625, 0.59375000),
real2(0.10156250, 0.34375000),
real2(0.10546875, 0.84375000),
real2(0.10937500, 0.21875000),
real2(0.11328125, 0.71875000),
real2(0.11718750, 0.46875000),
real2(0.12109375, 0.96875000),
real2(0.12500000, 0.01562500),
real2(0.12890625, 0.51562500),
real2(0.13281250, 0.26562500),
real2(0.13671875, 0.76562500),
real2(0.14062500, 0.14062500),
real2(0.14453125, 0.64062500),
real2(0.14843750, 0.39062500),
real2(0.15234375, 0.89062500),
real2(0.15625000, 0.07812500),
real2(0.16015625, 0.57812500),
real2(0.16406250, 0.32812500),
real2(0.16796875, 0.82812500),
real2(0.17187500, 0.20312500),
real2(0.17578125, 0.70312500),
real2(0.17968750, 0.45312500),
real2(0.18359375, 0.95312500),
real2(0.18750000, 0.04687500),
real2(0.19140625, 0.54687500),
real2(0.19531250, 0.29687500),
real2(0.19921875, 0.79687500),
real2(0.20312500, 0.17187500),
real2(0.20703125, 0.67187500),
real2(0.21093750, 0.42187500),
real2(0.21484375, 0.92187500),
real2(0.21875000, 0.10937500),
real2(0.22265625, 0.60937500),
real2(0.22656250, 0.35937500),
real2(0.23046875, 0.85937500),
real2(0.23437500, 0.23437500),
real2(0.23828125, 0.73437500),
real2(0.24218750, 0.48437500),
real2(0.24609375, 0.98437500),
real2(0.25000000, 0.00781250),
real2(0.25390625, 0.50781250),
real2(0.25781250, 0.25781250),
real2(0.26171875, 0.75781250),
real2(0.26562500, 0.13281250),
real2(0.26953125, 0.63281250),
real2(0.27343750, 0.38281250),
real2(0.27734375, 0.88281250),
real2(0.28125000, 0.07031250),
real2(0.28515625, 0.57031250),
real2(0.28906250, 0.32031250),
real2(0.29296875, 0.82031250),
real2(0.29687500, 0.19531250),
real2(0.30078125, 0.69531250),
real2(0.30468750, 0.44531250),
real2(0.30859375, 0.94531250),
real2(0.31250000, 0.03906250),
real2(0.31640625, 0.53906250),
real2(0.32031250, 0.28906250),
real2(0.32421875, 0.78906250),
real2(0.32812500, 0.16406250),
real2(0.33203125, 0.66406250),
real2(0.33593750, 0.41406250),
real2(0.33984375, 0.91406250),
real2(0.34375000, 0.10156250),
real2(0.34765625, 0.60156250),
real2(0.35156250, 0.35156250),
real2(0.35546875, 0.85156250),
real2(0.35937500, 0.22656250),
real2(0.36328125, 0.72656250),
real2(0.36718750, 0.47656250),
real2(0.37109375, 0.97656250),
real2(0.37500000, 0.02343750),
real2(0.37890625, 0.52343750),
real2(0.38281250, 0.27343750),
real2(0.38671875, 0.77343750),
real2(0.39062500, 0.14843750),
real2(0.39453125, 0.64843750),
real2(0.39843750, 0.39843750),
real2(0.40234375, 0.89843750),
real2(0.40625000, 0.08593750),
real2(0.41015625, 0.58593750),
real2(0.41406250, 0.33593750),
real2(0.41796875, 0.83593750),
real2(0.42187500, 0.21093750),
real2(0.42578125, 0.71093750),
real2(0.42968750, 0.46093750),
real2(0.43359375, 0.96093750),
real2(0.43750000, 0.05468750),
real2(0.44140625, 0.55468750),
real2(0.44531250, 0.30468750),
real2(0.44921875, 0.80468750),
real2(0.45312500, 0.17968750),
real2(0.45703125, 0.67968750),
real2(0.46093750, 0.42968750),
real2(0.46484375, 0.92968750),
real2(0.46875000, 0.11718750),
real2(0.47265625, 0.61718750),
real2(0.47656250, 0.36718750),
real2(0.48046875, 0.86718750),
real2(0.48437500, 0.24218750),
real2(0.48828125, 0.74218750),
real2(0.49218750, 0.49218750),
real2(0.49609375, 0.99218750),
real2(0.50000000, 0.00390625),
real2(0.50390625, 0.50390625),
real2(0.50781250, 0.25390625),
real2(0.51171875, 0.75390625),
real2(0.51562500, 0.12890625),
real2(0.51953125, 0.62890625),
real2(0.52343750, 0.37890625),
real2(0.52734375, 0.87890625),
real2(0.53125000, 0.06640625),
real2(0.53515625, 0.56640625),
real2(0.53906250, 0.31640625),
real2(0.54296875, 0.81640625),
real2(0.54687500, 0.19140625),
real2(0.55078125, 0.69140625),
real2(0.55468750, 0.44140625),
real2(0.55859375, 0.94140625),
real2(0.56250000, 0.03515625),
real2(0.56640625, 0.53515625),
real2(0.57031250, 0.28515625),
real2(0.57421875, 0.78515625),
real2(0.57812500, 0.16015625),
real2(0.58203125, 0.66015625),
real2(0.58593750, 0.41015625),
real2(0.58984375, 0.91015625),
real2(0.59375000, 0.09765625),
real2(0.59765625, 0.59765625),
real2(0.60156250, 0.34765625),
real2(0.60546875, 0.84765625),
real2(0.60937500, 0.22265625),
real2(0.61328125, 0.72265625),
real2(0.61718750, 0.47265625),
real2(0.62109375, 0.97265625),
real2(0.62500000, 0.01953125),
real2(0.62890625, 0.51953125),
real2(0.63281250, 0.26953125),
real2(0.63671875, 0.76953125),
real2(0.64062500, 0.14453125),
real2(0.64453125, 0.64453125),
real2(0.64843750, 0.39453125),
real2(0.65234375, 0.89453125),
real2(0.65625000, 0.08203125),
real2(0.66015625, 0.58203125),
real2(0.66406250, 0.33203125),
real2(0.66796875, 0.83203125),
real2(0.67187500, 0.20703125),
real2(0.67578125, 0.70703125),
real2(0.67968750, 0.45703125),
real2(0.68359375, 0.95703125),
real2(0.68750000, 0.05078125),
real2(0.69140625, 0.55078125),
real2(0.69531250, 0.30078125),
real2(0.69921875, 0.80078125),
real2(0.70312500, 0.17578125),
real2(0.70703125, 0.67578125),
real2(0.71093750, 0.42578125),
real2(0.71484375, 0.92578125),
real2(0.71875000, 0.11328125),
real2(0.72265625, 0.61328125),
real2(0.72656250, 0.36328125),
real2(0.73046875, 0.86328125),
real2(0.73437500, 0.23828125),
real2(0.73828125, 0.73828125),
real2(0.74218750, 0.48828125),
real2(0.74609375, 0.98828125),
real2(0.75000000, 0.01171875),
real2(0.75390625, 0.51171875),
real2(0.75781250, 0.26171875),
real2(0.76171875, 0.76171875),
real2(0.76562500, 0.13671875),
real2(0.76953125, 0.63671875),
real2(0.77343750, 0.38671875),
real2(0.77734375, 0.88671875),
real2(0.78125000, 0.07421875),
real2(0.78515625, 0.57421875),
real2(0.78906250, 0.32421875),
real2(0.79296875, 0.82421875),
real2(0.79687500, 0.19921875),
real2(0.80078125, 0.69921875),
real2(0.80468750, 0.44921875),
real2(0.80859375, 0.94921875),
real2(0.81250000, 0.04296875),
real2(0.81640625, 0.54296875),
real2(0.82031250, 0.29296875),
real2(0.82421875, 0.79296875),
real2(0.82812500, 0.16796875),
real2(0.83203125, 0.66796875),
real2(0.83593750, 0.41796875),
real2(0.83984375, 0.91796875),
real2(0.84375000, 0.10546875),
real2(0.84765625, 0.60546875),
real2(0.85156250, 0.35546875),
real2(0.85546875, 0.85546875),
real2(0.85937500, 0.23046875),
real2(0.86328125, 0.73046875),
real2(0.86718750, 0.48046875),
real2(0.87109375, 0.98046875),
real2(0.87500000, 0.02734375),
real2(0.87890625, 0.52734375),
real2(0.88281250, 0.27734375),
real2(0.88671875, 0.77734375),
real2(0.89062500, 0.15234375),
real2(0.89453125, 0.65234375),
real2(0.89843750, 0.40234375),
real2(0.90234375, 0.90234375),
real2(0.90625000, 0.08984375),
real2(0.91015625, 0.58984375),
real2(0.91406250, 0.33984375),
real2(0.91796875, 0.83984375),
real2(0.92187500, 0.21484375),
real2(0.92578125, 0.71484375),
real2(0.92968750, 0.46484375),
real2(0.93359375, 0.96484375),
real2(0.93750000, 0.05859375),
real2(0.94140625, 0.55859375),
real2(0.94531250, 0.30859375),
real2(0.94921875, 0.80859375),
real2(0.95312500, 0.18359375),
real2(0.95703125, 0.68359375),
real2(0.96093750, 0.43359375),
real2(0.96484375, 0.93359375),
real2(0.96875000, 0.12109375),
real2(0.97265625, 0.62109375),
real2(0.97656250, 0.37109375),
real2(0.98046875, 0.87109375),
real2(0.98437500, 0.24609375),
real2(0.98828125, 0.74609375),
real2(0.99218750, 0.49609375),
real2(0.99609375, 0.99609375)
};
#endif
// Loads elements from one of the precomputed tables for sample counts of 16, 32, 64, 256.
// Computes sample positions at runtime otherwise.
real2 Hammersley2d(uint i, uint sampleCount)
{
switch (sampleCount)
{
#ifdef HAMMERSLEY_USE_CB
case 16: return hammersley2dSeq16[i].xy;
case 32: return hammersley2dSeq32[i].xy;
case 64: return hammersley2dSeq64[i].xy;
case 256: return hammersley2dSeq256[i].xy;
#else
case 16: return k_Hammersley2dSeq16[i];
case 32: return k_Hammersley2dSeq32[i];
case 64: return k_Hammersley2dSeq64[i];
case 256: return k_Hammersley2dSeq256[i];
#endif
default: return Hammersley2dSeq(i, sampleCount);
}
}
#if SHADER_API_MOBILE || SHADER_API_GLES || SHADER_API_GLES3
#pragma warning (enable : 3205) // conversion of larger type to smaller
#endif
#endif // UNITY_HAMMERSLEY_INCLUDED

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: aa5e319c8b8499f4fba1c3ecdd133545
timeCreated: 1482325231
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,75 @@
// This structure abstract uv mapping inside one struct.
// It represent a mapping of any uv (with its associated tangent space for derivative if SurfaceGradient mode) - UVSet0 to 4, planar, triplanar
#ifndef __SAMPLEUVMAPPING_HLSL__
#define __SAMPLEUVMAPPING_HLSL__
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl"
#define UV_MAPPING_UVSET 0
#define UV_MAPPING_PLANAR 1
#define UV_MAPPING_TRIPLANAR 2
struct UVMapping
{
int mappingType;
float2 uv; // Current uv or planar uv
// Triplanar specific
float2 uvZY;
float2 uvXZ;
float2 uvXY;
float3 normalWS; // vertex normal
float3 triplanarWeights;
#ifdef SURFACE_GRADIENT
// tangent basis to use when mappingType is UV_MAPPING_UVSET
// these are vertex level in world space
float3 tangentWS;
float3 bitangentWS;
// TODO: store also object normal map for object triplanar
#endif
};
// Multiple includes of the file to handle all variations of textures sampling for regular, lod and bias
// Regular sampling functions
#define ADD_FUNC_SUFFIX(Name) Name
#define SAMPLE_TEXTURE_FUNC(textureName, samplerName, uvMapping, unused) SAMPLE_TEXTURE2D(textureName, samplerName, uvMapping)
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Sampling/SampleUVMappingInternal.hlsl"
#undef ADD_FUNC_SUFFIX
#undef SAMPLE_TEXTURE_FUNC
// Lod sampling functions
#define ADD_FUNC_SUFFIX(Name) MERGE_NAME(Name, Lod)
#define SAMPLE_TEXTURE_FUNC(textureName, samplerName, uvMapping, lod) SAMPLE_TEXTURE2D_LOD(textureName, samplerName, uvMapping, lod)
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Sampling/SampleUVMappingInternal.hlsl"
#undef ADD_FUNC_SUFFIX
#undef SAMPLE_TEXTURE_FUNC
// Bias sampling functions
#define ADD_FUNC_SUFFIX(Name) MERGE_NAME(Name, Bias)
#define SAMPLE_TEXTURE_FUNC(textureName, samplerName, uvMapping, bias) SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, uvMapping, bias)
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Sampling/SampleUVMappingInternal.hlsl"
#undef ADD_FUNC_SUFFIX
#undef SAMPLE_TEXTURE_FUNC
// Macro to improve readibility of surface data
#define SAMPLE_UVMAPPING_TEXTURE2D(textureName, samplerName, uvMapping) SampleUVMapping(TEXTURE2D_ARGS(textureName, samplerName), uvMapping, 0.0) // Last 0.0 is unused
#define SAMPLE_UVMAPPING_TEXTURE2D_LOD(textureName, samplerName, uvMapping, lod) SampleUVMappingLod(TEXTURE2D_ARGS(textureName, samplerName), uvMapping, lod)
#define SAMPLE_UVMAPPING_TEXTURE2D_BIAS(textureName, samplerName, uvMapping, bias) SampleUVMappingBias(TEXTURE2D_ARGS(textureName, samplerName), uvMapping, bias)
#define SAMPLE_UVMAPPING_NORMALMAP(textureName, samplerName, uvMapping, scale) SampleUVMappingNormal(TEXTURE2D_ARGS(textureName, samplerName), uvMapping, scale, 0.0)
#define SAMPLE_UVMAPPING_NORMALMAP_LOD(textureName, samplerName, uvMapping, scale, lod) SampleUVMappingNormalLod(TEXTURE2D_ARGS(textureName, samplerName), uvMapping, scale, lod)
#define SAMPLE_UVMAPPING_NORMALMAP_BIAS(textureName, samplerName, uvMapping, scale, bias) SampleUVMappingNormalBias(TEXTURE2D_ARGS(textureName, samplerName), uvMapping, scale, bias)
#define SAMPLE_UVMAPPING_NORMALMAP_AG(textureName, samplerName, uvMapping, scale) SampleUVMappingNormalAG(TEXTURE2D_ARGS(textureName, samplerName), uvMapping, scale, 0.0)
#define SAMPLE_UVMAPPING_NORMALMAP_AG_LOD(textureName, samplerName, uvMapping, scale, lod) SampleUVMappingNormalAGLod(TEXTURE2D_ARGS(textureName, samplerName), uvMapping, scale, lod)
#define SAMPLE_UVMAPPING_NORMALMAP_AG_BIAS(textureName, samplerName, uvMapping, scale, bias) SampleUVMappingNormalAGBias(TEXTURE2D_ARGS(textureName, samplerName), uvMapping, scale, bias)
#define SAMPLE_UVMAPPING_NORMALMAP_RGB(textureName, samplerName, uvMapping, scale) SampleUVMappingNormalRGB(TEXTURE2D_ARGS(textureName, samplerName), uvMapping, scale, 0.0)
#define SAMPLE_UVMAPPING_NORMALMAP_RGB_LOD(textureName, samplerName, uvMapping, scale, lod) SampleUVMappingNormalRGBLod(TEXTURE2D_ARGS(textureName, samplerName), uvMapping, scale, lod)
#define SAMPLE_UVMAPPING_NORMALMAP_RGB_BIAS(textureName, samplerName, uvMapping, scale, bias) SampleUVMappingNormalRGBBias(TEXTURE2D_ARGS(textureName, samplerName), uvMapping, scale, bias)
#endif //__SAMPLEUVMAPPING_HLSL__

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: f3e4d64dcf820e040a738f576d8d1f79
timeCreated: 1485260584
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,64 @@
// These functions are use to hide the handling of triplanar mapping
// Normal need a specific treatment as they use special encoding for both base and detail map
// Also we use multiple inclusion to handle the various variation for lod and bias
// param can be unused, lod or bias
real4 ADD_FUNC_SUFFIX(SampleUVMapping)(TEXTURE2D_PARAM(textureName, samplerName), UVMapping uvMapping, real param)
{
if (uvMapping.mappingType == UV_MAPPING_TRIPLANAR)
{
real3 triplanarWeights = uvMapping.triplanarWeights;
real4 val = real4(0.0, 0.0, 0.0, 0.0);
if (triplanarWeights.x > 0.0)
val += triplanarWeights.x * SAMPLE_TEXTURE_FUNC(textureName, samplerName, uvMapping.uvZY, param);
if (triplanarWeights.y > 0.0)
val += triplanarWeights.y * SAMPLE_TEXTURE_FUNC(textureName, samplerName, uvMapping.uvXZ, param);
if (triplanarWeights.z > 0.0)
val += triplanarWeights.z * SAMPLE_TEXTURE_FUNC(textureName, samplerName, uvMapping.uvXY, param);
return val;
}
else // UV_MAPPING_UVSET / UV_MAPPING_PLANAR
{
return SAMPLE_TEXTURE_FUNC(textureName, samplerName, uvMapping.uv, param);
}
}
// Nested multiple includes of the file to handle all variations of normal map (AG, RG or RGB)
// This version is use for the base normal map (BC5 or DXT5nm)
#define ADD_NORMAL_FUNC_SUFFIX(Name) Name
#if defined(UNITY_ASTC_NORMALMAP_ENCODING)
#define UNPACK_NORMAL_FUNC UnpackNormalAG
#define UNPACK_DERIVATIVE_FUNC UnpackDerivativeNormalAG
#elif defined(UNITY_NO_DXT5nm)
#define UNPACK_NORMAL_FUNC UnpackNormalRGB
#define UNPACK_DERIVATIVE_FUNC UnpackDerivativeNormalRGB
#else
#define UNPACK_NORMAL_FUNC UnpackNormalmapRGorAG
#define UNPACK_DERIVATIVE_FUNC UnpackDerivativeNormalRGorAG
#endif
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Sampling/SampleUVMappingNormalInternal.hlsl"
#undef ADD_NORMAL_FUNC_SUFFIX
#undef UNPACK_NORMAL_FUNC
#undef UNPACK_DERIVATIVE_FUNC
// This version is for normalmap with AG encoding only. Use with details map encoded with others properties (like smoothness).
#define ADD_NORMAL_FUNC_SUFFIX(Name) MERGE_NAME(Name, AG)
#define UNPACK_NORMAL_FUNC UnpackNormalAG
#define UNPACK_DERIVATIVE_FUNC UnpackDerivativeNormalAG
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Sampling/SampleUVMappingNormalInternal.hlsl"
#undef ADD_NORMAL_FUNC_SUFFIX
#undef UNPACK_NORMAL_FUNC
#undef UNPACK_DERIVATIVE_FUNC
// This version is for normalmap with RGB encoding only, i.e uncompress or BC7.
#define ADD_NORMAL_FUNC_SUFFIX(Name) MERGE_NAME(Name, RGB)
#define UNPACK_NORMAL_FUNC UnpackNormalRGB
#define UNPACK_DERIVATIVE_FUNC UnpackDerivativeNormalRGB
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Sampling/SampleUVMappingNormalInternal.hlsl"
#undef ADD_NORMAL_FUNC_SUFFIX
#undef UNPACK_NORMAL_FUNC
#undef UNPACK_DERIVATIVE_FUNC

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 01b8f0e33ff01164da19412b5fbdc7d4
timeCreated: 1485250177
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,57 @@
real3 ADD_FUNC_SUFFIX(ADD_NORMAL_FUNC_SUFFIX(SampleUVMappingNormal))(TEXTURE2D_PARAM(textureName, samplerName), UVMapping uvMapping, real scale, real param)
{
if (uvMapping.mappingType == UV_MAPPING_TRIPLANAR)
{
real3 triplanarWeights = uvMapping.triplanarWeights;
#ifdef SURFACE_GRADIENT
// Height map gradient. Basically, it encodes height map slopes along S and T axes.
real2 derivXplane;
real2 derivYPlane;
real2 derivZPlane;
derivXplane = derivYPlane = derivZPlane = real2(0.0, 0.0);
if (triplanarWeights.x > 0.0)
derivXplane = triplanarWeights.x * UNPACK_DERIVATIVE_FUNC(SAMPLE_TEXTURE_FUNC(textureName, samplerName, uvMapping.uvZY, param), scale);
if (triplanarWeights.y > 0.0)
derivYPlane = triplanarWeights.y * UNPACK_DERIVATIVE_FUNC(SAMPLE_TEXTURE_FUNC(textureName, samplerName, uvMapping.uvXZ, param), scale);
if (triplanarWeights.z > 0.0)
derivZPlane = triplanarWeights.z * UNPACK_DERIVATIVE_FUNC(SAMPLE_TEXTURE_FUNC(textureName, samplerName, uvMapping.uvXY, param), scale);
// Assume derivXplane, derivYPlane and derivZPlane sampled using (z,y), (x,z) and (x,y) respectively
// ie using Morten's convention http://jcgt.org/published/0009/03/04/ p80-81
real3 volumeGrad = real3(derivZPlane.x + derivYPlane.x, derivZPlane.y + derivXplane.y, derivXplane.x + derivYPlane.y);
return SurfaceGradientFromVolumeGradient(uvMapping.normalWS, volumeGrad);
#else
real3 val = real3(0.0, 0.0, 0.0);
if (triplanarWeights.x > 0.0)
val += triplanarWeights.x * UNPACK_NORMAL_FUNC(SAMPLE_TEXTURE_FUNC(textureName, samplerName, uvMapping.uvZY, param), scale);
if (triplanarWeights.y > 0.0)
val += triplanarWeights.y * UNPACK_NORMAL_FUNC(SAMPLE_TEXTURE_FUNC(textureName, samplerName, uvMapping.uvXZ, param), scale);
if (triplanarWeights.z > 0.0)
val += triplanarWeights.z * UNPACK_NORMAL_FUNC(SAMPLE_TEXTURE_FUNC(textureName, samplerName, uvMapping.uvXY, param), scale);
return normalize(val);
#endif
}
#ifdef SURFACE_GRADIENT
else if (uvMapping.mappingType == UV_MAPPING_PLANAR)
{
// Note: Planar is on uv coordinate (and not uvXZ)
real2 derivYPlane = UNPACK_DERIVATIVE_FUNC(SAMPLE_TEXTURE_FUNC(textureName, samplerName, uvMapping.uv, param), scale);
// See comment above
real3 volumeGrad = real3(derivYPlane.x, 0.0, derivYPlane.y);
return SurfaceGradientFromVolumeGradient(uvMapping.normalWS, volumeGrad);
}
#endif
else
{
#ifdef SURFACE_GRADIENT
real2 deriv = UNPACK_DERIVATIVE_FUNC(SAMPLE_TEXTURE_FUNC(textureName, samplerName, uvMapping.uv, param), scale);
return SurfaceGradientFromTBN(deriv, uvMapping.tangentWS, uvMapping.bitangentWS);
#else
return UNPACK_NORMAL_FUNC(SAMPLE_TEXTURE_FUNC(textureName, samplerName, uvMapping.uv, param), scale);
#endif
}
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: f941b2119184e624a8ecd126735c5ed0
timeCreated: 1487475828
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,329 @@
#ifndef UNITY_SAMPLING_INCLUDED
#define UNITY_SAMPLING_INCLUDED
#if SHADER_API_MOBILE || SHADER_API_GLES || SHADER_API_GLES3
#pragma warning (disable : 3205) // conversion of larger type to smaller
#endif
//-----------------------------------------------------------------------------
// Sample generator
//-----------------------------------------------------------------------------
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Sampling/Fibonacci.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Sampling/Hammersley.hlsl"
//-----------------------------------------------------------------------------
// Coordinate system conversion
//-----------------------------------------------------------------------------
// Transforms the unit vector from the spherical to the Cartesian (right-handed, Z up) coordinate.
real3 SphericalToCartesian(real cosPhi, real sinPhi, real cosTheta)
{
real sinTheta = SinFromCos(cosTheta);
return real3(real2(cosPhi, sinPhi) * sinTheta, cosTheta);
}
real3 SphericalToCartesian(real phi, real cosTheta)
{
real sinPhi, cosPhi;
sincos(phi, sinPhi, cosPhi);
return SphericalToCartesian(cosPhi, sinPhi, cosTheta);
}
// Converts Cartesian coordinates given in the right-handed coordinate system
// with Z pointing upwards (OpenGL style) to the coordinates in the left-handed
// coordinate system with Y pointing up and Z facing forward (DirectX style).
real3 TransformGLtoDX(real3 v)
{
return v.xzy;
}
// Performs conversion from equiareal map coordinates to Cartesian (DirectX cubemap) ones.
real3 ConvertEquiarealToCubemap(real u, real v)
{
real phi = TWO_PI - TWO_PI * u;
real cosTheta = 1.0 - 2.0 * v;
return TransformGLtoDX(SphericalToCartesian(phi, cosTheta));
}
// Convert a texel position into normalized position [-1..1]x[-1..1]
real2 CubemapTexelToNVC(uint2 unPositionTXS, uint cubemapSize)
{
return 2.0 * real2(unPositionTXS) / real(max(cubemapSize - 1, 1)) - 1.0;
}
// Map cubemap face to world vector basis
static const real3 CUBEMAP_FACE_BASIS_MAPPING[6][3] =
{
//XPOS face
{
real3(0.0, 0.0, -1.0),
real3(0.0, -1.0, 0.0),
real3(1.0, 0.0, 0.0)
},
//XNEG face
{
real3(0.0, 0.0, 1.0),
real3(0.0, -1.0, 0.0),
real3(-1.0, 0.0, 0.0)
},
//YPOS face
{
real3(1.0, 0.0, 0.0),
real3(0.0, 0.0, 1.0),
real3(0.0, 1.0, 0.0)
},
//YNEG face
{
real3(1.0, 0.0, 0.0),
real3(0.0, 0.0, -1.0),
real3(0.0, -1.0, 0.0)
},
//ZPOS face
{
real3(1.0, 0.0, 0.0),
real3(0.0, -1.0, 0.0),
real3(0.0, 0.0, 1.0)
},
//ZNEG face
{
real3(-1.0, 0.0, 0.0),
real3(0.0, -1.0, 0.0),
real3(0.0, 0.0, -1.0)
}
};
// Convert a normalized cubemap face position into a direction
real3 CubemapTexelToDirection(real2 positionNVC, uint faceId)
{
real3 dir = CUBEMAP_FACE_BASIS_MAPPING[faceId][0] * positionNVC.x
+ CUBEMAP_FACE_BASIS_MAPPING[faceId][1] * positionNVC.y
+ CUBEMAP_FACE_BASIS_MAPPING[faceId][2];
return normalize(dir);
}
//-----------------------------------------------------------------------------
// Sampling function
// Reference : http://www.cs.virginia.edu/~jdl/bib/globillum/mis/shirley96.pdf + PBRT
//-----------------------------------------------------------------------------
// Performs uniform sampling of the unit disk.
// Ref: PBRT v3, p. 777.
real2 SampleDiskUniform(real u1, real u2)
{
real r = sqrt(u1);
real phi = TWO_PI * u2;
real sinPhi, cosPhi;
sincos(phi, sinPhi, cosPhi);
return r * real2(cosPhi, sinPhi);
}
// Performs cubic sampling of the unit disk.
real2 SampleDiskCubic(real u1, real u2)
{
real r = u1;
real phi = TWO_PI * u2;
real sinPhi, cosPhi;
sincos(phi, sinPhi, cosPhi);
return r * real2(cosPhi, sinPhi);
}
real3 SampleConeUniform(real u1, real u2, real cos_theta)
{
float r0 = cos_theta + u1 * (1.0f - cos_theta);
float r = sqrt(max(0.0, 1.0 - r0 * r0));
float phi = TWO_PI * u2;
return float3(r * cos(phi), r * sin(phi), r0);
}
real3 SampleSphereUniform(real u1, real u2)
{
real phi = TWO_PI * u2;
real cosTheta = 1.0 - 2.0 * u1;
return SphericalToCartesian(phi, cosTheta);
}
// Performs cosine-weighted sampling of the hemisphere.
// Ref: PBRT v3, p. 780.
real3 SampleHemisphereCosine(real u1, real u2)
{
real3 localL;
// Since we don't really care about the area distortion,
// we substitute uniform disk sampling for the concentric one.
localL.xy = SampleDiskUniform(u1, u2);
// Project the point from the disk onto the hemisphere.
localL.z = sqrt(1.0 - u1);
return localL;
}
// Cosine-weighted sampling without the tangent frame.
// Ref: http://www.amietia.com/lambertnotangent.html
real3 SampleHemisphereCosine(real u1, real u2, real3 normal)
{
// This function needs to used safenormalize because there is a probability
// that the generated direction is the exact opposite of the normal and that would lead
// to a nan vector otheriwse.
real3 pointOnSphere = SampleSphereUniform(u1, u2);
return SafeNormalize(normal + pointOnSphere);
}
real3 SampleHemisphereUniform(real u1, real u2)
{
real phi = TWO_PI * u2;
real cosTheta = 1.0 - u1;
return SphericalToCartesian(phi, cosTheta);
}
void SampleSphere(real2 u,
real4x4 localToWorld,
real radius,
out real lightPdf,
out real3 P,
out real3 Ns)
{
real u1 = u.x;
real u2 = u.y;
Ns = SampleSphereUniform(u1, u2);
// Transform from unit sphere to world space
P = radius * Ns + localToWorld[3].xyz;
// pdf is inverse of area
lightPdf = 1.0 / (FOUR_PI * radius * radius);
}
void SampleHemisphere(real2 u,
real4x4 localToWorld,
real radius,
out real lightPdf,
out real3 P,
out real3 Ns)
{
real u1 = u.x;
real u2 = u.y;
// Random point at hemisphere surface
Ns = -SampleHemisphereUniform(u1, u2); // We want the y down hemisphere
P = radius * Ns;
// Transform to world space
P = mul(real4(P, 1.0), localToWorld).xyz;
Ns = mul(Ns, (real3x3)(localToWorld));
// pdf is inverse of area
lightPdf = 1.0 / (TWO_PI * radius * radius);
}
// Note: The cylinder has no end caps (i.e. no disk on the side)
void SampleCylinder(real2 u,
real4x4 localToWorld,
real radius,
real width,
out real lightPdf,
out real3 P,
out real3 Ns)
{
real u1 = u.x;
real u2 = u.y;
// Random point at cylinder surface
real t = (u1 - 0.5) * width;
real theta = 2.0 * PI * u2;
real cosTheta = cos(theta);
real sinTheta = sin(theta);
// Cylinder are align on the right axis
P = real3(t, radius * cosTheta, radius * sinTheta);
Ns = normalize(real3(0.0, cosTheta, sinTheta));
// Transform to world space
P = mul(real4(P, 1.0), localToWorld).xyz;
Ns = mul(Ns, (real3x3)(localToWorld));
// pdf is inverse of area
lightPdf = 1.0 / (TWO_PI * radius * width);
}
void SampleRectangle(real2 u,
real4x4 localToWorld,
real width,
real height,
out real lightPdf,
out real3 P,
out real3 Ns)
{
// Random point at rectangle surface
P = real3((u.x - 0.5) * width, (u.y - 0.5) * height, 0);
Ns = real3(0, 0, -1); // Light down (-Z)
// Transform to world space
P = mul(real4(P, 1.0), localToWorld).xyz;
Ns = mul(Ns, (real3x3)(localToWorld));
// pdf is inverse of area
lightPdf = 1.0 / (width * height);
}
void SampleDisk(real2 u,
real4x4 localToWorld,
real radius,
out real lightPdf,
out real3 P,
out real3 Ns)
{
// Random point at disk surface
P = real3(radius * SampleDiskUniform(u.x, u.y), 0);
Ns = real3(0.0, 0.0, -1.0); // Light down (-Z)
// Transform to world space
P = mul(real4(P, 1.0), localToWorld).xyz;
Ns = mul(Ns, (real3x3)(localToWorld));
// pdf is inverse of area
lightPdf = 1.0 / (PI * radius * radius);
}
// Solid angle cone sampling.
// Takes the cosine of the aperture as an input.
void SampleCone(real2 u, real cosHalfAngle,
out real3 dir, out real rcpPdf)
{
real cosTheta = lerp(1, cosHalfAngle, u.x);
real phi = TWO_PI * u.y;
dir = SphericalToCartesian(phi, cosTheta);
rcpPdf = TWO_PI * (1 - cosHalfAngle);
}
// Returns uniformly distributed sample vectors in a cone using
// "golden angle spiral method" described here: http://blog.marmakoide.org/?p=1
// note: the first sample is always [0, 0, 1]
real3 SampleConeStrata(uint sampleIdx, real rcpSampleCount, real cosHalfApexAngle)
{
real z = 1.0f - ((1.0f - cosHalfApexAngle) * sampleIdx) * rcpSampleCount;
real r = sqrt(1.0f - z * z);
real a = sampleIdx * 2.3999632297286f; // pi*(3-sqrt(5))
real sphi = sin(a);
real cphi = cos(a);
return real3(r * cphi, r * sphi, z);
}
#if SHADER_API_MOBILE || SHADER_API_GLES || SHADER_API_GLES3
#pragma warning (enable : 3205) // conversion of larger type to smaller
#endif
#endif // UNITY_SAMPLING_INCLUDED

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f4c850bea2c5d45449ba8e228333c82c
timeCreated: 1472140530
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,25 @@
#ifndef UNITY_SCREEN_COORD_OVERRIDE_INCLUDED
#define UNITY_SCREEN_COORD_OVERRIDE_INCLUDED
float2 ScreenCoordApplyScaleBias(float2 xy, float4 screenCoordScaleBias)
{
return screenCoordScaleBias.zw + xy * screenCoordScaleBias.xy;
}
float2 ScreenCoordRemoveScaleBias(float2 xy, float4 screenCoordScaleBias)
{
return (xy - screenCoordScaleBias.zw) / screenCoordScaleBias.xy;
}
// Note that SCREEN_SIZE_OVERRIDE will be redefined in HDRP to use _PostProcessScreenSize.
#if defined(SCREEN_COORD_OVERRIDE)
#define SCREEN_COORD_APPLY_SCALEBIAS(xy) ScreenCoordApplyScaleBias(xy, _ScreenCoordScaleBias)
#define SCREEN_COORD_REMOVE_SCALEBIAS(xy) ScreenCoordRemoveScaleBias(xy, _ScreenCoordScaleBias)
#define SCREEN_SIZE_OVERRIDE _ScreenSizeOverride
#else
#define SCREEN_COORD_APPLY_SCALEBIAS(xy) xy
#define SCREEN_COORD_REMOVE_SCALEBIAS(xy) xy
#define SCREEN_SIZE_OVERRIDE _ScreenSize
#endif
#endif // UNITY_SCREEN_COORD_OVERRIDE_INCLUDED

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 435c74ddc7b1fd744b934a196d6d3d82
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,300 @@
#ifndef SHADER_DEBUG_PRINT_INCLUDED
#define SHADER_DEBUG_PRINT_INCLUDED
// NOTE: For URP - set ENABLE_SHADER_DEBUG_PRINT in the project to enable CPU-side integration.
// NOTE: Currently works in game view/play mode.
//
// Include this header to any shader to enable debug printing values from shader code to console.
//
// Select threads/pixels to print using plain 'if'.
//
// Example:
// float4 colorRGBA = float4(0.1, 0.2, 0.3, 0.4);
// if(all(int2(pixel.xy) == int2(100, 100)))
// ShaderDebugPrint(ShaderDebugTag('C','o','l'), colorRGBA);
// ----
// Output:
// Frame #270497: Col float4(0.1f, 0.2f, 0.3f, 0.4f)
// ----
//
// Example:
// #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/ShaderDebugPrint.hlsl"
//
// Print pixel at mouse position.
// ShaderDebugPrintMouseOver(int2(thisPixel.xy), pixelColor);
//
// Print pixel at mouse position on button press.
// ShaderDebugPrintMouseButtonOver(int2(thisPixel.xy), pixelColor);
// Output buffer bound into "last" (DX11) slot by convention.
// Avoids extra editing elsewhere and allows to just include this header.
RWStructuredBuffer<uint> shaderDebugOutputData : register(u7);
static const uint MaxShaderDebugOutputElements = 1024 * 16; // Must match the C# side buffer size (16K elems / 6 (header+tag+payload) ~= 2730 uint4s)
// Input Constants
CBUFFER_START(ShaderDebugPrintInput)
float4 _ShaderDebugPrintInputMouse;
int _ShaderDebugPrintInputFrame;
CBUFFER_END
// Mouse coordinates in pixels
// Relative to game view surface/rendertarget
// (Typically (0,0) is bottom-left in Unity. TIP: print mouse coords to check if unsure.)
int2 ShaderDebugMouseCoords() { return _ShaderDebugPrintInputMouse.xy; }
// Mouse buttons
// Returns true on button down.
int ShaderDebugMouseButtonLeft() { return _ShaderDebugPrintInputMouse.z; }
int ShaderDebugMouseButtonRight() { return _ShaderDebugPrintInputMouse.w; }
int ShaderDebugMouseButton(int button) { return button == 0 ? ShaderDebugMouseButtonLeft() : ShaderDebugMouseButtonRight(); }
int ShaderDebugFrameNumber() { return _ShaderDebugPrintInputFrame; }
// Output Data type encodings
// Must match C# side decoding
static const uint ValueTypeUint = 1;
static const uint ValueTypeInt = 2;
static const uint ValueTypeFloat = 3;
static const uint ValueTypeUint2 = 4;
static const uint ValueTypeInt2 = 5;
static const uint ValueTypeFloat2 = 6;
static const uint ValueTypeUint3 = 7;
static const uint ValueTypeInt3 = 8;
static const uint ValueTypeFloat3 = 9;
static const uint ValueTypeUint4 = 10;
static const uint ValueTypeInt4 = 11;
static const uint ValueTypeFloat4 = 12;
static const uint ValueTypeBool = 13;
static const uint ValueTypeHasTag = 128;
// Data-buffer format
// 1 uint header
// 1 uint tag (optional)
// 1-4 uint value (type dependent)
//
// Header format
// 1 byte Type id + tag flag
// bits 0..6 value type id/enum
// bit 7 has tag flag
// 3 bytes (empty)
#define PRINT1(TYPE, VALUE, HASTAG, TAG) \
{ \
if (shaderDebugOutputData[0] < MaxShaderDebugOutputElements) \
{ \
uint index; \
uint elements = 2; \
if (HASTAG) elements++; \
InterlockedAdd(shaderDebugOutputData[0], elements, index); \
index++; \
if (index < MaxShaderDebugOutputElements) \
{ \
shaderDebugOutputData[index++] = TYPE | HASTAG; \
if (HASTAG) shaderDebugOutputData[index++] = TAG; \
shaderDebugOutputData[index++] = VALUE; \
} \
} \
}
#define PRINT2(TYPE, VALUE, HASTAG, TAG) \
{ \
if (shaderDebugOutputData[0] < MaxShaderDebugOutputElements) \
{ \
uint index; \
uint elements = 3; \
if (HASTAG) elements++; \
InterlockedAdd(shaderDebugOutputData[0], elements, index); \
index++; \
if (index < MaxShaderDebugOutputElements) \
{ \
shaderDebugOutputData[index++] = TYPE | HASTAG; \
if (HASTAG) shaderDebugOutputData[index++] = TAG; \
shaderDebugOutputData[index++] = VALUE.x; \
shaderDebugOutputData[index++] = VALUE.y; \
} \
} \
}
#define PRINT3(TYPE, VALUE, HASTAG, TAG) \
{ \
if (shaderDebugOutputData[0] < MaxShaderDebugOutputElements) \
{ \
uint index; \
uint elements = 4; \
if (HASTAG) elements++; \
InterlockedAdd(shaderDebugOutputData[0], elements, index); \
index++; \
if (index < MaxShaderDebugOutputElements) \
{ \
shaderDebugOutputData[index++] = TYPE | HASTAG; \
if (HASTAG) shaderDebugOutputData[index++] = TAG; \
shaderDebugOutputData[index++] = VALUE.x; \
shaderDebugOutputData[index++] = VALUE.y; \
shaderDebugOutputData[index++] = VALUE.z; \
} \
} \
}
#define PRINT4(TYPE, VALUE, HASTAG, TAG) \
{ \
if (shaderDebugOutputData[0] < MaxShaderDebugOutputElements) \
{ \
uint index; \
uint elements = 5; \
if (HASTAG) elements++; \
InterlockedAdd(shaderDebugOutputData[0], elements, index); \
index++; \
if (index < MaxShaderDebugOutputElements) \
{ \
shaderDebugOutputData[index++] = TYPE | HASTAG; \
if (HASTAG) shaderDebugOutputData[index++] = TAG; \
shaderDebugOutputData[index++] = VALUE.x; \
shaderDebugOutputData[index++] = VALUE.y; \
shaderDebugOutputData[index++] = VALUE.z; \
shaderDebugOutputData[index++] = VALUE.w; \
} \
} \
}
static const uint ShaderDebugNoTag;
// Create 1-4 letter tags encoded into a uint
// For example
// ShaderDebugTag( 'M', 'y', 'I', 'd' );
uint ShaderDebugTag(uint a, uint b, uint c, uint d) { return a | (b << 8) | (c << 16) | (d << 24); }
uint ShaderDebugTag(uint a, uint b, uint c) { return ShaderDebugTag( a, b, c, 0); }
uint ShaderDebugTag(uint a, uint b) { return ShaderDebugTag( a, b, 0); }
uint ShaderDebugTag(uint a) { return ShaderDebugTag( a, 0); }
// Print value to (Unity) console
// Be careful to not print all N threads (thousands). Use if statements and thread ids to pick values only from a few threads.
// (tag), an optional text tag for the print. Use ShaderDebugTag() helper to create.
// value, to be printed
void ShaderDebugPrint(uint tag, bool value) PRINT1(ValueTypeBool, uint(value), ValueTypeHasTag, tag);
void ShaderDebugPrint(uint tag, uint value) PRINT1(ValueTypeUint, value, ValueTypeHasTag, tag);
void ShaderDebugPrint(uint tag, int value) PRINT1(ValueTypeInt, asuint(value), ValueTypeHasTag, tag);
void ShaderDebugPrint(uint tag, float value) PRINT1(ValueTypeFloat, asuint(value), ValueTypeHasTag, tag);
void ShaderDebugPrint(uint tag, uint2 value) PRINT2(ValueTypeUint2, value, ValueTypeHasTag, tag)
void ShaderDebugPrint(uint tag, int2 value) PRINT2(ValueTypeInt2, asuint(value), ValueTypeHasTag, tag)
void ShaderDebugPrint(uint tag, float2 value) PRINT2(ValueTypeFloat2, asuint(value), ValueTypeHasTag, tag)
void ShaderDebugPrint(uint tag, uint3 value) PRINT3(ValueTypeUint3, value, ValueTypeHasTag, tag)
void ShaderDebugPrint(uint tag, int3 value) PRINT3(ValueTypeInt3, asuint(value), ValueTypeHasTag, tag)
void ShaderDebugPrint(uint tag, float3 value) PRINT3(ValueTypeFloat3, asuint(value), ValueTypeHasTag, tag)
void ShaderDebugPrint(uint tag, uint4 value) PRINT4(ValueTypeUint4, value, ValueTypeHasTag, tag)
void ShaderDebugPrint(uint tag, int4 value) PRINT4(ValueTypeInt4, asuint(value), ValueTypeHasTag, tag)
void ShaderDebugPrint(uint tag, float4 value) PRINT4(ValueTypeFloat4, asuint(value), ValueTypeHasTag, tag)
void ShaderDebugPrint(bool value) PRINT1(ValueTypeBool, uint(value), 0, ShaderDebugNoTag)
void ShaderDebugPrint(uint value) PRINT1(ValueTypeUint, value, 0, ShaderDebugNoTag)
void ShaderDebugPrint(int value) PRINT1(ValueTypeInt, asuint(value), 0, ShaderDebugNoTag)
void ShaderDebugPrint(float value) PRINT1(ValueTypeFloat, asuint(value), 0, ShaderDebugNoTag)
void ShaderDebugPrint(uint2 value) PRINT2(ValueTypeUint2, value, 0, ShaderDebugNoTag)
void ShaderDebugPrint(int2 value) PRINT2(ValueTypeInt2, asuint(value), 0, ShaderDebugNoTag)
void ShaderDebugPrint(float2 value) PRINT2(ValueTypeFloat2, asuint(value), 0, ShaderDebugNoTag)
void ShaderDebugPrint(uint3 value) PRINT3(ValueTypeUint3, value, 0, ShaderDebugNoTag)
void ShaderDebugPrint(int3 value) PRINT3(ValueTypeInt3, asuint(value), 0, ShaderDebugNoTag)
void ShaderDebugPrint(float3 value) PRINT3(ValueTypeFloat3, asuint(value), 0, ShaderDebugNoTag)
void ShaderDebugPrint(uint4 value) PRINT4(ValueTypeUint4, value, 0, ShaderDebugNoTag)
void ShaderDebugPrint(int4 value) PRINT4(ValueTypeInt4, asuint(value), 0, ShaderDebugNoTag)
void ShaderDebugPrint(float4 value) PRINT4(ValueTypeFloat4, asuint(value), 0, ShaderDebugNoTag)
#undef PRINT1
#undef PRINT2
#undef PRINT3
#undef PRINT4
#define PRINT_MOUSE(VALUE) \
{ \
if(all(pixelPos == ShaderDebugMouseCoords())) \
ShaderDebugPrint(VALUE); \
}
#define PRINT_MOUSE_WITH_TAG(VALUE, TAG) \
{ \
if(all(pixelPos == ShaderDebugMouseCoords())) \
ShaderDebugPrint(TAG, VALUE); \
}
// Print value for pixel under mouse cursor
// pixelPos, screen pixel coordinates for this fragment shader thread. Typically .xy of fragment shader input parameter with SV_Position semantic.
// NOTE: Any render target scaling (or offset) is NOT taken into account as that can be arbitrary. You must correct scaling manually.
// (For example: fragment.xy * _ScreenParams.xy / _ScaledScreenParams.xy or similar)
// TIP: Color the pixel (or a box) at mouse coords to debug scaling/offset.
// (tag), an optional text tag for the print. Use ShaderDebugTag() helper to create.
// value, to be printed
void ShaderDebugPrintMouseOver(int2 pixelPos, uint tag, bool value) PRINT_MOUSE_WITH_TAG(value, tag);
void ShaderDebugPrintMouseOver(int2 pixelPos, uint tag, uint value) PRINT_MOUSE_WITH_TAG(value, tag);
void ShaderDebugPrintMouseOver(int2 pixelPos, uint tag, int value) PRINT_MOUSE_WITH_TAG(value, tag);
void ShaderDebugPrintMouseOver(int2 pixelPos, uint tag, float value) PRINT_MOUSE_WITH_TAG(value, tag);
void ShaderDebugPrintMouseOver(int2 pixelPos, uint tag, uint2 value) PRINT_MOUSE_WITH_TAG(value, tag);
void ShaderDebugPrintMouseOver(int2 pixelPos, uint tag, int2 value) PRINT_MOUSE_WITH_TAG(value, tag);
void ShaderDebugPrintMouseOver(int2 pixelPos, uint tag, float2 value) PRINT_MOUSE_WITH_TAG(value, tag);
void ShaderDebugPrintMouseOver(int2 pixelPos, uint tag, uint3 value) PRINT_MOUSE_WITH_TAG(value, tag);
void ShaderDebugPrintMouseOver(int2 pixelPos, uint tag, int3 value) PRINT_MOUSE_WITH_TAG(value, tag);
void ShaderDebugPrintMouseOver(int2 pixelPos, uint tag, float3 value) PRINT_MOUSE_WITH_TAG(value, tag);
void ShaderDebugPrintMouseOver(int2 pixelPos, uint tag, uint4 value) PRINT_MOUSE_WITH_TAG(value, tag);
void ShaderDebugPrintMouseOver(int2 pixelPos, uint tag, int4 value) PRINT_MOUSE_WITH_TAG(value, tag);
void ShaderDebugPrintMouseOver(int2 pixelPos, uint tag, float4 value) PRINT_MOUSE_WITH_TAG(value, tag);
void ShaderDebugPrintMouseOver(int2 pixelPos, bool value) PRINT_MOUSE(value);
void ShaderDebugPrintMouseOver(int2 pixelPos, uint value) PRINT_MOUSE(value);
void ShaderDebugPrintMouseOver(int2 pixelPos, int value) PRINT_MOUSE(value);
void ShaderDebugPrintMouseOver(int2 pixelPos, float value) PRINT_MOUSE(value);
void ShaderDebugPrintMouseOver(int2 pixelPos, uint2 value) PRINT_MOUSE(value);
void ShaderDebugPrintMouseOver(int2 pixelPos, int2 value) PRINT_MOUSE(value);
void ShaderDebugPrintMouseOver(int2 pixelPos, float2 value) PRINT_MOUSE(value);
void ShaderDebugPrintMouseOver(int2 pixelPos, uint3 value) PRINT_MOUSE(value);
void ShaderDebugPrintMouseOver(int2 pixelPos, int3 value) PRINT_MOUSE(value);
void ShaderDebugPrintMouseOver(int2 pixelPos, float3 value) PRINT_MOUSE(value);
void ShaderDebugPrintMouseOver(int2 pixelPos, uint4 value) PRINT_MOUSE(value);
void ShaderDebugPrintMouseOver(int2 pixelPos, int4 value) PRINT_MOUSE(value);
void ShaderDebugPrintMouseOver(int2 pixelPos, float4 value) PRINT_MOUSE(value);
#undef PRINT_MOUSE
#undef PRINT_MOUSE_WITH_TAG
#define PRINT_MOUSE_BUTTON(BUTTON, VALUE) \
{ \
if(ShaderDebugMouseButton(BUTTON) && all(pixelPos == ShaderDebugMouseCoords())) \
ShaderDebugPrint(VALUE); \
}
#define PRINT_MOUSE_BUTTON_WITH_TAG(BUTTON, VALUE, TAG) \
{ \
if(ShaderDebugMouseButton(BUTTON) && all(pixelPos == ShaderDebugMouseCoords())) \
ShaderDebugPrint(TAG, VALUE); \
}
// Print value for pixel under mouse cursor when mouse left button is pressed
// pixelPos, screen pixel coordinates for this fragment shader thread. Typically .xy of fragment shader input parameter with SV_Position semantic.
// (tag), an optional text tag for the print. Use ShaderDebugTag() helper to create.
// value, to be printed
void ShaderDebugPrintMouseButtonOver(int2 pixelPos, uint tag, bool value) PRINT_MOUSE_BUTTON_WITH_TAG(0, value, tag);
void ShaderDebugPrintMouseButtonOver(int2 pixelPos, uint tag, uint value) PRINT_MOUSE_BUTTON_WITH_TAG(0, value, tag);
void ShaderDebugPrintMouseButtonOver(int2 pixelPos, uint tag, int value) PRINT_MOUSE_BUTTON_WITH_TAG(0, value, tag);
void ShaderDebugPrintMouseButtonOver(int2 pixelPos, uint tag, float value) PRINT_MOUSE_BUTTON_WITH_TAG(0, value, tag);
void ShaderDebugPrintMouseButtonOver(int2 pixelPos, uint tag, uint2 value) PRINT_MOUSE_BUTTON_WITH_TAG(0, value, tag);
void ShaderDebugPrintMouseButtonOver(int2 pixelPos, uint tag, int2 value) PRINT_MOUSE_BUTTON_WITH_TAG(0, value, tag);
void ShaderDebugPrintMouseButtonOver(int2 pixelPos, uint tag, float2 value) PRINT_MOUSE_BUTTON_WITH_TAG(0, value, tag);
void ShaderDebugPrintMouseButtonOver(int2 pixelPos, uint tag, uint3 value) PRINT_MOUSE_BUTTON_WITH_TAG(0, value, tag);
void ShaderDebugPrintMouseButtonOver(int2 pixelPos, uint tag, int3 value) PRINT_MOUSE_BUTTON_WITH_TAG(0, value, tag);
void ShaderDebugPrintMouseButtonOver(int2 pixelPos, uint tag, float3 value) PRINT_MOUSE_BUTTON_WITH_TAG(0, value, tag);
void ShaderDebugPrintMouseButtonOver(int2 pixelPos, uint tag, uint4 value) PRINT_MOUSE_BUTTON_WITH_TAG(0, value, tag);
void ShaderDebugPrintMouseButtonOver(int2 pixelPos, uint tag, int4 value) PRINT_MOUSE_BUTTON_WITH_TAG(0, value, tag);
void ShaderDebugPrintMouseButtonOver(int2 pixelPos, uint tag, float4 value) PRINT_MOUSE_BUTTON_WITH_TAG(0, value, tag);
void ShaderDebugPrintMouseButtonOver(int2 pixelPos, bool value) PRINT_MOUSE_BUTTON(0, value);
void ShaderDebugPrintMouseButtonOver(int2 pixelPos, uint value) PRINT_MOUSE_BUTTON(0, value);
void ShaderDebugPrintMouseButtonOver(int2 pixelPos, int value) PRINT_MOUSE_BUTTON(0, value);
void ShaderDebugPrintMouseButtonOver(int2 pixelPos, float value) PRINT_MOUSE_BUTTON(0, value);
void ShaderDebugPrintMouseButtonOver(int2 pixelPos, uint2 value) PRINT_MOUSE_BUTTON(0, value);
void ShaderDebugPrintMouseButtonOver(int2 pixelPos, int2 value) PRINT_MOUSE_BUTTON(0, value);
void ShaderDebugPrintMouseButtonOver(int2 pixelPos, float2 value) PRINT_MOUSE_BUTTON(0, value);
void ShaderDebugPrintMouseButtonOver(int2 pixelPos, uint3 value) PRINT_MOUSE_BUTTON(0, value);
void ShaderDebugPrintMouseButtonOver(int2 pixelPos, int3 value) PRINT_MOUSE_BUTTON(0, value);
void ShaderDebugPrintMouseButtonOver(int2 pixelPos, float3 value) PRINT_MOUSE_BUTTON(0, value);
void ShaderDebugPrintMouseButtonOver(int2 pixelPos, uint4 value) PRINT_MOUSE_BUTTON(0, value);
void ShaderDebugPrintMouseButtonOver(int2 pixelPos, int4 value) PRINT_MOUSE_BUTTON(0, value);
void ShaderDebugPrintMouseButtonOver(int2 pixelPos, float4 value) PRINT_MOUSE_BUTTON(0, value);
#undef PRINT_MOUSE_BUTTON
#undef PRINT_MOUSE_BUTTON_WITH_TAG
#endif // SHADER_DEBUG_PRINT_INCLUDED

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6487e82b005541789deacb92eaa88bed
timeCreated: 1592907589

Some files were not shown because too many files have changed in this diff Show More