static void InitializeShadowData(LightweightRenderPipelineAsset settings, NativeArray <VisibleLight> visibleLights, bool mainLightCastShadows, bool additionalLightsCastShadows, out ShadowData shadowData) { m_ShadowBiasData.Clear(); for (int i = 0; i < visibleLights.Length; ++i) { Light light = visibleLights[i].light; LWRPAdditionalLightData data = (light != null) ? light.gameObject.GetComponent <LWRPAdditionalLightData>() : null; if (data && !data.usePipelineSettings) { m_ShadowBiasData.Add(new Vector4(light.shadowBias, light.shadowNormalBias, 0.0f, 0.0f)); } else { m_ShadowBiasData.Add(new Vector4(settings.shadowDepthBias, settings.shadowNormalBias, 0.0f, 0.0f)); } } shadowData.bias = m_ShadowBiasData; // Until we can have keyword stripping forcing single cascade hard shadows on gles2 bool supportsScreenSpaceShadows = SystemInfo.graphicsDeviceType != GraphicsDeviceType.OpenGLES2; //seongdae;vxsm // compute shader for screen space shadows. // todo : need to fix retransform for world space in screen space on OpenGLES3.1 bool supportsComputeScreenSpaceShadows = SystemInfo.graphicsDeviceType != GraphicsDeviceType.OpenGLES2 && SystemInfo.graphicsDeviceType != GraphicsDeviceType.OpenGLES3; //seongdae;vxsm shadowData.supportsMainLightShadows = settings.supportsMainLightShadows && mainLightCastShadows; shadowData.supportsMainLightVxShadows = settings.supportsVxShadows && mainLightCastShadows; //seongdae;vxsm // we resolve shadows in screenspace when cascades are enabled to save ALU as computing cascade index + shadowCoord on fragment is expensive shadowData.requiresScreenSpaceShadowResolve = shadowData.supportsMainLightShadows && supportsScreenSpaceShadows && settings.shadowCascadeOption != ShadowCascadesOption.NoCascades; shadowData.requiresScreenSpaceShadowCompute = shadowData.supportsMainLightVxShadows && supportsComputeScreenSpaceShadows; //seongdae;vxsm int shadowCascadesCount; switch (settings.shadowCascadeOption) { case ShadowCascadesOption.FourCascades: shadowCascadesCount = 4; break; case ShadowCascadesOption.TwoCascades: shadowCascadesCount = 2; break; default: shadowCascadesCount = 1; break; } shadowData.mainLightShadowCascadesCount = (shadowData.requiresScreenSpaceShadowResolve) ? shadowCascadesCount : 1; shadowData.mainLightShadowmapWidth = settings.mainLightShadowmapResolution; shadowData.mainLightShadowmapHeight = settings.mainLightShadowmapResolution; switch (shadowData.mainLightShadowCascadesCount) { case 1: shadowData.mainLightShadowCascadesSplit = new Vector3(1.0f, 0.0f, 0.0f); break; case 2: shadowData.mainLightShadowCascadesSplit = new Vector3(settings.cascade2Split, 1.0f, 0.0f); break; default: shadowData.mainLightShadowCascadesSplit = settings.cascade4Split; break; } //seongdae;vxsm if (shadowData.supportsMainLightShadows && settings.supportsVxShadows) { int mainLightIndex = GetMainLightIndex(settings, visibleLights); var mainLight = visibleLights[mainLightIndex].light; var dirVxShadowMap = mainLight.GetComponent <DirectionalVxShadowMap>(); bool dirVxShadowMapIsValid = dirVxShadowMap != null && dirVxShadowMap.IsValid(); shadowData.requiresScreenSpaceShadowCompute = dirVxShadowMapIsValid; shadowData.mainLightVxShadowQuality = (int)settings.vxShadowsQuality; } else { shadowData.requiresScreenSpaceShadowCompute = false; shadowData.mainLightVxShadowQuality = 0; } //seongdae;vxsm shadowData.supportsAdditionalLightShadows = settings.supportsAdditionalLightShadows && additionalLightsCastShadows; shadowData.additionalLightsShadowmapWidth = shadowData.additionalLightsShadowmapHeight = settings.additionalLightsShadowmapResolution; shadowData.supportsSoftShadows = settings.supportsSoftShadows && (shadowData.supportsMainLightShadows || shadowData.supportsAdditionalLightShadows); shadowData.shadowmapDepthBufferBits = 16; }
static void InitializeShadowData(LightweightRenderPipelineAsset settings, NativeArray <VisibleLight> visibleLights, bool mainLightCastShadows, bool additionalLightsCastShadows, out ShadowData shadowData) { m_ShadowBiasData.Clear(); for (int i = 0; i < visibleLights.Length; ++i) { Light light = visibleLights[i].light; LWRPAdditionalLightData data = (light != null) ? light.gameObject.GetComponent <LWRPAdditionalLightData>() : null; if (data && !data.usePipelineSettings) { m_ShadowBiasData.Add(new Vector4(light.shadowBias, light.shadowNormalBias, 0.0f, 0.0f)); } else { m_ShadowBiasData.Add(new Vector4(settings.shadowDepthBias, settings.shadowNormalBias, 0.0f, 0.0f)); } } shadowData.bias = m_ShadowBiasData; // Until we can have keyword stripping forcing single cascade hard shadows on gles2 bool supportsScreenSpaceShadows = SystemInfo.graphicsDeviceType != GraphicsDeviceType.OpenGLES2; shadowData.supportsMainLightShadows = settings.supportsMainLightShadows && mainLightCastShadows; // we resolve shadows in screenspace when cascades are enabled to save ALU as computing cascade index + shadowCoord on fragment is expensive shadowData.requiresScreenSpaceShadowResolve = false; int shadowCascadesCount; switch (settings.shadowCascadeOption) { case ShadowCascadesOption.FourCascades: shadowCascadesCount = 4; break; case ShadowCascadesOption.TwoCascades: shadowCascadesCount = 2; break; default: shadowCascadesCount = 1; break; } shadowData.mainLightShadowCascadesCount = shadowCascadesCount; shadowData.mainLightShadowmapWidth = settings.mainLightShadowmapResolution; shadowData.mainLightShadowmapHeight = settings.mainLightShadowmapResolution; switch (shadowData.mainLightShadowCascadesCount) { case 1: shadowData.mainLightShadowCascadesSplit = new Vector3(1.0f, 0.0f, 0.0f); break; case 2: shadowData.mainLightShadowCascadesSplit = new Vector3(settings.cascade2Split, 1.0f, 0.0f); break; default: shadowData.mainLightShadowCascadesSplit = settings.cascade4Split; break; } shadowData.supportsAdditionalLightShadows = settings.supportsAdditionalLightShadows && additionalLightsCastShadows; shadowData.additionalLightsShadowmapWidth = shadowData.additionalLightsShadowmapHeight = settings.additionalLightsShadowmapResolution; shadowData.supportsSoftShadows = settings.supportsSoftShadows && (shadowData.supportsMainLightShadows || shadowData.supportsAdditionalLightShadows); shadowData.shadowmapDepthBufferBits = 16; }
void InitializeLightConstants(NativeArray <VisibleLight> lights, int lightIndex, out Vector4 lightPos, out Vector4 lightColor, out Vector4 lightAttenuation, out Vector4 lightSpotDir, out LightCookie cookie) { lightPos = k_DefaultLightPosition; lightColor = k_DefaultLightColor; lightAttenuation = k_DefaultLightAttenuation; lightSpotDir = k_DefaultLightSpotDirection; cookie = null; // When no lights are visible, main light will be set to -1. // In this case we initialize it to default values and return if (lightIndex < 0) { return; } VisibleLight lightData = lights[lightIndex]; if (lightData.lightType == LightType.Directional) { Vector4 dir = -lightData.localToWorldMatrix.GetColumn(2); lightPos = new Vector4(dir.x, dir.y, dir.z, 1.0f); } else { Vector4 pos = lightData.localToWorldMatrix.GetColumn(3); lightPos = new Vector4(pos.x, pos.y, pos.z, 1.0f); } // VisibleLight.finalColor already returns color in active color space lightColor = lightData.finalColor; // Directional Light attenuation is initialize so distance attenuation always be 1.0 if (lightData.lightType != LightType.Directional) { // Light attenuation in lightweight matches the unity vanilla one. // attenuation = 1.0 / distanceToLightSqr // We offer two different smoothing factors. // The smoothing factors make sure that the light intensity is zero at the light range limit. // The first smoothing factor is a linear fade starting at 80 % of the light range. // smoothFactor = (lightRangeSqr - distanceToLightSqr) / (lightRangeSqr - fadeStartDistanceSqr) // We rewrite smoothFactor to be able to pre compute the constant terms below and apply the smooth factor // with one MAD instruction // smoothFactor = distanceSqr * (1.0 / (fadeDistanceSqr - lightRangeSqr)) + (-lightRangeSqr / (fadeDistanceSqr - lightRangeSqr) // distanceSqr * oneOverFadeRangeSqr + lightRangeSqrOverFadeRangeSqr // The other smoothing factor matches the one used in the Unity lightmapper but is slower than the linear one. // smoothFactor = (1.0 - saturate((distanceSqr * 1.0 / lightrangeSqr)^2))^2 float lightRangeSqr = lightData.range * lightData.range; float fadeStartDistanceSqr = 0.8f * 0.8f * lightRangeSqr; float fadeRangeSqr = (fadeStartDistanceSqr - lightRangeSqr); float oneOverFadeRangeSqr = 1.0f / fadeRangeSqr; float lightRangeSqrOverFadeRangeSqr = -lightRangeSqr / fadeRangeSqr; float oneOverLightRangeSqr = 1.0f / Mathf.Max(0.0001f, lightData.range * lightData.range); // On mobile: Use the faster linear smoothing factor. // On other devices: Use the smoothing factor that matches the GI. lightAttenuation.x = Application.isMobilePlatform ? oneOverFadeRangeSqr : oneOverLightRangeSqr; lightAttenuation.y = lightRangeSqrOverFadeRangeSqr; } if (lightData.lightType == LightType.Spot) { Vector4 dir = lightData.localToWorldMatrix.GetColumn(2); lightSpotDir = new Vector4(-dir.x, -dir.y, -dir.z, 0.0f); // Spot Attenuation with a linear falloff can be defined as // (SdotL - cosOuterAngle) / (cosInnerAngle - cosOuterAngle) // This can be rewritten as // invAngleRange = 1.0 / (cosInnerAngle - cosOuterAngle) // SdotL * invAngleRange + (-cosOuterAngle * invAngleRange) // If we precompute the terms in a MAD instruction float cosOuterAngle = Mathf.Cos(Mathf.Deg2Rad * lightData.spotAngle * 0.5f); // We neeed to do a null check for particle lights // This should be changed in the future // Particle lights will use an inline function float cosInnerAngle; if (lightData.light != null) { cosInnerAngle = Mathf.Cos(LightmapperUtils.ExtractInnerCone(lightData.light) * 0.5f); } else { cosInnerAngle = Mathf.Cos((2.0f * Mathf.Atan(Mathf.Tan(lightData.spotAngle * 0.5f * Mathf.Deg2Rad) * (64.0f - 18.0f) / 64.0f)) * 0.5f); } float smoothAngleRange = Mathf.Max(0.001f, cosInnerAngle - cosOuterAngle); float invAngleRange = 1.0f / smoothAngleRange; float add = -cosOuterAngle * invAngleRange; lightAttenuation.z = invAngleRange; lightAttenuation.w = add; } Light light = lightData.light; Texture lightTex = light.cookie; LWRPAdditionalLightData data = light.gameObject.GetComponent <LWRPAdditionalLightData>(); if (lightTex && data) { cookie = new LightCookie { Tex = lightTex, LightMat = light.transform.worldToLocalMatrix, CookieSize = light.cookieSize, Falloff = data.lightCookieFalloff, cookieColor = data.lightCookieColor, }; } if (light != null && light.bakingOutput.mixedLightingMode == MixedLightingMode.Subtractive && light.bakingOutput.lightmapBakeType == LightmapBakeType.Mixed) { if (m_MixedLightingSetup == MixedLightingSetup.None && lightData.light.shadows != LightShadows.None) { m_MixedLightingSetup = MixedLightingSetup.Subtractive; } } }