private static void GenerateSplit(EEDCamera Camera, DVector3 ShadowVector) { Vector3 Up = new Vector3(0, 1, 0); NewShadowPos = Camera.position; DVector3.Normalize(ShadowVector); float d = Vector3.Dot(ShadowVector, Up); if (d == 1 || d == -1) { Up = new Vector3(1, 0, 0); } NewShadowPos -= ShadowDistance * ShadowVector; const int ShadowStep = 50; NewShadowPos.X = ((int)NewShadowPos.X) / ShadowStep * ShadowStep; NewShadowPos.Y = ((int)NewShadowPos.Y) / ShadowStep * ShadowStep; NewShadowPos.Z = ((int)NewShadowPos.Z) / ShadowStep * ShadowStep; double Coff = 0.125f; for (int i = 0; i < SplitsNumber + 1; i++) { SplitSlices[i] = (Camera.nearClip + (Camera.farClip - Camera.nearClip) * (float)i / (float)SplitsNumber) * (Coff); SplitSlices[i] += (Camera.nearClip * System.Math.Pow(Camera.farClip / Camera.nearClip, (float)i / (float)SplitsNumber)) * (1 - Coff); SplitSlices[i] /= Camera.farClip; SplitSlices[i] *= ShadowDistance; CamFrustumPos[i, 0] = Camera.position + (Camera.FarT1 - Camera.position) * (SplitSlices[i] / Camera.farClip); CamFrustumPos[i, 1] = Camera.position + (Camera.FarT2 - Camera.position) * (SplitSlices[i] / Camera.farClip); CamFrustumPos[i, 2] = Camera.position + (Camera.FarT3 - Camera.position) * (SplitSlices[i] / Camera.farClip); CamFrustumPos[i, 3] = Camera.position + (Camera.FarT4 - Camera.position) * (SplitSlices[i] / Camera.farClip); } Matrix ProjShadowMatrix = Matrix.OrthoRH(100f, 100f, (float)ShadowDistance / 1000f, (float)ShadowDistance * 2f); Matrix ViewShadowMatrix = Matrix.LookAtRH(new Vector3(0, 0, 0), Conversion.ToVector3(ShadowVector), Vector3.Cross(Camera.direction, ShadowVector)); LightViewProjMatrix = ViewShadowMatrix * ProjShadowMatrix; for (int i = 0; i < SplitsNumber; i++) { Vector3[] TransformSplit = new Vector3[8]; for (int t = 0; t < 4; t++) { TransformSplit[t] = Conversion.ToVector3(Vector3.Transform(Conversion.ToVector3(CamFrustumPos[i, t] - NewShadowPos), LightViewProjMatrix)); TransformSplit[t + 4] = Conversion.ToVector3(Vector3.Transform(Conversion.ToVector3(CamFrustumPos[i + 1, t] - NewShadowPos), LightViewProjMatrix)); } Vector3 AABBMax = TransformSplit[0]; Vector3 AABBMin = TransformSplit[0]; for (int y = 0; y < 8; y++) { if (AABBMax.X < TransformSplit[y].X) AABBMax.X = TransformSplit[y].X; if (AABBMax.Y < TransformSplit[y].Y) AABBMax.Y = TransformSplit[y].Y; if (AABBMax.Z < TransformSplit[y].Z) AABBMax.Z = TransformSplit[y].Z; if (AABBMin.X > TransformSplit[y].X) AABBMin.X = TransformSplit[y].X; if (AABBMin.Y > TransformSplit[y].Y) AABBMin.Y = TransformSplit[y].Y; if (AABBMin.Z > TransformSplit[y].Z) AABBMin.Z = TransformSplit[y].Z; } /* AABBMax += new Vector3(0.05f); AABBMin -= new Vector3(0.05f); */ // Create the crop matrix float scaleX, scaleY, scaleZ; float offsetX, offsetY, offsetZ; // Use default near-plane value AABBMin.Z = 0.0f; scaleX = 2.0f / (AABBMax.X - AABBMin.X); scaleY = 2.0f / (AABBMax.Y - AABBMin.Y); offsetX = -0.5f * (AABBMax.X + AABBMin.X) * scaleX; offsetY = -0.5f * (AABBMax.Y + AABBMin.Y) * scaleY; scaleZ = 1.0f / ((AABBMax.Z - AABBMin.Z)); offsetZ = -AABBMin.Z * scaleZ; const int CoffShadowStep = 5; const float CoffMulti = 100f; const float CoffMultiScale = 1000f; offsetX = ((float)(((int)(offsetX * CoffMulti)) / CoffShadowStep * CoffShadowStep)) / CoffMulti; offsetY = ((float)(((int)(offsetY * CoffMulti)) / CoffShadowStep * CoffShadowStep)) / CoffMulti; offsetZ = ((float)(((int)(offsetZ * CoffMulti)) / CoffShadowStep * CoffShadowStep)) / CoffMulti; scaleX = ((float)(((int)(scaleX * CoffMultiScale)) / CoffShadowStep * CoffShadowStep)) / CoffMultiScale; scaleY = ((float)(((int)(scaleY * CoffMultiScale)) / CoffShadowStep * CoffShadowStep)) / CoffMultiScale; scaleZ = ((float)(((int)(scaleZ * CoffMultiScale)) / CoffShadowStep * CoffShadowStep)) / CoffMultiScale; CropMatrices[i] = new Matrix(scaleX, 0.0f, 0.0f, 0.0f, 0.0f, scaleY, 0.0f, 0.0f, 0.0f, 0.0f, scaleZ, 0.0f, offsetX, offsetY, offsetZ, 1.0f); DMatrix Inv = DMatrix.Invert(Conversion.ToDoubleMatrix(LightViewProjMatrix * CropMatrices[i])); DVector3 LocPos = DVector3.Transform(new DVector3(), Inv); NewCamPositions[i] = NewShadowPos + LocPos; } }
public static void RenderObj(float TimeMili, Device device, EEDCamera Camera, Vector3 LightDirection, Vector3 LightColor, List<GameObject> GOs) { Matrix[] S_VP = new Matrix[SplitsNumber]; float[] SplitDistances = new float[SplitsNumber]; for (int i = 0; i < SplitsNumber; i++) { S_VP[i] = LightViewProjMatrix * CropMatrices[i]; SplitDistances[i] = (float)SplitSlices[i + 1];///Camera.farClip; } DMatrix W_S_CAM = DMatrix.CreateTranslation(-NewShadowPos); Matrix[] S_WVP = new Matrix[SplitsNumber]; for (int i = 0; i < GOs.Count; i++) if (GOs[i] != null) { for (int y = 0; y < SplitsNumber; y++) { S_WVP[y] = Conversion.ToMatrix(GOs[i].Transformation * DMatrix.CreateTranslation(-NewShadowPos)) * S_VP[y]; } if (GOs[i].StopSplit > -1) GOs[i].DrawPSSM(device, TimeMili, Camera, LightDirection, LightColor, S_WVP, SplitDistances); else GOs[i].Draw(device, Camera, LightColor, LightDirection); } }
public void DrawSplitShadows(float TimeMili, Matrix Transform, Matrix VP, Vector3 LightDirection, Vector3 LightColor, Matrix[] SMatrixs, float[] SplitDistances) { constants.WVP = Matrix.Transpose(Transform * VP); constants.World = Matrix.Transpose(Transform); constants.LightPosition = Conversion.ToVector4(LightDirection);//LShadow.Position - Camera.position); constants.H = new Vector4(PSSMsHelper.SplitShadowsSize, 0, 0, 0); unsafe { fixed (float* buffer = constants.cropMatrix) { for (int x = 0; x < PSSMsHelper.SplitsNumber; x++) { buffer[x * 16 + 0] = SMatrixs[x].M11; buffer[x * 16 + 1] = SMatrixs[x].M21; buffer[x * 16 + 2] = SMatrixs[x].M31; buffer[x * 16 + 3] = SMatrixs[x].M41; buffer[x * 16 + 4] = SMatrixs[x].M12; buffer[x * 16 + 5] = SMatrixs[x].M22; buffer[x * 16 + 6] = SMatrixs[x].M32; buffer[x * 16 + 7] = SMatrixs[x].M42; buffer[x * 16 + 8] = SMatrixs[x].M13; buffer[x * 16 + 9] = SMatrixs[x].M23; buffer[x * 16 + 10] = SMatrixs[x].M33; buffer[x * 16 + 11] = SMatrixs[x].M43; buffer[x * 16 + 12] = SMatrixs[x].M14; buffer[x * 16 + 13] = SMatrixs[x].M24; buffer[x * 16 + 14] = SMatrixs[x].M34; buffer[x * 16 + 15] = SMatrixs[x].M44; } } fixed (float* buffer = constants.SplitPlane) { for (int x = 0; x < PSSMsHelper.SplitsNumber; x++) buffer[x*4] = SplitDistances[x]; } } Program.context.InputAssembler.InputLayout = Materials[0].Effect.layout; Program.context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; Program.context.InputAssembler.SetVertexBuffers(0, binding); Program.context.InputAssembler.SetIndexBuffer(Indices, Format.R32_UInt, 0); DifuseName = ""; SpecularMapName = ""; NormalMapName = ""; SelfMapName = ""; UV2DifuseName = ""; ShaderName = ""; //NoDoubleSide for (int i = 0; i < Materials.Length; i++) { if (!Materials[i].DoubleSide) { if (ShaderName != Materials[i].Effect.Name) { Materials[i].Effect.renderTechniques[2].GetPassByIndex(0).Apply(Program.context); ShaderName = Materials[i].Effect.Name; DifuseName = ""; SpecularMapName = ""; NormalMapName = ""; SelfMapName = ""; UV2DifuseName = ""; ShaderName = ""; Program.context.PixelShader.SetShaderResource(5, Program.MyScene.SkyBox.CubeSRV); Program.context.PixelShader.SetSampler(5, DrawHelper.SamplLinWrapMip); Program.context.PixelShader.SetShaderResource(6, PSSMsHelper.SMArraySRV); } CahseSetTexture(Materials[i]); constants.Color = Conversion.ToVector4(LightColor, Materials[i].Alpha / 255f); SetConstants(false); Program.context.DrawIndexed(Meshes[i].IndexCount, Meshes[i].StartIndex, 0); } } DifuseName = ""; SpecularMapName = ""; NormalMapName = ""; SelfMapName = ""; UV2DifuseName = ""; ShaderName = ""; //DoubleSide for (int i = 0; i < Materials.Length; i++) { if (Materials[i].DoubleSide) { if (ShaderName != Materials[i].Effect.Name) { Materials[i].Effect.renderTechniques[2].GetPassByIndex(1).Apply(Program.context); ShaderName = Materials[i].Effect.Name; DifuseName = ""; SpecularMapName = ""; NormalMapName = ""; SelfMapName = ""; UV2DifuseName = ""; ShaderName = ""; Program.context.PixelShader.SetShaderResource(5, Program.MyScene.SkyBox.CubeSRV); Program.context.PixelShader.SetSampler(5, DrawHelper.SamplLinWrapMip); Program.context.PixelShader.SetShaderResource(6, PSSMsHelper.SMArraySRV); } CahseSetTexture(Materials[i]); constants.Color = Conversion.ToVector4(LightColor, Materials[i].Alpha / 255f); SetConstants(false); Program.context.DrawIndexed(Meshes[i].IndexCount, Meshes[i].StartIndex, 0); } } }
public void DrawSplit(float TimeMili, Matrix MainWVP, Matrix[] CropMatrix, int StartIndex, int StopIndex) { constants.WVP = Matrix.Transpose(MainWVP); constants.Color = Conversion.ToVector4(new Vector3(), 0); constants.StartSplit = StartIndex; constants.StopSplit = StopIndex; unsafe { fixed (float* buffer = constants.cropMatrix) { for (int x = 0; x < PSSMsHelper.SplitsNumber; x++) { buffer[x * 16 + 0 ] = CropMatrix[x].M11; buffer[x * 16 + 1 ] = CropMatrix[x].M21; buffer[x * 16 + 2 ] = CropMatrix[x].M31; buffer[x * 16 + 3 ] = CropMatrix[x].M41; buffer[x * 16 + 4 ] = CropMatrix[x].M12; buffer[x * 16 + 5 ] = CropMatrix[x].M22; buffer[x * 16 + 6 ] = CropMatrix[x].M32; buffer[x * 16 + 7 ] = CropMatrix[x].M42; buffer[x * 16 + 8 ] = CropMatrix[x].M13; buffer[x * 16 + 9 ] = CropMatrix[x].M23; buffer[x * 16 + 10] = CropMatrix[x].M33; buffer[x * 16 + 11] = CropMatrix[x].M43; buffer[x * 16 + 12] = CropMatrix[x].M14; buffer[x * 16 + 13] = CropMatrix[x].M24; buffer[x * 16 + 14] = CropMatrix[x].M34; buffer[x * 16 + 15] = CropMatrix[x].M44; } } } Program.context.InputAssembler.InputLayout = Materials[0].Effect.layout; Program.context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; Program.context.InputAssembler.SetVertexBuffers(0, binding); Program.context.InputAssembler.SetIndexBuffer(Indices, Format.R32_UInt, 0); //NoDoubleSide&NoAlphaTest { Materials[0].Effect.renderTechniques[1].GetPassByIndex(0).Apply(Program.context); SetConstants(true); for (int i = 0; i < Materials.Length; i++) { if (!Materials[i].DoubleSide && Materials[i].Alpha < 1) { Program.context.DrawIndexed(Meshes[i].IndexCount, Meshes[i].StartIndex, 0); } } } DifuseName = ""; //NoDoubleSide&AlphaTest for (int i = 0; i < Materials.Length; i++) { if (!Materials[i].DoubleSide && Materials[i].Alpha >= 1) { if (ShaderName != Materials[i].Effect.Name) { Materials[i].Effect.renderTechniques[1].GetPassByIndex(0).Apply(Program.context); ShaderName = Materials[i].Effect.Name; DifuseName = ""; } if (DifuseName != Materials[i].Diffuse.Name) { Program.context.PixelShader.SetShaderResource(0, Materials[i].Diffuse.TextureResource); Program.context.PixelShader.SetSampler(0, Materials[i].DiffuseSamplerState); DifuseName = Materials[i].Diffuse.Name; } constants.Color = Conversion.ToVector4(new Vector3(), Materials[i].Alpha / 255f); SetConstants(true); Program.context.DrawIndexed(Meshes[i].IndexCount, Meshes[i].StartIndex, 0); } } //DoubleSide&AlphaTest for (int i = 0; i < Materials.Length; i++) { if (Materials[i].DoubleSide) { if (ShaderName != Materials[i].Effect.Name) { Materials[i].Effect.renderTechniques[1].GetPassByIndex(1).Apply(Program.context); ShaderName = Materials[i].Effect.Name; DifuseName = ""; } if (DifuseName != Materials[i].Diffuse.Name) { Program.context.PixelShader.SetShaderResource(0, Materials[i].Diffuse.TextureResource); Program.context.PixelShader.SetSampler(0, Materials[i].DiffuseSamplerState); DifuseName = Materials[i].Diffuse.Name; } constants.Color = Conversion.ToVector4(new Vector3(), Materials[i].Alpha / 255f); SetConstants(true); Program.context.DrawIndexed(Meshes[i].IndexCount, Meshes[i].StartIndex, 0); } } }
public void DrawNoShadows(float TimeMili, Matrix Transform, Matrix VP, Vector3 LightDirection, Vector3 LightColor) { constants.WVP = Matrix.Transpose(Transform * VP); constants.World = Matrix.Transpose(Transform); constants.LightPosition = Conversion.ToVector4(LightDirection);//LShadow.Position - Camera.position); Program.context.InputAssembler.InputLayout = Materials[0].Effect.layout; Program.context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; Program.context.InputAssembler.SetVertexBuffers(0, binding); Program.context.InputAssembler.SetIndexBuffer(Indices, Format.R32_UInt, 0); DifuseName = ""; SpecularMapName = ""; NormalMapName = ""; SelfMapName = ""; UV2DifuseName = ""; ShaderName = ""; //NoDoubleSide for (int i = 0; i < Materials.Length; i++) { if(!Materials[i].DoubleSide) { if (ShaderName != Materials[i].Effect.Name) { Materials[i].Effect.renderTechniques[0].GetPassByIndex(0).Apply(Program.context); ShaderName = Materials[i].Effect.Name; DifuseName = ""; SpecularMapName = ""; NormalMapName = ""; SelfMapName = ""; UV2DifuseName = ""; ShaderName = ""; Program.context.PixelShader.SetShaderResource(5, Program.MyScene.SkyBox.CubeSRV); //Program.context.PixelShader.SetShaderResource(5, PSSMsHelper.SMArraySRV); Program.context.PixelShader.SetSampler(5, DrawHelper.SamplLinWrapMip); } CahseSetTexture(Materials[i]); constants.Color = Conversion.ToVector4(LightColor, Materials[i].Alpha / 255f); SetConstants(false); Program.context.DrawIndexed(Meshes[i].IndexCount, Meshes[i].StartIndex, 0); } } DifuseName = ""; SpecularMapName = ""; NormalMapName = ""; SelfMapName = ""; UV2DifuseName = ""; ShaderName = ""; //DoubleSide for (int i = 0; i < Materials.Length; i++) { if (Materials[i].DoubleSide) { if (ShaderName != Materials[i].Effect.Name) { Materials[i].Effect.renderTechniques[0].GetPassByIndex(1).Apply(Program.context); ShaderName = Materials[i].Effect.Name; DifuseName = ""; SpecularMapName = ""; NormalMapName = ""; SelfMapName = ""; UV2DifuseName = ""; ShaderName = ""; Program.context.PixelShader.SetShaderResource(5, Program.MyScene.SkyBox.CubeSRV); Program.context.PixelShader.SetSampler(5, DrawHelper.SamplLinWrapMip); } CahseSetTexture(Materials[i]); constants.Color = Conversion.ToVector4(LightColor, Materials[i].Alpha / 255f); SetConstants(false); Program.context.DrawIndexed(Meshes[i].IndexCount, Meshes[i].StartIndex, 0); } } }
public void DrawDepth(float TimeMili, Matrix MainWVP, EEDCamera Camera) { constants.WVP = Matrix.Transpose(MainWVP); constants.Color = new Vector4(0, 0, 0, 0); constants.CamPosition.Z = Camera.farClip; constants.CamPosition.W = Camera.nearClip; Program.context.InputAssembler.InputLayout = Materials[0].Effect.layout; Program.context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; Program.context.InputAssembler.SetVertexBuffers(0, binding); Program.context.InputAssembler.SetIndexBuffer(Indices, Format.R32_UInt, 0); //NoDoubleSide&NoAlphaTest { Materials[0].Effect.renderTechniques[1].GetPassByIndex(2).Apply(Program.context); SetConstants(false); for (int i = 0; i < Materials.Length; i++) { if (!Materials[i].DoubleSide && Materials[i].Alpha < 1) Program.context.DrawIndexed(Meshes[i].IndexCount, Meshes[i].StartIndex, 0); } } DifuseName = ""; //NoDoubleSide&AlphaTest for (int i = 0; i < Materials.Length; i++) { if (!Materials[i].DoubleSide && Materials[i].Alpha >= 1) { if (ShaderName != Materials[i].Effect.Name) { Materials[i].Effect.renderTechniques[1].GetPassByIndex(2).Apply(Program.context); ShaderName = Materials[i].Effect.Name; DifuseName = ""; } if (DifuseName != Materials[i].Diffuse.Name) { Program.context.PixelShader.SetShaderResource(0, Materials[i].Diffuse.TextureResource); Program.context.PixelShader.SetSampler(0, Materials[i].DiffuseSamplerState); DifuseName = Materials[i].Diffuse.Name; } constants.Color = Conversion.ToVector4(new Vector3(), Materials[i].Alpha / 255f); SetConstants(false); Program.context.DrawIndexed(Meshes[i].IndexCount, Meshes[i].StartIndex, 0); } } //DoubleSide&AlphaTest for (int i = 0; i < Materials.Length; i++) { if (Materials[i].DoubleSide) { if (ShaderName != Materials[i].Effect.Name) { Materials[i].Effect.renderTechniques[1].GetPassByIndex(3).Apply(Program.context); ShaderName = Materials[i].Effect.Name; DifuseName = ""; } if (DifuseName != Materials[i].Diffuse.Name) { Program.context.PixelShader.SetShaderResource(0, Materials[i].Diffuse.TextureResource); Program.context.PixelShader.SetSampler(0, Materials[i].DiffuseSamplerState); DifuseName = Materials[i].Diffuse.Name; } constants.Color = Conversion.ToVector4(new Vector3(), Materials[i].Alpha / 255f); SetConstants(false); Program.context.DrawIndexed(Meshes[i].IndexCount, Meshes[i].StartIndex, 0); } } }