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

相关文章

Vue3组件中getCurrentInstance()获取App实例,但是返回null的解决方案

《Vue3组件中getCurrentInstance()获取App实例,但是返回null的解决方案》:本文主要介绍Vue3组件中getCurrentInstance()获取App实例,但是返回nu... 目录vue3组件中getCurrentInstajavascriptnce()获取App实例,但是返回n

SQL表间关联查询实例详解

《SQL表间关联查询实例详解》本文主要讲解SQL语句中常用的表间关联查询方式,包括:左连接(leftjoin)、右连接(rightjoin)、全连接(fulljoin)、内连接(innerjoin)、... 目录简介样例准备左外连接右外连接全外连接内连接交叉连接自然连接简介本文主要讲解SQL语句中常用的表

Java调用C++动态库超详细步骤讲解(附源码)

《Java调用C++动态库超详细步骤讲解(附源码)》C语言因其高效和接近硬件的特性,时常会被用在性能要求较高或者需要直接操作硬件的场合,:本文主要介绍Java调用C++动态库的相关资料,文中通过代... 目录一、直接调用C++库第一步:动态库生成(vs2017+qt5.12.10)第二步:Java调用C++

C# WinForms存储过程操作数据库的实例讲解

《C#WinForms存储过程操作数据库的实例讲解》:本文主要介绍C#WinForms存储过程操作数据库的实例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、存储过程基础二、C# 调用流程1. 数据库连接配置2. 执行存储过程(增删改)3. 查询数据三、事务处

springboot security验证码的登录实例

《springbootsecurity验证码的登录实例》:本文主要介绍springbootsecurity验证码的登录实例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录前言代码示例引入依赖定义验证码生成器定义获取验证码及认证接口测试获取验证码登录总结前言在spring

tomcat多实例部署的项目实践

《tomcat多实例部署的项目实践》Tomcat多实例是指在一台设备上运行多个Tomcat服务,这些Tomcat相互独立,本文主要介绍了tomcat多实例部署的项目实践,具有一定的参考价值,感兴趣的可... 目录1.创建项目目录,测试文China编程件2js.创建实例的安装目录3.准备实例的配置文件4.编辑实例的

python+opencv处理颜色之将目标颜色转换实例代码

《python+opencv处理颜色之将目标颜色转换实例代码》OpenCV是一个的跨平台计算机视觉库,可以运行在Linux、Windows和MacOS操作系统上,:本文主要介绍python+ope... 目录下面是代码+ 效果 + 解释转HSV: 关于颜色总是要转HSV的掩膜再标注总结 目标:将红色的部分滤

在C#中调用Python代码的两种实现方式

《在C#中调用Python代码的两种实现方式》:本文主要介绍在C#中调用Python代码的两种实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#调用python代码的方式1. 使用 Python.NET2. 使用外部进程调用 Python 脚本总结C#调

SpringCloud之LoadBalancer负载均衡服务调用过程

《SpringCloud之LoadBalancer负载均衡服务调用过程》:本文主要介绍SpringCloud之LoadBalancer负载均衡服务调用过程,具有很好的参考价值,希望对大家有所帮助,... 目录前言一、LoadBalancer是什么?二、使用步骤1、启动consul2、客户端加入依赖3、以服务

Spring 中使用反射创建 Bean 实例的几种方式

《Spring中使用反射创建Bean实例的几种方式》文章介绍了在Spring框架中如何使用反射来创建Bean实例,包括使用Class.newInstance()、Constructor.newI... 目录1. 使用 Class.newInstance() (仅限无参构造函数):2. 使用 Construc