3D 模型渲染
- 模型(Model)
-
- Primitives 简单的模型
- 复杂的模型
- 模型的组成
-
- 几何
- 纹理图片
- 材质模型及描述
- 模型文件格式
- 什么叫渲染
- 渲染管线
-
- 顶点着色(顶点处理)
- 片段着色(片段处理)
- UE4 模型渲染
-
- UE4程序化模型渲染
-
- UProceduralMeshComponent
- UStaticMeshComponent
- UPrimitiveComponent&UMeshComponent
- 参考
模型(Model)
Primitives 简单的模型
复杂的模型
模型的组成
几何
例如最简单的obj格式的模型文件存储的内容:
纹理图片
材质模型及描述
- MeshBasicMaterial(贴图或本身颜色
- MeshLambertMaterial(基于顶点)
- MeshPhongMaterial (基于像素)
- MeshStandardMaterial (粗糙度和金属度)
- MeshPhysicalMaterial
模型文件格式
模型的格式有很多中,如obj、gltf、stl、fbx、3dmax、OSGB、3DTiles、Revit及IFC等等,除了以上最基本的数据外,还保存了其他诸如场景关系、属性数据、拓扑数据及动画骨骼数据等等。
什么叫渲染
简单来说就是用Image来表达Model,即几何数据(3D&2D Model)的可视化展现。
渲染管线
顶点着色(顶点处理)
一个顶点着色器的工作是生成裁剪空间坐标值。
模型中几何顶点数据大都是以局部坐标存储的,即模型的中心点在模型上或是附近。将模型渲染到屏幕上需要进行的一系列坐标转换(Transform)。
UE4 封装的相关函数:
void FSceneView::DeprojectScreenToWorldconst FVector2D& ScreenPos, const FIntRect& ViewRect, const FMatrix& InvViewProjMatrix, FVector& out_WorldOrigin, FVector& out_WorldDirection)
{float PixelX = FMath::TruncToFloatScreenPos.X);float PixelY = FMath::TruncToFloatScreenPos.Y);// Get the eye position and direction of the mouse cursor in two stages inverse transform projection, then inverse transform view).// This avoids the numerical instability that occurs when a view matrix with large translation is composed with a projection matrix// Get the pixel coordinates into 0..1 normalized coordinates within the constrained view rectangleconst float NormalizedX = PixelX - ViewRect.Min.X) / float)ViewRect.Width));const float NormalizedY = PixelY - ViewRect.Min.Y) / float)ViewRect.Height));// Get the pixel coordinates into -1..1 projection spaceconst float ScreenSpaceX = NormalizedX - 0.5f) * 2.0f;const float ScreenSpaceY = 1.0f - NormalizedY) - 0.5f) * 2.0f;// The start of the ray trace is defined to be at mousex,mousey,1 in projection space z=1 is near, z=0 is far - this gives us better precision)// To get the direction of the ray trace we need to use any z between the near and the far plane, so let's use mousex, mousey, 0.5)const FVector4 RayStartProjectionSpace = FVector4ScreenSpaceX, ScreenSpaceY, 1.0f, 1.0f);const FVector4 RayEndProjectionSpace = FVector4ScreenSpaceX, ScreenSpaceY, 0.5f, 1.0f);// Projection changing the W coordinate) is not handled by the FMatrix transforms that work with vectors, so multiplications// by the projection matrix should use homogeneous coordinates i.e. FPlane).const FVector4 HGRayStartWorldSpace = InvViewProjMatrix.TransformFVector4RayStartProjectionSpace);const FVector4 HGRayEndWorldSpace = InvViewProjMatrix.TransformFVector4RayEndProjectionSpace);FVector RayStartWorldSpaceHGRayStartWorldSpace.X, HGRayStartWorldSpace.Y, HGRayStartWorldSpace.Z);FVector RayEndWorldSpaceHGRayEndWorldSpace.X, HGRayEndWorldSpace.Y, HGRayEndWorldSpace.Z);// divide vectors by W to undo any projection and get the 3-space coordinateif HGRayStartWorldSpace.W != 0.0f){RayStartWorldSpace /= HGRayStartWorldSpace.W;}if HGRayEndWorldSpace.W != 0.0f){RayEndWorldSpace /= HGRayEndWorldSpace.W;}const FVector RayDirWorldSpace = RayEndWorldSpace - RayStartWorldSpace).GetSafeNormal);// Finally, store the results in the outputsout_WorldOrigin = RayStartWorldSpace;out_WorldDirection = RayDirWorldSpace;
}
bool FSceneView::ProjectWorldToScreenconst FVector& WorldPosition, const FIntRect& ViewRect, const FMatrix& ViewProjectionMatrix, FVector2D& out_ScreenPos)
{FPlane Result = ViewProjectionMatrix.TransformFVector4FVector4WorldPosition, 1.f));if Result.W > 0.0f ){// the result of this will be x and y coords in -1..1 projection spaceconst float RHW = 1.0f / Result.W;FPlane PosInScreenSpace = FPlaneResult.X * RHW, Result.Y * RHW, Result.Z * RHW, Result.W);// Move from projection space to normalized 0..1 UI spaceconst float NormalizedX = PosInScreenSpace.X / 2.f ) + 0.5f;const float NormalizedY = 1.f - PosInScreenSpace.Y / 2.f ) - 0.5f;FVector2D RayStartViewRectSpace NormalizedX * float)ViewRect.Width) ), NormalizedY * float)ViewRect.Height) ));out_ScreenPos = RayStartViewRectSpace + FVector2Dstatic_cast<float>ViewRect.Min.X), static_cast<float>ViewRect.Min.Y));return true;}return false;
}
片段着色(片段处理)
一个片段着色器的工作是为当前光栅化的像素提供颜色值。
每一个片段(像素)的color值,由你所选的“材质”决定,光照的影响及本身特性(颜色)组合。
UE4 模型渲染
UE4 引擎提供了强大的编辑器(场景编辑器、材质编辑器及蓝图编辑器等等),大大简化三维渲染的复杂性。
- 场景编辑器:模型的拖动、缩放和旋转,简单操作就可以实现局部坐标到世界坐标的转换。
- 材质编辑器:不用考虑复杂的顶点着色和片段着色器代码的编写(HLSL)。
- 蓝图编辑器:不用写C++代码,就可以完成一些游戏逻辑。
UE4程序化模型渲染
在UE4开发中, 通常用到的Mesh有StaticMesh,SkeletalMesh,ProceduralMesh等等, 它们对应都有相应的渲染组件如UStaticMeshComponent, UProceduralMeshComponent, 本质上这些Mesh组件都继承了UPrimitiveComponent, UPrimitiveComponent通过FPrimitiveSceneProxy渲染代理负责将特定的Mesh的渲染数据VertexBuffer, IndexBuffer, Material)从游戏线程送往渲染线程。有时候为了定制某种特殊的Mesh渲染, 我们得自定义新的PrimitiveComponent。当然UProceduralMeshComponent往往满足了定制新的Mesh需求, 但有时候为了进一步的性能或者进行特殊的MeshPass得定制PrimitiveComponent)。
UE4中涉及Mesh Model的组件:
UProceduralMeshComponent
UProceduralMeshComponent* meshComp =NewObject<UProceduralMeshComponent>this, meshName);
meshComp->RegisterComponent);
meshComp->AttachToComponentRootComponent,
UTexture2D* texture = GetTextrue2DmeshInfo->mImageResolutionS, meshInfo->mImageResolutionT, meshInfo->mImageSize, meshInfo->mImageData, meshInfo->mTextureFormat);
TArray<FVector> normals; //法线
TArray<FProcMeshTangent> tangents;
TArray<FLinearColor> vertexColors; //顶点颜色
meshComp->CreateMeshSection_LinearColor0, meshInfo->mVerticeArray, meshInfo->mTriangleArray, normals,meshInfo->mTexCoordArray, vertexColors, tangents, true);
if materialTemp != nullptr)
{UMaterialInstanceDynamic* dynamicMaterial = UMaterialInstanceDynamic::CreatematerialTemp, this);dynamicMaterial->SetTextureParameterValue"PagedLodTex", texture);meshComp->SetMaterial0, dynamicMaterial);
}
UStaticMeshComponent
参考cesium for unreal 相关代码
CesiumForUnreal\Source\CesiumRuntime\Private\CesiumGltfComponent.cpp
UPrimitiveComponent&UMeshComponent
参考电缆Mesh的实现:Engine\Plugins\Runtime\CableComponent\Source\CableComponent\Classes\CableComponent.h
参考
1、https://www.bilibili.com/video/BV1X7411F744/?spm_id_from=333.999.0.0&vd_source=378fcf68e20d55ad4334c47f1ce0a8f7
2、https://www.bilibili.com/video/BV1sN4y1A7Xv/?spm_id_from=333.1007.top_right_bar_window_history.content.click&vd_source=378fcf68e20d55ad4334c47f1ce0a8f7
查看全文
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.dgrt.cn/a/2087742.html
如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!
相关文章:
3D 模型渲染
3D 模型渲染模型(Model)Primitives 简单的模型复杂的模型模型的组成几何纹理图片材质模型及描述模型文件格式什么叫渲染渲染管线顶点着色(顶点处理)片段着色(片段处理)UE4 模型渲染UE4程序化模型渲染UProce……
3月28日,30秒知全网,精选7个热点///对抗衰老和癌症的新方法出现///全国首个半导体领域知识产权运营中心在江苏无锡启动
///一亩田与河南省农业农村厅达成战略合作
根据协议,双方的合作将从高素质农民培训、区域公用品牌建设、农业大数据合作及预制菜产业影响力建设四个方面展开 ///巨人网络携手百度推出首个由国产AI打造的手游形象
巨人同时宣布,将在球球IP赛道开设并面向……
KDZD8600漏电保护检测仪
一、产品概述
KDZD8600漏电保护检测仪是针对漏电保护器检测工作而专门设计生产的一种高效、便携式产品。按照GB16917-1997的要求,可在线、离线测试漏电保护器的动作电流和动作时间。具有操作简便、自动检测、数据保留等特点,适合于用电安检部门和各级供……
Maven:简单的JavaWeb程序有关问题
今天使用Maven创建了一个简单的javaweb程序,遇到了很多奇葩问题,比如:一直提示类不能强制转为servlet,等等。脑瓜子嗡嗡的!!!不过好在不负有心人,在不懈的努力下一个一个的解决了。 ……
【学习笔记】CF794G Replace All
我不好说。这题考场上没推出来。*3400的难度,然而是非常无聊的推式子题。不过看到大家都没推出来我就放心了
第一个结论,对于给定的串s,ts,ts,t,若∣s∣≠∣t∣|s|\ne |t|∣s∣∣t∣,并且其拼接完全相同(至少有一个……
美国网站服务器DDoS攻击原理分析
美国网站服务器的DDoS攻击中文全称为分散式阻断服务攻击,主要的攻击原理是黑客操控大量被入侵的主机,通过进行发送大量无用并无法简单过滤的网络封包,来达到目标美国网站服务器网络瘫痪的目的,也是现今较为普遍的网络攻击方式。本……
eNSP 构建基本WLAN
配置项配置参数AP组 名称:hcia-group 应用模板:域管理模板hcia-domain、VAP模板hcia-vap 域管理模板 名称:hcia-domain 国家码:cn SSID模板 名称:hcia-ssid SSID名称:hcia-wlan 安全模板 名称:h……
LeetCode SQL 511. 游戏玩法分析 I 简单
本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章……
想转行做程序员,该怎么选择开发语言?哪个岗位工资最高?
本文主要针对零基础想了解或者转行从事开发岗的同学。 我们收集了往届毕业同学和一些正在咨询的同学,发现大家在学习初期,对转行互联网做开发,最多的疑问或者顾虑大体分为几类: 现在哪门语言比较火? 学什么语言好找到工……
Generic family ‘sans-serif‘ not found because none of the following families
1背景
python使用matplot绘图标注中文时,出现乱码,部分python代码如下: # 解决中文显示问题plt.rcParams[font.sans-serif] [SimHei]plt.rcParams[axes.unicode_minus] False
2原因
因为上述代码中使用了SimHei字体,但是在当……
vue2+vue3
vue2vue3尚硅谷vue2vue2 课程简介【02:24】vue2 Vue简介【17:59】vue2 Vue官网使用指南【14:07】vue2 搭建Vue开发环境【13:54】vue2 Hello小案例【22:25】了解: 不常用常用:id 更常用 简单class差值总结vue 实例vue 模板 : 先 取 ࿰……
【hello Linux】环境变量
目录 1. 环境变量的概念 2. 常见的环境变量 3. 查看环境变量 4. 和环境变量相关的命令 5. 环境变量的组织方式 6. 通过代码获取环境变量 7. 通过系统调用获取环境变量 Linux🌷 在开始今天的内容之前,先来看一幅图片吧! 不知道你们是否和我一……
【Linux基础】常用命令整理
ls命令
-a选项,可以展示隐藏的文件和文件夹-l选项,以列表形式展示内容-h,需要和-l搭配使用,可以展示文件的大小单位ls -lah等同于la -a -l -h
cd命令(change directory)
语法:cd [Linux路径]……
客快物流大数据项目(一百一十二):初识Spring Cloud
文章目录
初识Spring Cloud
一、Spring Cloud简介
二、SpringCloud 基础架构图…
C和C++中的struct有什么区别
区别一: C语言中: Struct是用户自定义数据类型(UDT)。 C语言中: Struct是抽象数据类型(ADT),支持成员函数的定义。
区别二:
C中的struct是没有权限设置的,……
docker的数据卷详解
数据卷 数据卷是宿主机中的一个目录或文件,当容器目录和数据卷目录绑定后,对方修改会立即同步
一个数据卷可以同时被多个容器同时挂载,一个容器也可以被挂载多个数据卷
数据卷作用:容器数据持久化 /外部机器和容器间接通信 /容器……
13、Qt生成dll-QLibrary方式使用
Qt创建dll,使用QLibrary类方式调用dll
一、创建项目
1、新建项目->其他项目->Empty qmake Project->Choose 2、输入项目名,选择项目位置,下一步 3、选择MinGW,下一步 4、完成 5、.pro中添加TEMPLATE subdirsÿ……
基于mapreduce 的 minHash 矩阵压缩
Minhash作用: 对大矩阵进行降维处理,在进行计算俩个用户之间的相似度。
比如: 俩个用户手机下载的APP的相似度,在一个矩阵中会有很多很多的用户要比较没俩个用户之间的相似度是一个很大的计算任务 如果首先对这个矩阵降维处理&am……
关于hashmap使用迭代器的问题
keySet获得的只是key值的集合,valueSet获得的是value集合,entryset获得的是键值对的集合。 package com.test2.test;import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;public class mapiterator……
Hadoop入口FileSystem HDFS操作 本地文件合并到HDFS和HDFS文件合并
Hadoop 文件API的起点是FileSystem类。这是一个与文件系统交互的抽象类。存在不同的具体实现子类来处理HDFS和本地文件系统。
HDFS接口的FileSystem对象:
Configuration conf new Configuration);
FileSystem hdfs FileSystem.getconf); HDFS直接操作&#x……
编程日记2023/4/16 14:50:36