UnityShader实例07:在shader调用unity内置lightmap和light Probes

2024-05-28 23:32

本文主要是介绍UnityShader实例07:在shader调用unity内置lightmap和light Probes,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在shader调用unity内置lightmap和Light Probes


在编写unity shader的时候,有时候会有需求,希望写的shader能支持unity内置lightmap或者light probe (灯光探测器)。如果是用surface 编写的话,这些自然不用考虑,unity会自动编译支持,但如果是用vert&frag编写shader,这些需要自己添加相关代码调用了 。


unity内置lightmap的调用


为了使unity内置数据和各种宏定义(如本文的LIGHTMAP_OFF)起作用,需要添加#pragma指令:

#pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON


在unity5.0之前的版本需要声明一下两个内置参数,unity5.0的话就不需要这两句了:

half4 unity_LightmapST;
sampler2D unity_Lightmap;

Lightmap是使用模型的uv2 ,因此接下来在顶点输入结构体里声明uv2:


float2 texcoord1 : TEXCOORD1;

在另一个顶点结构里面定义用来接收uv2的uv值:

#ifndef LIGHTMAP_OFF
half2 uvLM : TEXCOORD4;
#endif

在vert函数里面给uvLM赋值:

#ifndef LIGHTMAP_OFF
o.uvLM = v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
#endif

然后frag函数里对lightmap贴图采样并叠加给主颜色:

#ifndef LIGHTMAP_OFF
fixed3 lm = DecodeLightmap (UNITY_SAMPLE_TEX2D(unity_Lightmap, i.uvLM.xy));
col.rgb*=lm;
#endif
在上面的代码中使用了DecodeLightmap解码unity的内置光照贴图,这是因为 Unity烘焙的LightMap是32bit的HDR图,在桌面端,光照贴图的编码为RGBM,而在移动端,大部分情况下,光照贴图的编码为double-LDR,因此需要针对不同平台提供不同的编码方式。DecodeLightmap作用就在这里,它可以针对不同的平台对光照贴图进行解码


VF版本代码01:

Shader "PengLu/Unlit/TextureLM" {
Properties {_MainTex ("Base (RGB)", 2D) = "white" {}
}SubShader {Tags { "RenderType"="Opaque" }LOD 100Pass {  CGPROGRAM#pragma vertex vert#pragma fragment frag#pragma multi_compile_fog#pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON#include "UnityCG.cginc"struct appdata_t {float4 vertex : POSITION;float2 texcoord : TEXCOORD0;float2 texcoord1 : TEXCOORD1;};struct v2f {float4 vertex : SV_POSITION;half2 texcoord : TEXCOORD0;#ifndef LIGHTMAP_OFFhalf2 uvLM : TEXCOORD1;#endif UNITY_FOG_COORDS(1)};sampler2D _MainTex;float4 _MainTex_ST;v2f vert (appdata_t v){v2f o;o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);#ifndef LIGHTMAP_OFFo.uvLM = v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;#endifUNITY_TRANSFER_FOG(o,o.vertex);return o;}fixed4 frag (v2f i) : SV_Target{fixed4 col = tex2D(_MainTex, i.texcoord);UNITY_APPLY_FOG(i.fogCoord, col);UNITY_OPAQUE_ALPHA(col.a);#ifndef LIGHTMAP_OFFfixed3 lm = DecodeLightmap (UNITY_SAMPLE_TEX2D(unity_Lightmap, i.uvLM.xy));col.rgb*=lm;#endifreturn col;}ENDCG}
}}

VF版本代码01效果:



unity内置Light Probes的调用


在shader中我们是通过unity定义的half3 ShadeSH9(half4 normal)来调用Light Probes的,Light Probes照明使用的是一种叫球谐光照(Sphere Harmonic)的模拟,简称SH,因此在ShadeSH9函数需要一个世界坐标中的Normal来决定物体表面的光照。

首先我们在顶点输出结构定义一个参数SHLighting:

fixed3  SHLighting : COLOR;

然后在顶点函数里为它赋值:

 

float3 worldNormal = mul((float3x3)_Object2World, v.normal);//获得世界坐标中的normalo.SHLighting= ShadeSH9(float4(worldNormal,1)) ;

VF版本代码02:

Shader "PengLu/Unlit/TextureLM" {
Properties {_MainTex ("Base (RGB)", 2D) = "white" {}_SHLightingScale("LightProbe influence scale",float) = 1
}SubShader {Tags { "Queue"="Geometry""LightMode"="ForwardBase""RenderType"="Opaque"   }LOD 100Pass {  CGPROGRAM#pragma vertex vert#pragma fragment frag#pragma multi_compile_fog#include "UnityCG.cginc"struct v2f {float4 vertex : SV_POSITION;half2 texcoord : TEXCOORD0;fixed3  SHLighting : COLOR;UNITY_FOG_COORDS(1)};sampler2D _MainTex;float4 _MainTex_ST;float _SHLightingScale;v2f vert (appdata_base v){v2f o;o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);float3 worldNormal = mul((float3x3)_Object2World, v.normal);o.SHLighting= ShadeSH9(float4(worldNormal,1)) ;UNITY_TRANSFER_FOG(o,o.vertex);return o;}fixed4 frag (v2f i) : SV_Target{fixed4 col = tex2D(_MainTex, i.texcoord);col.rgb*=i.SHLighting;UNITY_APPLY_FOG(i.fogCoord, col);UNITY_OPAQUE_ALPHA(col.a);return col*_SHLightingScale;}ENDCG}
}}

VF版本代码02效果




这篇关于UnityShader实例07:在shader调用unity内置lightmap和light Probes的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1011998

相关文章

如何在页面调用utility bar并传递参数至lwc组件

1.在app的utility item中添加lwc组件: 2.调用utility bar api的方式有两种: 方法一,通过lwc调用: import {LightningElement,api ,wire } from 'lwc';import { publish, MessageContext } from 'lightning/messageService';import Ca

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

C++操作符重载实例(独立函数)

C++操作符重载实例,我们把坐标值CVector的加法进行重载,计算c3=c1+c2时,也就是计算x3=x1+x2,y3=y1+y2,今天我们以独立函数的方式重载操作符+(加号),以下是C++代码: c1802.cpp源代码: D:\YcjWork\CppTour>vim c1802.cpp #include <iostream>using namespace std;/*** 以独立函数

实例:如何统计当前主机的连接状态和连接数

统计当前主机的连接状态和连接数 在 Linux 中,可使用 ss 命令来查看主机的网络连接状态。以下是统计当前主机连接状态和连接主机数量的具体操作。 1. 统计当前主机的连接状态 使用 ss 命令结合 grep、cut、sort 和 uniq 命令来统计当前主机的 TCP 连接状态。 ss -nta | grep -v '^State' | cut -d " " -f 1 | sort |

【LabVIEW学习篇 - 21】:DLL与API的调用

文章目录 DLL与API调用DLLAPIDLL的调用 DLL与API调用 LabVIEW虽然已经足够强大,但不同的语言在不同领域都有着自己的优势,为了强强联合,LabVIEW提供了强大的外部程序接口能力,包括DLL、CIN(C语言接口)、ActiveX、.NET、MATLAB等等。通过DLL可以使用户很方便地调用C、C++、C#、VB等编程语言写的程序以及windows自带的大

Java Websocket实例【服务端与客户端实现全双工通讯】

Java Websocket实例【服务端与客户端实现全双工通讯】 现很多网站为了实现即时通讯,所用的技术都是轮询(polling)。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发 出HTTP request,然后由服务器返回最新的数据给客服端的浏览器。这种传统的HTTP request 的模式带来很明显的缺点 – 浏 览器需要不断的向服务器发出请求,然而HTTP

828华为云征文|华为云Flexus X实例docker部署rancher并构建k8s集群

828华为云征文|华为云Flexus X实例docker部署rancher并构建k8s集群 华为云最近正在举办828 B2B企业节,Flexus X实例的促销力度非常大,特别适合那些对算力性能有高要求的小伙伴。如果你有自建MySQL、Redis、Nginx等服务的需求,一定不要错过这个机会。赶紧去看看吧! 什么是华为云Flexus X实例 华为云Flexus X实例云服务是新一代开箱即用、体

string字符会调用new分配堆内存吗

gcc的string默认大小是32个字节,字符串小于等于15直接保存在栈上,超过之后才会使用new分配。

京东物流查询|开发者调用API接口实现

快递聚合查询的优势 1、高效整合多种快递信息。2、实时动态更新。3、自动化管理流程。 聚合国内外1500家快递公司的物流信息查询服务,使用API接口查询京东物流的便捷步骤,首先选择专业的数据平台的快递API接口:物流快递查询API接口-单号查询API - 探数数据 以下示例是参考的示例代码: import requestsurl = "http://api.tanshuapi.com/a

Python 内置的一些数据结构

文章目录 1. 列表 (List)2. 元组 (Tuple)3. 字典 (Dictionary)4. 集合 (Set)5. 字符串 (String) Python 提供了几种内置的数据结构来存储和操作数据,每种都有其独特的特点和用途。下面是一些常用的数据结构及其简要说明: 1. 列表 (List) 列表是一种可变的有序集合,可以存放任意类型的数据。列表中的元素可以通过索