コード例 #1
0
    /// <summary>
    /// 法线映射
    /// </summary>
    /// <param name="vertex"></param>
    /// <returns></returns>
    public Color01 NormalMappingWithLambert(Vertex vertex, Mesh mesh, Light light)
    {
        // 从法线贴图中取出法线(切线空间下的)
        Color01 UndecryptedNormal = Texture.Tex2D(normalTexture, vertex.u, vertex.v);
        // 把法线从[0,1]区间变回到[-1,1]区间
        Vector3 normal = new Vector3(
            UndecryptedNormal.R * 2 - 1,
            UndecryptedNormal.G * 2 - 1,
            UndecryptedNormal.B * 2 - 1
            );

        // 获得世界坐标下的法线
        Vector3 worldNormal = mesh.mMatrix * vertex.normal;

        worldNormal.Normlize();
        // 获得世界坐标下的切线
        Vector3 worldTangent = mesh.mMatrix * vertex.tangent;

        worldTangent.Normlize();
        // 获得世界坐标下的副切线
        Vector3 worldBinormal = Vector3.Cross(worldNormal, worldTangent) * vertex.tangent.W;

        worldBinormal.Normlize();

        // 构建 切线-世界 变换矩阵
        Matrix4x4 TtoW = new Matrix4x4();

        TtoW.Identity();

        TtoW.value[0, 0] = worldTangent.X;
        TtoW.value[1, 0] = worldTangent.Y;
        TtoW.value[2, 0] = worldTangent.Z;

        TtoW.value[0, 1] = worldBinormal.X;
        TtoW.value[1, 1] = worldBinormal.Y;
        TtoW.value[2, 1] = worldBinormal.Z;

        TtoW.value[0, 2] = worldNormal.X;
        TtoW.value[1, 2] = worldNormal.Y;
        TtoW.value[2, 2] = worldNormal.Z;

        // 将切线空间的法线变为世界坐标
        normal = TtoW * normal;
        normal.Normlize();

        // 增大凹凸比例
        normal.X *= 3;
        normal.Y *= 3;
        normal.Z *= MathF.Sqrt(1 - MathF.Clamp01(normal.X * normal.X + normal.Y * normal.Y));

        Color01 albedo = Texture.Tex2D(texture2D, vertex.u, vertex.v) * vertex.color;

        Vector3 worldPos = mesh.mMatrix * vertex.modelSpacePos;

        float radiance = Vector3.Dot(normal, light.GetDirection(worldPos)) * 0.5f + 0.5f;

        Color01 diffuse = albedo * radiance;

        return(diffuse);
    }
コード例 #2
0
ファイル: ColorPicker.xaml.cs プロジェクト: xorza/NetGL
 private static void ClampVectorComponents(ref Vector4 v)
 {
     v.X = MathF.Clamp01(v.X);
     v.Y = MathF.Clamp01(v.Y);
     v.Z = MathF.Clamp01(v.Z);
     v.W = MathF.Clamp01(v.W);
 }
コード例 #3
0
ファイル: MathFTest.cs プロジェクト: pyneer/case
 [Test] public void Clamp01Checks()
 {
     Assert.AreEqual(MathF.Clamp01(-0.0f), 0.0f, Epsilon);
     Assert.AreEqual(MathF.Clamp01(0.0f), 0.0f, Epsilon);
     Assert.AreEqual(MathF.Clamp01(0.001f), 0.001f, Epsilon);
     Assert.AreEqual(MathF.Clamp01(1.0001f), 1.0f, Epsilon);
     Assert.AreEqual(MathF.Clamp01(1.0f), 1.0f, Epsilon);
     Assert.AreEqual(MathF.Clamp01(0.999f), 0.999f, Epsilon);
     Assert.AreEqual(MathF.Clamp01(0.567f), 0.567f, Epsilon);
 }
コード例 #4
0
        public override float GetAtten(Vector3 targetPosition)
        {
            // θ,片元指向光源的方向与聚光灯朝向的夹角(cos)
            float cosTheta = Vector3.Dot(-GetDirection(targetPosition).normlize, spotDir.normlize);
            // Epsilon是内外圆锥的余弦差值
            float epsilon = cosInnerAngle - cosPhi;
            // 聚光灯强度
            float intensity = MathF.Clamp01((cosTheta - cosPhi) / epsilon);

            return(intensity);
        }
コード例 #5
0
        public override void Draw(IDrawDevice device)
        {
            if (_sprites == null)
            {
                return;
            }

            float warpTime   = MathF.Max(MinWarpTime, WarpTime);
            float chargeTime = MathF.Max(MinChargeTime, ChargeTime);

            if (ElapsedTime < chargeTime)
            {
                float alpha = MathF.Clamp01(ElapsedTime / chargeTime);
                foreach (var sprite in _sprites)
                {
                    SpriteGlowEffect.RenderSpriteGlow(device, sprite, GlowType.Position | GlowType.Scale, 1.1f, 10f, Color.WithAlpha(alpha), DrawTechnique.Res, -100);
                }
                foreach (var geom in _geometries)
                {
                    SpriteGlowEffect.RenderSpriteGlow(device, geom, GlowType.Position | GlowType.Scale, 1.1f, 10f, Color.WithAlpha(alpha), DrawTechnique.Res, -100);
                }
            }
            else if (ElapsedTime >= chargeTime && ElapsedTime <= chargeTime + warpTime)
            {
                foreach (var spr in _sprites)
                {
                    spr.Active = false;
                }

                var vel    = 100f;
                var vector = Ship.Transform.GetWorldVector(new Vector2(vel, 0));

                var rb = Ship.GetComponent <RigidBody>();
                rb.Active = false;
                //rb.ApplyLocalForce(vector * rb.Mass);
                Ship.Transform.Pos += new Vector3(vector, Ship.Transform.Pos.Z);

                float alpha = 1f - MathF.Clamp01((ElapsedTime - chargeTime) / warpTime);

                foreach (var sprite in _sprites)
                {
                    SpriteGlowEffect.RenderSpriteGlow(device, sprite, GlowType.Position | GlowType.Scale, 1.1f, 10f, Color.WithAlpha(alpha), DrawTechnique.Res, -100);
                }
                foreach (var geom in _geometries)
                {
                    SpriteGlowEffect.RenderSpriteGlow(device, geom, GlowType.Position | GlowType.Scale, 1.1f, 10f, Color.WithAlpha(alpha), DrawTechnique.Res, -100);
                }
            }
            else
            {
                _isWarpDone = true;
            }
            ElapsedTime += Time.DeltaTime;
        }
コード例 #6
0
    /// <summary>
    /// 山寨版片元着色器,
    /// 根据一个顶点的各属性,计算当前顶点(屏幕空间下)的像素的颜色
    /// </summary>
    /// <param name="vertex"></param>
    /// <returns></returns>
    public Color01 FragmentShader(Vertex vertex)
    {
        // 基于半兰伯特光照模型的光照
        //return LightingWithLambert(vertex);

        // 从法线贴图中取出法线(切线空间下的)
        Color01 UndecryptedNormal = Texture.Tex2D(normalTexture, vertex.u, vertex.v);
        // 把法线从[0,1]区间变回到[-1,1]区间
        Vector3 normal = new Vector3(
            UndecryptedNormal.R * 2 - 1,
            UndecryptedNormal.G * 2 - 1,
            UndecryptedNormal.B * 2 - 1
            );

        // 获得世界坐标下的法线
        Vector3 worldNormal = vertex.mMatrix * vertex.normal;

        worldNormal.Normlize();
        // 获得世界坐标下的切线
        Vector3 worldTangent = vertex.mMatrix * vertex.tangent;

        worldTangent.Normlize();
        // 获得世界坐标下的副切线
        Vector3 worldBinormal = Vector3.Cross(worldNormal, worldTangent) * vertex.tangent.W;

        worldBinormal.Normlize();

        // 构建 切线-世界 变换矩阵
        Matrix4x4 TtoW = new Matrix4x4();

        TtoW.Identity();

        TtoW.value[0, 0] = worldTangent.X;
        TtoW.value[1, 0] = worldTangent.Y;
        TtoW.value[2, 0] = worldTangent.Z;

        TtoW.value[0, 1] = worldBinormal.X;
        TtoW.value[1, 1] = worldBinormal.Y;
        TtoW.value[2, 1] = worldBinormal.Z;

        TtoW.value[0, 2] = worldNormal.X;
        TtoW.value[1, 2] = worldNormal.Y;
        TtoW.value[2, 2] = worldNormal.Z;

        // 将切线空间的法线变为世界坐标
        normal = TtoW * normal;
        normal.Normlize();

        // 增大凹凸比例
        normal.X *= 3;
        normal.Y *= 3;
        normal.Z *= MathF.Sqrt(1 - MathF.Clamp01(normal.X * normal.X + normal.Y * normal.Y));

        Color01 albedo = Texture.Tex2D(texture2D, vertex.u, vertex.v);

        float radiance = Vector3.Dot(normal, DirectionLight) * 0.5f + 0.5f;

        Color01 diffuse = albedo * radiance;

        return(diffuse);
    }