UnityShader源码2017---学习笔记与自我拓展039

2024-08-20 15:48

本文主要是介绍UnityShader源码2017---学习笔记与自我拓展039,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

源自 Illumin-Bumped,Illumin-BumpSpec,Illumin-Diffuse,Illumin-Glossy,Illumin-Parallax,Illumin-ParallaxSpec,Illumin-VertexLit

记得很久很久以前。。。。long long ago

那还是4.x的年底,shader中如果这么写

Shader "Self-Illumin/New Unlit NoFog"

是的,只有shader的一级文件夹是Self-Illumin,那么shader的自发光部分就可以bake到lightmap中

时过境迁,unity迎来的PBR的时代。之前的套路已经没有了效果。

先搁置下Illumin-VertexLit这个shader,看其他的

其他shader中能说的之前都说了,只有一处,这一处也是这些shader的共同点

#if defined (UNITY_PASS_META)o.Emission *= _Emission.rrr;
#endif

也就是说如果定义了UNITY_PASS_META这个宏,就会让自发光的强度与_Emission做倍率乘法。

而META是unity用来做GI等的。

所以就是说,可以bake到lightmap中。

我为了减少变量的影响,注释掉了fallback

//FallBack "Legacy Shaders/Self-Illumin/VertexLit"

然后bake,效果如下。

也就是说,lightmap的bake不是fallback里的meta的pass做的。可能是surface shader的一些魔法吧

后来我测试了直接只有一个pass,然后fallback到vertexlit里的meta 的pass似乎找不到meta,不知为何,表现的结果就是lightmap烘焙结果没有预期。

 

然后返回shader中,定睛一看。。。

CustomEditor "LegacyIlluminShaderGUI"

然后我有开始扒拉源码中,并没有发现这个Editor的cs源码。

unity真是爸爸。。。

算了,看一眼mat里的吧

也就是说,这个是这个editor的关键之处。

可惜找不到出处。。。。。(这个留给之后看PBR时再说吧。。。)

想了想还是这里一下子说完这一块吧。。。

using UnityEngine;namespace UnityEditor
{internal class LegacyIlluminShaderGUI : ShaderGUI{public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] props){base.OnGUI(materialEditor, props);materialEditor.LightmapEmissionProperty(0);foreach (Material target in materialEditor.targets)target.globalIlluminationFlags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack;}}
}

这个问题先导此位置。

看一眼Illumin-VertexLit,

直接定位meta(vertex mode下没有什么可说的)

先说一个疑似bug的部分。

metaIN.Emission = c.rgb * tex2D(_Illum, i.uvIllum).a;
#if defined (UNITY_PASS_META)o.Emission *= _Emission.rrr;
#endif

o从何而来。。。。应该是这样

metaIN.Emission = c.rgb * tex2D(_Illum, i.uvIllum).a;
#if defined (UNITY_PASS_META)metaIN.Emission *= _Emission.rrr;
#endif

个人觉得是个bug

然后去看了下builtin_shaders-2018.1.6f1中的发现

这里已经修复。。。删除了#if的判断,直接保留了语句变成了这样

 metaIN.Emission = c.rgb * tex2D(_Illum, i.uvIllum).a;

但是同样的。发现_Emission的使用却消失了。。。。官方还是留了个bug?

 

纵使如此,fallback的问题(后来我测试了直接只有一个pass,然后fallback到vertexlit里的meta 的pass似乎找不到meta,不知为何,表现的结果就是lightmap烘焙结果没有预期。)还是遗留下来了,随着2018版本的一次又一次更迭,我觉定放弃这部分的问题。或许官方就是这么想的。。。。

 

关于lightmap的研究下面还有实验。

回归正题,把vert部分的UnityMetaVertexPosition()说完这一部分就结束了

o.pos = UnityMetaVertexPosition(v.vertex, v.texcoord1.xy, v.texcoord2.xy, unity_LightmapST, unity_DynamicLightmapST);
float4 UnityMetaVertexPosition (float4 vertex, float2 uv1, float2 uv2, float4 lightmapST, float4 dynlightmapST)
{if (unity_MetaVertexControl.x){vertex.xy = uv1 * lightmapST.xy + lightmapST.zw;// OpenGL right now needs to actually use incoming vertex position,// so use it in a very dummy wayvertex.z = vertex.z > 0 ? 1.0e-4f : 0.0f;}if (unity_MetaVertexControl.y){vertex.xy = uv2 * dynlightmapST.xy + dynlightmapST.zw;// OpenGL right now needs to actually use incoming vertex position,// so use it in a very dummy wayvertex.z = vertex.z > 0 ? 1.0e-4f : 0.0f;}return mul(UNITY_MATRIX_VP, float4(vertex.xyz, 1.0));
}

先看unity_MetaVertexControl,在UnityMetaPass.cginc里

CBUFFER_START(UnityMetaPass)// x = use uv1 as raster position// y = use uv2 as raster positionbool4 unity_MetaVertexControl;// x = return albedo// y = return normalbool4 unity_MetaFragmentControl;// Control which VisualizationMode we will// display in the editorint unity_VisualizationMode;
CBUFFER_END

unity_MetaVertexControl的x分量是个布尔值(在C的语法里,0为false,非零为true):是否使用uv1作为光栅化的坐标

y分量:是否使用uv2作为光栅化的坐标

下面的码很明显的,就是做了TRNASFOMR_TEX这个函数做的,只不过把判断Z,如果大于零z=0.0001,否则就是0

带来的疑问是什么时候会用uv1做光栅化的坐标呢?

不明白这里是用做干什么的,或许unity还有一些未发觉的技能。下面是一个简单的测试

 

 

 

下面是lightmap的一点实验性的操作(这里不测试_Emission为负值时带来的反色的lightmap的效果)

这里就意思一下,具体含义不细说,详情看手册吧

效果如上。

4.x年代的手法已经失效,那么在新版unity里如何做的,手册里也说了meta的pass管这个。

于是,就有了meta的pass

Pass
{Tags { "LightMode"="Meta" }CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;};struct v2f{float4 vertex : SV_POSITION;};fixed4 _Color;float _Emission;v2f vert (appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);return o;}fixed4 frag (v2f i) : SV_Target{fixed4 col = _Color*_Emission;return col;}ENDCG
}

这里简单的写的meta,或许不会符合unity的规范,这里先简单的测试。

我们把_Emission调到0.1,然后bake(使用这个shader的材质在light explorer的static  emissives页签下并没有记录)

效果如下图

这里有个问题就是,自己写的meta中的_Emission的值竟然影响旁边红色的材质(自带的standard shader的mat)。可以调_Emission成1试试,整个都是爆掉的,然后红色的部分用来黄绿色。

说明了什么,只能说明我的操作不规范。

然后我用了自带的过来时的shader  bake一下

也是有问题的。

然后两个standard。

看来Emission的值不能过大。

 

 

 

这篇关于UnityShader源码2017---学习笔记与自我拓展039的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Java深度学习库DJL实现Python的NumPy方式

《Java深度学习库DJL实现Python的NumPy方式》本文介绍了DJL库的背景和基本功能,包括NDArray的创建、数学运算、数据获取和设置等,同时,还展示了如何使用NDArray进行数据预处理... 目录1 NDArray 的背景介绍1.1 架构2 JavaDJL使用2.1 安装DJL2.2 基本操

Go中sync.Once源码的深度讲解

《Go中sync.Once源码的深度讲解》sync.Once是Go语言标准库中的一个同步原语,用于确保某个操作只执行一次,本文将从源码出发为大家详细介绍一下sync.Once的具体使用,x希望对大家有... 目录概念简单示例源码解读总结概念sync.Once是Go语言标准库中的一个同步原语,用于确保某个操

Java汇编源码如何查看环境搭建

《Java汇编源码如何查看环境搭建》:本文主要介绍如何在IntelliJIDEA开发环境中搭建字节码和汇编环境,以便更好地进行代码调优和JVM学习,首先,介绍了如何配置IntelliJIDEA以方... 目录一、简介二、在IDEA开发环境中搭建汇编环境2.1 在IDEA中搭建字节码查看环境2.1.1 搭建步

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]