Unity中获取地形的法线
序
之前,生成了地形图:(42条消息) 从灰度图到地形图_averagePerson的博客-CSDN博客
那末,地形的法线贴图怎么获取?
大概分为两个部分吧,先拿到法线数据,再画到纹理中去。
关于法线
计算
Unity - Scripting API: Mesh.RecalculateNormals (unity3d.com)
这个链接讲的是法线的计算,它是什么空间下的?无所谓了……
这里也不对地形搞什么几何变换,而且它是方向,模型空间世界空间是一个结果。
获取
Unity - Scripting API: Mesh.normals (unity3d.com)
直接一个等于号,然后这个法线是对顶点不是对三角形面片。
就这两点,没了。

存到纹理中
构造
Unity - Scripting API: Texture2D (unity3d.com)
这个变量,好像在unity shader里也经常出现嘞
要把法线数据存到Texture2D里,首先得构造一下对象啊,构造函数是什么?
Unity - Scripting API: Texture2D.Texture2D (unity3d.com)
RGBA32,构造RenderTexture的时候也有你。

怎么赋值?
赋值
Unity - Scripting API: Texture2D.SetPixels (unity3d.com)
直接传数组
数组要展平【mesh.normals其实就是一维的,那就可以直接用了】
最后需要Apply
从左到右从下到上【地形顶点正好也是这个顺序的】

官方示例代码:
using UnityEngine;
using System.Collections;public class ExampleClass : MonoBehaviour
{void Start(){Renderer rend = GetComponent<Renderer>();// duplicate the original texture and assign to the materialTexture2D texture = Instantiate(rend.material.mainTexture) as Texture2D;rend.material.mainTexture = texture;// colors used to tint the first 3 mip levelsColor[] colors = new Color[3];colors[0] = Color.red;colors[1] = Color.green;colors[2] = Color.blue;int mipCount = Mathf.Min(3, texture.mipmapCount);// tint each mip levelfor (int mip = 0; mip < mipCount; ++mip){Color[] cols = texture.GetPixels(mip);for (int i = 0; i < cols.Length; ++i){cols[i] = Color.Lerp(cols[i], colors[mip], 0.33f);}texture.SetPixels(cols, mip);}// actually apply all SetPixels, don't recalculate mip levelstexture.Apply(false);}
}
试一试
根据文档,调api就行了。
代码
计算法线的
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Terrian : MonoBehaviour
{public int N = 10;public Texture2D texture2dHeightMap;[Range(1,100)]public float heightRatio = 30.0f;//一个系数,控制地形总体的高度的public Texture2D normalTex;MeshRenderer meshRenderer;MeshFilter meshFilter;// 用来存放顶点数据List<Vector3> verts;List<int> indices;Vector3[] normals;private void Awake(){}private void Start(){verts = new List<Vector3>();indices = new List<int>();meshRenderer = GetComponent<MeshRenderer>();meshFilter = GetComponent<MeshFilter>();//normalTex = new Texture2D(texture2dHeightMap.width, texture2dHeightMap.height, TextureFormat.RGB24,-1,false);normalTex = new Texture2D(N,N, TextureFormat.RGB24, -1, false);//2.5D的地形,顶点的法线,法线贴图规模不是灰度图规模}private void Update(){Generate();normals = new Vector3[N * N];normals = meshFilter.mesh.normals;for(int i = 0; i < 10; ++i){print(normals[i]);}Color[] colors = new Color[N * N];for(int i = 0; i < N * N; ++i){colors[i] = new Color(normals[i].x, normals[i].y, normals[i].z);}normalTex.SetPixels(colors);normalTex.Apply(false);}public void Generate(){ClearMeshData();// 把数据填写好AddMeshData();// 把数据传递给Mesh,生成真正的网格Mesh mesh = new Mesh();mesh.vertices = verts.ToArray();mesh.triangles = indices.ToArray();mesh.RecalculateNormals();mesh.RecalculateBounds();meshFilter.mesh = mesh;}void ClearMeshData(){verts.Clear();indices.Clear();}void AddMeshData(){//01填充顶点数据for (int z = 0; z < N; ++z)//按先x后z的顶点排列顺序,所以先循环的是z{for(int x = 0; x < N; ++x){int u = Mathf.FloorToInt(1.0f * x / N * texture2dHeightMap.width);int v = Mathf.FloorToInt(1.0f * z / N * texture2dHeightMap.height);float grayValue = texture2dHeightMap.GetPixel(u,v).grayscale;float height = grayValue*heightRatio;Vector3 temp = new Vector3(x, height, z);verts.Add(temp);}}//02填充索引数据for(int z = 0; z < N - 1; ++z){for(int x = 0; x < N - 1; ++x){int index_lb = z * N + x;//index of the left bottom vertex. lb = left bottomint index_lt = (z + 1) * N + x;int index_rt = (z + 1) * N + x + 1;int index_rb = z * N + x + 1;indices.Add(index_lb);indices.Add(index_lt);indices.Add(index_rt);indices.Add(index_rt);indices.Add(index_rb);indices.Add(index_lb);}}}}
显示法线贴图的。这个是在摄像机上的——屏幕后处理嘛!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class ShowTexture2D : MonoBehaviour
{public Terrian terrian;// Start is called before the first frame updatevoid Start(){}// Update is called once per framevoid Update(){}private void OnRenderImage(RenderTexture source, RenderTexture destination){Graphics.Blit(terrian.normalTex, destination);}}
结果
看着……走势差不多吧。而且,绿色的,表示向上,符合的。
对不对?在这种情况下,没法看出来。只能接着往下做,然后拔出萝卜带出泥巴。

纯平面是纯绿色


高度系数越大,颜色越深
相关文章:

Unity中获取地形的法线
序之前,生成了地形图:(42条消息) 从灰度图到地形图_averagePerson的博客-CSDN博客那末,地形的法线贴图怎么获取?大概分为两个部分吧,先拿到法线数据,再画到纹理中去。关于法线计算Unity - Scripting API: M…...

模型解释性:PFI、PDP、ICE等包的用法
本篇主要介绍几种其他较常用的模型解释性方法。 1. Permutation Feature Importance(PFI) 1.1 算法原理 置换特征重要性(Permutation Feature Importance)的概念很简单,其衡量特征重要性的方法如下:计算特征改变后模型预测误差的增加。如果打乱该特征的…...
spring常见面试题(2023最新)
目录前言1.spring是什么2.spring的设计核心是什么3.IOC和AOP面试题4.spring的优点和缺点5.spring中bean的作用域6.spring中bean的注入方式7.BeanFactory 和 ApplicationContext有什么区别?8.循环依赖的情况,怎么解决?9.spring中单例Bean是线程…...

华为OD机试题,用 Java 解【压缩报文还原】问题
最近更新的博客 华为OD机试题,用 Java 解【停车场车辆统计】问题华为OD机试题,用 Java 解【字符串变换最小字符串】问题华为OD机试题,用 Java 解【计算最大乘积】问题华为OD机试题,用 Java 解【DNA 序列】问题华为OD机试 - 组成最大数(Java) | 机试题算法思路 【2023】使…...

机器学习-BM-FKNCN、BM-FKNN等分类器对比实验
目录 一、简介和环境准备 二、算法简介 2.1四种方法类: 2.1.1FKNN 2.1.2FKNCN 2.1.3BM-FKNN 2.1.3BM-FKNCN 2.2数据预处理 2.3输出视图 2.4调用各种方法看准确率 2.4.1BM-FKNCN 2.4.2BM-FKNN 2.4.3FKNCN 2.4.4FKNN 2.4.5KNN 一、简介和环境准备 k…...

ChatGPT火了,对话式人工智能还能干嘛?
身兼数职的ChatGPT 从2022火到了2023 连日来一直是各大平台的热议对象 其实除了写诗、敲代码、处理文档 以ChatGPT为代表的 对话式人工智能 还有更重要的工作要做 对话式AI与聊天机器人 相信大多数人…...
十一、操作数栈的特点(Operand Sstack)
1.每一个独立的栈帧中除了包含局部变量表以外,还包含一个后进先出的操作数栈,也可以称之为表达式栈。 2.操作数栈,在方法执行过程中,根据字节码指令,往栈中写入数据,或提取数据,即入栈ÿ…...
拆解瑞幸新用户激活流程,如何让用户“动”起来?
Aha时刻 一个产品的拉新环节,是多种方式并存的;新用户可能来自于商务搭建了新的渠道,运营策划了新的活动,企划发布了新的广告,销售谈下了新的客户,市场推广了新的群体,以及产品本身的口碑传播,功能更新带来的自然流量。 这是一个群策群力的环节,不同的团队背负不同的K…...

tkinter界面的TCP通信/开启线程等待接收数据
前言 用简洁的语言写一个可以与TCP客户端实时通信的界面。之前做了一个项目是要与PLC进行信息交互的界面,在测试的时候就利用TCP客户端来实验,文末会附上TCP客户端。本文分为三部分,第一部分是在界面向TCP发送数据,第二部分是接收…...

华为OD机试题,用 Java 解【任务混部】问题
最近更新的博客 华为OD机试题,用 Java 解【停车场车辆统计】问题华为OD机试题,用 Java 解【字符串变换最小字符串】问题华为OD机试题,用 Java 解【计算最大乘积】问题华为OD机试题,用 Java 解【DNA 序列】问题华为OD机试 - 组成最大数(Java) | 机试题算法思路 【2023】使…...
看linux内核启动流程需要的汇编指令解释
一、指令 0.MRS 和MSR MRS 指令: 对状态寄存器CPSR和SPSR进行读操作。 MSR指令: 对状态寄存器CPSR和SPSR进行写操作。 1.adrp adrp x0, boot_args把boot_args的页基地址提取出来,放到x0中。 2.stp stp x21, x1, [x0]将 x21, x1 的值存入 x0寄存器记录的地址中…...

【巨人的肩膀】JAVA面试总结(二)
1、💪 目录1、💪1.0、什么是面向对象1.1、JDK、JRE、JVM之间的区别1.2、什么是字节码1.3、hashCode()与equals()之间的联系1.4、String、StringBuffer、StringBuilder的区别1.5、和equals方法的区别1.6、重载和重写的区别1.7、List和Set的区别1.8、Array…...

【网络安全入门】零基础小白必看!!!
看到很多小伙伴都想学习 网络安全 ,让自己掌握更多的 技能,但是学习兴趣有了,却发现自己不知道哪里有 学习资源◇瞬间兴致全无!◇ 😄在线找人要资料太卑微,自己上网下载又发现要收费0 🙃差点当…...
字节前端经典面试题(附答案)
有哪些可能引起前端安全的问题? 跨站脚本 (Cross-Site Scripting, XSS): ⼀种代码注⼊⽅式, 为了与 CSS 区分所以被称作 XSS。早期常⻅于⽹络论坛, 起因是⽹站没有对⽤户的输⼊进⾏严格的限制, 使得攻击者可以将脚本上传到帖⼦让其他⼈浏览到有恶意脚本的⻚⾯, 其注⼊⽅式很简…...

数据库管理工具的使用
目录 摘要 一、Navicat是什么? 二、使用步骤 1.如何下载与安装 2.如何连接远程数据库 总结 摘要 本文主要介绍数据库管理工具的使用 一、Navicat是什么? 它是一款数据库管理工具,将此工具连接数据库,你可以从中看到各种数据库的详细…...

让马斯克反悔的毫米波雷达,被国产雷达头部厂商木牛科技迭代到了5D时代
近日,特斯拉或将在其HW4.0硬件系统配置一枚高精度4D毫米波雷达的消息在外网刷屏。据分析,“纯视觉”信仰者马斯克之所以做出这样的决定,一方面是减配了雷达的特斯拉自动驾驶,表现不尽如人意;另一方面也跟毫米波雷达的技…...

MaxWell原理概述
文章目录1.MaxWell概述2.Maxwell输出数据格式3.Maxwell原理3.1 MySQL二进制日志3.2 MySQL主从复制1.MaxWell概述 Maxwell 是由美国Zendesk公司开源,用Java编写的MySQL变更数据抓取软件。它会实时监控Mysql数据库的数据变更操作(包括insert、update、dele…...

电子技术——AB类输出阶
电子技术——AB类输出阶 原理 交越失真可以通过通过一个较小的偏置电流解除,如下图: QNQ_NQN 和 QPQ_PQP 的基极之间存在偏置电压 VBBV_{BB}VBB 。对于完美匹配的晶体管,当 vI0v_I 0vI0 的时候,此时 vO0v_O 0vO0 。每…...
Archlinux个人安装流程
操作环境: 时间:2023-02-17 电脑型号:联想拯救者R720 cpu:Intel Core i5-7300HQ 4x 3.5GHz gpu:NVIDIA GeForce GTX 1050 Ti 安装系统: 1.下载镜像: 请访问https://archlinux.org/查找镜…...

【Autoware】2小时安装Autoware1.13(保姆级教程)
前言:ROS的出现使得机器人软件开发更加快速和模块化,在此基础上,Autoware.ai开源项目可以让我们很容易地将一套完整的自动驾驶软件部署到我们的测试车辆上,并见证它跑起来! 文章目录1.Autoware简介2.电脑软硬件配置要求…...

SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...

C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...

多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...