예제 #1
0
        private void CreateLightmap(float dist2, Vector3 badPoint, string path, int texIndex, float hemisphereSizeDivisor, TextureMap texMap, ref float maxIntensity)
        {
            int gatherCount = 100;

            int   width               = (int)(texMap.Width);  // * RadiosityHelper.LightmapScale);
            int   height              = (int)(texMap.Height); // * RadiosityHelper.LightmapScale);
            float heightF             = (float)texMap.Height; // *RadiosityHelper.LightmapScale;
            float widthF              = (float)texMap.Width;  // *RadiosityHelper.LightmapScale;
            float currentMaxIntensity = float.MinValue;
            float diffuse             = (float)RadiosityHelper.RadiosityDiffuseConstant;

            widthF  -= 1f;
            heightF -= 1f;

            SetOperation("Creating texture #" + (texIndex + 1));
            //List<CompressedPhoton> photons;

            Bitmap bitm = new Bitmap(width, height, PixelFormat.Format32bppRgb);

            RadiosityMaterial mat; Vector3 norm;

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < heightF; y++)
                {
                    bitm.SetPixel(x, y, m_bsp[0].ConvertUVTo3D(x, y, texIndex, 1, out mat, out norm) != Vector3.Empty ? new RealColor(1, 1, 1).ToARGB() : RealColor.Black.ToARGB());
                }
            }
            bitm.Save("k:\\convmap_" + texIndex + "_" + 1);

            //CreateLightmapWork(dist2, ref badPoint, texIndex, hemisphereSizeDivisor, texMap, width, height, heightF, widthF, ref currentMaxIntensity);

            // We are going to cycle through the materials of the bsp.
            EnhancedMesh[] meshes = m_bsp[0].GetMeshes(texIndex);
            for (int m = 0; m < meshes.Length; m++)
            {
                EnhancedMesh            material  = meshes[m];
                int                     faceCount = material.Indices.Length;
                RectangleBounds <float> bounds    = new RectangleBounds <float>(material.Vertices[0].u2, material.Vertices[0].v2);

                // First we're going to figure out a rectangle for this material.
                for (int v = 0; v < material.Vertices.Length; v++)
                {
                    bounds.Update(material.Vertices[v].u2, material.Vertices[v].v2);
                }
                int x      = (int)Math.Floor((widthF * bounds.left));
                int startX = x;
                int endX   = (int)Math.Ceiling(widthF * bounds.right);
                int y      = (int)Math.Floor(heightF * bounds.top);
                int endY   = (int)Math.Ceiling(heightF * bounds.bottom);

                //System.Diagnostics.Debugger.Break();

                for (; y <= endY; y++)
                {
                    x = startX;
                    for (; x <= endX; x++)
                    {
                        RadiosityMaterial illMaterial;
                        Vector3           faceNormal;

                        //if (y == 81)
                        // // if (x == 2)
                        //System.Diagnostics.Debugger.Break();
                        Vector3 worldPoint = m_bsp[0].ConvertUVTo3D(x, y, texIndex, m, out illMaterial, out faceNormal);
                        //AddDebugRay(worldPoint, faceNormal);

                        if (worldPoint != Vector3.Empty)
                        {
                            AddDebugPoint(worldPoint, RadiosityDebugPointListID.EstimateLocations);

                            var photons = photonMap.RetrieveNearestNeighbors((PhotonVector3)worldPoint, dist2, gatherCount, faceNormal);

                            RealColor estimate = RealColor.Black;

                            if (photons.Count > 0)
                            {
                                for (int p = 0; p < photons.Count; p++)
                                {
                                    if (photons.list[p].photonPtr == null)
                                    {
                                        continue;
                                    }
                                    float dotP = Vector3.Dot(photons.list[p].photonPtr.Direction, faceNormal);
                                    if (dotP < 0)
                                    {
                                        dotP *= -1;
                                        //AddDebugPoint(photons.list[p].photonPtr
                                        //AddDebugRay(photons.list[p].photonPtr.position.ToVector3(), photons.list[p].photonPtr.Direction);
                                    }

                                    estimate.Add(photons.list[p].photonPtr.Power.Copy().Multiply(dotP));
                                }

                                estimate.Multiply(diffuse);
                                estimate.Multiply(hemisphereSizeDivisor);
                                estimate.Multiply(illMaterial.AmbientLight);
                                //estimate.Multiply(1f / photons.Count);

                                if (RadiosityHelper.DoDistantLights)
                                {
                                    if (illMaterial.DistantLightCount > 1)
                                    {
                                        estimate.LambertianShade(faceNormal, illMaterial.DistantLight2Color, illMaterial.DistantLight2Direction, illMaterial.AmbientLight);
                                        estimate.LambertianShade(faceNormal, illMaterial.DistantLight1Color, illMaterial.DistantLight1Direction, illMaterial.AmbientLight);
                                    }
                                    else if (illMaterial.DistantLightCount > 0)
                                    {
                                        estimate.LambertianShade(faceNormal, illMaterial.DistantLight1Color, illMaterial.DistantLight1Direction, illMaterial.AmbientLight);
                                    }
                                }
                                texMap.SetPixel(x, y, estimate);
                            }
                            else
                            {
                                texMap.SetPixel(x, y, new RealColor(Color.Pink));
                            }
                        }
                        //else continue; // if there is no normal, the estimate is useless.
                    }
                }
            }

            if (currentMaxIntensity > maxIntensity)
            {
                maxIntensity = currentMaxIntensity;
            }

            texMap.SaveHDR(path + "lightmap_" + texIndex + ".hdr");
            bitm = texMap.Filter(new LinearToneMapper(), false);

            bitm.Save(path + "lightmap_" + texIndex + ".bmp");
        }