浏览代码

Added multiple lights support to LightweightStandardShader.

/RenderPassXR_Sandbox
Felipe Lira 7 年前
当前提交
56be11e4
共有 4 个文件被更改,包括 84 次插入89 次删除
  1. 15
      Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPipeline.shader
  2. 27
      Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPipelineInput.cginc
  3. 2
      Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPipelineShadows.cginc
  4. 129
      Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightStandardShader.shader

15
Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPipeline.shader


#include "LightweightPipelineCore.cginc"
#include "LightweightPipelineLighting.cginc"
LightweightVertexOutputSimple vert(LightweightVertexInput v)
LightweightVertexOutput vert(LightweightVertexInput v)
LightweightVertexOutputSimple o = (LightweightVertexOutputSimple)0;
LightweightVertexOutput o = (LightweightVertexOutput)0;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);

o.hpos = UnityObjectToClipPos(v.vertex);
float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
o.posWS = worldPos;
o.posWS.xyz = worldPos;
o.viewDir.xyz = normalize(_WorldSpaceCameraPos - o.posWS);
o.viewDir.xyz = normalize(_WorldSpaceCameraPos - worldPos);
half3 normal = normalize(UnityObjectToWorldNormal(v.normal));
#if _NORMALMAP

return o;
}
half4 frag(LightweightVertexOutputSimple i) : SV_Target
half4 frag(LightweightVertexOutput i) : SV_Target
{
half4 diffuseAlpha = tex2D(_MainTex, i.uv01.xy);
half3 diffuse = LIGHTWEIGHT_GAMMA_TO_LINEAR(diffuseAlpha.rgb) * _Color.rgb;

SpecularGloss(i.uv01.xy, alpha, specularGloss);
half3 viewDir = i.viewDir.xyz;
float3 worldPos = i.posWS.xyz;
half3 lightDirection;

half lightAtten = ComputeLightAttenuation(lightInput, normal, i.posWS, lightDirection);
half lightAtten = ComputeLightAttenuation(lightInput, normal, worldPos, lightDirection);
#ifdef _SHADOWS
lightAtten *= ComputeShadowAttenuation(i, _ShadowLightDirection.xyz);
#endif

LightInput lightData;
int lightIndex = unity_4LightIndices0[lightIter];
INITIALIZE_LIGHT(lightData, lightIndex);
half lightAtten = ComputeLightAttenuation(lightData, normal, i.posWS, lightDirection);
half lightAtten = ComputeLightAttenuation(lightData, normal, worldPos, lightDirection);
#ifdef _SHADOWS
lightAtten *= max(shadowAttenuation, half(lightIter != _ShadowData.x));
#endif

27
Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPipelineInput.cginc


UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct LightweightVertexOutputSimple
struct LightweightVertexOutput
float3 posWS : TEXCOORD1;
float4 posWS : TEXCOORD1;
#if _NORMALMAP
half3 tangentToWorld0 : TEXCOORD2; // tangentToWorld matrix
half3 tangentToWorld1 : TEXCOORD3; // tangentToWorld matrix

UNITY_VERTEX_OUTPUT_STEREO
};
struct LightweightVertexOutput
{
UNITY_POSITION(pos);
float4 uv01 : TEXCOORD0;
half4 eyeVec : TEXCOORD1; // w: grazingTerm
//SHADOW_COORDS(2)
half4 fogCoord : TEXCOORD3;
half4 normalWorld : TEXCOORD4;
#ifdef _NORMALMAP
half3 tangentSpaceLightDir : TEXCOORD5;
#if SPECULAR_HIGHLIGHTS
half3 tangentSpaceEyeVec : TEXCOORD6;
#endif
#endif
UNITY_VERTEX_OUTPUT_STEREO
};
inline void NormalMap(LightweightVertexOutputSimple i, out half3 normal)
inline void NormalMap(LightweightVertexOutput i, out half3 normal)
{
#if _NORMALMAP
half3 normalmap = UnpackNormal(tex2D(_BumpMap, i.uv01.xy));

2
Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPipelineShadows.cginc


return attenuation * 0.25;
}
inline half ComputeShadowAttenuation(LightweightVertexOutputSimple i, half3 shadowDir)
inline half ComputeShadowAttenuation(LightweightVertexOutput i, half3 shadowDir)
{
#if _NORMALMAP
half3 vertexNormal = half3(i.tangentToWorld0.z, i.tangentToWorld1.z, i.tangentToWorld2.z);

129
Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightStandardShader.shader


#pragma shader_feature _ _GLOSSYREFLECTIONS_OFF
#pragma shader_feature _PARALLAXMAP
#pragma multi_compile _ _SINGLE_DIRECTIONAL_LIGHT
#pragma multi_compile _ _SINGLE_DIRECTIONAL_LIGHT _SINGLE_SPOT_LIGHT _SINGLE_POINT_LIGHT
#pragma multi_compile _ LIGHTWEIGHT_LINEAR
#pragma multi_compile _ UNITY_SINGLE_PASS_STEREO STEREO_INSTANCING_ON STEREO_MULTIVIEW_ON
#pragma multi_compile _ _SINGLE_DIRECTIONAL_LIGHT

LightweightVertexOutput LightweightVertex(LightweightVertexInput v)
{
UNITY_SETUP_INSTANCE_ID(v);
UNITY_SETUP_INSTANCE_ID(v);
float4 posWorld = mul(unity_ObjectToWorld, v.vertex);
o.pos = UnityObjectToClipPos(v.vertex);
#ifdef LIGHTMAP_ON
o.uv01.zw = v.lightmapUV * unity_LightmapST.xy + unity_LightmapST.zw;
#endif
o.hpos = UnityObjectToClipPos(v.vertex);
#ifdef LIGHTMAP_ON
o.uv01.zw = v.lightmapUV * unity_LightmapST.xy + unityLightmapST.wz;
float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
o.posWS.xyz = worldPos;
half3 viewDir = normalize(_WorldSpaceCameraPos - worldPos);
o.viewDir.xyz = viewDir;
#ifndef _METALLICGLOSSMAP
o.viewDir.w = saturate(_Glossiness + MetallicSetup_Reflectivity()); // grazing term
half3 eyeVec = normalize(_WorldSpaceCameraPos - posWorld.xyz);
half3 normalWorld = UnityObjectToWorldNormal(v.normal);
half3 normal = normalize(UnityObjectToWorldNormal(v.normal));
o.normalWorld.xyz = normalWorld;
o.eyeVec.xyz = eyeVec;
#if _NORMALMAP
half sign = v.tangent.w * unity_WorldTransformParams.w;
half3 tangent = normalize(UnityObjectToWorldDir(v.tangent));
half3 binormal = cross(normal, tangent) * v.tangent.w;
#ifdef _NORMALMAP
half3 tangentSpaceEyeVec;
TangentSpaceLightingInput(normalWorld, v.tangent, _WorldSpaceLightPos0.xyz, eyeVec, o.tangentSpaceLightDir, tangentSpaceEyeVec);
#if SPECULAR_HIGHLIGHTS
o.tangentSpaceEyeVec = tangentSpaceEyeVec;
// Initialize tangetToWorld in column-major to benefit from better glsl matrix multiplication code
o.tangentToWorld0 = half3(tangent.x, binormal.x, normal.x);
o.tangentToWorld1 = half3(tangent.y, binormal.y, normal.y);
o.tangentToWorld2 = half3(tangent.z, binormal.z, normal.z);
#else
o.normal = normal;
#endif
// TODO:
//TRANSFER_SHADOW(o);
o.posWS.w = Pow4(1 - saturate(dot(normal, viewDir))); // fresnel term
o.fogCoord.yzw += max(half3(0, 0, 0), ShadeSH9(half4(normalWorld, 1)));
#endif
o.normalWorld.w = Pow4(1 - saturate(dot(normalWorld, eyeVec))); // fresnel term
#if !GLOSSMAP
o.eyeVec.w = saturate(_Glossiness + MetallicSetup_Reflectivity()); // grazing term
o.fogCoord.yzw += max(half3(0, 0, 0), ShadeSH9(half4(normal, 1)));
UNITY_TRANSFER_FOG(o, o.pos);
UNITY_TRANSFER_FOG(o, o.hpos);
return o;
}

half oneMinusReflectivity;
half3 specColor;
half3 diffColor = DiffuseAndSpecularFromMetallic(albedo, metallicGloss.x, /*out*/ specColor, /*out*/ oneMinusReflectivity);
#if defined(_NORMALMAP)
half3 tangentSpaceNormal = NormalInTangentSpace(i.uv01.xy);
half3 reflectVec = reflect(-i.tangentSpaceEyeVec, tangentSpaceNormal);
#else
half3 reflectVec = reflect(-i.eyeVec, i.normalWorld.xyz);
#endif
half3 diffColor = DiffuseAndSpecularFromMetallic(albedo, metallicGloss.x, specColor, oneMinusReflectivity);
half3 normal;
NormalMap(i, normal);
half3 reflectVec = reflect(-i.viewDir.xyz, normal);
#if GLOSSMAP
#ifdef _METALLICGLOSSMAP
#else
half grazingTerm = i.eyeVec.w;
#endif
half perVertexFresnelTerm = i.normalWorld.w;
#else
half grazingTerm = i.viewDir.w;
#endif
half perVertexFresnelTerm = i.posWS.w;
half3 lightDirection;
// TODO: SPOT & POINT keywords
#ifdef _SINGLE_DIRECTIONAL_LIGHT
UnityLight mainLight;
mainLight.color = _LightColor.rgb;
mainLight.dir = _LightPosition.xyz;
#ifndef _MULTIPLE_LIGHTS
LightInput light;
INITIALIZE_MAIN_LIGHT(light);
half lightAtten = ComputeLightAttenuation(light, normal, i.posWS.xyz, lightDirection);
#if defined(_NORMALMAP)
half NdotL = saturate(dot(s.tangentSpaceNormal, i.tangentSpaceLightDir));
#else
half NdotL = saturate(dot(i.normalWorld.xyz, mainLight.dir));
#endif
#ifdef _SHADOWS
lightAtten *= ComputeShadowAttenuation(i, _ShadowLightDirection.xyz);
#endif
// TODO: Atten/Shadow
half atten = 1;
half RdotL = dot(reflectVec, mainLight.dir);
half3 attenuatedLightColor = mainLight.color * NdotL;
half NdotL = saturate(dot(normal, lightDirection));
half RdotL = saturate(dot(reflectVec, lightDirection));
half3 attenuatedLightColor = light.color * (NdotL * lightAtten);
#else
// TODO: LIGHTLOOP
color = half3(0, 1, 0);
#endif
#else
#ifdef _SHADOWS
half shadowAttenuation = ComputeShadowAttenuation(i, _ShadowLightDirection.xyz);
#endif
int pixelLightCount = min(globalLightCount.x, unity_LightIndicesOffsetAndCount.y);
for (int lightIter = 0; lightIter < pixelLightCount; ++lightIter)
{
LightInput light;
int lightIndex = unity_4LightIndices0[lightIter];
INITIALIZE_LIGHT(light, lightIndex);
half lightAtten = ComputeLightAttenuation(light, normal, i.posWS.xyz, lightDirection);
#ifdef _SHADOWS
lightAtten *= max(shadowAttenuation, half(lightIter != _ShadowData.x));
#endif
half NdotL = saturate(dot(normal, lightDirection));
half RdotL = saturate(dot(reflectVec, lightDirection));
half3 attenuatedLightColor = light.color * (NdotL * lightAtten);
color += LightweightBRDFDirect(diffColor, specColor, smoothness, RdotL) * attenuatedLightColor;
}
#endif
color += Emission(uv);
UNITY_APPLY_FOG(i.fogCoord, color);

正在加载...
取消
保存