浏览代码

Added support to directional light cookie.

/Add-support-for-light-specular-color-tint
Felipe Lira 7 年前
当前提交
8ea2f9d8
共有 7 个文件被更改,包括 60 次插入13 次删除
  1. 4
      ScriptableRenderPipeline/LightweightPipeline/LightweightConstantBuffer.cs
  2. 40
      ScriptableRenderPipeline/LightweightPipeline/LightweightPipeline.cs
  3. 17
      ScriptableRenderPipeline/LightweightPipeline/LightweightPipelineUtils.cs
  4. 7
      ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightLighting.cginc
  5. 1
      ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightStandard.shader
  6. 1
      ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightStandardSimpleLighting.shader
  7. 3
      ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightStandardTerrain.shader

4
ScriptableRenderPipeline/LightweightPipeline/LightweightConstantBuffer.cs


public static int _MainLightColor;
public static int _MainLightAttenuationParams;
public static int _MainLightSpotDir;
public static int _MainLightCookie;
public static int _WorldToLight;
public static int _AdditionalLightCount;
public static int _AdditionalLightPosition;

}
}
}

40
ScriptableRenderPipeline/LightweightPipeline/LightweightPipeline.cs


PerFrameBuffer._GlossyEnvironmentColor = Shader.PropertyToID("_GlossyEnvironmentColor");
PerFrameBuffer._AttenuationTexture = Shader.PropertyToID("_AttenuationTexture");
// Lights are culled per-camera. Therefore we need to reset light buffers on each camera render
PerCameraBuffer._MainLightCookie = Shader.PropertyToID("_MainLightCookie");
PerCameraBuffer._WorldToLight = Shader.PropertyToID("_WorldToLight");
PerCameraBuffer._AdditionalLightCount = Shader.PropertyToID("_AdditionalLightCount");
PerCameraBuffer._AdditionalLightPosition = Shader.PropertyToID("_AdditionalLightPosition");
PerCameraBuffer._AdditionalLightColor = Shader.PropertyToID("_AdditionalLightColor");

private void SetupShaderConstants(VisibleLight[] visibleLights, ref ScriptableRenderContext context, ref LightData lightData)
{
CommandBuffer cmd = CommandBufferPool.Get("SetupShaderConstants");
SetupShaderLightConstants(cmd, visibleLights, ref lightData, ref m_CullResults, ref context);
SetupShaderLightConstants(cmd, visibleLights, ref lightData);
SetShaderKeywords(cmd, ref lightData, visibleLights);
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);

lightData.shadowsRendered = false;
if (visibleLightsCount <= 1)
{
// If there's exactly one visible light that will be picked as main light.
// Otherwise we disable main light by setting its index to -1.
lightData.mainLightIndex = visibleLightsCount - 1;
lightData.mainLightIndex = GetMainLight(visibleLights);
lightData.pixelAdditionalLightsCount = 0;
lightData.totalAdditionalLightsCount = 0;
return;

{
int totalVisibleLights = visibleLights.Length;
bool shadowsEnabled = m_Asset.AreShadowsEnabled();
// Particle system lights have the light property as null. We sort lights so all particles lights
// come last. Therefore, if first light is particle light then all lights are particle lights.
// In this case we have no main light.
if (totalVisibleLights == 0 || visibleLights[0].light == null)
return -1;
// If shadows are supported and the first visible light has shadows then this is main light
if (shadowsEnabled && visibleLights[0].light.shadows != LightShadows.None)

CommandBufferPool.Release (cmd);
}
private void SetupShaderLightConstants(CommandBuffer cmd, VisibleLight[] lights, ref LightData lightData, ref CullResults cullResults, ref ScriptableRenderContext context)
private void SetupShaderLightConstants(CommandBuffer cmd, VisibleLight[] lights, ref LightData lightData)
SetupMainLightConstants(cmd, lights, lightData.mainLightIndex, ref context);
SetupMainLightConstants(cmd, lights, lightData.mainLightIndex);
SetupShadowShaderConstants(cmd, ref context, ref lights[lightData.mainLightIndex], m_ShadowCasterCascadesCount);
SetupShadowShaderConstants(cmd, ref lights[lightData.mainLightIndex], m_ShadowCasterCascadesCount);
SetupAdditionalListConstants(cmd, lights, ref lightData, ref context);
SetupAdditionalListConstants(cmd, lights, ref lightData);
private void SetupMainLightConstants(CommandBuffer cmd, VisibleLight[] lights, int lightIndex, ref ScriptableRenderContext context)
private void SetupMainLightConstants(CommandBuffer cmd, VisibleLight[] lights, int lightIndex)
{
Vector4 lightPos, lightColor, lightSpotDir, lightAttenuationParams;
InitializeLightConstants(lights, lightIndex, out lightPos, out lightColor, out lightSpotDir, out lightAttenuationParams);

cmd.SetGlobalVector(PerCameraBuffer._MainLightSpotDir, lightSpotDir);
cmd.SetGlobalVector(PerCameraBuffer._MainLightAttenuationParams, lightAttenuationParams);
if (lightIndex >= 0 && LightweightUtils.IsSupportedCookieType(lights[lightIndex].lightType) && lights[lightIndex].light.cookie != null)
{
Matrix4x4 lightCookieMatrix;
LightweightUtils.GetLightCookieMatrix(lights[lightIndex], out lightCookieMatrix);
cmd.SetGlobalTexture(PerCameraBuffer._MainLightCookie, lights[lightIndex].light.cookie);
cmd.SetGlobalMatrix(PerCameraBuffer._WorldToLight, lightCookieMatrix);
}
private void SetupAdditionalListConstants(CommandBuffer cmd, VisibleLight[] lights, ref LightData lightData, ref ScriptableRenderContext context)
private void SetupAdditionalListConstants(CommandBuffer cmd, VisibleLight[] lights, ref LightData lightData)
{
int additionalLightIndex = 0;

cmd.SetGlobalVectorArray (PerCameraBuffer._AdditionalLightSpotDir, m_LightSpotDirections);
}
private void SetupShadowShaderConstants(CommandBuffer cmd, ref ScriptableRenderContext context, ref VisibleLight shadowLight, int cascadeCount)
private void SetupShadowShaderConstants(CommandBuffer cmd, ref VisibleLight shadowLight, int cascadeCount)
{
Vector3 shadowLightDir = Vector3.Normalize(shadowLight.localToWorld.GetColumn(2));

LightweightUtils.SetKeyword(cmd, "_VERTEX_LIGHTS", vertexLightsCount > 0);
int mainLightIndex = lightData.mainLightIndex;
// Currently only directional light cookie is supported
LightweightUtils.SetKeyword(cmd, "_MAIN_LIGHT_COOKIE", mainLightIndex != -1 && LightweightUtils.IsSupportedCookieType(visibleLights[mainLightIndex].lightType) && visibleLights[mainLightIndex].light.cookie != null);
LightweightUtils.SetKeyword (cmd, "_MAIN_DIRECTIONAL_LIGHT", mainLightIndex == -1 || visibleLights[mainLightIndex].lightType == LightType.Directional);
LightweightUtils.SetKeyword (cmd, "_MAIN_SPOT_LIGHT", mainLightIndex != -1 && visibleLights[mainLightIndex].lightType == LightType.Spot);
LightweightUtils.SetKeyword (cmd, "_MAIN_POINT_LIGHT", mainLightIndex != -1 && visibleLights[mainLightIndex].lightType == LightType.Point);

17
ScriptableRenderPipeline/LightweightPipeline/LightweightPipelineUtils.cs


public static class LightweightUtils
{
public static void GetLightCookieMatrix(VisibleLight light, out Matrix4x4 cookieMatrix)
{
cookieMatrix = Matrix4x4.Inverse(light.localToWorld);
float scale = 1.0f / light.light.cookieSize;
// apply cookie scale and offset by 0.5 to convert from [-0.5, 0.5] to texture space [0, 1]
Vector4 row0 = cookieMatrix.GetRow(0);
Vector4 row1 = cookieMatrix.GetRow(1);
cookieMatrix.SetRow(0, new Vector4(row0.x * scale, row0.y * scale, row0.z * scale, row0.w * scale + 0.5f));
cookieMatrix.SetRow(1, new Vector4(row1.x * scale, row1.y * scale, row1.z * scale, row1.w * scale + 0.5f));
}
public static void SetKeyword(CommandBuffer cmd, string keyword, bool enable)
{
if (enable)

public static bool IsSupportedShadowType(LightType lightType)
{
return lightType == LightType.Directional || lightType == LightType.Spot;
}
public static bool IsSupportedCookieType(LightType lightType)
{
return lightType == LightType.Directional;
}
public static bool PlatformSupportsMSAABackBuffer()

7
ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightLighting.cginc


CBUFFER_END
CBUFFER_START(_PerCamera)
sampler2D _MainLightCookie;
float4x4 _WorldToLight;
half4 _AdditionalLightCount;
float4 _AdditionalLightPosition[MAX_VISIBLE_LIGHTS];

#ifdef _MAIN_DIRECTIONAL_LIGHT
// Light pos holds normalized light dir
lightDirection = lightInput.pos;
#ifdef _MAIN_LIGHT_COOKIE
float2 cookieUV = mul(_WorldToLight, float4(worldPos, 1.0)).xy;
return tex2D(_MainLightCookie, cookieUV).a;
#endif
return 1.0;
#else
return ComputePixelLightAttenuation(lightInput, normal, worldPos, lightDirection);

1
ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightStandard.shader


#pragma shader_feature _GLOSSYREFLECTIONS_OFF
#pragma shader_feature _SPECULAR_SETUP
#pragma multi_compile _ _MAIN_LIGHT_COOKIE
#pragma multi_compile _MAIN_DIRECTIONAL_LIGHT _MAIN_SPOT_LIGHT _MAIN_POINT_LIGHT
#pragma multi_compile _ _ADDITIONAL_LIGHTS
#pragma multi_compile _ UNITY_SINGLE_PASS_STEREO STEREO_INSTANCING_ON STEREO_MULTIVIEW_ON

1
ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightStandardSimpleLighting.shader


#pragma shader_feature _NORMALMAP
#pragma shader_feature _EMISSION
#pragma multi_compile _ _MAIN_LIGHT_COOKIE
#pragma multi_compile _MAIN_DIRECTIONAL_LIGHT _MAIN_SPOT_LIGHT _MAIN_POINT_LIGHT
#pragma multi_compile _ _ADDITIONAL_LIGHTS
#pragma multi_compile _ UNITY_SINGLE_PASS_STEREO STEREO_INSTANCING_ON STEREO_MULTIVIEW_ON

3
ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightStandardTerrain.shader


#pragma fragment SpatmapFragment
#include "LightweightLighting.cginc"
#pragma multi_compile _ _MAIN_LIGHT_COOKIE
#pragma multi_compile _MAIN_DIRECTIONAL_LIGHT _MAIN_SPOT_LIGHT _MAIN_POINT_LIGHT
#pragma multi_compile _ _ADDITIONAL_LIGHTS
#pragma multi_compile _ UNITY_SINGLE_PASS_STEREO STEREO_INSTANCING_ON STEREO_MULTIVIEW_ON

half3 viewDirectionWS = SafeNormalize(_WorldSpaceCameraPos - IN.positionWS);
half fogFactor = IN.fogFactorAndVertexLight.x;
half4 color = LightweightFragmentPBR(IN.positionWS, normalWS, viewDirectionWS, fogFactor, indirectDiffuse,
half4 color = LightweightFragmentPBR(IN.positionWS, normalWS, viewDirectionWS, fogFactor, indirectDiffuse,
IN.fogFactorAndVertexLight.yzw, albedo, metallic, specular, smoothness, /* occlusion */ 1.0, /* emission */ half3(0, 0, 0), alpha);
return color;
}

正在加载...
取消
保存