Games101学习 - 光栅化

Games101中讲解的光栅化的基础知识,本文就来梳理一下。

在UE中使用UTexture2D可以逐像素绘制纹理:
https://blog.csdn.net/grayrail/article/details/142165442

1.绘制三角形

这里可以通过101中讲解的叉积法逐像素绘制三角形:
在这里插入图片描述
绘制效果:
在这里插入图片描述
代码如下:

UTexture2D* UMyBlueprintFunctionLibrary::GenTexture(int32 Width, int32 Height)
{// 创建临时纹理UTexture2D* NewTexture = UTexture2D::CreateTransient(Width, Height);// 配置纹理NewTexture->MipGenSettings = TMGS_NoMipmaps;NewTexture->CompressionSettings = TC_VectorDisplacementmap;NewTexture->SRGB = false;// 锁定纹理数据进行写入FTexture2DMipMap& Mip = NewTexture->PlatformData->Mips[0];void* TextureData = Mip.BulkData.Lock(LOCK_READ_WRITE);// 设置默认颜色为黑色FColor* FormattedImageData = static_cast<FColor*>(TextureData);for (int32 y = 0; y < Height; ++y){for (int32 x = 0; x < Width; ++x){FormattedImageData[y * Width + x] = FColor::Black; // 背景颜色设置为黑色}}// 定义三角形顶点(A, B, C)FVector2D A(Width / 2, Height / 4);  // 三角形顶点AFVector2D B(Width / 4, 3 * Height / 4); // 三角形顶点BFVector2D C(3 * Width / 4, 3 * Height / 4); // 三角形顶点C// 深红色FColor TriangleColor = FColor(139, 0, 0, 255);// 叉乘判断点P是否在三角形ABC内auto IsPointInTriangle = [](const FVector2D& P, const FVector2D& A, const FVector2D& B, const FVector2D& C) -> bool{FVector2D AP = P - A;FVector2D BP = P - B;FVector2D CP = P - C;FVector2D AB = B - A;FVector2D BC = C - B;FVector2D CA = A - C;// 叉乘结果float Cross1 = AB.X * AP.Y - AB.Y * AP.X; // AB 和 AP 的叉乘float Cross2 = BC.X * BP.Y - BC.Y * BP.X; // BC 和 BP 的叉乘float Cross3 = CA.X * CP.Y - CA.Y * CP.X; // CA 和 CP 的叉乘// 如果三个叉乘结果符号相同,则点在三角形内return (Cross1 >= 0 && Cross2 >= 0 && Cross3 >= 0) || (Cross1 <= 0 && Cross2 <= 0 && Cross3 <= 0);};// 超采样抗锯齿:每个像素划分为2x2子像素int32 SubPixelCount = 4; // 超采样为2x2子像素float InvSubPixelCount = 1.0f / SubPixelCount;// 遍历每个像素并应用抗锯齿逻辑for (int32 y = 0; y < Height; ++y){for (int32 x = 0; x < Width; ++x){int32 CoveredSubPixels = 0;// 遍历2x2子像素for (int32 subY = 0; subY < 2; ++subY){for (int32 subX = 0; subX < 2; ++subX){FVector2D SubPixelPos = FVector2D(x + subX / 2, y + (subY + 0.5f) * 0.5f); // 子像素位置if (IsPointInTriangle(SubPixelPos, A, B, C)){CoveredSubPixels++;}}}// 计算覆盖率并设置像素颜色float Coverage = CoveredSubPixels * InvSubPixelCount; // 覆盖率(0 到 1)if (Coverage > 0){// 根据覆盖率设置颜色,颜色的Alpha通道根据Coverage调整FColor FinalColor = TriangleColor;FinalColor.A = FMath::RoundToInt(255 * Coverage); // 根据覆盖率设置透明度FormattedImageData[y * Width + x] = FinalColor;}}}// 解锁纹理数据Mip.BulkData.Unlock();NewTexture->UpdateResource();return NewTexture;
}

注意:如需了解具体的头文件、Build.cs引用等请看上一篇:https://blog.csdn.net/grayrail/article/details/142165442

2.抗锯齿

绘制好的三角形放大看会有锯齿:
在这里插入图片描述
Games101中提到了SSAA(超分辨率抗锯齿/反走样)的方法,来消除锯齿:

在这里插入图片描述
大致思路是将一个像素点划分为多个子像素,例如1个像素点细分为4个子像素,然后做叉积包含判断,如果4个像素点有1个包含,覆盖率结果就是0.25,有2个包含结果就是0.5,根据覆盖率的百分比作为插值系数进行绘制,从而得到更好的效果。

UE中绘制效果:
在这里插入图片描述
代码如下:

UTexture2D* UMyBlueprintFunctionLibrary::GenTexture(int32 Width, int32 Height)
{// 创建临时纹理UTexture2D* NewTexture = UTexture2D::CreateTransient(Width, Height);// 配置纹理NewTexture->MipGenSettings = TMGS_NoMipmaps;NewTexture->CompressionSettings = TC_VectorDisplacementmap;NewTexture->SRGB = false;// 锁定纹理数据进行写入FTexture2DMipMap& Mip = NewTexture->PlatformData->Mips[0];void* TextureData = Mip.BulkData.Lock(LOCK_READ_WRITE);// 设置默认颜色为黑色FColor* FormattedImageData = static_cast<FColor*>(TextureData);for (int32 y = 0; y < Height; ++y){for (int32 x = 0; x < Width; ++x){FormattedImageData[y * Width + x] = FColor::Black; // 背景颜色设置为黑色}}// 定义三角形顶点(A, B, C)FVector2D A(Width / 2, Height / 4);  // 三角形顶点AFVector2D B(Width / 4, 3 * Height / 4); // 三角形顶点BFVector2D C(3 * Width / 4, 3 * Height / 4); // 三角形顶点C// 深红色FColor TriangleColor = FColor(139, 0, 0, 255);// 叉乘判断点P是否在三角形ABC内auto IsPointInTriangle = [](const FVector2D& P, const FVector2D& A, const FVector2D& B, const FVector2D& C) -> bool{FVector2D AP = P - A;FVector2D BP = P - B;FVector2D CP = P - C;FVector2D AB = B - A;FVector2D BC = C - B;FVector2D CA = A - C;// 叉乘结果float Cross1 = AB.X * AP.Y - AB.Y * AP.X; // AB 和 AP 的叉乘float Cross2 = BC.X * BP.Y - BC.Y * BP.X; // BC 和 BP 的叉乘float Cross3 = CA.X * CP.Y - CA.Y * CP.X; // CA 和 CP 的叉乘// 如果三个叉乘结果符号相同,则点在三角形内return (Cross1 >= 0 && Cross2 >= 0 && Cross3 >= 0) || (Cross1 <= 0 && Cross2 <= 0 && Cross3 <= 0);};int SubPixelCount = 8;// 超采样抗锯齿:子像素划分float SubPixelStep = 1.0f / SubPixelCount; // 子像素的步长int32 TotalSubPixels = SubPixelCount * SubPixelCount; // 子像素的总数// 遍历每个像素并应用抗锯齿逻辑for (int32 y = 0; y < Height; ++y){for (int32 x = 0; x < Width; ++x){int32 CoveredSubPixels = 0;// 遍历 SubPixelCount x SubPixelCount 子像素for (int32 subY = 0; subY < SubPixelCount; ++subY){for (int32 subX = 0; subX < SubPixelCount; ++subX){FVector2D SubPixelPos = FVector2D(x + (subX + 0.5f) * SubPixelStep, y + (subY + 0.5f) * SubPixelStep); // 子像素位置if (IsPointInTriangle(SubPixelPos, A, B, C)){CoveredSubPixels++;}}}// 计算覆盖率并设置像素颜色float Coverage = static_cast<float>(CoveredSubPixels) / TotalSubPixels; // 覆盖率(0 到 1)if (Coverage > 0){FColor FinalColor = TriangleColor;FinalColor.R = FMath::RoundToInt(255 * Coverage);FormattedImageData[y * Width + x] = FinalColor;}}}// 解锁纹理数据Mip.BulkData.Unlock();NewTexture->UpdateResource();return NewTexture;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1534084.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

表单标记form

1.form:表单域标记&#xff0c;表示表单范围&#xff0c;所有的表单元素必须放进form标记中 2.input:用来设置表单输入元素&#xff0c;<input>元素根据不同的属性&#xff0c;可以有多种形式&#xff0c;如文本框&#xff08;text&#xff09;,密码框&#xff08;passw…

信息安全数学基础(9)素数的算数基本定理

前言 在信息安全数学基础中&#xff0c;素数的算数基本定理&#xff08;也称为唯一分解定理或算术基本定理&#xff09;是一个极其重要的定理&#xff0c;它描述了正整数如何唯一地分解为素数的乘积。这个定理不仅是数论的基础&#xff0c;也是许多密码学算法&#xff08;如RSA…

Java面试篇基础部分-Java泛型详解

导语   Java中泛型的本质是参数化类型,泛型提供了编译时类型的安全检测机制。泛型机制允许程序在编译的时候检测非法的类型,例如要实现一个对于字符串、整型、浮点型、对象类型等比较其大小的方法,就可以使用泛型,在使用的时候在明确所要比较的数据类型就可以了。 当然如…

OAExploit一款基于OA产品的一键扫描工具

OAExploit一款基于OA产品的一键扫描工具 01 项目介绍 一款扩展性高的渗透测试框架渗透测试框架 出现卡死的几种情况&#xff1a;1.点击按钮太快 2. 打印log 的异常 02 工具展示

【有啥问啥】复习变分下界即证据下界(Evidence Lower Bound, ELBO):原理与应用

复习变分下界即证据下界&#xff08;Evidence Lower Bound, ELBO&#xff09;&#xff1a;原理与应用 变分下界&#xff08;Variational Lower Bound&#xff09;&#xff0c;也称为“证据下界”&#xff08;Evidence Lower Bound, ELBO&#xff09;&#xff0c;是概率模型中的…

git编译安装报错

编译安装步骤 卸载旧的 yum -y remove gitcd /usr/local/src/wget https://www.kernel.org/pub/software/scm/git/git-2.15.1.tar.xztar -vxf git-2.15.1.tar.xzcd git-2.15.1make prefix/usr/local/git allmake prefix/usr/local/git installecho "export PATH$PATH:/usr…

c#中给winform定义快捷键的几种方式

快捷键的使用在日常的开发中频率比较高&#xff0c;这里总结了最常见的各种快捷键的设置方式&#xff0c;需要的时候大家直接照抄就可以了&#xff0c;不用再去查询如何实现了。 文章目录 一、按钮快捷键二、菜单快捷键三、全局快捷键1、重写ProcessCmdKey2、使用KeyPreview属…

操作系统的重点笔记-1

一、操作系统的设计目标 1.易用性 使计算机易于使用&#xff0c;提供文件抽象后&#xff0c;对文件的操作就是对磁盘的操作&#xff0c;不再需要考虑如何通过控制磁盘移动&#xff0c;实现对磁盘某个信号的读写细节 2.高效性 完成特定功能的效率&#xff0c;如时间效率&…

Golang | Leetcode Golang题解之第404题左叶子之和

题目&#xff1a; 题解&#xff1a; func isLeafNode(node *TreeNode) bool {return node.Left nil && node.Right nil }func sumOfLeftLeaves(root *TreeNode) (ans int) {if root nil {return}q : []*TreeNode{root}for len(q) > 0 {node : q[0]q q[1:]if no…

Win11 频繁蓝屏重启

一、问题描述 最近在使用笔记本的时候时不时的蓝屏重启&#xff0c;甚至重启完进系统立马蓝屏重启&#xff0c;还好我凭借快速的手速拍到了错误的原因&#xff0c;如下图所示。 失败的操作是Netwtw12.sys&#xff0c;查了一下这个错误是由于无线网卡导致的&#xff0c;经过测试…

全网最适合入门的面向对象编程教程:48 Python函数方法与接口-位置参数、默认参数、可变参数和关键字参数

全网最适合入门的面向对象编程教程&#xff1a;48 Python 函数方法与接口-位置参数、默认参数、可变参数和关键字参数 摘要&#xff1a; 在 Python 中&#xff0c;函数可以接受多种不同类型的参数&#xff0c;包括位置参数、默认参数、可变参数和关键字参数等&#xff0c;理解…

什么是交换机级联?

在现代计算机网络中&#xff0c;交换机级联是一种广泛应用的技术&#xff0c;有助于提升网络的扩展性和灵活性。本文将深入探讨交换机级联相关知识&#xff0c;详细介绍其基本概念和连接配置方法&#xff0c;并对常见技术问题进行解答。 交换机级联概述 交换机级联是指通过将…

聊点基础的,关于监控,关于告警(prometheus—+grafana+夜莺如何丝滑使用?)

事情的起因是这样的&#xff0c;昨天又群友在群里咨询一个关于grafana和prometheus配置文件的用法&#xff0c;整了半天也没回复&#xff0c;正好知道就帮了一把&#xff0c;今天整理成文章&#xff0c;希望帮到更多的朋友 大致问题的话就是图里面提到的几个&#xff0c;其实都…

webpack的热更新原理

Webpack热更新&#xff08; Hot Module Replacement&#xff0c;简称 HMR&#xff09;&#xff0c;无需完全刷新整个页面的同时&#xff0c;更新所有类型的模块&#xff0c;是 Webpack 提供的最有用的功能之一。 保留在完全重新加载页面期间丢失的应用程序状态。只更新变更内容…

Qt_控件的QWidget属性介绍

目录 1、QWidget的核心属性 2、enabled 3、geometry 3.1 代码测试geometry 4、windowTitle 4.1 代码测试windowTitle 5、windowIcon 5.1 QIcon设置图标 5.2 qrc机制 5.3 代码测试windowIcon 6、windowOpacity 6.1 代码测试windowOpacity 7、cursor 7.1 代码测试…

多线程篇(线程池 - 整体介绍)(持续更新迭代)

目录 一、线程池&#xff08;并发编程的艺术&#xff09; 1. Java中的线程池 1.1. 线程池的实现原理 1.2 线程池的使用 1. 线程池的创建 2. 向线程池提交任务 3. 关闭线程池 4. 合理地配置线程池 5. 线程池的监控 1.3 本章小结 2. Executor框架 2.1 Executor框架简介…

2-93 基于matlab的无人机FMCW(频率调制连续波)毫米波高度计雷达仿真

基于matlab的无人机FMCW&#xff08;频率调制连续波&#xff09;毫米波高度计雷达仿真&#xff0c;不考虑环境杂波和收发信号隔离泄漏。通过考虑雷达天线、波束形成、信号传播、回波接收等环节影响。建立FMCW毫米波雷达系统的数学模型&#xff0c;评估无人机在不同高度下的高度…

Google推出Data Commons解决AI“幻觉”

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

LeetCode 热题 100 回顾12

干货分享&#xff0c;感谢您的阅读&#xff01;原文见&#xff1a;LeetCode 热题 100 回顾_力code热题100-CSDN博客 一、哈希部分 1.两数之和 &#xff08;简单&#xff09; 题目描述 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标…

PCL 点云基于曲率大小渲染颜色

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.2完整代码 三、实现效果 3.1原始点云 3.2处理后点云 PCL点云算法汇总及实战案例汇总的目录地址链接&#xff1a; PCL点云算法与项目实战案例汇总&#xff08;长期更新&#xff09; 一、概…