public void Process(SpotLightComponent spotLight, ShadowMapComponent shadowMap, CameraComponent shadowMapCamera) { var world = Matrix.Invert(shadowMapCamera.Camera.ViewProjection); this.Effect.WorldViewProjection = world * this.FrameService.CameraComponent.Camera.ViewProjection; this.Effect.CameraPosition = this.FrameService.CameraComponent.Camera.Position; this.Effect.Albedo = this.FrameService.GBuffer.Albedo; this.Effect.Normal = this.FrameService.GBuffer.Normal; this.Effect.Depth = this.FrameService.GBuffer.Depth; this.Effect.Material = this.FrameService.GBuffer.Material; this.Effect.GBufferSampler = SamplerState.LinearClamp; this.Effect.InverseViewProjection = Matrix.Invert(this.FrameService.CameraComponent.Camera.ViewProjection); this.Effect.Position = shadowMapCamera.Camera.Position; this.Effect.Color = spotLight.Color.ToVector4(); this.Effect.Strength = spotLight.Strength; this.Effect.ShadowMap = shadowMap.DepthMap; this.Effect.ShadowSampler = ShadowMapSampler.State; this.Effect.ShadowViewProjection = shadowMapCamera.Camera.ViewProjection; this.Effect.Apply(); this.Volume.Render(this.Device); }
/// <summary> /// Initialize shadowmask per frame buffers /// </summary> public static void UpdateShadowMaskState(ref ShadowMaskComponent shadMask, ref ShadowMapComponent shadMap, ref Matrix4x4[] cascadeShadowMapVP, ref Vector4[] shadowCameraPos) { shadMask.afterLightingBuffer.Clear(); shadMask.afterLightingBuffer.SetGlobalMatrixArray(ShaderIDs._ShadowMapVPs, cascadeShadowMapVP); shadMask.afterLightingBuffer.SetGlobalVectorArray(ShaderIDs._ShadowCamPoses, shadowCameraPos); shadMask.afterLightingBuffer.SetGlobalTexture(ShaderIDs._DirShadowMap, shadMap.shadowmapTexture); shadMask.afterLightingBuffer.BlitSRT(BuiltinRenderTextureType.CameraTarget, shadMask.shadowmaskMaterial, 0); }
/// <summary> /// Set Shadowcamera Position /// </summary> /// <param name="shadMap"></param> Shadowmap component /// <param name="settings"></param> Shadowmap Settings public static void SetShadowCameraPositionCloseFit(ref ShadowMapComponent shadMap, ref ShadowmapSettings settings) { Camera shadowCam = shadMap.shadowCam; NativeArray <AspectInfo> shadowFrustumPlanes = shadMap.shadowFrustumPlanes; AspectInfo info = shadowFrustumPlanes[0]; info.planeNormal = shadowCam.transform.right; shadowFrustumPlanes[0] = info; info = shadowFrustumPlanes[1]; info.planeNormal = shadowCam.transform.up; shadowFrustumPlanes[1] = info; info = shadowFrustumPlanes[2]; info.planeNormal = shadowCam.transform.forward; shadowFrustumPlanes[2] = info; for (int i = 0; i < 3; ++i) { info = shadowFrustumPlanes[i]; float least = float.MaxValue; float maximum = float.MinValue; Vector3 lessPoint = Vector3.zero; Vector3 morePoint = Vector3.zero; for (int x = 0; x < 8; ++x) { float dotValue = Vector3.Dot(info.planeNormal, shadMap.frustumCorners[x]); if (dotValue < least) { least = dotValue; lessPoint = shadMap.frustumCorners[x]; } if (dotValue > maximum) { maximum = dotValue; morePoint = shadMap.frustumCorners[x]; } } info.size = (maximum - least) / 2f; info.inPlanePoint = lessPoint + info.planeNormal * info.size; shadowFrustumPlanes[i] = info; } AspectInfo temp = shadowFrustumPlanes[2]; temp.size = settings.farestDistance; //Farest Cascade Distance shadowFrustumPlanes[2] = temp; Transform tr = shadowCam.transform; for (int i = 0; i < 3; ++i) { info = shadowFrustumPlanes[i]; float dist = Vector3.Dot(info.inPlanePoint, info.planeNormal) - Vector3.Dot(tr.position, info.planeNormal); tr.position += dist * info.planeNormal; } shadowCam.orthographicSize = shadowFrustumPlanes[1].size; shadowCam.aspect = shadowFrustumPlanes[0].size / shadowFrustumPlanes[1].size; shadowCam.nearClipPlane = 0; shadowCam.farClipPlane = shadowFrustumPlanes[2].size * 2; tr.position -= shadowFrustumPlanes[2].size * shadowFrustumPlanes[2].planeNormal; }
/// <summary> /// Initialize per cascade shadowmap buffers /// </summary> public static void UpdateCascadeState(ref ShadowMapComponent comp, float bias) { Camera shadowCam = comp.shadowCam; Vector4 shadowcamDir = shadowCam.transform.forward; shadowcamDir.w = bias; Shader.SetGlobalVector(ShaderIDs._ShadowCamDirection, shadowcamDir); Matrix4x4 rtVp = GL.GetGPUProjectionMatrix(shadowCam.projectionMatrix, true) * shadowCam.worldToCameraMatrix; comp.shadowDepthMaterial.SetMatrix(ShaderIDs._ShadowMapVP, rtVp); Shader.SetGlobalVector(ShaderIDs._ShadowCamPos, shadowCam.transform.position); }
public (SpotLightComponent spotLight, ShadowMapComponent shadowMap, CameraComponent viewPoint) CreateSpotLight(int resolution) { var entity = this.Entities.Create(); var spotLight = new SpotLightComponent(entity, Color.White, 100.0f); var shadowMap = ShadowMapComponent.Create(entity, this.Device, resolution); var camera = new CameraComponent(entity, new PerspectiveCamera(this.Device.Viewport.AspectRatio)); this.Components.Add(spotLight, shadowMap, camera); return(spotLight, shadowMap, camera); }
/// <summary> /// Initialize Per frame shadowmap buffers for Shadowmap shader /// </summary> public static void UpdateShadowMapState(ref ShadowMapComponent comp, ref ShadowmapSettings settings) { Camera shadowCam = comp.shadowCam; Shader.SetGlobalFloat(ShaderIDs._ShadowCamFarClip, shadowCam.farClipPlane); Graphics.SetRenderTarget(comp.shadowmapTexture); GL.Clear(true, true, Color.white); Shader.SetGlobalVector(ShaderIDs._NormalBiases, settings.normalBias); Shader.SetGlobalVector(ShaderIDs._ShadowDisableDistance, new Vector4(settings.firstLevelDistance, settings.secondLevelDistance, settings.thirdLevelDistance, settings.farestDistance)); Shader.SetGlobalVector(ShaderIDs._LightDirection, -comp.light.transform.forward); Shader.SetGlobalVector(ShaderIDs._LightFinalColor, comp.light.color * comp.light.intensity); Shader.SetGlobalVector(ShaderIDs._SoftParam, settings.cascadeSoftValue / settings.resolution); }
/// <summary> /// Get Frustum Corners /// </summary> /// <param name="distance"></param> target distance range /// <param name="shadMap"></param> shadowmap component /// <param name="mask"></param> shadowmask component public static void GetfrustumCorners(Vector2 distance, ref ShadowMapComponent shadMap, Camera targetCamera) { //bottom left shadMap.frustumCorners[0] = targetCamera.ViewportToWorldPoint(new Vector3(0, 0, distance.x)); // bottom right shadMap.frustumCorners[1] = targetCamera.ViewportToWorldPoint(new Vector3(1, 0, distance.x)); // top left shadMap.frustumCorners[2] = targetCamera.ViewportToWorldPoint(new Vector3(0, 1, distance.x)); // top right shadMap.frustumCorners[3] = targetCamera.ViewportToWorldPoint(new Vector3(1, 1, distance.x)); //bottom left shadMap.frustumCorners[4] = targetCamera.ViewportToWorldPoint(new Vector3(0, 0, distance.y)); // bottom right shadMap.frustumCorners[5] = targetCamera.ViewportToWorldPoint(new Vector3(1, 0, distance.y)); // top left shadMap.frustumCorners[6] = targetCamera.ViewportToWorldPoint(new Vector3(0, 1, distance.y)); // top right shadMap.frustumCorners[7] = targetCamera.ViewportToWorldPoint(new Vector3(1, 1, distance.y)); }
public static void RenderShadowProcedural(ref ShadowMapComponent shadMap, ref PipelineBaseBuffer baseBuffer, int pass) { shadMap.shadowDepthMaterial.SetPass(pass); Graphics.DrawProceduralIndirect(MeshTopology.Triangles, baseBuffer.instanceCountBuffer); }