您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
221 行
6.0 KiB
221 行
6.0 KiB
#ifndef LIGHTWEIGHT_INPUT_INCLUDED
|
|
#define LIGHTWEIGHT_INPUT_INCLUDED
|
|
|
|
#define MAX_VISIBLE_LIGHTS 16
|
|
|
|
// Main light initialized without indexing
|
|
#define INITIALIZE_MAIN_LIGHT(light) \
|
|
light.pos = _LightPosition; \
|
|
light.color = _LightColor; \
|
|
light.atten = _LightAttenuationParams; \
|
|
light.spotDir = _LightSpotDir;
|
|
|
|
// Indexing might have a performance hit for old mobile hardware
|
|
#define INITIALIZE_LIGHT(light, lightIndex) \
|
|
light.pos = globalLightPos[lightIndex]; \
|
|
light.color = globalLightColor[lightIndex]; \
|
|
light.atten = globalLightAtten[lightIndex]; \
|
|
light.spotDir = globalLightSpotDir[lightIndex]
|
|
|
|
#if !(defined(_SINGLE_DIRECTIONAL_LIGHT) || defined(_SINGLE_SPOT_LIGHT) || defined(_SINGLE_POINT_LIGHT))
|
|
#define _MULTIPLE_LIGHTS
|
|
#endif
|
|
|
|
#ifdef _SPECULAR_SETUP
|
|
#define SAMPLE_METALLICSPECULAR(uv) tex2D(_SpecGlossMap, uv)
|
|
#else
|
|
#define SAMPLE_METALLICSPECULAR(uv) tex2D(_MetallicGlossMap, uv)
|
|
#endif
|
|
|
|
#if defined(UNITY_COLORSPACE_GAMMA) && defined(_LIGHTWEIGHT_FORCE_LINEAR)
|
|
// Ideally we want an approximation of gamma curve 2.0 to save ALU on GPU but as off now it won't match the GammaToLinear conversion of props in engine
|
|
#define LIGHTWEIGHT_GAMMA_TO_LINEAR(gammaColor) gammaColor * gammaColor
|
|
#define LIGHTWEIGHT_LINEAR_TO_GAMMA(linColor) sqrt(color)
|
|
//#define LIGHTWEIGHT_GAMMA_TO_LINEAR(sRGB) sRGB * (sRGB * (sRGB * 0.305306011h + 0.682171111h) + 0.012522878h)
|
|
//#define LIGHTWEIGHT_LINEAR_TO_GAMMA(linRGB) max(1.055h * pow(max(linRGB, 0.h), 0.416666667h) - 0.055h, 0.h)
|
|
#else
|
|
#define LIGHTWEIGHT_GAMMA_TO_LINEAR(color) color
|
|
#define LIGHTWEIGHT_LINEAR_TO_GAMMA(color) color
|
|
#endif
|
|
|
|
|
|
struct LightInput
|
|
{
|
|
float4 pos;
|
|
half4 color;
|
|
float4 atten;
|
|
half4 spotDir;
|
|
};
|
|
|
|
sampler2D _AttenuationTexture;
|
|
|
|
// Per object light list data
|
|
#ifdef _MULTIPLE_LIGHTS
|
|
half4 unity_LightIndicesOffsetAndCount;
|
|
half4 unity_4LightIndices0;
|
|
|
|
// The variables are very similar to built-in unity_LightColor, unity_LightPosition,
|
|
// unity_LightAtten, unity_SpotDirection as used by the VertexLit shaders, except here
|
|
// we use world space positions instead of view space.
|
|
half4 globalLightCount;
|
|
half4 globalLightColor[MAX_VISIBLE_LIGHTS];
|
|
float4 globalLightPos[MAX_VISIBLE_LIGHTS];
|
|
half4 globalLightSpotDir[MAX_VISIBLE_LIGHTS];
|
|
float4 globalLightAtten[MAX_VISIBLE_LIGHTS];
|
|
#else
|
|
float4 _LightPosition;
|
|
half4 _LightColor;
|
|
float4 _LightAttenuationParams;
|
|
half4 _LightSpotDir;
|
|
#endif
|
|
|
|
half _Shininess;
|
|
half4 _GlossyEnvironmentColor;
|
|
|
|
struct LightweightVertexInput
|
|
{
|
|
float4 vertex : POSITION;
|
|
float3 normal : NORMAL;
|
|
float4 tangent : TANGENT;
|
|
float2 texcoord : TEXCOORD0;
|
|
float2 lightmapUV : TEXCOORD1;
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
};
|
|
|
|
struct LightweightVertexOutput
|
|
{
|
|
float4 uv01 : TEXCOORD0; // uv01.xy: uv0, uv01.zw: uv1
|
|
float4 posWS : TEXCOORD1;
|
|
#if _NORMALMAP
|
|
half3 tangentToWorld0 : TEXCOORD2; // tangentToWorld matrix
|
|
half3 tangentToWorld1 : TEXCOORD3; // tangentToWorld matrix
|
|
half3 tangentToWorld2 : TEXCOORD4; // tangentToWorld matrix
|
|
#else
|
|
half3 normal : TEXCOORD2;
|
|
#endif
|
|
half4 viewDir : TEXCOORD5; // xyz: viewDir
|
|
half4 fogCoord : TEXCOORD6; // x: fogCoord, yzw: vertexColor
|
|
float4 hpos : SV_POSITION;
|
|
UNITY_VERTEX_OUTPUT_STEREO
|
|
};
|
|
|
|
struct SurfaceData
|
|
{
|
|
half3 albedo;
|
|
half alpha;
|
|
half4 metallicSpecGloss;
|
|
half3 normalWorld;
|
|
half ao;
|
|
half3 emission;
|
|
};
|
|
|
|
struct BRDFData
|
|
{
|
|
half3 diffuse;
|
|
half3 specular;
|
|
half perceptualRoughness;
|
|
half roughness;
|
|
half grazingTerm;
|
|
};
|
|
|
|
inline half Alpha(half albedoAlpha)
|
|
{
|
|
#if defined(_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A)
|
|
half alpha = _Color.a;
|
|
#else
|
|
half alpha = albedoAlpha * _Color.a;
|
|
#endif
|
|
|
|
#if defined(_ALPHATEST_ON)
|
|
clip(alpha - _Cutoff);
|
|
#endif
|
|
|
|
return alpha;
|
|
}
|
|
|
|
inline half3 Normal(LightweightVertexOutput i)
|
|
{
|
|
#if _NORMALMAP
|
|
half3 normalTangent = UnpackNormal(tex2D(_BumpMap, i.uv01.xy));
|
|
|
|
// glsl compiler will generate underperforming code by using a row-major pre multiplication matrix: mul(normalmap, i.tangentToWorld)
|
|
// i.tangetToWorld was initialized as column-major in vs and here dot'ing individual for better performance.
|
|
// The code below is similar to post multiply: mul(i.tangentToWorld, normalmap)
|
|
half3 normalWorld = normalize(half3(dot(normalTangent, i.tangentToWorld0), dot(normalTangent, i.tangentToWorld1), dot(normalTangent, i.tangentToWorld2)));
|
|
#else
|
|
half3 normalWorld = normalize(i.normal);
|
|
#endif
|
|
|
|
return normalWorld;
|
|
}
|
|
|
|
inline void SpecularGloss(half2 uv, half alpha, out half4 specularGloss)
|
|
{
|
|
specularGloss = half4(0, 0, 0, 1);
|
|
#ifdef _SPECGLOSSMAP
|
|
specularGloss = tex2D(_SpecGlossMap, uv);
|
|
specularGloss.rgb = LIGHTWEIGHT_GAMMA_TO_LINEAR(specularGloss.rgb);
|
|
#elif defined(_SPECULAR_COLOR)
|
|
specularGloss = _SpecColor;
|
|
#endif
|
|
|
|
#ifdef _GLOSSINESS_FROM_BASE_ALPHA
|
|
specularGloss.a = alpha;
|
|
#endif
|
|
}
|
|
|
|
half4 MetallicSpecGloss(float2 uv, half albedoAlpha)
|
|
{
|
|
half4 specGloss;
|
|
|
|
#ifdef _METALLICSPECGLOSSMAP
|
|
specGloss = specGloss = SAMPLE_METALLICSPECULAR(uv);
|
|
#ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
|
|
specGloss.a = albedoAlpha * _GlossMapScale;
|
|
#else
|
|
specGloss.a *= _GlossMapScale;
|
|
#endif
|
|
|
|
#else // _METALLICSPECGLOSSMAP
|
|
#if _METALLIC_SETUP
|
|
specGloss.rgb = _Metallic.rrr;
|
|
#else
|
|
specGloss.rgb = _SpecColor.rgb;
|
|
#endif
|
|
|
|
#ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
|
|
specGloss.a = albedoAlpha * _GlossMapScale;
|
|
#else
|
|
specGloss.a = _Glossiness;
|
|
#endif
|
|
#endif
|
|
|
|
return specGloss;
|
|
}
|
|
|
|
half OcclusionLW(float2 uv)
|
|
{
|
|
#ifdef _OCCLUSIONMAP
|
|
#if (SHADER_TARGET < 30)
|
|
// SM20: instruction count limitation
|
|
// SM20: simpler occlusion
|
|
return tex2D(_OcclusionMap, uv).g;
|
|
#else
|
|
half occ = tex2D(_OcclusionMap, uv).g;
|
|
return LerpOneTo(occ, _OcclusionStrength);
|
|
#endif
|
|
#else
|
|
return 1.0;
|
|
#endif
|
|
}
|
|
|
|
half3 EmissionLW(float2 uv)
|
|
{
|
|
#ifndef _EMISSION
|
|
return 0;
|
|
#else
|
|
return LIGHTWEIGHT_GAMMA_TO_LINEAR(tex2D(_EmissionMap, uv).rgb) * _EmissionColor.rgb;
|
|
#endif
|
|
}
|
|
|
|
#endif
|