精华内容
下载资源
问答
  • 假设具有恒定状态方程的完美流体是米糠中唯一的能量成分,我们研究了... 因此,额外维度像时间一样的模型中,我们的宇宙可以永远过去地保持爱因斯坦静态,这意味着大爆炸的奇点性可以通过一种紧急情况成功解决。
  • 这周完成从max导出静态模型模型查看器渲染了,接下来要重构一下引擎,然后完善模型查看器,接着做骨骼动画。 转载于:https://www.cnblogs.com/youweibin/archive/2011/07/02/2096234.html...

    这周完成从max中导出静态模型并在模型查看器中渲染了,接下来要重构一下引擎,然后完善模型查看器,接着做骨骼动画。

     

    转载于:https://www.cnblogs.com/youweibin/archive/2011/07/02/2096234.html

    展开全文
  • 目前世面上有许多方法来部署机器学习模型。最常见的方法是通过 API 或 serverless functions 将模型公开为 Web 服务。将模型部署为 Web 服务时,...由于模型通常只是静态文件,因此部署模型的另一种方法是作为 Web...

    目前世面上有许多方法来部署机器学习模型。最常见的方法是通过 API 或 serverless functions 将模型公开为 Web 服务。将模型部署为 Web 服务时,其中一个注意事项是延迟和性能。使用模型基于 HTTP 进行预测的过程包括接受用户输入、从文件中加载模型的序列化版本、使用模型进行预测以及将预测返回给用户。由于模型通常只是静态文件,因此部署模型的另一种方法是作为 Web 上的静态资产,就像任何其他 HTML、CSS 或 JavaScript 文件一样。此部署方法与 TensorFlow.js 类似。以这种方式进行部署有几个优点。一是不再有 Web 服务只是为了为模型提供服务,从而使其更具成本效益。另一个是一旦模型下载到用户的 PC 上,此时使用的资源是用户 PC 的资源,而不是模型本来会托管的服务器。最后,由于模型是静态文件,因此可以通过 CDN 进行分发。

    其中一个挑战是机器学习模型通常使用 JavaScript 以外的语言构建。这使得使用相同的代码/库构建模型变得困难或几乎不可能。WebAssembly 允许 Rust、C++、C# 和其他语言在浏览器中本机运行,从而改变了这一点。有了这种能力,加载模型和进行预测的代码/逻辑就更容易,几乎与本机平台的代码/逻辑相当。Blazor WebAssembly 为用户提供了在 C# 中完全创建基于组件的现代 Web 应用程序的能力。此外,Blazor WebAssembly 还允许用户以简单且经济高效的方式发布和部署其应用程序作为静态网站。ML.NET是一个开源的跨平台框架,允许开发人员使用 .NET 创建机器学习模型。在这篇文章中,我将演示如何训练一个多分类机器学习模型,预测鸢尾花种类。然后,我将采用该模型并将其与 Blazor WebAssembly 静态网站一起部署到 Azure 。此应用程序的完整代码可以在GitHub 上的 MLNETBlazorWASMSample 存储库中找到。

    先决条件

    这个项目是在Windows PC上构建的,但应该在Mac或Linux上执行以体现跨平台特性。

    • .NET 核心 SDK 3.1

    • Blazor WebAssembly模板

    • Azure 订阅

    • Azure 存储资源管理器

    设置解决方案

    本文中构建的解决方案包含三个项目:

    • SchemaLibrary:C# .NET 标准 2.0 类库,其中包含用于训练模型的数据的架构定义类以及模型生成的预测输出。

    • TrainingConsole:用于训练机器学习模型的 C# .NET Core 3.1 控制台应用程序。

    • BlazorWebApp:Blazor WebAssembly Web 应用程序,使用由TrainingConsole应用程序训练的机器学习模型进行预测。

    安装Blazor WebAssembly模板

    使用 .NET CLI 在命令提示符中运行以下命令:

    dotnet new -i Microsoft.AspNetCore.Blazor.Templates::3.2.0-preview1.20073.1

    创建解决方案

    给命名MLNETBlazorWASMSample的解决方案创建新目录。

    mkdir MLNETBlazorWASMSample

    导航到新创建的解决方案目录并创建解决方案:

    cd MLNETBlazorWASMSample
    dotnet new sln

    创建schema类库

    模型输入和输出的数据架构在训练期间和进行预测时共享。要共享资源,请创建ConsoleTraining 和 BlazorWebApp 项目共享的类库。在解决方案目录中,输入以下命令:

    dotnet new classlib -o SchemaLibrary

    安装Microsoft.ML NuGet 包(此解决方案是使用版本 1.4.0 构建的)。整个解决方案都使用Microsoft.ML包。

    dotnet add SchemaLibrary package Microsoft.ML

    将库项目添加到解决方案。

    dotnet sln add SchemaLibrary

    创建训练控制台应用程序

    控制台应用程序包含用于训练模型的一系列数据转换和算法。在解决方案目录中,创建新的控制台应用程序。

    dotnet new console -o TrainingConsole

    将控制台应用程序添加到解决方案。

    dotnet sln add TrainingConsole

    引用 SchemaLibrary 项目。

    dotnet add TrainingConsole reference SchemaLibrary

    创建 Blazor WebAssembly Web 应用程序

    Web 应用程序包含一些输入元素,因此用户可以提供模型随后用于进行预测的新数据。在解决方案目录中,创建新的 Blazor WebAssembly 应用程序。

    dotnet new blazorwasm -o BlazorWebApp

    将 Web 应用程序项目添加到解决方案。

    dotnet sln add BlazorWebApp

    引用 SchemaLibrary 项目。

    dotnet add BlazorWebApp reference SchemaLibrary

    定义架构

    了解数据

    用于训练模型的数据来自iris dataset。它包含四个数值列,即花瓣和萼片的度量,最后一列为鸢尾花的种类。这是数据的示例。

    Sepal length (cm)Sepal width (cm)Petal length (cm)Petal width (cm)Class (iris species)
    5.13.51.40.2Iris-setosa
    7.03.24.71.4Iris-versicolor
    6.33.36.02.5Iris-virginica

    定义模型输入架构

    SchemaLibrary项目中,创建一个ModelInput类,用于数据建模并作为模型输入。 

    ni ModelInput.cs

    ModelInput类应如下所示:

    using Microsoft.ML.Data;namespace SchemaLibrary
    {
    public class ModelInput
    {
    [LoadColumn(
    0)]public float SepalLength { get; set; }
    [LoadColumn(
    1)]public float SepalWidth { get; set; }
    [LoadColumn(
    2)]public float PetalLength { get; set; }
    [LoadColumn(
    3)]public float PetalWidth { get; set; }
    [LoadColumn(
    4)]public string Label { get; set; }
    }
    }

    请注意,该列现在是一个称为ClassLabel的属性。原因有二:

    1. 避免使用class关键字。

    2. 在ML.NET中,算法要预测的列的默认列名称为Label。

    另请注意每个属性顶部的LoadColumn属性。这用于告诉加载程序列的索引,其中相应属性的数据所在的位置。

    定义模型输出架构

    与输入架构类似,有模型输出的架构。此解决方案中使用的模型类型是多类分类模型,因为鸢尾花种有两个以上类别可供选择。多分类模型输出称为一个列,该列包含预测类别的名称。在SchemaLibrary项目中,创建一个PredictedLabelModelOutput类,用于对模型所做的预测建模。 

    ni ModelOutput.cs

    ModelOutput类应如下所示:

    namespace SchemaLibrary
    {
    public class ModelOutput
    {
    public string PredictedLabel { get; set; }
    }
    }

    训练模型

    现在是时候创建训练模型的应用程序了。

    获取数据

    下载数据并将其保存在TrainingConsole项目目录中。

    curl https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data -o iris.data

    定义数据准备和训练步骤

    TrainingConsole项目中,打开Program.cs文件,并在顶部添加以下内容:

    using System;using System.Linq;using Microsoft.ML;using SchemaLibrary;

    然后,删除Main方法内的内容,并将其替换为以下内容。

    // 1. Initialize MLContext
    MLContext mlContext = new MLContext();// 2. Load the data
    IDataView data = mlContext.Data.LoadFromTextFile("iris.data", separatorChar:',');// 3. Shuffle the data
    IDataView shuffledData = mlContext.Data.ShuffleRows(data);// 3. Define the data preparation and training pipeline.
    IEstimator pipeline =
    mlContext.Transforms.Concatenate(
    "Features","SepalLength","SepalWidth","PetalLength","PetalWidth")
    .Append(mlContext.Transforms.NormalizeMinMax(
    "Features"))
    .Append(mlContext.Transforms.Conversion.MapValueToKey(
    "Label"))
    .Append(mlContext.MulticlassClassification.Trainers.NaiveBayes())
    .Append(mlContext.Transforms.Conversion.MapKeyToValue(
    "PredictedLabel"));// 4. Train with cross-validationvar cvResults = mlContext.MulticlassClassification.CrossValidate(shuffledData, pipeline);// 5. Get the highest performing model and its accuracy
    (ITransformer, double) model =
    cvResults
    .OrderByDescending(fold
    => fold.Metrics.MacroAccuracy)
    .Select(fold
    => (fold.Model, fold.Metrics.MacroAccuracy))
    .First();
    Console.WriteLine($
    "Top performing model's macro-accuracy: {model.Item2}");// 6. Save the model
    mlContext.Model.Save(model.Item1, data.Schema, "model.zip");
    Console.WriteLine(
    "Model trained");

    训练应用程序从文件iris.data加载数据并应用一系列转换。首先,所有单独的数字列都合并到单个矢量中,并存储在称为Features的新列中。然后,该Features列需要预处理归一化,MapValueToKey转换用于将Label列中的文本转换为数字。然后,转换后的数据用于使用NaiveBayes算法训练模型。请注意,在撰写本文时,对于多分类问题,只有 Naive Bayes 已确认与 Blazor WebAssembly 合作。最后,将PredictedLabel存储为数字,以便必须将其转换回文本。

    使用Fit方法,将数据应用于管道。由于数据集很小,因此使用称为交叉验证的技术来构建更健壮的模型。训练模型后,具有最高性能的模型将序列化并保存到名为model.zip的文件,以供以后在 Web 应用程序中使用。

    最终Program.cs文件应类似于以下内容:

    using System;using System.Linq;using Microsoft.ML;using SchemaLibrary;namespace TrainingConsole
    {
    class Program
    {
    static void Main(string[] args)
    {
    // 1. Initialize MLContext
    MLContext mlContext = new MLContext();// 2. Load the data
    IDataView data = mlContext.Data.LoadFromTextFile("iris.data", separatorChar:',');// 3. Shuffle the data
    IDataView shuffledData = mlContext.Data.ShuffleRows(data);// 3. Define the data preparation and training pipeline.
    IEstimator pipeline =
    mlContext.Transforms.Concatenate(
    "Features","SepalLength","SepalWidth","PetalLength","PetalWidth")
    .Append(mlContext.Transforms.NormalizeMinMax(
    "Features"))
    .Append(mlContext.Transforms.Conversion.MapValueToKey(
    "Label"))
    .Append(mlContext.MulticlassClassification.Trainers.NaiveBayes())
    .Append(mlContext.Transforms.Conversion.MapKeyToValue(
    "PredictedLabel"));// 4. Train with cross-validationvar cvResults = mlContext.MulticlassClassification.CrossValidate(shuffledData, pipeline);// 5. Get the highest performing model and its accuracy
    (ITransformer, double) model =
    cvResults
    .OrderByDescending(fold
    => fold.Metrics.MacroAccuracy)
    .Select(fold
    => (fold.Model, fold.Metrics.MacroAccuracy))
    .First();
    Console.WriteLine($
    "Top performing model's macro-accuracy: {model.Item2}");// 6. Save the model
    mlContext.Model.Save(model.Item1, data.Schema, "model.zip");
    Console.WriteLine(
    "Model trained");
    }
    }
    }

    运行应用程序

    TrainConsole项目目录中,使用以下命令运行应用程序并训练模型:

    dotnet run

    托管模型

    保存模型后,使用 Azure 门户创建 Azure 存储帐户。

    6487933f7c45e4050c928b64ee9a6208.png

    然后,导航到新创建的存储帐户资源,并创建名为models的 Blob 容器。

    9254f07130f6b7a6468664ba162490a6.png

     创建容器后,导航到它并上传model.zip文件。

    9cbd29dbdbbaf2a120224151361b4b42.png  

    创建预测网页

    要进行预测,请创建一个网页以获取用户输入。然后向模型提供用户输入,并将预测显示给用户。

    设置导入

    BlazorWebApp项目目录中,打开_Imports.razor文件。这包含应用程序中页面和组件的 using 语句。添加以下使用语句:

    @using System.IO
    @using Microsoft.ML
    @using SchemaLibrary

    创建用户输入页

    BlazorWebApp项目中,在Pages目录中创建一个名为"Prediction.razor"的新razor页面。

    ni Prediction.razor

    向其中添加以下内容:

    @page "/prediction"
    @inject HttpClient _client
    <label>Sepal Length: label><input type="text" @bind="_sepalLength"><br><label>Sepal Width: label><input type="text" @bind="_sepalWidth"><br><label>Petal Length: label><input type="text" @bind="_petalLength"><br><label>Petal Width: label><input type="text" @bind="_petalWidth"><br><button @onclick="GetPrediction">Make predictionbutton>
    @if(@ModelPrediction == null)
    {
    <p>Enter data to get a predictionp>
    } else
    {
    <p>@ModelPredictionp>
    }
    @code {
    private PredictionEngine
    <ModelInput,ModelOutput> _predictionEngine;
    private string _sepalLength, _sepalWidth, _petalLength, _petalWidth, ModelPrediction;
    protected override async Task OnInitializedAsync()
    {
    Stream savedModel = await _client.GetStreamAsync("
    <YOUR-MODEL-ENDPOINT>");
    MLContext mlContext = new MLContext();
    ITransformer _model = mlContext.Model.Load(savedModel,out DataViewSchema schema);
    _predictionEngine = mlContext.Model.CreatePredictionEngine
    <ModelInput,ModelOutput>(_model);
    }
    private void GetPrediction()
    {
    ModelInput input = new ModelInput
    {
    SepalLength=float.Parse(_sepalLength),
    SepalWidth=float.Parse(_sepalWidth),
    PetalLength=float.Parse(_petalLength),
    PetalWidth=float.Parse(_petalWidth)
    };
    ModelOutput prediction = _predictionEngine.Predict(input);
    ModelPrediction = prediction.PredictedLabel;
    }
    }

    Prediction.razor页包含模型原始训练的每个列的文本输入元素。初始化页面时,将从 Azure 存储加载模型并创建PredictionEngine请确保将替换为包含模型的 blob 的 URL。PredictionEngine是进行单个预测的便利 API。传统上,当模型用作 Web 服务时,建议使用该PredictionEnginePool服务,因为它在多线程应用程序中具有线程安全且性能更高。但是,在这种情况下,由于模型被下载到单个用户的浏览器上,因此可以使用PredictionEngine。用户输入输入值并单击"创建预测"按钮后,该GetPrediction方法通过获取用户输入并使用PredictionEngine进行预测来执行。然后,预测将显示在浏览器中。

    添加到导航菜单

    BlazorWebApp项目中,在Shared目录中打开NavMenu.razor文件。

    将以下列表项添加到元素。

    <li class="nav-item px-3"><NavLink class="nav-link" href="prediction"><span class="oi oi-list-rich" aria-hidden="true">span> PredictionNavLink>li>

    最终的NavMenu.razor页面应如下所示:

    <div class="top-row pl-4 navbar navbar-dark"><a class="navbar-brand" href="">BlazorWebAppa><button class="navbar-toggler" @onclick="ToggleNavMenu"><span class="navbar-toggler-icon">span>button>div><div class="@NavMenuCssClass" @onclick="ToggleNavMenu"><ul class="nav flex-column"><li class="nav-item px-3"><NavLink class="nav-link" href="" Match="NavLinkMatch.All"><span class="oi oi-home" aria-hidden="true">span> HomeNavLink>li><li class="nav-item px-3"><NavLink class="nav-link" href="counter"><span class="oi oi-plus" aria-hidden="true">span> CounterNavLink>li><li class="nav-item px-3"><NavLink class="nav-link" href="fetchdata"><span class="oi oi-list-rich" aria-hidden="true">span> Fetch dataNavLink>li><li class="nav-item px-3"><NavLink class="nav-link" href="prediction"><span class="oi oi-list-rich" aria-hidden="true">span> PredictionNavLink>li>ul>div>
    @code {
    private bool collapseNavMenu = true;
    private string NavMenuCssClass => collapseNavMenu ? "collapse" : null;
    private void ToggleNavMenu()
    {
    collapseNavMenu = !collapseNavMenu;
    }
    }

    配置 Web 应用程序

    Web 应用程序将作为 Azure 存储上的静态站点托管。

    在 Azure 门户中,导航到托管模型的存储帐户资源。

    启用静态网站

    为存储帐户启用静态网站,并将索引文档名称和错误文档路径设置为index.html

    a96980699af1f2639903f126e4ca0b98.png

     此时,在存储帐户中创建了名为$web的新容器。这是您网站的所有静态文件将驻留的位置。此外,还会创建一个主终结点。这是您将用于访问应用程序的 URL

    配置 CORS

    存储帐户具有一些默认的 CORS 设置。为了从应用程序下载和使用模型,您必须对其进行配置。

    78d922e5f85f8108bce2a881135a1d18.png

    对于"Allowed origins",请输入主终结点。

    发布和部署 Web 应用程序

    要发布应用程序,请运行以下命令:

    dotnet publish -c Release

    这将生成在BlazorWebApp项目的 bin/Release/netstandard2.1/publish/BlazorWebApp/dist 目录中所需的文件托管为Web 应用程序静态网站。

    要部署应用程序,请使用 Azure 存储资源管理器将dist目录中的所有文件复制到 Azure 存储帐户的$web容器中。

    841b5d6fe13c806601c66b008f2c8170.png

    测试应用程序

    在浏览器中,导航到静态网站的主终结点,然后选择"Prediction"页。输入数据并单击"Make prediction"。页面应如下所示。

    d21bd57cc0953228689d55d6bcc41a01.png

    您可能会注意到,Naive Bayes 在此数据集上的性能不是最好的,因此某些预测可能不太准确。我现在可以接受这一点,因为这是一个概念验证,以展示这些技术如何协同工作。也许使用更好的数据集可以产生更好的结果。

    结论

    在这篇文章中,我考虑如何将ML.NET多分类模型与 Blazor WebAssembly 静态网站一起部署到 Azure。虽然由于 WebAssembly 和 Blazor WebAssembly 的早期阶段,与其他部署方法相比,这一点更为有限,但这表明了这些技术的可能性。以这种方式部署可减少部署这些模型所需的资源量,并将处理从服务器或 Web 服务转移到客户端的浏览器,从而使机器学习模型的部署和分发更加高效、可扩展且更具成本效益。

    展开全文
  • 静态模型,动态模型!

    千次阅读 2016-12-09 15:52:17
    在上一节的4.4 -隐式类型转换(强制),你知道,编译器有时会隐式转换一个值从一个数据类型到另一个。当您想从一个数据类型提升到一个更大的类似数据类型的值时,使用隐式类型转换系统是好的。 许多新的程序员...
    在上一节中的4.4 -隐式类型转换(强制),你知道,编译器有时会隐式转换一个值从一个数据类型到另一个。当您想从一个数据类型提升到一个更大的类似数据类型的值时,使用隐式类型转换系统是好的。
    许多新的程序员尝试这样的东西:浮动F = 10 / 4;。然而,因为10和4都是整数,没有升级发生。在10 / 4上执行整数除法,产生2的值,然后将其隐式转换为2,并赋给F!
    在使用文本值(如10或4)的情况下,用浮点文本值(或10)替换一个或两个整数的文本值(或4),将导致两个操作数转换为浮点值,并使用浮点数学来完成除法运算。

    但是,如果你使用的变量是什么?考虑这种情况:


    int i1 = 10;
    int i2 = 4;
    float f = i1 / i2;

    变量F将以2的值结束。我们如何告诉编译器,我们要使用浮点除法,而不是整数除法?答案是通过使用一种类型的操作符(通常被称为一个演员)来告诉编译器做显式类型转换。一个演员是由程序员做一个类型转换的一个明确的要求。
    型铸造
    在C++中,有5种不同类型的转换:C风格转换,静态模型,动态模型,并将const,reinterpret cast。
    我们将在本课C风格转换和静态模型。动态转换,我们将保存,直到我们覆盖指针和继承。
    const转换和reinterpret cast一般应避免因为他们在罕见的情况下才有用,可能是有害的如果使用不当。
    规则:避免const转换和reinterpret cast的除非你有一个很好的理由去使用它们。
    2
    3
    int i1 = 10;
    int i2 = 4;
    float f = (float)i1 / i2;

    static_cast的主要优点是它提供了编译时类型检查,很难做一个无心的错误。static_cast也(故意)比C风格转换不那么强大,所以你不能不小心删除const或你可能没有打算做其他的事情。
    使用强制转换来进行隐式转换清除
    当执行不安全的隐式类型转换时,编译器会经常抱怨。例如,考虑下面的程序:
    展开全文
  • 沉井下沉过程中静态力学模型的建立与应用,楼淑君,何俊裕,本文前人的基础上,利用已有的地基极限承载力公式,推算沉井刃脚反力;并结合已有的沉井侧摩阻力计算公式,建立了沉井下沉过程
  • 图1:场景混合阴影效果示例上图,方块和地板为场景静态模型,近处地板上阴影清晰的部分为方块和角色的实时阴影,远处红框选中部分为方块的静态阴影。这里把地板的LightMap烘焙质量调低,同时把CSM的清晰度调高,让...

    62fe6772062085798875fc5e73926866.png

    前言

    UE4的场景阴影采用静态和实时混合的计算方式:CSM(级联阴影)范围内的阴影通过实时计算得到,CSM范围外的阴影信息从预烘焙的静态贴图中获取。

    292b4159bfcd22f1c0f11a57df8e8092.png
    图1:场景混合阴影效果示例

    上图中,方块和地板为场景静态模型,近处地板上阴影清晰的部分为方块和角色的实时阴影,远处红框选中部分为方块的静态阴影。

    这里把地板的LightMap烘焙质量调低,同时把CSM的清晰度调高,让CSM范围边界更明显。

    预烘焙的灯光信息存储在离线构建的贴图“簇”中,包含存储颜色信息的LightMap贴图和存储静态阴影信息的ShadowMask贴图。

    c6ec626f431f062e1f2f446d80298f87.png
    图2:ShadowMask贴图

    上图为所示场景的ShadowMask贴图,其中红框选中部分为地板在ShadowMask贴图中的占用部分。

    在移动端的灯光方案中,一般不会为场景开启实时阴影。没有场景实时的阴影遮挡,角色能否获取场景阴影信息用于渲染呢?

    实现

    在光源方向不变的前提下,场景静态阴影跟实时阴影的信息是一致的,角色虽然没有静态阴影信息,但所处的地面静态模型有。

    实现过程为:在角色位置向下Trace地面,获取碰撞地面模型关联的ShadowMask贴图和坐标ScaleBias,再根据碰撞三角面插值得到角色位置的LightMapUV坐标,最后用该坐标结合ScaleBias去采样ShadowMask贴图。

    1.获取ShadowMask贴图

    静态Mesh烘焙相关的LightMap、ShadowMask贴图等通过FPrimitiveSceneProxy的FLightCacheInterface接口获取:

    FPrimitiveSceneProxy::FLCIArray LCIs;
    PrimitiveSceneProxy->GetLCIs(LCIs);
    const FLightmapResourceCluster* LRC = LCIs[0]->GetResourceCluster();
    UTexture* ShadowMaskTexture = (UTexture*)LRC->Input.ShadowMapTexture;

    2.获取坐标ScaleBias

    每个静态Mesh有自己唯一的坐标ScaleBias,用于结合LightMapUV坐标,“标识”在贴图中的采样区域,同样通过FLightCacheInterface获取:

    const FShadowMapInteraction ShadowMapInteraction = LCIs[0] ? LCIs[0]->GetShadowMapInteraction(GMaxRHIFeatureLevel) : FShadowMapInteraction();
    if (ShadowMapInteraction.GetType() == SMIT_Texture)
    {
        CoordinateScaleBias = FVector4(ShadowMapInteraction.GetCoordinateScale(), ShadowMapInteraction.GetCoordinateBias());
    }

    在Unity中,烘焙得到的ShadowMask贴图布局跟LightMap贴图布局一样,LightMapUV坐标没有ScaleBias的转换过程。

    3.获取LightMapUV坐标

    碰撞返回的FHitResult对象的FaceIndex成员记录了碰撞三角面的索引,通过FaceIndex可以获取三角面的LightMapUV坐标信息:

     int32 Index0 = Indices[IndexBufferIdx];
     int32 Index1 = Indices[IndexBufferIdx + 1];
     int32 Index2 = Indices[IndexBufferIdx + 2];
     
     FVector2D LightMapUV0 = StaticMeshVertexBuffer.GetVertexUV(Index0, 1);
     FVector2D LightMapUV1 = StaticMeshVertexBuffer.GetVertexUV(Index1, 1);
     FVector2D LightMapUV2 = StaticMeshVertexBuffer.GetVertexUV(Index2, 1);

    代码中的3个LightMapUV?为碰撞三角面的3个顶点的LightMapUV坐标,碰撞点的LightMapUV坐标由它们插值得到,插值算法为通过世界坐标插值:

     FVector WorldVert0 = InStaticMeshComponent->GetComponentTransform().TransformPosition(PositionVertexBuffer.VertexPosition(Index0));
     FVector WorldVert1 = InStaticMeshComponent->GetComponentTransform().TransformPosition(PositionVertexBuffer.VertexPosition(Index1));
     FVector WorldVert2 = InStaticMeshComponent->GetComponentTransform().TransformPosition(PositionVertexBuffer.VertexPosition(Index2));
     FVector BaryCoords = FMath::GetBaryCentric2D(InHitLocation, WorldVert0, WorldVert1, WorldVert2);
     
     FVector2D InterpLightMapUV = BaryCoords.X * LightMapUV0 + BaryCoords.Y * LightMapUV1 + BaryCoords.Z * LightMapUV2;
     
     OutLightMapUV = InterpLightMapUV;

    因为这里涉及到CPU端访问Mesh的顶点、索引信息 ,所以确保地面模型Mesh开启Allow CPUAccess选项。

    4.传递材质参数

    上面获取的3类参数传递给材质,材质结点图为:

    b55f22a051dae0149b89b6704248ef63.png
    图3:材质结点图

    图中结点实现LightMapUV坐标与ScaleBias的结合方式,等同与EngineShadersPrivateLocalVertexFactory.ush中的计算公式:

    ShadowMapCoordinate = LightMapCoordinateInput * ShadowMapCoordinateScaleBias.xy + ShadowMapCoordinateScaleBias.zw;

    计算得到UV用于采样ShadowMask贴图,采样结果的r通道输出到ShadowMapMask,ShadowMapMask为自定义的CustomOutput结点。

    添加自定义的CustomOutput结点需要修改引擎代码,也可以把现有不用的自定义结点开放出来传递。

    5.修改引擎Shader

    在EngineShadersPrivateMobileBasePassPixelShader.usf文件中添加:

    #if NUM_MATERIAL_OUTPUTS_GETSHADOWMAPMASK > 0
        Shadow = GetShadowMapMask0(MaterialParameters);
    #endif

    代码中的GetShadowMapMask0返回之前自定义CustomOutput结点的输出值,这样角色便拿到了所处地面的静态阴影信息。

    效果

    805657cd1e5afef80ca0d98e2fbfd7ab.png
    图四:修改前后效果对比

    e495b8997f0425862d71cb1a887b8f03.gif
    图五:动态展示

    完整Demo工程:

    https://github.com/chenyong2github/ShadowMapMaskDemogithub.com

    UE4引擎修改库(基于4.24.3版本):

    https://github.com/chenyong2github/UnrealEnginegithub.com

    本文的实现方法是处理移动端缺少场景阴影遮挡信息,角色在场景阴影区暗不下来的一种解决方案。场景预烘焙的Lighting Samples使角色适配场景的明暗,阴影遮挡是对其的补充,想象一下角色在阴影区被直接光照亮。不过因为本文的实现——角色是作为整个模型来判断是否在阴影中,所有无法做到像实时阴影那种半身阴影的效果。

    最后再提一下另外一种实现方式——在角色位置去Trace光源位置,射线跟场景有碰撞的话就认为是在阴影中,这种方式实现简单,获取阴影遮罩信息可能也是够的,但是本文是实现方式扩展性要更好,比如不仅想获取角色所处位置的阴影信息,还想获取LightMap信息,so~~~

    参考文献:

    [1] https://forums.unrealengine.com/development-discussion/blueprint-visual-scripting/108614-getvertexcolordata-not-working-on-packaged-build

    展开全文
  • 组件图-静态模型

    2019-09-13 12:39:39
    组件图也被描述为一个静态的实施的系统视图,一个特定的时刻,静态执行代表组织的组成部分。 一个单一的组件图不能代表整个系统,但图的集合可用来代表整个。 组件图的目的概括如下: 可视化系统...
  • 对比分析了现有词包式、层次树式和链式这3类主流话题模型的形态特征,尤其深入探讨了静态和动态话题模型拟合话题脉络的优势和劣势,并提出一种基于特征重叠比的核捕捉衰减评价策略,专门用于衡量静态和动态话题模型追踪...
  • <p>Eloquent provides almost all methods as <code>static</code> methods. I need to add my custom methods in model.... What's best in terms of implementation and performance? </div>
  • 版块汇总建模和应用数学模型工程实例工具箱-6 静态优化模型.pdf 下面使我们建模,学习,应用经常用到的一些数学模型,期望对您的工作学习有所帮助。
  • 在静态,可以使用动态图的方法,即正向使用动态图,反向使用静态图,这样就可以兼顾二者的优势。 在具体实现上,仍然以静态图为主要部分,在需要使用动态图模型的部分时,可以调用 tf.py_function函数实现动态...
  • 考虑了一个具有高斯帽形项和宇宙学常数项的(n + 1)维引力模型。 当采用具有对角线宇宙学度量的ansatz时,对于n> 3,分析与比例因子aiiexp(vit),i = 1 ,,, n呈指数关系的解。 我们研究具有非静态体积因数(即K...
  • 静态网格模型组件可以将一个几何体用作...Static Mesh 是一个包含一组静态多边形的几何体,是虚幻引擎 4 的场景创建世界几何体所用的基本单位。除构建场景外,静态网格模型还能用于创建运动体(如门或电梯)、刚体
  • 目前对C/C++漏洞的检测,研究比较深入的是针对源代码的静态扫描技术,主要的静态分析方法有以下几类。  词法分析:是早被用来进行缓冲区溢出漏洞检测的方法。这种方法是对软件源程序进行扫描分析,同时与特征库...
  • 建立自己的3D静态模型文件

    千次阅读 2007-04-15 09:23:00
    我有一个能画出微软例子tiger.x的工程,其中创建Mesh的代码片断如下(代码有一些变量.h文档定义的): HRESULT CMyMesh::Create( LPDIRECT3DDEVICE9 pDevice, string MeshFile ) { if( pDevice == NULL )...
  • 机器学习工程模型持久化是一个不可或缺的操作,无论是训练工程用于容灾的断点续训 (re-training)、模型调优的 fine-tuning,还是模型训练完成后部署到线上推理环境,都需要对模型进行序列化和反序列化。...
  • 今日问题1问题:我的数据是微观企业的平衡面板数据,...今日解答1 解答:如果想在模型中加入行业固定和地区固定,那么需要两步完成:第一步,将行业和地区转化为数值型,具体的转换方法,可以encode命令将字符转化为...
  • 针对静态手势识别任务,传统基于人工提取特征方法耗时耗力,识别率较低,现有卷积神经网络依赖单一卷积核提取特征不够充分的问题,提出双通道卷积神经网络模型。输入手势图片通过两个相互独立的通道进行特征提取,...
  • 然后,基于静态贝叶斯博弈预测恶意程序的传染行为,得到博弈双方基于贝叶斯纳什均衡(Bayesian Nash equilibrium,BNE)确定的最优行动,并将其应用到上述传染模型,从而揭示恶意程序WSN的传染动力学特征。...
  • 针对静态膨胀生裂技术问题,通过参考文献的实测数据和理论推导,...建立实验模型测试静态膨胀剂突出煤体的致裂效果。此次实验测试,水泥槽实验模型突出煤体发生了裂隙发育、裂隙传播和裂隙扩展贯通3个明显变化过程。
  • 静态属性包含要封装的数据,可以由所有类的实例共享。实际上,除了属于一个固定的类并限制访问方式外,类的静态属性非常类似于函数的全局变量。 我们在下例使用了一个静态属性Counter::$count。它属于...
  • 首先我们先来说说jvm内存模型:jvm内存分为:方法区、堆、栈和程序计数器。下面我们来简单的说说方法区、栈和堆:方法区:是各个线程共享的区域,存放类信息/常量/静态变量;栈:其实每个线程都会分配一个栈,其生命...
  • 一个出行时间不确定的网络, 路径的实际到达时间也是不确定的, 以偏好到达时间为分界点, 本文对实际到达时间所处的可能区域进行了划分, 累积前景理论框架下建立了到达时间感知价值函数, 此基础上假设累积感知...
  •  这几天一直研究怎样取得由静态模型(.x)所建立的地形取得对应坐标的高度值。期间研究了很多的问题,.x文件的格式,从mesh的buffer读取得到其顶点信息,射线跟面的相交检测等等。最后终于做了个实验...
  • C++和蓝图各自有各自的痛点,真希望UE4能够二者之间再增加一种脚本语言,那就完美了。目前的话,C++和蓝图结合的开发方式应该算是最佳实践了 这个简单的例子,体现了UE4 C++和蓝图的合作方式 C++侧重于宏观以及...
  • 介绍了当前主流的静态代码分析技术,分析讨论其优缺点的基础上提出了一种新的静态代码检测模型。该模型结合了当前成熟的静态分析技术,并借鉴了编译器数据流和控制流分析的思想,获取上下文关联的数据信息,从而...
  • Unity3D ShaderLab 静态贴图光照模型

    千次阅读 2015-02-01 23:40:37
    其实unity的光照模型中,我们可以把光照讯息烘培进入一个2D贴图,来实现着色器的光照效果。  更多精彩请关注【狗刨学习网】  下面是unity中关闭灯光和打开灯光的对比效果。所以这类着色器的缺点就是...
  • 今日问题1问题:我的数据是微观企业的平衡面板...今日解答1 解答:如果想在模型中加入行业固定和地区固定,那么需要两步完成:第一步,将行业和地区转化为数值型,具体的转换方法,可以encode命令将字符转化为数值;...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,044
精华内容 2,417
关键字:

在静态模型中