如何在 Unity Shader 中实现简单的高度图

2023-12-30

首先我要说的是我对着色器编程知之甚少。我这里的很多内容都是由在线资源和现有资产拼接而成的。我只需要知道如何将高度图正确集成到统一着色器中。它不必比标准 Unity 着色器更复杂。我无法使用标准着色器,因为我需要一个将多个纹理平铺在一起的着色器,这可能就是我尚未找到此问题的解决方案的原因。

我混合并移动了代码,删除了一些变量,重命名了一些变量,并在网上查找了有类似问题的人。

Shader "Unlit/TRUE_EARTH"
{
    Properties
    {
        _TexA1 ("Tex A1", 2D) = "white" {}
        _TexA2 ("Tex A2", 2D) = "white" {}
        _TexB1 ("Tex B1", 2D) = "white" {}
        _TexB2 ("Tex B2", 2D) = "white" {}
        _TexC1 ("Tex C1", 2D) = "white" {}
        _TexC2 ("Tex C2", 2D) = "white" {}
        _TexD1 ("Tex D1", 2D) = "white" {}
        _TexD2 ("Tex D2", 2D) = "white" {}
    _BumpScale("Scale", Float) = 1.0
    [Normal] _BumpMap("Normal Map", 2D) = "bump" {}

    _Height("Height Scale", Range(0.005, 0.08)) = 0.02
    _HeightMap("Height Map", 2D) = "black" {}

    _OcclusionStrength("Strength", Range(0.0, 1.0)) = 1.0
    _OcclusionMap("Occlusion", 2D) = "white" {}
}
SubShader
{
    Tags { "RenderType"="Opaque" }
    Lighting Off
    ZWrite Off

    Pass
    {
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag
        // make fog work
        #pragma multi_compile_fog

        #include "UnityCG.cginc"

        sampler2D _TexA1;
        sampler2D _TexA2;   
        sampler2D _TexB1;
        sampler2D _TexB2;
        sampler2D _TexC1;
        sampler2D _TexC2;   
        sampler2D _TexD1;
        sampler2D _TexD2;
        sampler2D _NormalMap;
        sampler2D _HeightMap;
        half _BumpAmount;
        half _Height;

        struct v2f
        {
           float4 pos     : SV_POSITION;
           float2 uv      : TEXCOORD0;
           half3 normal: TEXCOORD1;
           #if WPM_BUMPMAP_ENABLED
           half3 tspace0 : TEXCOORD2; // tangent.x, bitangent.x, normal.x
           half3 tspace1 : TEXCOORD3; // tangent.y, bitangent.y, normal.y
           half3 tspace2 : TEXCOORD4; // tangent.z, bitangent.z, normal.z
           #endif
        };


        v2f vert (float4 vertex : POSITION, half3 normal : NORMAL, half4 tangent : TANGENT, float2 uv : TEXCOORD5, appdata_full v) {
            v2f o;
            float4 heightMap = tex2Dlod(_HeightMap, float4(v.texcoord.xy, 0, 0));
            vertex.z += heightMap.b * _Height;
            o.pos               = UnityObjectToClipPos (vertex);
            o.uv                = uv;
            half3 wNormal       = UnityObjectToWorldNormal(normal);
            o.normal            = wNormal;


            #if WPM_BUMPMAP_ENABLED
            half3 wTangent = UnityObjectToWorldDir(tangent.xyz);
            half tangentSign = tangent.w * unity_WorldTransformParams.w;
            half3 wBitangent = cross(wNormal, wTangent) * tangentSign;
            //output the tangent space matrix
            o.tspace0 = half3(wTangent.x, wBitangent.x, wNormal.x);
            o.tspace1 = half3(wTangent.y, wBitangent.y, wNormal.y);
            o.tspace2 = half3(wTangent.z, wBitangent.z, wNormal.z);
            #endif

            return o;
        }

        half4 frag (v2f i) : SV_Target
        {
            // compute Earth pixel color
                half4 color;

                // compute Earth pixel color
                if (i.uv.x<0.25) 
                {
                    if (i.uv.y>0.4999) 
                    {
                        color = tex2Dlod(_TexA1, float4(i.uv.x * 4.0, (i.uv.y - 0.5) * 2.0, 0, 0));
                    } 
                    else 
                    {
                        color = tex2Dlod(_TexA2, float4(i.uv.x * 4.0, i.uv.y * 2.0, 0, 0));
                    }
                } 
                else if (i.uv.x < 0.5) 
                {
                    if (i.uv.y>0.4999) 
                    {
                        color = tex2Dlod(_TexB1, float4((i.uv.x - 0.25) * 4.0f, (i.uv.y - 0.5) * 2.0, 0, 0));
                    } 
                    else 
                    {
                        color = tex2Dlod(_TexB2, float4((i.uv.x - 0.25) * 4.0f, i.uv.y * 2.0, 0, 0));
                    }
                }
                else if (i.uv.x < 0.75) 
                {
                    if (i.uv.y>0.4999) 
                    {
                        color = tex2Dlod(_TexC1, float4((i.uv.x - 0.50) * 4.0f, (i.uv.y - 0.5) * 2.0, 0, 0));
                    } 
                    else 
                    {
                        color = tex2Dlod(_TexC2, float4((i.uv.x - 0.50) * 4.0f, i.uv.y * 2.0, 0, 0));
                    }
                }
                else if (i.uv.x < 1.01) 
                {
                    if (i.uv.y>0.4999) 
                    {
                        color = tex2Dlod(_TexD1, float4((i.uv.x - 0.75) * 4.0f, (i.uv.y - 0.5) * 2.0, 0, 0));
                    } 
                    else 
                    {
                        color = tex2Dlod(_TexD2, float4((i.uv.x - 0.75) * 4.0f, i.uv.y * 2.0, 0, 0));
                    }
                }

                // sphere normal (without bump-map)
                half3 snormal = normalize(i.normal);

                // transform normal from tangent to world space
                #if WPM_BUMPMAP_ENABLED
                half3 tnormal = UnpackNormal(tex2D(_NormalMap, i.uv)); 
                half3 worldNormal;
                worldNormal.x = dot(i.tspace0, tnormal);
                worldNormal.y = dot(i.tspace1, tnormal);
                worldNormal.z = dot(i.tspace2, tnormal);
                half3 normal = normalize(lerp(snormal, worldNormal, _BumpAmount));
                #else
                half3 normal = snormal;
                #endif

                return color;
        }
        ENDCG
    }
}
}

纹理效果很好,但没有高度贴图。一切都是平的。


有 3 个部分需要更改。

  1. 确保您的属性与变量匹配:

    _Height("Height Scale", Range(0.005, 0.08)) = 0.02
    _HeightMap("Height Map", 2D) = "black" {}
    
    ....
    
    sampler2D _HeightMap;
    half _Height;
    
  2. 在将顶点存储到之前对其进行修改o

  3. 修改顶点的 y 分量而不是 z:

    float4 heightMap = tex2Dlod(_HeightMap, float4(v.texcoord.xy, 0, 0));
    vertex.y += heightMap.b * _Height;
    o.pos               = UnityObjectToClipPos (vertex);
    
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Unity Shader 中实现简单的高度图 的相关文章

  • 以相反的顺序迭代可变参数模板参数

    如果我手动反转传递给它的模板参数的顺序 以下代码将起作用 template
  • MVC 重定向到没有控制器的视图

    希望应该是一个简单的 我创建了一个通用错误视图 当整个站点的操作方法内发生异常时 我想显示该视图 我创建了一个部分页面 所有导航都位于其中 因此我不需要在此视图上使用控制器 那么如何从控制器内的操作方法重定向到它 像这样的东西 HttpPo
  • 必须打开存储才能执行此操作 - System.IO.Packaging.Package

    我正在使用 System IO Packaing Package 类来压缩文件 我的应用程序的多个实例可以同时运行 并读取和保存文件 当处理小文件时 一切似乎都很好 但是当涉及大文件时 如果应用程序的两个实例同时保存 我会收到一个异常 消息
  • SetWindowsHookEx 函数返回 NULL

    我正在研究 DLL 注入 但收到错误如下 挂接进程失败 87 参数不正确 目标进程和dll都是64位的 注入代码为 BOOL HookInjection TCHAR target TCHAR dll name https msdn micr
  • 在运行时设置 DataGridView 上的 DataFormatString?

    是否可以在运行时设置 ASP NET DataGridView 中的列或单元格的 DataFormatString 属性 这应该有效 BoundField priceField grid Columns 0 as BoundField pr
  • 关闭 XDOCUMENT 的实例

    我收到这个错误 该进程无法访问文件 C test Person xml 因为它是 被另一个进程使用 IOException 未处理 保存文件内容后如何关闭 xml 文件的实例 using System using System Collec
  • 如何在 Windows 窗体中运行屏幕保护程序作为其背景?

    如何在 Windows 窗体中运行屏幕保护程序作为其背景 用户还可以在屏幕保护程序运行时与表单控件进行交互 为什么这个 我们有一个案例 需要在用户时运行 Windows Bubbles 屏幕保护程序 可以继续与表单控件交互吗 您可以使用以下
  • 如何使用泛型类型的 DataContractSerializer 编写自定义序列化器?

    我想编写一个自定义序列化器 用于将会话状态存储到Azure 缓存 预览版 这意味着这个自定义序列化器必须实现IDataCacheObjectSerializer 如果我错了 请告诉我 我需要编写这个自定义序列化程序的原因是我需要序列化一些包
  • 在“using”语句中使用各种类型 (C#)

    自从C usingstatements只是try finally dispose 的语法糖 为什么它接受多个对象仅当它们属于同一类型时 我不明白 因为它们需要的只是 IDisposable 如果它们都实现 IDisposable 应该没问题
  • c# 如何生成锦标赛括号 HTML 表

    所以我已经被这个问题困扰了三个星期 但我一生都无法弄清楚 我想做的是使用表格获得这种输出 演示 http www esl world net masters season6 hanover sc2 playoffs rankings htt
  • 无法通过 LINQ to Entities 使用某些功能?

    我正在尝试使用 LINQ 查询在项目上实现搜索功能 由于数据有时包含带有重音符号和其他符号的字符 因此我创建了一种方法来删除这些字符以进行搜索 这是我的代码 var addresses from a in db Addresses join
  • 理解 C++11 中的 std::atomic::compare_exchange_weak()

    bool compare exchange weak T expected T val compare exchange weak 是 C 11 中提供的比较交换原语之一 它是weak即使对象的值等于 它也会返回 falseexpected
  • Dynamics Crm:获取状态代码/状态代码映射的元数据

    在 Dynamics CRM 2011 中 在事件实体上 状态原因 选项集 也称为状态代码 与 状态 选项集 也称为状态代码 相关 例如看这个截图 当我使用 API 检索状态原因选项集时 如下所示 RetrieveAttributeRequ
  • 将一个 long 转换为两个 int 以进行重构

    我需要将一个参数作为两个 int 参数传递给 Telerik Report 因为它不能接受长参数 将 long 拆分为两个 int 并在不丢失数据的情况下重建它的最简单方法是什么 使用掩蔽和移位是最好的选择 根据文档 long 保证为 64
  • 如何强制执行特定的 UserControl 设计

    我正在编写一个基本用户控件 它将由一堆其他用户控件继承 我需要对所有这些后代控件强制执行某种设计 例如 顶部必须有几个按钮以及一个或两个标签 后代用户控件区域的其余部分可以自由放置任何内容 最初 我认为我可以将一个面板放到 Base Use
  • 程序退出后,TcpListener Socket 仍处于活动状态

    当我的程序退出时 我试图停止 TCP 侦听器 我不关心套接字或任何活动客户端套接字上当前活动的任何数据 套接字清理代码本质上是 try myServer Server Shutdown SocketShutdown Both catch E
  • 在何处将 CFLAG(例如 -std=gnu99)添加到 (Eclipse CDT) 自动工具项目中

    我有一个简单的 Autotools C 项目 不是 C 其框架是由 Eclipse CDT Juno 为我创建的 CFLAG 通过检查 似乎是 g O2 我希望所有生成的 make 文件也具有 std gnu99附加到 CFLAG 因为我使
  • 通过 cmake 链接作为外部项目包含的 opencv 库[重复]

    这个问题在这里已经有答案了 我对 cmake 比较陌生 经过几天的努力无法弄清楚以下事情 我有一个依赖于 opencv 的项目 它本身就是一个 cmake 项目 我想静态链接 opencv 库 我正在做的是我的项目中有一份 opencv 源
  • 使用剪贴板 SetText 换行

    如何使用 SetText 方法添加换行符 I tried Clipboard SetText eee n xxxx 但当我将剪贴板数据粘贴到记事本中时 它没有给我预期的结果 预期结果 eee xxxx 我怎样才能做到这一点 Windows
  • 如何确定给定方法可以抛出哪些异常?

    我的问题和这个真的一样 找出 C 中方法可能抛出的异常 https stackoverflow com questions 264747 finding out what exceptions a method might throw in

随机推荐

  • 使用 GPU 加速 MATLAB 代码?

    AccelerEyes 于 2012 年 12 月宣布与 Mathworks 合作开发 GPU 代码 并已停止生产 Jacket for MATLAB http blog accelereyes com blog 2012 12 12 ex
  • 构建maven项目时编译错误

    我们正在尝试从 Jenkins 构建并部署一个 Maven 工件到我们的 Nexus 存储库管理器中 但我们在构建过程中遇到了编译错误 这是我们收到的错误 错误 未能执行目标 org apache maven plugins maven c
  • 如何在 Chrome 上调试 JavaScript

    我有一个奇怪的问题 jquery load 有时在 chrome 上失败 我不会用细节来打扰你们 我只是在寻找如何调试这样的问题的指导者 我想也许 firebug 可以提供帮助 但问题只发生在 chrome 上 甚至适用于 IE 我做类似的
  • 使用 XMLHttpRequest 上传文件

    我正在尝试使用拖放插件 http pascalprecht github com DnD js 在javascript中使用ajax上传文件
  • 从 HTML 表单到 PDF

    有没有一种简单的方法可以在网页上创建 HTML 表单 当用户提交时 将数据放入 PDF 文件并将其发送给接收者 该网页在 net 上运行 Thanks Umbraco http our umbraco org projects websit
  • 如何使用 C# 或 XAML 创建自动动画轮播循环图像?

    我已经在 Web 开发中完成了轮播 但通过 XAML 或 C 在 WPF 中为它们设置动画对我来说是新鲜事 网上有一些例子 但它们要么已经过时 要么不是我想要的 即使当我玩弄其他项目的源代码时 这也不是我所希望的 我想让图像自动从左到右 水
  • Android webview中的无限滚动

    我有一些本地 html 文件 我想用无限滚动方法显示它们 NOTE 我无法更改 html 内容 所以请不要建议向其中添加 javascript 我必须在运行时执行此操作 所以 我发现我可以执行javascript在运行时通过loadUrl
  • 生成的 pdf 中的文本是反向的

    我正在使用 pdfbox 向 pdf 文件添加一行 但我添加的文字是相反的 File file new File filePath PDDocument document PDDocument load file PDPage page d
  • 如何从 Magento-1 价格中删除小数点?

    我在搜索中找到的只是一个编程解决方案 我知道我们可以修改 lib Zend Locale Data en xml 以用于英语商店 en xml中有这部分
  • 我们可以在每个 上方的 table 内添加 div 吗?

    您好 我正在尝试在每个上面添加一个 div tr 但是当我查看 html 控制台时 div 显示在表格之外 下面是html代码 table div tr td td tr div div tr td td tr div table 这是不允
  • 计算方法的执行时间

    可能的重复 如何测量函数运行的时间 https stackoverflow com questions 10107140 how to measure how long is a function running 我有一个 I O 计时方法
  • 如何在Google App Engine灵活环境中运行TensorFlow?

    之前我问为什么GAE在这里找不到TensorFlow libhttps stackoverflow com questions 40241846 why googleappengine gives me importerror no mod
  • Rails 5 处理 ActionController::ParameterMissing 的方法

    如果使用强参数缺少所需的参数 Rails 服务器将使用 HTTP 500 进行响应 这并不能让我控制向用户反馈到底出了什么问题 能够向他们发送缺少所需参数的消息是否没有意义 提供适当用户反馈的 Rails 方式 是什么ActionContr
  • SQLite 中的“如果不存在则插入”语句

    我有一个 SQLite 数据库 我正在尝试插入值 users id lessoninfo id 表中bookmarks 仅当两者之前不连续存在时 INSERT INTO bookmarks users id lessoninfo id VA
  • 如何更改另一个进程的内存空间中的值

    如果你能帮助我解决这个困境 现在 我知道C C 我知道asm 我知道dll注入 我知道虚拟内存寻址 但我就是不知道如何 像 CheatEngine 等软件可以在另一个进程中更改变量的值 对于那些不知道的人来说 第 3 方作弊引擎工具可以扫描
  • Python 的单元测试可以像鼻子一样并行测试吗?

    Python的NOSE测试框架有以下概念并行运行多个测试 https nose readthedocs io en latest plugins multiprocess html 这样做的目的不是为了测试代码中的并发性 而是为了让 没有副
  • 在 Eclipse 中禁用“下载源代码和 javadoc”

    我正在使用 Eclipse 20210312 0638 我已从首选项 第一张图片 中取消选中 下载工件源 和 下载工件 javadoc 它仍在下载它们 第二张图片 我还应该更改其他配置吗 有人已经修复了 Eclipse 中的一个错误 htt
  • 仅当字符串中存在小写字母时,使用一个正则表达式匹配所有大写单词

    我偶然发现了这个看似微不足道的问题 但我却被困住了 我有一个字符串 我想在其中匹配在一个正则表达式中全部大写单词only如果字符串中的某个位置至少有一个小写字母 基本上 我希望每一行 我们可以考虑将正则表达式分别应用于每一行 不需要进行一些
  • 致命:不是有效的对象名称:'master'

    我有一个运行 git 1 7 的私人服务器 当我 git init 它不会创建主分支的文件夹 因为当我这样做时 git branch 它没有列出任何内容 当我做 git bare init 它创建文件 当我打字时 git branch ma
  • 如何在 Unity Shader 中实现简单的高度图

    首先我要说的是我对着色器编程知之甚少 我这里的很多内容都是由在线资源和现有资产拼接而成的 我只需要知道如何将高度图正确集成到统一着色器中 它不必比标准 Unity 着色器更复杂 我无法使用标准着色器 因为我需要一个将多个纹理平铺在一起的着色