法线纹理采样+可视化Shader编辑器

法线贴图,对主纹理凹凸显示

        建模原理

                法线贴图:切线空间,存储xy切线,映射法线,法线信息存储在切线空间中。

                模型是否凹凸,是由模型顶点决定的,现在实现的法线贴图,控制凹凸,实际上是配合

                光照实现的,凹进去的部分,颜色偏暗,突出来的部分,颜色偏亮。

        导入法线贴图

                

                贴图类型转换为Normal Map,法线纹理类型。

        法线贴图计算

                法线贴图:存储有与法线垂直的切线信息,切线信息存储在切线空间中,使用内部

                值(x切线,y切线)时,需要将法线转换到世界空间中,再进行光照运算才能得到

                正确的结果。调整凹凸深度的参数:用户可配置,可以控制法线长短。

        Shader实现

                加载两张纹理:主纹理,光照法线纹理(切线空间存储数据)

                顶点着色器:

                        主纹理的UV偏移计算

                        法线纹理的UV偏移计算

                        计算切线空间到世界空间的转换矩阵(可变),用于变换光照法线

                片元着色器

                        解压主纹理

                        解压法线纹理,根据切线信息,转换光照法线信息,将光照法线从切线空间,

                        转到世界空间

                        拿法线纹理算出的光照法线,做光照运算。

相关实现代码示例如下所示:

// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'Shader "CreateTest/PhongNormalTexture"
{Properties{//用于显示材质纹理_MainTex("主纹理",2D)="white"{}//用于和主纹理混色_Color("混色",Color)=(1,1,1,1)//法线纹理_BumpTex("法线纹理",2D)="bump"{}//法线深度系数,可以控制法线高度_BumpScale("法线深度系数",Float) = 1_SpecularColor("高光反射材质颜色",Color) = (1,1,1,1)_Gloss("光晕系数",Range(8,256)) = 10}SubShader{Tags{"LightMode" = "ForwardBase"}Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "Lighting.cginc"//导入主纹理数据sampler2D _MainTex;float4 _MainTex_ST;fixed4 _Color;//导入法线信息sampler2D _BumpTex;float4 _BumpTex_ST;float _BumpScale;//导入高光信息fixed4 _SpecularColor;float _Gloss;//从CPU过来的数据struct c2v{float4 vertex:POSITION;//从CPU传递过来的模型空间下,需要渲染的点float4 texcoord : TEXCOORD0; //因为两张贴图的像素,除颜色外完全重叠,所以纹理坐标点可以通用float4 tangent:TANGENT;  //光照法线纹理,因为要计算切线空间下的信息,所以需要渲染点的切线信息float3 normal:NORMAL;};struct v2f{float4 pos:SV_POSITION;  //模型空间到裁剪空间转换后的点float4 uv:TEXCOORD1;  //因为要算出两张纹理的uv坐标,所以做一个float4,xy存储主纹理UV,zw存储法线纹理UVfloat4 MatrixRowOne:TEXCOORD2;  //用于传递从顶点着色器计算好的转换矩阵float4 MatrixRowTwo:TEXCOORD3;float4 MatrixRowThree:TEXCOORD4;};v2f vert(c2v data){v2f r;r.pos = UnityObjectToClipPos(data.vertex);//两张纹理的缩放和偏移可能不同,所以分别计算uv偏移信息,存储在v2f.uvr.uv.xy = data.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;r.uv.zw = data.texcoord.xy * _BumpTex_ST.xy + _BumpTex_ST.zw;//CPU传递过来的切线存储在模型空间下//法线纹理中的,光照法线推算信息,是存储在切线空间下的//CPU传递过来的切线信息与法线纹理中的切线信息,有转换关系,所以可以推算出一个转换矩阵用于切换法线//计算出来的转换矩阵应该是从(切线空间到模型空间)的转换//但是我们需要的是计算(从切线空间到世界空间)的转换矩阵(因为最终的光照运算,需要在世界空间中完成)//所以应该先把CPU传递过来的切线信息,转换到世界空间下//再计算切线的转换矩阵,这时就能得到从(切线空间,到世界空间)的转换矩阵//拥有了转换矩阵,就可以将法线纹理中,求解的法线信息,从切线空间,转换到世界空间下,进而可以计算光照//世界坐标系下的点的位置(片元着色器计算光照需求)float4 worldPos = mul(unity_ObjectToWorld, data.vertex);//世界空间下渲染点的法线信息float3 worldNormal = mul((float3x3)unity_ObjectToWorld, data.normal);//世界空间下切线的方向向量float3 worldTangent = mul((float3x3)unity_ObjectToWorld, data.tangent.xyz);//世界空间下计算与切线和法线垂直的线的方向向量(用于计算转换矩阵)float3 worldBinormal=cross(worldNormal, worldTangent)* data.tangent.w;//需要将转换矩阵,传递给片元着色器,用于转换切线空间下的法线到世界空间中r.MatrixRowOne = float4(worldTangent.x, worldBinormal.x, worldNormal.x, worldPos.x);r.MatrixRowTwo = float4(worldTangent.y, worldBinormal.y, worldNormal.y, worldPos.y);r.MatrixRowThree = float4(worldTangent.z, worldBinormal.z, worldNormal.z, worldPos.z);return r;}fixed4 frag(v2f data) :SV_Target{//世界空间下的点float3 worldPos = float3(data.MatrixRowOne.w,data.MatrixRowTwo.w,data.MatrixRowThree.w);//计算法线纹理中法线信息(重点),解出的法线在切线空间//解法线前,需要先对法线纹理贴图进行采样fixed3 bump = UnpackNormal(tex2D(_BumpTex, data.uv.zw));//通过缩放值,影响凹凸感bump.xy *= _BumpScale;//计算法线高度(数学公式)//法线还没有转换空间,所以计算出的法线,还在切线空间下bump.z = sqrt(1 - max(0, dot(bump.xy, bump.xy)));//通过顶点着色器传递过来的转换矩阵,转换法线,从切线空间到世界空间bump = float3(dot(data.MatrixRowOne.xyz, bump), dot(data.MatrixRowTwo.xyz, bump), dot(data.MatrixRowThree.xyz, bump));//解主纹理fixed4 texColor = tex2D(_MainTex, data.uv.xy) * _Color;//计算漫发射光照fixed3 diffuse = _LightColor0.rgb * texColor.rgb * max(0, dot(normalize(bump), normalize(_WorldSpaceLightPos0.xyz)));//计算高光反射光照fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - worldPos);fixed3 refDir = normalize(reflect(-_WorldSpaceLightPos0.xyz, normalize(bump)));fixed3 specular = _LightColor0.rgb * _SpecularColor.rgb * pow(max(0, dot(viewDir, refDir)), _Gloss);//Phong光照运算fixed3 color = UNITY_LIGHTMODEL_AMBIENT.xyz * texColor.rgb + diffuse + specular;return fixed4(color, 1);}ENDCG}}Fallback "Diffuse"
}

其实现效果如下图:

左侧为Standard的shader效果,右侧为上面代码下的shader效果,右侧较左边多了高光反射的相应数据,考虑到砖墙等一些粗糙表面现实情况下不会有如此明显的高光,应用此shader文件的同学可以将Phong光照模型的公式中的高光反射部分去除,在其他需要高光反射的情况下再进行视情况添加即可,法线贴图下第一个属性值为法线深度系数(数值0.6处,由于Shader文件未设置成UTF-8导致的中文乱码,读者可自行设置Shader文件的格式或采用英文命名),可通过调节系数对应加强法线纹理效果。

以下内容作者提供一个网址,方便读者下载Amplify Shader Editor,可找到该插件的网址如下:

amplify_shader_pack unity3D_游戏3d模型 免费下载 - 爱给网

插件中提供了很多较高质量动态Shader,有需要的可自行下载。

例:

导入Unity包后即可使用该可视化Shader编辑器,使用的Unity包例:

使用编辑器的过程:

若两边窗口未展开,点击左右上角的银灰色方框即可展开,部分使用示例如下:

更改Shader名称:

添加并编辑某一属性:(以Texture Sample [T]为例)

实现效果如图:

左侧黄色按钮,黄色为未保存,单击使其变为绿色,则成功保存期间的设置。

剩余属性可自行探索。

实现上面代码的功能对应在可视化编辑器中的操作结果如下所示:

其在检查器窗口的情况如下:

该系列专栏为网课课程笔记,仅用于学习参考。      

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OID是什么?

什么是 OID? OID 是 Object Identifier(对象标识符) 的缩写,是SNMP(Simple Network Management Protocol,简单网络管理协议)中用来唯一标识被管理对象(比如设备的某项信息)的一串数字。

STM32 ZIBEE DL-20 无线串口模块

一.配置方法 二.串口中断 u8 i; u16 buf[20],res; u8 receiving_flag 0; // 新增一个标志,用于标记是否开始接收数组 void USART1_IRQHandler(void) {if(USART_GetITStatus(USART1, USART_IT_RXNE) ! RESET) //接收中断{res USART_ReceiveData(USART1);if(receiv…

全感官交互革命:当 AI 大模型学会 “看、听、说、创”

引言:从 “文字对话” 到 “全感官体验”,AI 正在重塑人类认知边界 当 AI 不再局限于文本对话,而是能 “看懂” 图像、“听懂” 语音、“生成” 视频,并将这些模态无缝融合时,一场关于人机交互的革命已然开启。DeepSe…

C++模板知识

目录 引言 一、非类型模板参数 二、类模板的特化 (一)概念 (二)函数模板特化 (三)类模板特化 1. 全特化 2. 偏特化 (四)类模板特化应用示例 三、模板的分离编译 …

Pillow 移除或更改了 FreeTypeFont.getsize() 方法

w, h self.font.getsize(label) # text width, height AttributeError: FreeTypeFont object has no attribute getsize 在Pillow 项目的变更日志里可以查到哪个版本移除了 getsize() 方法,Pillow仓库: Releases python-pillow/Pillow GitHub 因为…

Matlab自学笔记

一、我下载的是Matlab R2016a软件,打开界面如下: 二、如何调整字体大小,路径为:“主页”->“预设”->“字体”。 三、命令行窗口是直接进行交互式的,如下输入“3 5”,回车,就得到结果“…

VR汽车线束:汽车制造的新变革

汽车线束,作为汽车电路网络的主体,宛如汽车的 “神经网络”,承担着连接汽车各个部件、传输电力与信号的重任,对汽车的正常运行起着关键作用。从汽车的发动机到仪表盘,从传感器到各类电子设备,无一不是通过线…

目标检测YOLO实战应用案例100讲-基于多级特征融合的小目标深度检测网络

目录 知识储备 基于多级特征融合的小目标深度检测网络实现 一、环境配置 二、核心代码实现 1. 多级特征融合模块(models/fpn.py ) 2. 主干网络(models/backbone.py ) 3. 检测头(models/detector.py ) 三、完整网络架构(models/net.py ) 四、训练代码(train.p…

【云原生】基于Centos7 搭建Redis 6.2 操作实战详解

目录 一、前言 二、Redis 6.2 安装过程 2.1 下载安装包 2.2 安装包解压 2.3 安装包编译 2.3 安装 2.4 启动redis 2.4.1 前台启动(不推荐) 2.4.2 后启动(推荐) 2.4.3 关闭redis服务 2.4.4 设置客户端连接 三、写在最后 …

云计算-容器云-服务网格

服务网格:创建VirtualService(3分) ​ 将Bookinfo应用部署到default命名空间下,为Bookinfo应用创建一个名为reviews的VirtualService,要求来自名为Jason的用户的所有流量将被路由到reviews服务的v2版本。(需要用到的软件包:ServiceMesh.tar.gz) # 上传解压 tar -xf Se…

【Res模块学习】结合CIFAR-100分类任务学习

初次尝试训练CIFAR-100:【图像分类】CIFAR-100图像分类任务-CSDN博客 1.训练模型(MyModel.py) import torch import torch.nn as nnclass BasicRes(nn.Module):def __init__(self, in_cha, out_cha, stride1, resTrue):super(BasicRes, sel…

爱胜品ICSP YPS-1133DN Plus黑白激光打印机报“自动进纸盒进纸失败”处理方法之一

故障现象如下图提示: 用户的爱胜品ICSP YPS-1133DN Plus黑白激光打印机在工作过程中提示自动进纸盒进纸失败并且红色故障灯闪烁; 给出常见故障一般处理建议如下: 当您的爱胜品ICSP YPS-1133DN Plus 黑白激光打印机出现“自动进纸盒进纸失败”…

Flinkcdc 实现 MySQL 写入 Doris

Flinkcdc 实现 MySQL 写入 Doris Flinkcdc 实现 MySQL 写入 Doris 一、环境配置 Doris:3.0.4 JDK 17 MySQL (业务数据库):5.7 MySQL(本地数据库):5.7 Flink:flink-1.19.1 flinkc…

【Linux庖丁解牛】—环境变量!

目录 1. 环境变量 1.1 概念介绍 1.2 命令行参数 1.3 一个例子,一个环境变量 1.4 认识更多的环境变量 1.5 获取环境变量的方法 a. 指令操作 b. 代码操作 1.6 理解环境变量的特性 a.环境变量具有全局特性 b.补充两个概念(为后面埋一个伏笔) 1. 环境变量 …

LangChain4j +DeepSeek大模型应用开发——7 项目实战 创建硅谷小鹿

这部分我们实现硅谷小鹿的基本聊天功能,包含聊天记忆、聊天记忆持久化、提示词 1. 创建硅谷小鹿 创建XiaoLuAgent package com.ai.langchain4j.assistant;import dev.langchain4j.service.*; import dev.langchain4j.service.spring.AiService;import static dev…

普通 html 项目也可以支持 scss_sass

项目结构示例 下载vscode的插件Live Sass Compiler 自动监听编译scss 下载插件Live Server 用于 web 服务器,打开 html 文件到浏览器,也可以不用这个,自己用 nginx 或者宝塔其他 web 工具 新建一个 index.scss打开,点击 vscode 底…

网工_IP协议

2025.02.17:小猿网&网工老姜学习笔记 第19节 IP协议 9.1 IP数据包的格式(首部数据部分)9.1.1 IP协议的首部格式(固定部分可变部分) 9.2 IP数据包分片(找题练)9.3 TTL生存时间的应用9.4 常见…

SQL语句练习 自学SQL网 在查询中使用表达式 统计

目录 Day 9 在查询中使用表达式 Day 10 在查询中进行统计 聚合函数 Day 11 在查询中进行统计 HAVING关键字 Day12 查询执行顺序 Day 9 在查询中使用表达式 SELECT id , Title , (International_salesDomestic_sales)/1000000 AS International_sales FROM moviesLEFT JOIN …

基于机器学习的舆情分析算法研究

标题:基于机器学习的舆情分析算法研究 内容:1.摘要 随着互联网的飞速发展,舆情信息呈现爆炸式增长,如何快速准确地分析舆情成为重要课题。本文旨在研究基于机器学习的舆情分析算法,以提高舆情分析的效率和准确性。方法上,收集了近…

菲索旋转齿轮法:首次地面光速测量的科学魔术

一、当齿轮邂逅光束:19世纪的光速实验室 1849年,法国物理学家阿曼德菲索(Armand Fizeau)在巴黎郊外的一座庄园里,用一组旋转齿轮、一面镜子和一盏油灯,完成了人类首次地面光速测量。他的实验测得光速为315…