コード例 #1
0
        static float ElementShadow(Vector3 v, float rSquared, Vector3 receiverNormal,

                                   Vector3 emitterNormal, float emitterArea)
        {
            // we assume that emitterArea has already been divided by PI

            return((1.0f - 1.0f / SstlHelper.Sqrt(emitterArea / rSquared + 1.0f)) *

                   SstlHelper.Clamp(Vector3.Dot(emitterNormal, v), 0f, 1.0f) *

                   SstlHelper.Clamp(4 * Vector3.Dot(receiverNormal, v), 0f, 1.0f));
        }
コード例 #2
0
        public static void AorThread(Mesh mesh, float[] squares, int offset, int count)
        {
            if (offset + count > mesh.Verteces.Count)
            {
                count = mesh.Verteces.Count - offset;
            }
            for (int i = offset; i < offset + count; i += 3)
            {
                var v0 = mesh.Verteces[i];
                var v1 = mesh.Verteces[i + 1];
                var v2 = mesh.Verteces[i + 2];
                //var center1 = (v0.Position + v1.Position + v2.Position) / 3;

                v0.Ao = v1.Ao = v2.Ao = 1.0f;
                float res = 0;
                for (int j = 0; j < mesh.Verteces.Count; j += 3)
                {
                    if (j < i || j > i + 2)
                    {
                        var vv0 = mesh.Verteces[j];
                        var vv1 = mesh.Verteces[j + 1];
                        var vv2 = mesh.Verteces[j + 2];
                        //var center2 = (vv0.Position + vv1.Position + vv2.Position) / 3;
                        var v  = vv0.Position - v0.Position;
                        var d2 = Vector3.Dot(v, v) + 1e-16;
                        v *= 1.0f / SstlHelper.Sqrt((float)d2);
                        //var rsq = (center1 - center2).LengthSquared;
                        //if (float.IsNaN(res))
                        //{
                        //    continue;
                        //}
                        var value = ElementShadow(v, (float)d2, v0.Normal, vv0.Normal, squares[j]);
                        if (float.IsNaN(value))
                        {
                            value = 1;
                        }
                        res += value;
                        if (res >= 1)
                        {
                            break;
                        } // http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter14.html
                    }
                }
                //res = SstlHelper.Clamp(res, 1, 0);

                v0.Ao = v1.Ao = v2.Ao = 1.0f - res;

                mesh.Verteces[i]     = v0;
                mesh.Verteces[i + 1] = v1;
                mesh.Verteces[i + 2] = v2;
                AorResult           += 3;
            }
        }
コード例 #3
0
        public void __Render(Matrix4 mvp)
        {
            if (Verteces.Count == 0)
            {
                return;
            }

            Vector3 ambient            = new Vector3(0.1f, 0.1f, 0.1f);
            Vector3 lightVecNormalized = Vector3.Normalize(new Vector3(0.5f, 0.5f, 2));
            Vector3 lightColor         = new Vector3(0.7f, 0.7f, 0.7f);
            Vector3 lightColorRefl     = new Vector3(0.7f, 0.0f, 0.0f);

            if (!AoTest)
            {
                GL.Begin(PrimitiveType.Triangles);
                for (int i = 0; i < Indeces.Count; i += 3)
                {
                    VertexPositionNormalTexture v0 = Verteces[(int)Indeces[i]];
                    var   normal  = -Vector4.Transform(new Vector4(v0.Normal, 0), mvp).Xyz;
                    float diffuse = SstlHelper.Clamp(Vector3.Dot(lightVecNormalized, Vector3.Normalize(normal)), 0.0f,
                                                     1.0f);
                    float diffuseRefl = SstlHelper.Clamp(Vector3.Dot(lightVecNormalized, Vector3.Normalize(-normal)),
                                                         0.0f, 1.0f);
                    var outFragColor = new Vector4(ambient + (diffuse * lightColor + diffuseRefl * lightColorRefl) * v0.Ao,
                                                   1.0f);
                    GL.Color4(outFragColor);
                    GL.Normal3(v0.Normal);
                    GL.Vertex3(v0.Position);
                    GL.Vertex3(Verteces[(int)Indeces[i + 1]].Position);
                    GL.Vertex3(Verteces[(int)Indeces[i + 2]].Position);
                }
                GL.End();
            }
            else
            {
                lightColor     = new Vector3(0.0f, 0.0f, 0.0f);
                lightColorRefl = new Vector3(1.0f, 0.0f, 0.0f);
                GL.Begin(PrimitiveType.Triangles);
                for (int i = 0; i < Indeces.Count; i += 3)
                {
                    VertexPositionNormalTexture v0 = Verteces[(int)Indeces[i]];
                    var outFragColor = new Vector4(Vector3.Lerp(lightColorRefl, lightColor, v0.Ao), 1.0f);
                    GL.Color4(outFragColor);
                    GL.Normal3(v0.Normal);
                    GL.Vertex3(v0.Position);
                    GL.Vertex3(Verteces[(int)Indeces[i + 1]].Position);
                    GL.Vertex3(Verteces[(int)Indeces[i + 2]].Position);
                }
                GL.End();
            }
        }
コード例 #4
0
        public static void AmbientOcclusionRecalc(Mesh mesh)
        {
            var squares = new float[mesh.Verteces.Count];

            for (int i = 0; i < mesh.Verteces.Count; i += 3)
            {
                var v0 = mesh.Verteces[i];
                var v1 = mesh.Verteces[i + 1];
                var v2 = mesh.Verteces[i + 2];

                var sq = SstlHelper.TriangleSquare(v0, v1, v2);
                squares[i] = squares[i + 1] = squares[i + 2] = sq;
            }

            AorResultTotal = mesh.Verteces.Count;
            AorResult      = 0;
            int processorCount = Environment.ProcessorCount;

            IAsyncResult[] results = new IAsyncResult[processorCount];
            var            t       = SstlHelper.NearestMod((int)(mesh.Verteces.Count / (float)processorCount), 3);

            for (int i = 0; i < processorCount; i++)
            {
                Action <Mesh, float[], int, int> aorT = AorThread;

                results[i] = aorT.BeginInvoke(mesh, squares, t * i, t, null, null);
            }

            while (true)
            {
                bool all = true;
                for (int i = 0; i < results.Length; i++)
                {
                    if (!results[i].IsCompleted)
                    {
                        all = false;
                    }
                }
                if (all)
                {
                    break;
                }
                Thread.Sleep(300);
            }
        }
コード例 #5
0
        public static Mesh SmartTesselate(Mesh mesh)
        {
            Mesh m = new Mesh();

            float size = 0;

            for (int i = 0; i < mesh.Indeces.Count; i += 3)
            {
                size += SstlHelper.TriangleSquare(mesh.Verteces[(int)mesh.Indeces[i]],
                                                  mesh.Verteces[(int)mesh.Indeces[i + 1]],
                                                  mesh.Verteces[(int)mesh.Indeces[i + 2]]);
            }
            size /= mesh.Indeces.Count;

            int off = 0;

            for (int i = 0; i < mesh.Indeces.Count; i += 3)
            {
                VertexPositionNormalTexture t;

                var sq = SstlHelper.TriangleSquare(mesh.Verteces[(int)mesh.Indeces[i]],
                                                   mesh.Verteces[(int)mesh.Indeces[i + 1]],
                                                   mesh.Verteces[(int)mesh.Indeces[i + 2]]);
                if (sq <= size * 6)
                {
                    m.Verteces.Add(mesh.Verteces[(int)mesh.Indeces[i]]);
                    m.Verteces.Add(mesh.Verteces[(int)mesh.Indeces[i + 1]]);
                    m.Verteces.Add(mesh.Verteces[(int)mesh.Indeces[i + 2]]);
                    m.Indeces.Add((uint)off + 0);
                    m.Indeces.Add((uint)off + 1);
                    m.Indeces.Add((uint)off + 2);
                    off += 3;
                    continue;
                }

                m.Verteces.Add(mesh.Verteces[(int)mesh.Indeces[i]]);
                m.Verteces.Add(mesh.Verteces[(int)mesh.Indeces[i + 1]]);
                m.Verteces.Add(mesh.Verteces[(int)mesh.Indeces[i + 2]]);

                t = (mesh.Verteces[(int)mesh.Indeces[i]] + mesh.Verteces[(int)mesh.Indeces[i + 1]]) / 2;
                m.Verteces.Add(t);

                t = (mesh.Verteces[(int)mesh.Indeces[i]] + mesh.Verteces[(int)mesh.Indeces[i + 2]]) / 2;
                m.Verteces.Add(t);

                t = (mesh.Verteces[(int)mesh.Indeces[i + 1]] + mesh.Verteces[(int)mesh.Indeces[i + 2]]) / 2;
                m.Verteces.Add(t);

                m.Indeces.Add((uint)off + 0);
                m.Indeces.Add((uint)off + 3);
                m.Indeces.Add((uint)off + 4);

                m.Indeces.Add((uint)off + 5);
                m.Indeces.Add((uint)off + 3);
                m.Indeces.Add((uint)off + 1);


                m.Indeces.Add((uint)off + 5);
                m.Indeces.Add((uint)off + 2);
                m.Indeces.Add((uint)off + 4);

                m.Indeces.Add((uint)off + 3);
                m.Indeces.Add((uint)off + 5);
                m.Indeces.Add((uint)off + 4);

                off += 6;
            }
            return(m);
        }