您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

211 行
7.0 KiB

#ifndef LIGHTWEIGHT_PIPELINE_CORE_INCLUDED
#define LIGHTWEIGHT_PIPELINE_CORE_INCLUDED
#include "CoreRP/ShaderLibrary/Common.hlsl"
#include "CoreRP/ShaderLibrary/Packing.hlsl"
#include "Input.hlsl"
#if !defined(SHADER_HINT_NICE_QUALITY)
#ifdef SHADER_API_MOBILE
#define SHADER_HINT_NICE_QUALITY 0
#else
#define SHADER_HINT_NICE_QUALITY 1
#endif
#endif
#ifndef BUMP_SCALE_NOT_SUPPORTED
#define BUMP_SCALE_NOT_SUPPORTED !SHADER_HINT_NICE_QUALITY
#endif
///////////////////////////////////////////////////////////////////////////////
#ifdef _NORMALMAP
#define OUTPUT_NORMAL(IN, OUT) OutputTangentToWorld(IN.tangent, IN.normal, OUT.tangent.xyz, OUT.binormal.xyz, OUT.normal.xyz)
#else
#define OUTPUT_NORMAL(IN, OUT) OUT.normal = TransformObjectToWorldNormal(IN.normal)
#endif
#if UNITY_REVERSED_Z
#if SHADER_API_OPENGL || SHADER_API_GLES || SHADER_API_GLES3
//GL with reversed z => z clip range is [near, -far] -> should remap in theory but dont do it in practice to save some perf (range is close enough)
#define UNITY_Z_0_FAR_FROM_CLIPSPACE(coord) max(-(coord), 0)
#else
//D3d with reversed Z => z clip range is [near, 0] -> remapping to [0, far]
//max is required to protect ourselves from near plane not being correct/meaningfull in case of oblique matrices.
#define UNITY_Z_0_FAR_FROM_CLIPSPACE(coord) max(((1.0-(coord)/_ProjectionParams.y)*_ProjectionParams.z),0)
#endif
#elif UNITY_UV_STARTS_AT_TOP
//D3d without reversed z => z clip range is [0, far] -> nothing to do
#define UNITY_Z_0_FAR_FROM_CLIPSPACE(coord) (coord)
#else
//Opengl => z clip range is [-near, far] -> should remap in theory but dont do it in practice to save some perf (range is close enough)
#define UNITY_Z_0_FAR_FROM_CLIPSPACE(coord) (coord)
#endif
// TODO: Really need a better define for iOS Metal than the framebuffer fetch one, that's also enabled on android and webgl (???)
#if defined(SHADER_API_VULKAN) || (defined(SHADER_API_METAL) && defined(UNITY_FRAMEBUFFER_FETCH_AVAILABLE))
// Renderpass inputs: Vulkan/Metal subpass input
#define UNITY_DECLARE_FRAMEBUFFER_INPUT_FLOAT(idx) cbuffer hlslcc_SubpassInput_f_##idx { float4 hlslcc_fbinput_##idx; }
#define UNITY_DECLARE_FRAMEBUFFER_INPUT_HALF(idx) cbuffer hlslcc_SubpassInput_h_##idx { half4 hlslcc_fbinput_##idx; }
#define UNITY_READ_FRAMEBUFFER_INPUT(idx, v2fname) hlslcc_fbinput_##idx
#else
// Renderpass inputs: General fallback path
#define UNITY_DECLARE_FRAMEBUFFER_INPUT_FLOAT(idx) TEXTURE2D_FLOAT(_UnityFBInput##idx); float4 _UnityFBInput##idx##_TexelSize
#define UNITY_DECLARE_FRAMEBUFFER_INPUT_HALF(idx) TEXTURE2D_HALF(_UnityFBInput##idx); float4 _UnityFBInput##idx##_TexelSize
#define UNITY_READ_FRAMEBUFFER_INPUT(idx, v2fvertexname) _UnityFBInput##idx.Load(uint3(v2fvertexname.xy, 0))
#endif
float4 GetScaledScreenParams()
{
return _ScaledScreenParams;
}
void AlphaDiscard(half alpha, half cutoff, half offset = 0.0h)
{
#ifdef _ALPHATEST_ON
clip(alpha - cutoff + offset);
#endif
}
half3 UnpackNormal(half4 packedNormal)
{
#if defined(UNITY_NO_DXT5nm)
return UnpackNormalRGBNoScale(packedNormal);
#else
// Compiler will optimize the scale away
return UnpackNormalmapRGorAG(packedNormal, 1.0);
#endif
}
half3 UnpackNormalScale(half4 packedNormal, half bumpScale)
{
#if defined(UNITY_NO_DXT5nm)
return UnpackNormalRGB(packedNormal, bumpScale);
#else
return UnpackNormalmapRGorAG(packedNormal, bumpScale);
#endif
}
void OutputTangentToWorld(half4 vertexTangent, half3 vertexNormal, out half3 tangentWS, out half3 binormalWS, out half3 normalWS)
{
// mikkts space compliant. only normalize when extracting normal at frag.
half sign = vertexTangent.w * GetOddNegativeScale();
normalWS = TransformObjectToWorldNormal(vertexNormal);
tangentWS = TransformObjectToWorldDir(vertexTangent.xyz);
binormalWS = cross(normalWS, tangentWS) * sign;
}
half3 FragmentNormalWS(half3 normal)
{
#if !SHADER_HINT_NICE_QUALITY
// World normal is already normalized in vertex. Small acceptable error to save ALU.
return normal;
#else
return normalize(normal);
#endif
}
half3 FragmentViewDirWS(half3 viewDir)
{
#if !SHADER_HINT_NICE_QUALITY
// View direction is already normalized in vertex. Small acceptable error to save ALU.
return viewDir;
#else
return SafeNormalize(viewDir);
#endif
}
half3 VertexViewDirWS(half3 viewDir)
{
#if !SHADER_HINT_NICE_QUALITY
// Normalize in vertex and avoid renormalizing it in frag to save ALU.
return SafeNormalize(viewDir);
#else
return viewDir;
#endif
}
half3 TangentToWorldNormal(half3 normalTangent, half3 tangent, half3 binormal, half3 normal)
{
half3x3 tangentToWorld = half3x3(tangent, binormal, normal);
return FragmentNormalWS(mul(normalTangent, tangentToWorld));
}
// TODO: A similar function should be already available in SRP lib on master. Use that instead
float4 ComputeScreenPos(float4 positionCS)
{
float4 o = positionCS * 0.5f;
o.xy = float2(o.x, o.y * _ProjectionParams.x) + o.w;
o.zw = positionCS.zw;
return o;
}
half ComputeFogFactor(float z)
{
float clipZ_01 = UNITY_Z_0_FAR_FROM_CLIPSPACE(z);
#if defined(FOG_LINEAR)
// factor = (end-z)/(end-start) = z * (-1/(end-start)) + (end/(end-start))
float fogFactor = saturate(clipZ_01 * unity_FogParams.z + unity_FogParams.w);
return half(fogFactor);
#elif defined(FOG_EXP) || defined(FOG_EXP2)
// factor = exp(-(density*z)^2)
// -density * z computed at vertex
return half(unity_FogParams.x * clipZ_01);
#else
return 0.0h;
#endif
}
void ApplyFogColor(inout half3 color, half3 fogColor, half fogFactor)
{
#if defined(FOG_LINEAR) || defined(FOG_EXP) || defined(FOG_EXP2)
#if defined(FOG_EXP)
// factor = exp(-density*z)
// fogFactor = density*z compute at vertex
fogFactor = saturate(exp2(-fogFactor));
#elif defined(FOG_EXP2)
// factor = exp(-(density*z)^2)
// fogFactor = density*z compute at vertex
fogFactor = saturate(exp2(-fogFactor*fogFactor));
#endif
color = lerp(fogColor, color, fogFactor);
#endif
}
void ApplyFog(inout half3 color, half fogFactor)
{
ApplyFogColor(color, unity_FogColor.rgb, fogFactor);
}
// Stereo-related bits
#if defined(UNITY_STEREO_INSTANCING_ENABLED) || defined(UNITY_STEREO_MULTIVIEW_ENABLED)
#define SCREENSPACE_TEXTURE TEXTURE2D_ARRAY
#define SCREENSPACE_TEXTURE_FLOAT TEXTURE2D_ARRAY_FLOAT
#define SCREENSPACE_TEXTURE_HALF TEXTURE2D_ARRAY_HALF
#else
#define SCREENSPACE_TEXTURE TEXTURE2D
#define SCREENSPACE_TEXTURE_FLOAT TEXTURE2D_FLOAT
#define SCREENSPACE_TEXTURE_HALF TEXTURE2D_HALF
#endif
#if defined(UNITY_SINGLE_PASS_STEREO)
float2 TransformStereoScreenSpaceTex(float2 uv, float w)
{
// TODO: RVS support can be added here, if LWRP decides to support it
float4 scaleOffset = unity_StereoScaleOffset[unity_StereoEyeIndex];
return uv.xy * scaleOffset.xy + scaleOffset.zw * w;
}
float2 UnityStereoTransformScreenSpaceTex(float2 uv)
{
return TransformStereoScreenSpaceTex(saturate(uv), 1.0);
}
#else
#define UnityStereoTransformScreenSpaceTex(uv) uv
#endif // defined(UNITY_SINGLE_PASS_STEREO)
#endif