钢铁侠材质制作——3、基础光照模型实现

news/2024/11/9 0:58:25/

钢铁侠Unlit光照Shader,三种效果变化


返回目录

大家好,我是阿赵,这里是钢铁侠材质制作的第三部分,基础光照模型实现。

这一个过程我不太想多说了,因为都是套用之前的光照模型而已,不过这次有具体的模型,也可以顺便看看各个过程对模型实际显示效果产生的影响。
在这里使用的光照模型,都是可以自己选择的,比如漫反射模型我是选择了HalfLambert,高光模型我是选择了BlinnPhong。这不是固定的,也可以换成自己喜欢的其他光照模型来实现。
最后的计算结果,还是环境光颜色+漫反射颜色+高光颜色。

1、漫反射贴图

在这里插入图片描述

这个过程只用采样了模型的漫反射贴图,并显示出来。

2、使用HalfLambert漫反射光照模型

在这里插入图片描述

可以看出这个过程模型产生了一些亮面和暗面的差异,模型有了一些立体感。

3、使用BlinnPhong高光模型

在这里插入图片描述

加上高光之后,模型就更立体了,不过有点油腻

4、加上高光遮罩贴图:

在这里插入图片描述
在这里插入图片描述

加上高光遮罩贴图之后,可以控制模型不同位置产生高光的强度不一样,这样模型看起来没那么油腻。不过这张高光贴图是我下载模型的时候自带的,我个人感觉它似乎只是拿漫反射贴图直接转的,高光的变化太均匀,效果并不是很理想。这里我只是演示一下怎样去使用遮罩图,所以我也没有再去修整这张图片了。

5、加上法线贴图

在这里插入图片描述

加上法线贴图后,可以为光照效果增加很多细节,看起来更细腻。

需要注意的是,我在Shader里面自己做了UnpackScaleNormal的操作,所以法线贴图的导入选项里面,就不需要选择Normal了,正常的贴图格式就行。不然重复的Unpack,效果反而不对。

6、完整Shader:

Shader "azhao/IronManBodyCode"
{Properties{_RimBias("RimBias", Float) = 1_RimPow("RimlPow", Float) = 2_RimlCol("RimCol", Color) = (0,0,0,0)_NoiseMap("NoiseMap",2D) = "black"{}_NoiseTiling("NoiseTiling",Vector) = (1,1,0,0)_NoiseSpeed("NoiseSpeed",float) = 0_AmbientStength("AmbientStength",float) = 1_MainTex("BaseCol",2D) = "white"{}_NormalMap("NormalMap",2D) = "black"{}_NormalScale("NormalScale",float) = 1_SpecCol("SpecCol",Color) = (1,1,1,1)_Shininess("_Shininess",float) = 1_SpecStength("SpecStength",float) = 1_SpecMask("SpecMask",2D) = "white"{}}SubShader{Tags { "RenderType"="Opaque" }LOD 100Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"//简化版的转换法线并缩放的方法half3 UnpackScaleNormal(half4 packednormal, half bumpScale){half3 normal;//由于法线贴图代表的颜色是0到1,而法线向量的范围是-1到1//所以通过*2-1,把色值范围转换到-1到1normal = packednormal * 2 - 1;//对法线进行缩放normal.xy *= bumpScale;//向量标准化normal = normalize(normal);return normal;}//获取HalfLambert漫反射值float GetHalfLambertDiffuse(float3 worldPos, float3 worldNormal){float3 lightDir = UnityWorldSpaceLightDir(worldPos);float NDotL = saturate(dot(worldNormal, lightDir));float halfVal = NDotL * 0.5 + 0.5;return halfVal;}//获取BlinnPhong高光float GetBlinnPhongSpec(float3 worldPos, float3 worldNormal,float shininess){float3 viewDir = normalize(UnityWorldSpaceViewDir(worldPos));float3 halfDir = normalize((viewDir + _WorldSpaceLightPos0.xyz));float specDir = max(dot(normalize(worldNormal), halfDir),0);float specVal = pow(specDir, shininess);return specVal;}struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;float3 normal : NORMAL;float4 tangent : TANGENT;};struct v2f{float4 pos : SV_POSITION;float2 uv : TEXCOORD0;float3 worldPos :TEXCOORD1;float3 worldNormal : TEXCOORD2;float3 worldTangent :TEXCOORD3;float3 worldBitangent : TEXCOORD4;};float _RimBias;float _RimPow;float4 _RimlCol;sampler2D _NoiseMap;float4 _NoiseTiling;float _NoiseSpeed;sampler2D _MainTex;sampler2D _NormalMap;float _NormalScale;float _AmbientStength;float4 _SpecCol;float _Shininess;float _SpecStength;sampler2D _SpecMask;v2f vert (appdata v){v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.uv = v.uv;o.worldPos = mul(unity_ObjectToWorld, v.vertex);o.worldNormal = UnityObjectToWorldNormal(v.normal);o.worldTangent = UnityObjectToWorldDir(v.tangent);o.worldBitangent = cross(o.worldNormal, o.worldTangent);return o;}half4 frag (v2f i) : SV_Target{/*光线轮廓暂时先屏蔽掉float3 worldViewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));float NdotV = dot(i.worldNormal, worldViewDir);float fresnelVal = pow((1 - NdotV)*_RimBias, _RimPow);float2 noiseUV = i.worldPos.xy *_NoiseTiling.xy + _NoiseTiling.zw;noiseUV.y += frac(_Time.y)*_NoiseSpeed;float4 noiseCol = tex2D(_NoiseMap, noiseUV);half4 RimRGBA = _RimlCol * (fresnelVal+noiseCol.r);*/half4 baseCol = tex2D(_MainTex,i.uv);half4 normalCol = tex2D(_NormalMap, i.uv);//得到切线空间的法线方向half3 normalVal = UnpackScaleNormal(normalCol, _NormalScale).rgb;//构建TBN矩阵float3 tanToWorld0 = float3(i.worldTangent.x, i.worldBitangent.x, i.worldNormal.x);float3 tanToWorld1 = float3(i.worldTangent.y, i.worldBitangent.y, i.worldNormal.y);float3 tanToWorld2 = float3(i.worldTangent.z, i.worldBitangent.z, i.worldNormal.z);//通过切线空间的法线方向和TBN矩阵,得出法线贴图代表的物体世界空间的法线方向float3 worldNormal = float3(dot(tanToWorld0, normalVal), dot(tanToWorld1, normalVal), dot(tanToWorld2, normalVal));float diffuseVal = GetHalfLambertDiffuse(i.worldPos, worldNormal);float4 specMaskVal = tex2D(_SpecMask, i.uv).r;float specVal = GetBlinnPhongSpec(i.worldPos, worldNormal, _Shininess)*specMaskVal*_SpecStength;half3 finalRGB = UNITY_LIGHTMODEL_AMBIENT * _AmbientStength + baseCol.rgb*diffuseVal+ _SpecCol.rgb*specVal;return half4(finalRGB,1);}ENDCG}}
}

http://www.ppmy.cn/news/273773.html

相关文章

【自制】我造了一台 钢 铁 侠 的 机 械 臂 !【硬核】

有人说:一个人从1岁活到80岁很平凡,但如果从80岁倒着活,那么一半以上的人都可能不凡。 生活没有捷径,我们踩过的坑都成为了生活的经验,这些经验越早知道,你要走的弯路就会越少。

看《钢铁侠》有感

刚刚看完了去年的大片《钢铁侠》,结果发现东西方的审美观点或者说是哲学观点有着很大的区别。 在《钢铁侠》中,美国人将武器设计的非常的负责,好像复杂的武器才能被称为是武器系统,才能有着极大的威力。 而中国人则相信简单就是…

Python版Day10

232. 用栈实现队列 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty): 实现 MyQueue 类: void push(int x) 将元素 x 推到队列的末尾 int pop() 从队列的开头移除并返回元素 int p…

Symfony v6.2.11 正式发布,经典 PHP Web 开发框架

导读Symfony v6.2.11 发布了!Symfony 是一款基于 MVC 架构的 PHP 框架,致力于减少重复代码的编写,以加速 Web 应用的开发和维护。Symfony 与许多关系型数据库集成的也非常好,成本也较小。 此外,Symfony 致力于在企业背…

iPhone将图片导入到 Mac

iPhone将图片导入到 Mac 1.用 USB 连接线将 iPhone、iPad 或 iPod touch 连接到 Mac。 2.在电脑上打开“照片”App。 3.“照片”App 会显示“导入”屏幕,其中包含所连接设备上的全部照片和视频。如果没有自动显示“导入”屏幕,请点按“照片”边栏中对应…

将windows电脑上的图片导入到iphone

1.电脑端安装iTools。 网上搜索找到iTools的官网之后,点击下载却没有什么反应,然后感觉是不是浏览器的问题,于是把google浏览器换成IE之后可以下载,下载完成之后点击安装。 2.导入图片 电脑端打开iTools之后,点击这里…

抹掉iPhone会有怎样后果 他人还能用吗

1、关于抹掉IPHONE,手机没有越狱,只要之前你在设置里打开了“查找我的iphone”,抹掉iphone后手机所有的资料全部抹除得干干净净,icloud不能再定位你的手机(不管手机有没有离线),但必须要用原来的…

移动端H5页面中加载的图片,在chrome和安卓手机中显示正常,在iphone和safari浏览器中个别图片显示问号的问题处理

最近开发了一个类似文章列表的页面,左边是图,右边是文字,配置在公众号中进行使用,测试通过以后线上运行发现个别项的图片在chrome和安卓手机下可以正常显示,在ios系统的sarafi下显示一个白方块中间一个蓝色的问号,如下…