public Cmd_CopyBufferToImage(SoftwareBuffer srcBuffer, SoftwareImage dstImage, VkImageLayout dstImageLayout, int regionCount, VkBufferImageCopy[] pRegions) { this.m_srcBuffer = srcBuffer; this.m_dstImage = dstImage; this.m_dstImageLayout = dstImageLayout; this.m_regionCount = regionCount; this.m_pRegions = pRegions; }
private VkResult InternalPresentDibBitmap(SoftwareImage image, Form form) { m_BitmapRenderTarget.WritePixels(image.m_imageData, 0); using (Graphics target = form.CreateGraphics()) { m_BitmapRenderTarget.DrawTo(target); return(VkResult.VK_SUCCESS); } }
public static T SampleEquirectangularMap <T>(SoftwareImage <T> image, Vector3 dir) where T : unmanaged { var th = Math.Atan2(dir.Y, dir.X) / Math.PI / 2; if (th < 0) { th += 1; } var u = (float)(th * image.Width); var xy = Math.Sqrt(dir.X * dir.X + dir.Y * dir.Y); var v = (float)(Math.Atan2(xy, dir.Z) / Math.PI * image.Height); return(SampleLinear(image, u, v)); }
public SoftwareImage <T> Generate() { const float ratio = 0.25f; var tr = Image.PixelTransformer; var ret = new SoftwareImage <T>(Image.Width / 2, Image.Height / 2, tr); for (int y = 0; y < Image.Height; ++y) { for (int x = 0; x < Image.Width; ++x) { ref var p = ref ret.GetPixel(x / 2, y / 2); p = tr.Add(p, tr.Scale(Image.GetPixel(x, y), ratio)); } }
private VkResult InternalPresent(SoftwareImage image, Form form) { switch (m_SurfacePresentMode) { case FormSurfacePresentMode.GraphicsDrawUnscaled: return(InternalDrawUnscaled(image, form)); case FormSurfacePresentMode.DibBitmapBitBlt: return(InternalPresentDibBitmap(image, form)); default: throw new NotImplementedException(); } }
public VkResult PresentImage(SoftwareImage image, VkExtent2D imageExtent) { var form = m_Form; if (form == null || form.IsDisposed) { return(VkResult.VK_ERROR_DEVICE_LOST); } VkResult result; if ((imageExtent.width != m_CurrentSurfaceExtents.width) || (imageExtent.height != m_CurrentSurfaceExtents.height)) { InternalDrawUnscaled(image, form); return(VkResult.VK_SUBOPTIMAL_KHR); } /* * if ((imageExtent.width < m_CurrentExtents.width) || (imageExtent.height < m_CurrentExtents.height)) * { * return VkResult.VK_ERROR_OUT_OF_DATE_KHR; * } */ if (form.InvokeRequired) { result = (VkResult)form.Invoke((Func <VkResult>)(() => { return(InternalPresent(image, form)); })); } else { result = InternalPresent(image, form); } if ((imageExtent.width != m_CurrentSurfaceExtents.width) || (imageExtent.height != m_CurrentSurfaceExtents.height)) { if (result == VkResult.VK_SUCCESS) { result = VkResult.VK_SUBOPTIMAL_KHR; } } return(result); }
public SoftwareImage <T>[] Generate(int newSize) { var faces = new SoftwareImage <T> [6]; faces[0] = new SoftwareImage <T>(newSize, newSize, _image.PixelTransformer); faces[1] = new SoftwareImage <T>(newSize, newSize, _image.PixelTransformer); faces[2] = new SoftwareImage <T>(newSize, newSize, _image.PixelTransformer); faces[3] = new SoftwareImage <T>(newSize, newSize, _image.PixelTransformer); faces[4] = new SoftwareImage <T>(newSize, newSize, _image.PixelTransformer); faces[5] = new SoftwareImage <T>(newSize, newSize, _image.PixelTransformer); var p = faces[0].PixelTransformer; var rand = new Random(); for (int z = 0; z < 6; ++z) { for (int y = 0; y < newSize; ++y) { for (int x = 0; x < newSize; ++x) { ////1. calculate center and a radius ////2. randomly generate samples within that radus //// use stratify method and jittering ////3. check whether the sample is in the pixel (by scaling the already known maximum dimension to 1) ////4. if check succeeds, write the point sample to destination var center = SkyboxHelper.CubeToDir(newSize, x, y, z); var r = (float)Math.Atan(0.5 / newSize); var sampler = new CircleDirectionalSampler(rand, center, r, 4); T total = default; for (int sample = 0; sample < sampler.SampleCount; ++sample) { var sampleDir = sampler.Sample(sample); var color = SkyboxHelper.SampleEquirectangularMap(_image, sampleDir); total = p.Add(total, color); } faces[z].GetPixel(x, y) = p.Scale(total, 1f / sampler.SampleCount); } } } return(faces); }
static void Main(string[] args) { //Convert skybox texture. { SoftwareImage <R32G32B32A32F> image = HdrImageLoader.Read(TestSceneResource("473-free-hdri-skies-com.hdr")); { var cubeImages = new SkyboxUniformCircleFilter <R32G32B32A32F>(image).Generate(32); SoftwareImage <R32G32B32A32F> .WriteSRDFileCube(TestSceneCompiled("sphere_cube_specular.srd"), cubeImages); } { var s1 = new HalfSize <R32G32B32A32F>(image).Generate(); s1 = new HalfSize <R32G32B32A32F>(s1).Generate(); s1 = new HalfSize <R32G32B32A32F>(s1).Generate(); s1 = new HalfSize <R32G32B32A32F>(s1).Generate(); s1 = new HalfSize <R32G32B32A32F>(s1).Generate(); image = s1; } image.WriteSRDFile(TestSceneCompiled("473-free-hdri-skies-com.srd")); { var cubeImages = new SkyboxLambertianDiffuseFilter <R32G32B32A32F>(image).Generate(16, 64); for (int i = 0; i < 6; ++i) { cubeImages[i] = new HalfSize <R32G32B32A32F>(cubeImages[i]).Generate(); cubeImages[i] = new HalfSize <R32G32B32A32F>(cubeImages[i]).Generate(); } SoftwareImage <R32G32B32A32F> .WriteSRDFileCube(TestSceneCompiled("sphere_cube_diffuse.srd"), cubeImages); } } //Generate model. { var model = Sphere.Generate(); model.WriteSRD(TestSceneCompiled("sphere.vb"), TestSceneCompiled("sphere.ib")); } { var model = ObjModelLoader.Load(TestSceneResource("bunny.obj.dat")); SwapModelCoordinate.SwapXZ(model); model.WriteSRD(TestSceneCompiled("bunny.vb"), TestSceneCompiled("bunny.ib")); } }
public VkResult InternalDrawUnscaled(SoftwareImage source, Control destination) { VkResult result = VkResult.VK_SUCCESS; PixelFormat pixelFormat = PixelFormat.Format32bppRgb; int sourceWidth = source.GetWidth(); int sourceHeight = source.GetHeight(); int pixelSize = 4; using (Bitmap bitmap = new Bitmap(sourceWidth, sourceHeight, pixelFormat)) { Rectangle rect = new Rectangle(0, 0, sourceWidth, sourceHeight); var bitmapData = bitmap.LockBits(rect, ImageLockMode.WriteOnly, pixelFormat); if (bitmapData.Stride == (bitmapData.Width * pixelSize)) { int arrayElements = bitmapData.Width * bitmapData.Height; Marshal.Copy(source.m_imageData, 0, bitmapData.Scan0, arrayElements); } else { for (int y = 0; y < sourceHeight; y++) { int sourceIndex = y * sourceWidth; int destIndex = y * bitmapData.Stride; Marshal.Copy(source.m_imageData, sourceIndex, bitmapData.Scan0 + destIndex, sourceWidth); } } bitmap.UnlockBits(bitmapData); using (Graphics target = destination.CreateGraphics()) { target.DrawImageUnscaled(bitmap, 0, 0); target.Flush(); } return(result); } }
private static T SampleLinear <T>(SoftwareImage <T> image, float x, float y) where T : unmanaged { float rx = x - 0.5f; float ry = y - 0.5f; int x0 = (int)Math.Floor(rx); int y0 = (int)Math.Floor(ry); int x1 = x0 + 1; int y1 = y0 + 1; float tx = rx - x0; float ty = ry - y0; var c00 = GetImagePixel(image, x0, y0); var c10 = GetImagePixel(image, x1, y0); var c01 = GetImagePixel(image, x0, y1); var c11 = GetImagePixel(image, x1, y1); var p = image.PixelTransformer; var cc = p.Scale(c00, (1 - tx) * (1 - ty)); cc = p.Add(cc, p.Scale(c10, tx * (1 - ty))); cc = p.Add(cc, p.Scale(c01, (1 - tx) * ty)); cc = p.Add(cc, p.Scale(c11, tx * ty)); return(cc); }
public SoftwareImage <T>[] Generate(int newSize, int nSample) { var faces = new SoftwareImage <T> [6]; faces[0] = new SoftwareImage <T>(newSize, newSize, _image.PixelTransformer); faces[1] = new SoftwareImage <T>(newSize, newSize, _image.PixelTransformer); faces[2] = new SoftwareImage <T>(newSize, newSize, _image.PixelTransformer); faces[3] = new SoftwareImage <T>(newSize, newSize, _image.PixelTransformer); faces[4] = new SoftwareImage <T>(newSize, newSize, _image.PixelTransformer); faces[5] = new SoftwareImage <T>(newSize, newSize, _image.PixelTransformer); var p = faces[0].PixelTransformer; var rand = new Random(); for (int z = 0; z < 6; ++z) { for (int y = 0; y < newSize; ++y) { for (int x = 0; x < newSize; ++x) { var center = SkyboxHelper.CubeToDir(newSize, x, y, z); center = Vector3.Normalize(center); var sampler = new SphereDirectionalSampler(rand, center, (float)Math.PI / 2, nSample); T total = default; for (int sample = 0; sample < sampler.SampleCount; ++sample) { var sampleDir = sampler.Sample(sample); var color = SkyboxHelper.SampleEquirectangularMap(_image, sampleDir); total = p.Add(total, p.Scale(color, Vector3.Dot(center, sampleDir))); } faces[z].GetPixel(x, y) = p.Scale(total, 1f / sampler.SampleCount / (float)Math.PI); } } } return(faces); }
public SkyboxLambertianDiffuseFilter(SoftwareImage <T> image) { _image = image; }
private static T GetImagePixel <T>(SoftwareImage <T> image, int x, int y) where T : unmanaged { x = (x + image.Width) % image.Width; y = (y + image.Height) % image.Height; return(image.GetPixel(x, y)); }
public HalfSize(SoftwareImage <T> image) { Image = image; }
public SkyboxUniformCircleFilter(SoftwareImage <T> image) { _image = image; }
static void Main(string[] args) { var normalMap = new SoftwareImage <R32G32B32A32F>(800, 600, new R32G32B32A32FTransformer()); normalMap.LoadRawDataFile(TestSceneCompiled("OutputNormal.raw")); var viewDirMap = new SoftwareImage <R32G32B32A32F>(800, 600, new R32G32B32A32FTransformer()); viewDirMap.LoadRawDataFile(TestSceneCompiled("OutputViewDir.raw")); SoftwareImage <R32G32B32A32F> skybox = HdrImageLoader.Read(TestSceneResource("473-free-hdri-skies-com.hdr")); SoftwareImage <R32G32B32A32F> skyboxSpecular = skybox; { skyboxSpecular = new HalfSize <R32G32B32A32F>(skyboxSpecular).Generate(); skyboxSpecular = new HalfSize <R32G32B32A32F>(skyboxSpecular).Generate(); skyboxSpecular = new HalfSize <R32G32B32A32F>(skyboxSpecular).Generate(); skyboxSpecular = new HalfSize <R32G32B32A32F>(skyboxSpecular).Generate(); skyboxSpecular = new HalfSize <R32G32B32A32F>(skyboxSpecular).Generate(); } SoftwareImage <R32G32B32A32F> skyboxDiffuse = skybox; { skyboxDiffuse = new HalfSize <R32G32B32A32F>(skyboxDiffuse).Generate(); skyboxDiffuse = new HalfSize <R32G32B32A32F>(skyboxDiffuse).Generate(); skyboxDiffuse = new HalfSize <R32G32B32A32F>(skyboxDiffuse).Generate(); skyboxDiffuse = new HalfSize <R32G32B32A32F>(skyboxDiffuse).Generate(); skyboxDiffuse = new HalfSize <R32G32B32A32F>(skyboxDiffuse).Generate(); skyboxDiffuse = new HalfSize <R32G32B32A32F>(skyboxDiffuse).Generate(); skyboxDiffuse = new HalfSize <R32G32B32A32F>(skyboxDiffuse).Generate(); } var p = skybox.PixelTransformer; //System.Drawing.Bitmap does not support concurrent SetPixel. Use our own instead. var bitmap = new SoftwareImage <R8G8B8A8>(800, 600, new R8G8B8A8Transformer()); Parallel.For(0, 600, (int y) => { var rand = _rand.Value; for (int x = 0; x < 800; ++x) { var normal = normalMap.GetPixel(x, y); if (normal.R == 0 && normal.G == 0 && normal.B == 0) { continue; } var viewDir = viewDirMap.GetPixel(x, y); var n = new Vector3(normal.R, normal.G, normal.B); var e = Vector3.Normalize(-new Vector3(viewDir.R, viewDir.G, viewDir.B)); var l = Vector3.Normalize(2 * Vector3.Dot(n, e) * n - e); R32G32B32A32F color = default; //Specular { //color = p.Add(color, SkyboxHelper.SampleEquirectangularMap(skyboxSpecular, l)); const int SpecularSampleCount = 40; var sampler = new SphereDirectionalSampler(rand, l, (float)Math.PI / 2, SpecularSampleCount); R32G32B32A32F total = default; for (int sample = 0; sample < sampler.SampleCount; ++sample) { var sampleDir = sampler.Sample(sample); if (Vector3.Dot(sampleDir, n) < 0) { continue; } var cc = SkyboxHelper.SampleEquirectangularMap(skyboxSpecular, sampleDir); total = p.Add(total, p.Scale(cc, Vector3.Dot(n, sampleDir) * (float)BRDF(n, sampleDir, e))); } color = p.Add(color, p.Scale(total, 1f / sampler.SampleCount * 5)); } //Diffuse { const int DiffuseSampleCount = 10; var sampler = new SphereDirectionalSampler(rand, n, (float)Math.PI / 2, DiffuseSampleCount); R32G32B32A32F total = default; for (int sample = 0; sample < sampler.SampleCount; ++sample) { var sampleDir = sampler.Sample(sample); var cc = SkyboxHelper.SampleEquirectangularMap(skyboxDiffuse, sampleDir); total = p.Add(total, p.Scale(cc, Vector3.Dot(n, sampleDir) / (float)Math.PI)); } color = p.Add(color, p.Scale(total, 1f / sampler.SampleCount * 0)); } var rgb = p.ToColor(color); bitmap.GetPixel(x, y) = new R8G8B8A8 { R = rgb.R, G = rgb.G, B = rgb.B, A = 255, }; } //} }); bitmap.ToBitmap().Save(TestSceneCompiled("Offline.png")); }