Unity中获取地形的法线

Unity角色脚部IK进阶实战:动态地形适配与防穿模解决方案 在游戏开发中,角色动画的真实感与沉浸感至关重要,而反向动力学(IK)技术是实现这一目标的核心手段之一。IK系统通过计算骨骼链末端效应器的位置和旋转,反向推导出中间关节的姿态,从而让角色肢体能够智能地适应环境交互。其技术价值在于能够显著提升角色与场景的物理贴合度,消除不自然的悬浮或穿透现象,广泛应用于角色行走、攀爬、抓握等复杂动画场景。本文聚焦于Unity引擎中脚部IK的进阶实现,针对动态地形适配与防穿模这两个工程实践中的核心挑战,深入剖析了基于射线检测与IK权重混合的解决方案。该方案通过预测性检测、法线对齐 阅读详情

序

之前,生成了地形图:(42条消息) 从灰度图到地形图_averagePerson的博客-优快云博客

那末,地形的法线贴图怎么获取?

大概分为两个部分吧,先拿到法线数据,再画到纹理中去。

关于法线

计算

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)

  1. 直接传数组

  1. 数组要展平【mesh.normals其实就是一维的,那就可以直接用了】

  1. 最后需要Apply

  1. 从左到右从下到上【地形顶点正好也是这个顺序的】

官方示例代码:

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour
{
    void Start()
    {
        Renderer rend = GetComponent<Renderer>();

        // duplicate the original texture and assign to the material
        Texture2D texture = Instantiate(rend.material.mainTexture) as Texture2D;
        rend.material.mainTexture = texture;

        // colors used to tint the first 3 mip levels
        Color[] 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 level
        for (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 levels
        texture.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 bottom
                int 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 update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    private void OnRenderImage(RenderTexture source, RenderTexture destination)
    {
        Graphics.Blit(terrian.normalTex, destination);
    }


}

结果

看着……走势差不多吧。而且,绿色的,表示向上,符合的。

对不对?在这种情况下,没法看出来。只能接着往下做,然后拔出萝卜带出泥巴。

纯平面是纯绿色

高度系数越大,颜色越深

Unity地形制作:Heightmap核心原理与实战全流程指南 高度图(Heightmap)是计算机图形学中用于定义三维地形表面起伏的核心数据格式,其本质是一张灰度图像,通过像素亮度值编码高度信息。这一原理使得地形数据能够以二维形式高效存储和处理,并直接驱动三维网格的生成。在游戏开发与虚拟仿真领域,Heightmap的技术价值在于极大地提升了大规模自然场景的创作效率与真实感,是实现开放世界、飞行模拟等应用场景中逼真地形的基石。通过结合Unity Terrain系统,开发者可以快速将Heightmap转换为可交互的地形,并利用纹理绘制、植被散布等功能进行细节丰富。本文聚焦 阅读详情

相关推荐

Unity脚部IK实战:5分钟解决角色爬坡穿模问题

在3D游戏角色动画中,正向动力学(FK)常用于制作预定义动作,但当角色在斜坡、楼梯等不平坦地形移动时,FK难以让脚掌自适应地面,导致模型“悬空”或“穿模”。反向动力学(IK)则从目标点出发,逆向计算关节姿态,使末端效应器(如脚掌)精准到达指定位置,从而解决地形适配问题。其技术价值在于通过实时物理检测与动画数据的融合,显著提升角色移动的真实感和沉浸感,广泛应用于第三人称游戏、角色控制器及需要复杂地形交互的场景。本文聚焦于Unity引擎中的脚部IK实现,通过射线检测地形高度,动态调整骨骼位置与旋转,并配合权重平

weixin_29009881的博客 314

Unity Shader - 简单山脉 - 顶点着色器重构法线

此文是基于之前的一篇:Unity Shader - 使用Noise噪点图生成简单山脉(使用tex2Dlod控制顶点高度)写的,这篇使用tex2Dlod的,虽然将控制顶点的高度逻辑放到了vertex shader(顶点着色器)中读取高度图来控制了,但是却丢失了实时的法线控制,因为之前在CSharp脚本控制山脉顶点高度时有调用:Mesh.RecalculateNormals();,所以运行后,可以看到...

Jave.Lin 的学习笔记 2378

【Unity基础】9.地形系统Terrain

今天学习地形系统Terrain~

Lampard的博客 2万+

【第005问 Unity中如何显示三角形中心法线?】

Unity中如何快速查看Mesh中三角形的法线?

平台不倒,记录不息 2447

Unity 2018.3地形功能更新介绍

Unity 2018.3将更新地形系统,此次更新涉及改进的工具和利用GPU实现的更高性能。它还添加了HDRP高清晰渲染管线和LWRP轻量级渲染管线的支持,同时兼容内置渲染管线和现有Unity地形系统。   请获取Unity 2018.3 Beta体验更新内容,但是需要注意:Unity 2018.3 Beta版仍处于开发阶段,新版本的用户界面和API可能会受到未来改动影响。   性能   在性...

qq_38456196的博客 2836

Unity Shader-法线贴图(Normal Map)与视差贴图(Parallax Map)

简介 法线贴图技术至今一直是游戏增强画面效果的利器之一。随着移动设备的性能越来越好,曾经的在PC平台的各种高级技术在移动平台也都开始大规模使用了。最近印象最深刻的就是《镇魔曲》,场景地形全部都加了法线,可以说是无所不用其极了....之前还没见过哪个游戏在移动平台敢这么大规模地使用法线。而且人模的渲染也是走的次时代的流程。不得不说大厂就是牛,本屌丝只能望别人家的游戏兴叹啊。本篇文章主要是研

puppet_master的专栏 1万+

Unity中实时获取网格上点的位置,还有对应的面和法线

在Unity中,可以使用Mesh类来获取一个网格上点的位置以及对应的面和法线。

shguxudong11的博客 2830

Unity3D4.0教程:地形如何显示法线效果2

Unity3D4.0教程:地形如何显示法线效果 Posted on 2013年01月25日 by U3d / Unity3D脚本/插件/被围观 374 次 1、

解析Unity3D中计算法线矩阵的函数

计算法线矩阵

m0_46183319的博客 883

[信号与系统]一阶与二阶连续时间系统和离散时间系统

定义:一阶连续时间系统由一阶线性常系数微分方程描述: dy(t)dt+ay(t)=bx(t) \frac{dy(t)}{dt} + a y(t) = b x(t) dtdy(t)​+ay(t)=bx(t)时间常数:时间常数 τ=1a\tau = \frac{1}{a}τ=a1​ 是系统响应速度的衡量指标。时间常数越小,系统响应越快。冲激响应:一阶系统的冲激响应是指数衰减或增长的形式。例如,对于一个单位冲激输入,响应为: h(t)=bae−at h(t) = \frac{b}{a} e^{-at} h(t)=

Andius的博客 2121

3步搞定专利数据爬取:用Selenium绕过国家知识产权局反爬(附完整代码)

本文详细介绍了3种高效获取专利数据的技术方案,重点解析了使用Selenium绕过国家知识产权局反爬的实战方法,并提供了完整代码示例。文章还探讨了Requests+lxml轻量级方案和混合技术策略,帮助开发者根据需求选择最佳数据爬取方案,特别适合需要专利统计数据的开发者参考。

weixin_29029995的博客 1111

Slope(斜坡) 法线生成算法,在地形渲染中的应用

原文出处:http://www.azure.com.cn/article.asp?id=285 如有转载,请注明:http://www.azure.com.cn      现在的地形渲染一般都使用高度图来作为数据源,高度图中每一个像素的颜色都代表着一个高度值,就为其y值,其x,z值为程序生成的规格数据。所以将所有这些顶点依次用三角形带绘制出来,即形成一块地形。      但问题出来了,

1393

SpringBoot多线程查询实战-查询库中所有数据多线程实现

但是,在数据量较大且服务器资源足够的情况下,多线程方法通常能够显著提高查询效率。此外,由于它是同步执行的,没有利用并行处理的能力,所以在处理大量数据时可能会比较慢。这个方法采用了分页查询的方式,每次只获取一部分数据,从而避免了内存溢出的问题。然而,它也是同步执行的,没有利用多线程或并行处理的能力。如果每次分页查询的数据量仍然很大,或者需要查询的轮数很多,那么这种方法的效率可能仍然会受到限制。​ ​ ​在比较这三种方式的效率时,我们需要考虑几个关键因素:数据量的大小、查询操作的复杂性、以及并行处理的能力。

勇敢牛牛,不怕困难! 4809

Unity三维地形精度不够?试试用ArcGIS Maps SDK加载本地高程tpkx来提升细节

本文详细解析了如何利用ArcGIS Maps SDK for Unity加载本地高程tpkx数据来提升三维地形精度。通过获取高精度DEM数据、生成优化tpkx切片包以及在Unity中进行地形优化实践,开发者可以实现毫米级地形还原,特别适用于GIS可视化、模拟训练和游戏开发等场景。

weixin_33728708的博客 266

ArchLinux下用Wine运行钉钉全攻略:从字体配置到中文输入法避坑

本文详细介绍了在ArchLinux系统上使用Wine运行钉钉的完整配置流程。从最新的WoW64架构环境准备、中文字体配置与DPI优化,到钉钉安装、关键系统库替换,再到解决中文输入法失效等核心难题,提供了实战避坑指南。旨在帮助Linux用户在企业办公场景下,获得接近原生的稳定使用体验。

alice7model的博客 588

点云结构面智能识别与裂隙网络分析系统

点云结构面智能识别系统摘要 本系统采用深度学习与传统几何算法融合的方法,实现岩石结构面的智能识别与分析。系统包含7个核心模块:点云预处理、结构面识别、分组分割、参数计算、粗糙度分析、裂隙网络生成和可视化。技术路线结合PointNet++深度学习架构与RANSAC、区域生长等传统算法,通过预处理→深度学习识别→几何精修→参数计算→网络构建的流程实现高精度分析。预处理模块实现点云降噪、下采样和法向量估计,深度学习模块基于改进的PointNet++架构进行特征提取和分类。系统支持多种点云格式输入,提供完整的结构面

huanghm88的专栏 345

Unity角色动画脚部IK实战:动态地形适配与旋转优化详解

在3D角色动画开发中,逆运动学(IK)是解决角色肢体与环境精准交互的核心技术。其原理是通过数学计算反向推导关节链的旋转与位移,使末端效应器(如手、脚)达到目标位置。这项技术的核心价值在于极大提升角色动画的真实感与沉浸感,尤其在角色移动、攀爬等与环境紧密互动的场景中至关重要。本文聚焦于脚部IK这一细分领域,深入探讨如何通过射线检测与骨骼操控实现动态地形适配,并利用投影法解决斜坡上的脚部旋转扭曲问题,从而让角色在各种复杂地形上都能呈现自然稳定的站姿与步态。

weixin_34138056的博客 338

手把手教你学Simulink——电机电磁兼容与可靠性场景示例:基于Simulink的电机噪声抑制控制仿真

本文带你完成了电机噪声抑制控制的Simulink仿真,实现了:✅ 揭示了电磁噪声从电流到声音的传递机理✅ 搭建了含死区、固定载波等噪声源的高保真模型随机PWM(消除啸叫)谐振控制器(抑制5/7次嗡鸣)谐波注入(降低THD) ✅ 通过综合方案将噪声降低10 dB以上(感知响度减半!) ✅ 为产品静音品质提升提供可落地的控制方案。

MHD0815的博客 94

三方向映射技术详解:解决UV拉伸,实现高质量纹理投影

纹理映射是三维图形渲染的基础技术,用于将二维图像贴合到三维模型表面。其核心原理是通过UV坐标建立纹理与模型顶点间的对应关系。传统UV映射在模型表面严重拉伸时,会出现纹理模糊、像素化等问题,影响视觉质量。三方向映射技术通过分析模型表面在世界空间中的法线朝向,将其划分为顶面、侧面和底面,并分别使用世界坐标平面(如XZ、XY、ZY)进行独立投影,生成三套不受模型变形影响的UV坐标。这项技术的核心价值在于彻底解决了地形、建筑墙面等场景中的纹理拉伸难题,使砖纹、地板等材质在任何角度的表面上都能保持恒定比例与清晰度,极

weixin_34208283的博客 456

104、线缆与终端匹配:特性阻抗、双绞线规格与端接电阻优化策略

摘要: CAN总线物理层可靠性取决于线缆特性阻抗、双绞线规格与终端电阻的精准匹配。核心要点包括: 特性阻抗须严格匹配120Ω(±10%),反射系数需≤0.05,线缆建议选用Belden 3086A等实测达标型号,避免网线替代; 双绞线应选AWG22~24纯铜线,绞距≤30mm,工业环境需屏蔽层单端接地,杜绝铜包铝线; 终端电阻需选用金属膜电阻(0.5W以上),阻值按实测线缆阻抗微调,长距离可采用分裂终端(60Ω+4.7nF)优化信号完整性; 拓扑适配:星型/树型拓扑需控制分支长度,环型拓扑必须断开; 实测验

2401_88858637的博客 51

Open3D 计算点云法向量的夹角【2026最新版】

计算法向量的夹角,博客长期更新,本文最新更新时间为:2026年3月7日。

点云侠的博客 3131

将unity地形转换为mesh

之前这个博客: https://blog.youkuaiyun.com/wodownload2/article/details/90263882 主要是关于如何把场景中的物件,进行空间划分,并且根据主角的位置,动态的加载周边的物件,对于大地形的处理,则没有涉及到。 经过搜索,主要收集了如下具有参考价值的网址: http://www.cnblogs.com/jietian331/p/5831062.html 本...

小孔明的专栏 7847

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

【Unity地形】使用地形工具创建场景环境-Terrain

如上图Unity的地形工具可以让我们实现创建复杂、丰富的3D室外环境。我们创建地形很简单,在层级面板中右键-3Dobject-Terrain 就可以创建一个默认的地形模型!这个模型是Unity内置的。接下来的地形编辑功能全部集中在这个地形的组件上。

leoysq的博客 8090

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Unity地形系统

一、什么是地形? 地形指的是地表各种各样的形态,具体指地表以上分布的固定性物体共同呈现出的高低起伏的各种状态。 二、创建地形 创建地形,地形属于3D Object类型,可以通过菜单栏GameObject去创建,也可以直接在Hierarchy面板中创建。 三、地形工具 从左到右分别是创建相邻地形、绘制工具、绘制树木工具、绘制细节工具、设置工具。 ​​​​​​​ ...

a451319296的博客 3137

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Unity中地形的设置

1.在开发过程中建议关闭烘焙效果(Window—lighting–auto generate) 2.Terrain Colider 为地形增添一种碰撞的效果,不能让游戏物体穿过。 3.创建地形时候应该设置地形,设置地形的宽度,高度,长度,Resolution(分辨率)。 4.设置地形的高度为20m,地形的海拔高度是20。 5.按住shift让地形下降, 6.地形中第三个参数是为了平滑地形 7.右键...

weixin_44469024的博客 3232

【Unity】Unity插件:地形编辑器MTE(Mesh Terrain Editor)

MTE(Mesh Terrain Editor)是一款Unity的地形编辑器插件,该插件能够更方便的创建和编辑地图,提升场景开发效率。

一个普普通通的游戏开发者 1万+
上一篇: 从灰度图到地形图
下一篇: 在线绘制灰度地
averagePerson
博客等级 码龄5年 381粉丝 113原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值