HDShadowData CreateShadowData(HDShadowRequest shadowRequest, HDShadowAtlas atlas) { HDShadowData data = new HDShadowData(); var devProj = shadowRequest.deviceProjection; var view = shadowRequest.view; data.proj = new Vector4(devProj.m00, devProj.m11, devProj.m22, devProj.m23); data.pos = shadowRequest.position; data.rot0 = new Vector3(view.m00, view.m01, view.m02); data.rot1 = new Vector3(view.m10, view.m11, view.m12); data.rot2 = new Vector3(view.m20, view.m21, view.m22); data.shadowToWorld = shadowRequest.shadowToWorld; data.cacheTranslationDelta = new Vector3(0.0f, 0.0f, 0.0f); var viewport = shadowRequest.isInCachedAtlas ? shadowRequest.cachedAtlasViewport : shadowRequest.dynamicAtlasViewport; // Compute the scale and offset (between 0 and 1) for the atlas coordinates float rWidth = 1.0f / atlas.width; float rHeight = 1.0f / atlas.height; data.atlasOffset = Vector2.Scale(new Vector2(rWidth, rHeight), new Vector2(viewport.x, viewport.y)); data.shadowMapSize = new Vector4(viewport.width, viewport.height, 1.0f / viewport.width, 1.0f / viewport.height); data.normalBias = shadowRequest.normalBias; data.worldTexelSize = shadowRequest.worldTexelSize; data.shadowFilterParams0.x = shadowRequest.shadowSoftness; data.shadowFilterParams0.y = HDShadowUtils.Asfloat(shadowRequest.blockerSampleCount); data.shadowFilterParams0.z = HDShadowUtils.Asfloat(shadowRequest.filterSampleCount); data.shadowFilterParams0.w = shadowRequest.minFilterSize; data.zBufferParam = shadowRequest.zBufferParam; if (atlas.HasBlurredEVSM()) { data.shadowFilterParams0 = shadowRequest.evsmParams; } data.isInCachedAtlas = shadowRequest.isInCachedAtlas ? 1.0f : 0.0f; return(data); }
unsafe public void PrepareGPUShadowDatas(CullingResults cullResults, HDCamera camera) { if (m_MaxShadowRequests == 0) { return; } int shadowIndex = 0; m_ShadowDatas.Clear(); // Create all HDShadowDatas and update them with shadow request datas for (int i = 0; i < m_ShadowRequestCount; i++) { Debug.Assert(m_ShadowRequests[i] != null); HDShadowAtlas atlas = m_Atlas; if (m_ShadowRequests[i].isInCachedAtlas) { atlas = cachedShadowManager.punctualShadowAtlas; } if (m_ShadowRequests[i].shadowMapType == ShadowMapType.CascadedDirectional) { atlas = m_CascadeAtlas; } else if (m_ShadowRequests[i].shadowMapType == ShadowMapType.AreaLightAtlas) { atlas = m_AreaLightShadowAtlas; if (m_ShadowRequests[i].isInCachedAtlas) { atlas = cachedShadowManager.areaShadowAtlas; } } HDShadowData shadowData; if (m_ShadowRequests[i].shouldUseCachedShadowData) { shadowData = m_ShadowRequests[i].cachedShadowData; } else { shadowData = CreateShadowData(m_ShadowRequests[i], atlas); m_ShadowRequests[i].cachedShadowData = shadowData; } m_ShadowDatas.Add(shadowData); m_ShadowRequests[i].shadowIndex = shadowIndex++; } int first = k_DirectionalShadowCascadeCount, second = k_DirectionalShadowCascadeCount; fixed(float *sphereBuffer = m_DirectionalShadowData.sphereCascades) { Vector4 *sphere = (Vector4 *)sphereBuffer; for (int i = 0; i < k_DirectionalShadowCascadeCount; i++) { first = (first == k_DirectionalShadowCascadeCount && sphere[i].w > 0.0f) ? i : first; second = ((second == k_DirectionalShadowCascadeCount || second == first) && sphere[i].w > 0.0f) ? i : second; } } // Update directional datas: if (second != k_DirectionalShadowCascadeCount) { m_DirectionalShadowData.cascadeDirection = (GetCascadeSphereAtIndex(second) - GetCascadeSphereAtIndex(first)).normalized; } else { m_DirectionalShadowData.cascadeDirection = Vector4.zero; } m_DirectionalShadowData.cascadeDirection.w = camera.volumeStack.GetComponent <HDShadowSettings>().cascadeShadowSplitCount.value; if (m_ShadowRequestCount > 0) { // Upload the shadow buffers to GPU m_ShadowDataBuffer.SetData(m_ShadowDatas); m_CachedDirectionalShadowData[0] = m_DirectionalShadowData; m_DirectionalShadowDataBuffer.SetData(m_CachedDirectionalShadowData); } }