void SetupMainLightConstants(CommandBuffer cmd, ref LightData lightData) { Vector4 lightPos, lightColor, lightAttenuation, lightSpotDir; InitializeLightConstants(lightData.visibleLights, lightData.mainLightIndex, out lightPos, out lightColor, out lightAttenuation, out lightSpotDir); cmd.SetGlobalVector(LightConstantBuffer._MainLightPosition, lightPos); cmd.SetGlobalVector(LightConstantBuffer._MainLightColor, lightColor); }
void SetupShaderLightConstants(CommandBuffer cmd, ref LightData lightData) { // Clear to default all light constant data for (int i = 0; i < LightweightRenderPipeline.maxVisibleAdditionalLights; ++i) { InitializeLightConstants(lightData.visibleLights, -1, out m_AdditionalLightPositions[i], out m_AdditionalLightColors[i], out m_AdditionalLightAttenuations[i], out m_AdditionalLightSpotDirections[i]); } m_MixedLightingSetup = MixedLightingSetup.None; // Main light has an optimized shader path for main light. This will benefit games that only care about a single light. // Lightweight pipeline also supports only a single shadow light, if available it will be the main light. SetupMainLightConstants(cmd, ref lightData); SetupAdditionalLightConstants(cmd, ref lightData); }
void SetupPerObjectLightIndices(CullingResults cullResults, ref LightData lightData) { if (lightData.additionalLightsCount == 0) { return; } var visibleLights = lightData.visibleLights; var perObjectLightIndexMap = cullResults.GetLightIndexMap(Allocator.Temp); int directionalLightsCount = 0; int additionalLightsCount = 0; // Disable all directional lights from the perobject light indices // Pipeline handles them globally. for (int i = 0; i < visibleLights.Length; ++i) { if (additionalLightsCount >= LightweightRenderPipeline.maxVisibleAdditionalLights) { break; } VisibleLight light = visibleLights[i]; if (light.lightType == LightType.Directional) { perObjectLightIndexMap[i] = -1; ++directionalLightsCount; } else { perObjectLightIndexMap[i] -= directionalLightsCount; ++additionalLightsCount; } } // Disable all remaining lights we cannot fit into the global light buffer. for (int i = directionalLightsCount + additionalLightsCount; i < visibleLights.Length; ++i) { perObjectLightIndexMap[i] = -1; } cullResults.SetLightIndexMap(perObjectLightIndexMap); perObjectLightIndexMap.Dispose(); }
static void InitializeLightData(PipelineSettings settings, NativeArray <VisibleLight> visibleLights, int mainLightIndex, int maxAdditionalLights, int maxPerObjectAdditionalLights, out LightData lightData) { lightData.mainLightIndex = mainLightIndex; if (settings.additionalLightsRenderingMode != LightRenderingMode.Disabled) { lightData.additionalLightsCount = Math.Min((mainLightIndex != -1) ? visibleLights.Length - 1 : visibleLights.Length, maxAdditionalLights); lightData.maxPerObjectAdditionalLightsCount = Math.Min(settings.maxAdditionalLights, maxPerObjectAdditionalLights); } else { lightData.additionalLightsCount = 0; lightData.maxPerObjectAdditionalLightsCount = 0; } lightData.shadeAdditionalLightsPerVertex = settings.additionalLightsRenderingMode == LightRenderingMode.PerVertex; lightData.visibleLights = visibleLights; lightData.supportsMixedLighting = settings.mixedLightingSupported; }
void SetupMainLightConstants(CommandBuffer cmd, ref LightData lightData) { LightCookie lightcookie; Vector4 lightPos, lightColor, lightAttenuation, lightSpotDir; InitializeLightConstants(lightData.visibleLights, lightData.mainLightIndex, out lightPos, out lightColor, out lightAttenuation, out lightSpotDir, out lightcookie); cmd.SetGlobalVector(LightConstantBuffer._MainLightPosition, lightPos); cmd.SetGlobalVector(LightConstantBuffer._MainLightColor, lightColor); if (lightcookie != null) { cmd.EnableShaderKeyword("_LIGHTCOOKIE"); cmd.SetGlobalMatrix(LightConstantBuffer._MainLightLightMat, lightcookie.LightMat); cmd.SetGlobalFloat(LightConstantBuffer._MainLightCookieSize, lightcookie.CookieSize); cmd.SetGlobalTexture(LightConstantBuffer._MainlightCookie, lightcookie.Tex); cmd.SetGlobalFloat(LightConstantBuffer._MainLightCookieFalloff, lightcookie.Falloff); cmd.SetGlobalColor(LightConstantBuffer._MainLightCookieColor, lightcookie.cookieColor); } else { cmd.DisableShaderKeyword("_LIGHTCOOKIE"); } }
void SetupMainLightConstants(CommandBuffer cmd, ref RenderingData renderingData) { LightData lightData = renderingData.lightData; LightCookie lightcookie; Vector4 lightPos, lightColor, lightAttenuation, lightSpotDir; InitializeLightConstants(lightData.visibleLights, lightData.mainLightIndex, out lightPos, out lightColor, out lightAttenuation, out lightSpotDir, out lightcookie); cmd.SetGlobalVector(LightConstantBuffer._MainLightPosition, lightPos); cmd.SetGlobalVector(LightConstantBuffer._MainLightColor, lightColor); Camera cam = renderingData.cameraData.camera; Matrix4x4 projMatrix = GL.GetGPUProjectionMatrix(cam.projectionMatrix, false); Matrix4x4 viewMatrix = cam.worldToCameraMatrix; Matrix4x4 viewProjMatrix = projMatrix * viewMatrix; Vector4 input = new Vector4(lightcookie.LightDir.x, lightcookie.LightDir.y, lightcookie.LightDir.z, 0.0f); Vector4 vpCoord = viewProjMatrix * input; float slope = vpCoord.y / vpCoord.x; //Debug.Log("Dir: "+lightcookie.LightDir + " viewCood:" + viewCood + " vpCoord " + vpCoord + " slope:" + slope); cmd.SetGlobalMatrix(LightConstantBuffer._MainLightLightMat, lightcookie.LightMat); cmd.SetGlobalFloat(LightConstantBuffer._MainLightSlope, slope); }
void SetupAdditionalLightConstants(CommandBuffer cmd, ref LightData lightData) { int maxVisibleAdditionalLights = LightweightRenderPipeline.maxVisibleAdditionalLights; var lights = lightData.visibleLights; if (lightData.additionalLightsCount > 0) { int additionalLightsCount = 0; for (int i = 0; i < lights.Length && additionalLightsCount < maxVisibleAdditionalLights; ++i) { VisibleLight light = lights[i]; if (light.lightType != LightType.Directional) { InitializeLightConstants(lights, i, out m_AdditionalLightPositions[additionalLightsCount], out m_AdditionalLightColors[additionalLightsCount], out m_AdditionalLightAttenuations[additionalLightsCount], out m_AdditionalLightSpotDirections[additionalLightsCount], out m_AdditionalLightOcclusionProbeChannels[additionalLightsCount]); additionalLightsCount++; } } cmd.SetGlobalVector(LightConstantBuffer._AdditionalLightsCount, new Vector4(lightData.maxPerObjectAdditionalLightsCount, 0.0f, 0.0f, 0.0f)); } else { cmd.SetGlobalVector(LightConstantBuffer._AdditionalLightsCount, Vector4.zero); } cmd.SetGlobalVectorArray(LightConstantBuffer._AdditionalLightsPosition, m_AdditionalLightPositions); cmd.SetGlobalVectorArray(LightConstantBuffer._AdditionalLightsColor, m_AdditionalLightColors); cmd.SetGlobalVectorArray(LightConstantBuffer._AdditionalLightsAttenuation, m_AdditionalLightAttenuations); cmd.SetGlobalVectorArray(LightConstantBuffer._AdditionalLightsSpotDir, m_AdditionalLightSpotDirections); cmd.SetGlobalVectorArray(LightConstantBuffer._AdditionalLightOcclusionProbeChannel, m_AdditionalLightOcclusionProbeChannels); }
void RenderMainLightCascadeShadowmap(ref ScriptableRenderContext context, ref CullingResults cullResults, ref LightData lightData, ref ShadowData shadowData) { int shadowLightIndex = lightData.mainLightIndex; if (shadowLightIndex == -1) { return; } VisibleLight shadowLight = lightData.visibleLights[shadowLightIndex]; CommandBuffer cmd = CommandBufferPool.Get(m_ProfilerTag); using (new ProfilingSample(cmd, m_ProfilerTag)) { var settings = new ShadowDrawingSettings(cullResults, shadowLightIndex); for (int cascadeIndex = 0; cascadeIndex < m_ShadowCasterCascadesCount; ++cascadeIndex) { var splitData = settings.splitData; splitData.cullingSphere = m_CascadeSplitDistances[cascadeIndex]; settings.splitData = splitData; Vector4 shadowBias = ShadowUtils.GetShadowBias(ref shadowLight, shadowLightIndex, ref shadowData, m_CascadeSlices[cascadeIndex].projectionMatrix, m_CascadeSlices[cascadeIndex].resolution); ShadowUtils.SetupShadowCasterConstantBuffer(cmd, ref shadowLight, shadowBias); ShadowUtils.RenderShadowSlice(cmd, ref context, ref m_CascadeSlices[cascadeIndex], ref settings, m_CascadeSlices[cascadeIndex].projectionMatrix, m_CascadeSlices[cascadeIndex].viewMatrix); } SetupMainLightShadowReceiverConstants(cmd, ref shadowData, shadowLight); } CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadows, true); CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadowCascades, shadowData.mainLightShadowCascadesCount > 1); CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.SoftShadows, shadowLight.light.shadows == LightShadows.Soft && shadowData.supportsSoftShadows); context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd); }
void RenderAdditionalShadowmapAtlas(ref ScriptableRenderContext context, ref CullingResults cullResults, ref LightData lightData, ref ShadowData shadowData) { NativeArray <VisibleLight> visibleLights = lightData.visibleLights; bool additionalLightHasSoftShadows = false; CommandBuffer cmd = CommandBufferPool.Get(m_ProfilerTag); using (new ProfilingSample(cmd, m_ProfilerTag)) { for (int i = 0; i < m_AdditionalShadowCastingLightIndices.Count; ++i) { int shadowLightIndex = m_AdditionalShadowCastingLightIndices[i]; VisibleLight shadowLight = visibleLights[shadowLightIndex]; if (m_AdditionalShadowCastingLightIndices.Count > 1) { ShadowUtils.ApplySliceTransform(ref m_AdditionalLightSlices[i], m_ShadowmapWidth, m_ShadowmapHeight); } var settings = new ShadowDrawingSettings(cullResults, shadowLightIndex); Vector4 shadowBias = ShadowUtils.GetShadowBias(ref shadowLight, shadowLightIndex, ref shadowData, m_AdditionalLightSlices[i].projectionMatrix, m_AdditionalLightSlices[i].resolution); ShadowUtils.SetupShadowCasterConstantBuffer(cmd, ref shadowLight, shadowBias); ShadowUtils.RenderShadowSlice(cmd, ref context, ref m_AdditionalLightSlices[i], ref settings, m_AdditionalLightSlices[i].projectionMatrix, m_AdditionalLightSlices[i].viewMatrix); additionalLightHasSoftShadows |= shadowLight.light.shadows == LightShadows.Soft; } SetupAdditionalLightsShadowReceiverConstants(cmd, ref shadowData); } // We share soft shadow settings for main light and additional lights to save keywords. // So we check here if pipeline supports soft shadows and either main light or any additional light has soft shadows // to enable the keyword. // TODO: In PC and Consoles we can upload shadow data per light and branch on shader. That will be more likely way faster. bool mainLightHasSoftShadows = shadowData.supportsMainLightShadows && lightData.mainLightIndex != -1 && visibleLights[lightData.mainLightIndex].light.shadows == LightShadows.Soft; bool softShadows = shadowData.supportsSoftShadows && (mainLightHasSoftShadows || additionalLightHasSoftShadows); CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.AdditionalLightShadows, true); CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.SoftShadows, softShadows); context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd); }