private static void RenderShadowShader(this Image <Rgba32> screen, float[,] zBuffer) { var shadowBuffer = new float[ScreenWidth, ScreenHeight]; var cameraPosition = new Vector3(1, 1, 3); var cameraTarget = new Vector3(0, 0, 0); var cameraUp = new Vector3(0, 1, 0); var viewPort = CreateViewPort(ScreenWidth / 8, ScreenHeight / 8, ScreenWidth * 3 / 4, ScreenHeight * 3 / 4); var projection = CreateProjection(-1 / (cameraPosition - cameraTarget).Length()); var modelView = CreateLookAt(cameraPosition, cameraTarget, cameraUp); var light = new Vector3(1, 1, 1); light = (projection * modelView).Multiply(light).Normalize(); var shadowProjection = Matrix4x4.Identity; var shadowModelView = CreateLookAt(light, cameraTarget, cameraUp); var model = ModelUtils.LoadModel(@"Resources\Diablo3\Model.obj"); var texture = TextureUtils.LoadTexture(@"Resources\Diablo3\Diffuse.png"); var normalMap = TextureUtils.LoadTexture(@"Resources\Diablo3\Normal.png"); var specularMap = TextureUtils.LoadTexture(@"Resources\Diablo3\Specular.png"); specularMap.Mutate(context => context.Flip(FlipType.Vertical)); IShader shader = new ZBufferShader { Transform = viewPort * shadowProjection * shadowModelView }; screen.Render(model, shader, shadowBuffer); shader = new ShadowShader { Transform = viewPort * projection * modelView, MIT = (projection * modelView).Invert().Transpose(), ShadowTransform = viewPort * shadowProjection * shadowModelView * (viewPort * projection * modelView).Invert(), Light = light, Texture = texture, NormalMap = normalMap, SpecularMap = specularMap, ShadowBuffer = shadowBuffer }; screen.Mutate(context => context.Fill(Rgba32.Black)); screen.Render(model, shader, zBuffer); }
private static void RenderAmbientOccolusion(this Image <Rgba32> screen, float[,] zBuffer) { var cameraPosition = new Vector3(1, 1, 3); var cameraTarget = new Vector3(0, 0, 0); var cameraUp = new Vector3(0, 1, 0); var viewPort = CreateViewPort(ScreenWidth / 8, ScreenHeight / 8, ScreenWidth * 3 / 4, ScreenHeight * 3 / 4); var projection = CreateProjection(-1 / (cameraPosition - cameraTarget).Length()); var modelView = CreateLookAt(cameraPosition, cameraTarget, cameraUp); IShader shader = new ZBufferShader { Transform = viewPort * projection * modelView }; var model = ModelUtils.LoadModel(@"Resources\Diablo3\Model.obj"); screen.Render(model, shader, zBuffer); screen.RenderAmbientOccolusion(zBuffer, ScreenWidth, ScreenHeight); }
public static Image <Rgba32> GenerateOccolusionMap(this IReadOnlyCollection <TriangleInfo> model, Matrix4x4 viewPort, int imageWidth, int imageHeight, int passNumber) { var screen = new Image <Rgba32>(imageWidth, imageHeight); screen.Mutate(context => context.Fill(Rgba32.Black)); var resultOcclusionMap = new Image <Rgba32>(imageWidth, imageHeight); resultOcclusionMap.Mutate(context => context.Fill(Rgba32.Black)); var passOcclusionMap = new Image <Rgba32>(imageWidth, imageHeight); passOcclusionMap.Mutate(context => context.Fill(Rgba32.Black)); var occlusionBuffer = new float[imageWidth, imageHeight]; var zBuffer = new float[imageWidth, imageHeight]; var zBufferShader = new ZBufferShader(); var occlusionShader = new OcclusionShader { PassOcclusionMap = passOcclusionMap, OcclusionBuffer = occlusionBuffer }; var cameraTarget = new Vector3(0, 0, 0); for (var pass = 1; pass <= passNumber; pass++) { Array.Clear(occlusionBuffer, 0, imageWidth * imageHeight); Array.Clear(zBuffer, 0, imageWidth * imageHeight); passOcclusionMap.Mutate(context => context.Fill(Rgba32.Black)); var cameraPosition = MathUtils.RandomOnUnitSphere(); cameraPosition.Y = Math.Abs(cameraPosition.Y); var cameraUp = MathUtils.RandomUnitVector3(); var modelView = MathUtils.CreateLookAt(cameraPosition, cameraTarget, cameraUp); var transform = viewPort * modelView; zBufferShader.Transform = transform; screen.Render(model, zBufferShader, occlusionBuffer); occlusionShader.Transform = transform; screen.Render(model, occlusionShader, zBuffer); for (var i = 0; i < imageWidth; i++) { for (var j = 0; j < imageHeight; j++) { var previous = resultOcclusionMap[i, j].R; var current = passOcclusionMap[i, j].R; var color = (byte)((float)(previous * (pass - 1) + current) / pass + .5f); resultOcclusionMap[i, j] = new Rgba32(color, color, color); } } } return(resultOcclusionMap); }