您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
226 行
7.8 KiB
226 行
7.8 KiB
#ifndef LIGHTWEIGHT_PASS_LIT_INCLUDED
|
|
#define LIGHTWEIGHT_PASS_LIT_INCLUDED
|
|
|
|
#include "LightweightLighting.cginc"
|
|
|
|
struct LightweightVertexInput
|
|
{
|
|
float4 vertex : POSITION;
|
|
float3 normal : NORMAL;
|
|
float4 tangent : TANGENT;
|
|
float2 texcoord : TEXCOORD0;
|
|
float2 lightmapUV : TEXCOORD1;
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
};
|
|
|
|
struct LightweightVertexOutput
|
|
{
|
|
float2 uv : TEXCOORD0;
|
|
float4 ambientOrLightmapUV : TEXCOORD1; // xy: lightmapUV, zw: dynamicLightmapUV OR color from SH
|
|
float4 posWS : TEXCOORD2;
|
|
#if _NORMALMAP
|
|
half3 tangent : TEXCOORD3;
|
|
half3 binormal : TEXCOORD4;
|
|
half3 normal : TEXCOORD5;
|
|
#else
|
|
half3 normal : TEXCOORD3;
|
|
#endif
|
|
half4 viewDir : TEXCOORD6; // xyz: viewDir
|
|
half4 fogFactorAndVertexLight : TEXCOORD7; // x: fogFactor, yzw: vertex light
|
|
float4 clipPos : SV_POSITION;
|
|
UNITY_VERTEX_OUTPUT_STEREO
|
|
};
|
|
|
|
inline void InitializeStandardLitSurfaceData(LightweightVertexOutput IN, out SurfaceData outSurfaceData)
|
|
{
|
|
float2 uv = IN.uv;
|
|
half4 albedoAlpha = tex2D(_MainTex, uv);
|
|
|
|
half4 specGloss = MetallicSpecGloss(uv, albedoAlpha);
|
|
outSurfaceData.albedo = LIGHTWEIGHT_GAMMA_TO_LINEAR(albedoAlpha.rgb) * _Color.rgb;
|
|
|
|
#if _METALLIC_SETUP
|
|
outSurfaceData.metallic = specGloss.r;
|
|
outSurfaceData.specular = half3(0.0h, 0.0h, 0.0h);
|
|
#else
|
|
outSurfaceData.metallic = 1.0h;
|
|
outSurfaceData.specular = specGloss.rgb;
|
|
#endif
|
|
|
|
outSurfaceData.smoothness = specGloss.a;
|
|
outSurfaceData.normal = Normal(uv);
|
|
outSurfaceData.occlusion = OcclusionLW(uv);
|
|
outSurfaceData.emission = EmissionLW(uv);
|
|
outSurfaceData.emission += IN.fogFactorAndVertexLight.yzw;
|
|
outSurfaceData.alpha = Alpha(albedoAlpha.a);
|
|
}
|
|
|
|
void InitializeSurfaceInput(LightweightVertexOutput IN, out SurfaceInput outSurfaceInput)
|
|
{
|
|
#if LIGHTMAP_ON
|
|
outSurfaceInput.lightmapUV = float4(IN.ambientOrLightmapUV.xy, 0.0, 0.0);
|
|
#else
|
|
outSurfaceInput.lightmapUV = float4(0.0, 0.0, 0.0, 0.0);
|
|
#endif
|
|
|
|
#if _NORMALMAP
|
|
outSurfaceInput.tangentWS = IN.tangent;
|
|
outSurfaceInput.bitangentWS = IN.binormal;
|
|
#else
|
|
outSurfaceInput.tangentWS = half3(1.0h, 0.0h, 0.0h);
|
|
outSurfaceInput.bitangentWS = half3(0.0h, 1.0h, 0.0h);
|
|
#endif
|
|
|
|
outSurfaceInput.normalWS = IN.normal;
|
|
outSurfaceInput.positionWS = IN.posWS;
|
|
outSurfaceInput.viewDirectionWS = IN.viewDir;
|
|
outSurfaceInput.fogFactor = IN.fogFactorAndVertexLight.x;
|
|
}
|
|
|
|
LightweightVertexOutput LitPassVertex(LightweightVertexInput v)
|
|
{
|
|
LightweightVertexOutput o = (LightweightVertexOutput)0;
|
|
|
|
UNITY_SETUP_INSTANCE_ID(v);
|
|
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
|
|
|
|
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
|
|
|
|
float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
|
|
o.posWS.xyz = worldPos;
|
|
|
|
half3 viewDir = normalize(_WorldSpaceCameraPos - worldPos);
|
|
o.viewDir.xyz = viewDir;
|
|
|
|
half3 normal = normalize(UnityObjectToWorldNormal(v.normal));
|
|
|
|
#if _NORMALMAP
|
|
half sign = v.tangent.w * unity_WorldTransformParams.w;
|
|
o.tangent = normalize(mul((half3x3)unity_ObjectToWorld, v.tangent.xyz));
|
|
o.binormal = cross(normal, o.tangent) * sign;
|
|
o.normal = normal;
|
|
#else
|
|
o.normal = normal;
|
|
#endif
|
|
|
|
#ifdef LIGHTMAP_ON
|
|
o.ambientOrLightmapUV.xy = v.lightmapUV * unity_LightmapST.xy + unity_LightmapST.zw;
|
|
// TODO: Dynamic Lightmap
|
|
o.ambientOrLightmapUV.zw = float2(0.0, 0.0);
|
|
|
|
// TODO: Currently there's no way to pass in ambient contribution to fragmentPBR.
|
|
// We should allow to create custom ambient computation for things like SH evaluation, lightmap, ambient color etc.
|
|
//#else
|
|
// o.ambientOrLightmapUV = half4(SHEvalLinearL2(half4(normal, 1.0)), 0.0h);
|
|
#endif
|
|
|
|
o.fogFactorAndVertexLight.yzw = half3(0.0h, 0.0h, 0.0h);
|
|
#if defined(_VERTEX_LIGHTS)
|
|
half3 diffuse = half3(1.0, 1.0, 1.0);
|
|
int vertexLightStart = _AdditionalLightCount.x;
|
|
int vertexLightEnd = min(_AdditionalLightCount.y, unity_LightIndicesOffsetAndCount.y);
|
|
for (int lightIter = vertexLightStart; lightIter < vertexLightEnd; ++lightIter)
|
|
{
|
|
LightInput lightData;
|
|
INITIALIZE_LIGHT(lightData, lightIter);
|
|
|
|
half3 lightDirection;
|
|
half atten = ComputeVertexLightAttenuation(lightData, normal, worldPos, lightDirection);
|
|
o.fogFactorAndVertexLight.yzw += LightingLambert(diffuse, lightDirection, normal, atten) * lightData.color;
|
|
}
|
|
#endif
|
|
|
|
float4 clipPos = UnityObjectToClipPos(v.vertex);
|
|
o.fogFactorAndVertexLight.x = ComputeFogFactor(clipPos.z);
|
|
o.clipPos = clipPos;
|
|
return o;
|
|
}
|
|
|
|
half4 LitPassFragment(LightweightVertexOutput IN) : SV_Target
|
|
{
|
|
SurfaceData surfaceData;
|
|
InitializeStandardLitSurfaceData(IN, surfaceData);
|
|
|
|
SurfaceInput surfaceInput;
|
|
InitializeSurfaceInput(IN, surfaceInput);
|
|
|
|
return LightweightFragmentPBR(surfaceInput.lightmapUV, surfaceInput.positionWS, surfaceInput.normalWS, surfaceInput.tangentWS, surfaceInput.bitangentWS, surfaceInput.viewDirectionWS, surfaceInput.fogFactor, surfaceData.albedo, surfaceData.metallic, surfaceData.specular, surfaceData.smoothness, surfaceData.normal, surfaceData.occlusion, surfaceData.emission, surfaceData.alpha);
|
|
}
|
|
|
|
half4 LitPassFragmentSimple(LightweightVertexOutput IN) : SV_Target
|
|
{
|
|
float2 uv = IN.uv;
|
|
|
|
half4 diffuseAlpha = tex2D(_MainTex, uv);
|
|
half3 diffuse = LIGHTWEIGHT_GAMMA_TO_LINEAR(diffuseAlpha.rgb) * _Color.rgb;
|
|
|
|
#ifdef _GLOSSINESS_FROM_BASE_ALPHA
|
|
half alpha = _Color.a;
|
|
#else
|
|
half alpha = diffuseAlpha.a * _Color.a;
|
|
#endif
|
|
|
|
// Keep for compatibility reasons. Shader Inpector throws a warning when using cutoff
|
|
// due overdraw performance impact.
|
|
#ifdef _ALPHATEST_ON
|
|
clip(alpha - _Cutoff);
|
|
#endif
|
|
|
|
#if _NORMALMAP
|
|
half3 normalTangent = Normal(uv);
|
|
half3 normalWorld = TangentToWorldNormal(normalTangent, IN.tangent, IN.binormal, IN.normal);
|
|
#else
|
|
half3 normalWorld = normalize(IN.normal);
|
|
#endif
|
|
|
|
half4 specularGloss;
|
|
SpecularGloss(uv, alpha, specularGloss);
|
|
|
|
half3 viewDir = IN.viewDir.xyz;
|
|
float3 worldPos = IN.posWS.xyz;
|
|
|
|
half3 lightDirection;
|
|
|
|
#if defined(LIGHTMAP_ON)
|
|
half3 color = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, IN.ambientOrLightmapUV.xy)) * diffuse;
|
|
#else
|
|
half3 color = (ShadeSH9(half4(normalWorld, 1.0)) + IN.ambientOrLightmapUV.xyz) * diffuse;
|
|
#endif
|
|
|
|
LightInput lightInput;
|
|
INITIALIZE_MAIN_LIGHT(lightInput);
|
|
half lightAtten = ComputeMainLightAttenuation(lightInput, normalWorld, worldPos, lightDirection);
|
|
lightAtten *= LIGHTWEIGHT_SHADOW_ATTENUATION(worldPos, normalize(IN.normal), _ShadowLightDirection.xyz);
|
|
|
|
#if defined(_SPECGLOSSMAP) || defined(_SPECULAR_COLOR)
|
|
color += LightingBlinnPhong(diffuse, specularGloss, lightDirection, normalWorld, viewDir, lightAtten) * lightInput.color;
|
|
#else
|
|
color += LightingLambert(diffuse, lightDirection, normalWorld, lightAtten) * lightInput.color;
|
|
#endif
|
|
|
|
#ifdef _ADDITIONAL_LIGHTS
|
|
int pixelLightCount = min(_AdditionalLightCount.x, unity_LightIndicesOffsetAndCount.y);
|
|
for (int lightIter = 0; lightIter < pixelLightCount; ++lightIter)
|
|
{
|
|
LightInput lightData;
|
|
INITIALIZE_LIGHT(lightData, lightIter);
|
|
half lightAtten = ComputePixelLightAttenuation(lightData, normalWorld, worldPos, lightDirection);
|
|
|
|
#if defined(_SPECGLOSSMAP) || defined(_SPECULAR_COLOR)
|
|
color += LightingBlinnPhong(diffuse, specularGloss, lightDirection, normalWorld, viewDir, lightAtten) * lightData.color;
|
|
#else
|
|
color += LightingLambert(diffuse, lightDirection, normalWorld, lightAtten) * lightData.color;
|
|
#endif
|
|
}
|
|
|
|
#endif // _ADDITIONAL_LIGHTS
|
|
|
|
color += EmissionLW(uv);
|
|
color += IN.fogFactorAndVertexLight.yzw;
|
|
|
|
// Computes Fog Factor per vextex
|
|
ApplyFog(color, IN.fogFactorAndVertexLight.x);
|
|
return OutputColor(color, alpha);
|
|
};
|
|
|
|
#endif
|