钢铁侠材质制作——4、反射效果叠加

news/2024/11/30 5:58:03/

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

返回目录

大家好,我是阿赵。这里是钢铁侠材质制作的第四部分,反射效果叠加。

1、光照模型的补充说明

我一直说光照模型的构成是
环境光+漫反射+高光。
其实最后一个高光,应该理解成是光线的反射。
所以最后光照模型的构成就变成了
环境光+漫反射+光线反射颜色

在之前的基础光照模型的漫反射和高光颜色之后,这一步需要加入反射的效果。

2、反射效果介绍

光线反射的实现有很多种,比如像Unity引擎官方例子的水面反射,或者是用CubeMap、反射探针(reflection probe)等都是可以的。
由于这个综合的例子本身已经有点复杂,出于性能考虑,这里选用了MatCap作为模拟反射的手段。为了能让模型的边缘有一些类似于补光的效果,所以我还加入了一点边缘光。

怎样使用MatCap材质之前已经介绍过,这里也不再多说,先看看效果,然后直接上代码。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

这里主要使用了2张贴图,一张是金属感比较强的MatCap材质,另外一张是之前用的高光遮罩贴图的G通道。

在这里插入图片描述

可以看到,加了MatCap模拟反射之后,模型的细节会变得更加的丰富。

3、完整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"{}_MatCapTex("_MatCapTex",2D) = "black"{}_MatCapStength("MatCapStength",float) = 1_MatCapPow("MatCapPow",float) = 2_RimAddStength("RimAddStength",float) = 1}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;}float2 GetMatCapUV(float3 normalWorld){float3 normalView = mul(UNITY_MATRIX_IT_MV, normalWorld);return normalView.xy*0.5 + 0.5;}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;sampler2D _MatCapTex;float _MatCapStength;float _MatCapPow;float _RimAddStength;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 RimLineRGBA = _RimlCol * (fresnelVal+noiseCol.r);*/half4 RimRGBA = _RimlCol * fresnelVal*_RimAddStength;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);float specVal = GetBlinnPhongSpec(i.worldPos, worldNormal, _Shininess)*specMaskVal.r*_SpecStength;float2 MatCapUV = GetMatCapUV(worldNormal);float4 MatCapCol = pow(tex2D(_MatCapTex, MatCapUV)*_MatCapStength*specMaskVal.g, _MatCapPow);half3 finalRGB = UNITY_LIGHTMODEL_AMBIENT * _AmbientStength + baseCol.rgb*diffuseVal+ _SpecCol.rgb*specVal + MatCapCol+ RimRGBA.rgb;return half4(finalRGB,1);}ENDCG}}
}

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

相关文章

HashTable, HashMap 和 ConcurrentHashMap

HashTable, HashMap 和 ConcurrentHashMap 都是 Java 集合框架中的类,用于存储和操作键值对。它们之间存在一些关键区别,如下所示: 1.同步性: HashTable:线程安全,所有的方法都是同步的(synchr…

Kafka3.0.0版本——生产者回调异步发送消息 (API代码示例)

目录一、回调函数的异步发送消息概述二、生产者带回调函数的异步发送消息(API代码示例)2.1、pom文件导入依赖2.2、API代码2.3、在 kafka集群服务器上开启 Kafka 消费者一、回调函数的异步发送消息概述 回调函数会在 producer 收到 ack 时调用&#xff0…

LeetCode349_349. 两个数组的交集

LeetCode349_349. 两个数组的交集 一、描述 给定两个数组 nums1 和 nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。 示例 1: 输入:nums1 [1,2,2,1], nums2 [2,2] 输出:[2…

为什么程序员都喜欢开源的软件?

程序员宝藏库:https://gitee.com/sharetech_lee/CS-Books-Store 商业软件:下载、安装、注册账号、登陆、看广告…费了半天功夫之后发现竟然收费! 开源软件:开放透明、完全免费。 这么明显的对比,为啥不喜欢用开源软件…

One-YOLOv5 v1.2.0发布:支持分类、检测、实例分割

One-YOLOv5 v1.2.0正式发布。完整更新列表请查看链接:https://github.com/Oneflow-Inc/one-yolov5/releases/tag/v1.2.0,欢迎体验新版本,期待你的反馈。 1 新版本特性 1. 同步了Ultralytics YOLOv5的上游分支v7.0,同时支持分类、目…

都2023了,学习自动化测试还有必要么?会不会浪费我时间

最近收到不少小伙伴私信提问,其中问得比较多的就是“学习自动化测试有那么重要吗?”。 我的回答是肯定的——很重要。 相信不少同学都有诸如此类的疑问,例如:“日常工作中好像用不上自动化?”、“手工点点点好像也可…

该不该放弃嵌入式,单片机这条路?

本文几乎浓缩了我从业10几年的精华,内容涵盖我转行、打工、创业的经历。 建议从头到尾不要错过一字一句,因为字里行间的经验之谈,或许能成为你人生重要转折点。 全文3700多字,写了6个多小时,如果你赶时间,建…

《花雕学AI》04:尝鲜功能丰富且容易上手的AI绘画工具——Leonardo AI

偶然机缘,我接触到了另外一个AI绘画平台:Leonardo.AI 它是一个新的 AI 图像平台,其输出质量可与目前最火的Midjourney 相媲美,当然差距还是有的。其链接是https://leonardo.ai/,界面如下图。 我填写了电邮地址&#xf…