从0开始的技美实战(七)

本篇主要用于记录自己的实战操作,以及一些碎碎念(观后感),如果有什么好想法或者本篇出现什么错误,请多指教~

本篇的内容参考视频:庄懂的技术美术入门课(美术向)
使用软件:Unity 2019 3.6f1 ,ShaderForge

本篇主要内容包含:对大佬作品的分析,法线贴图连连看与编程;


一.大佬作品分析

1.虫子

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

思路分析:用Phong模型做RampTexture,然后用兰伯特模型乘一个基础颜色作为底色,用lerp节点对Phong模型的结果与一个颜色基于用normal向量取绿通道的遮罩做运算与兰伯特模块相加,得到结果;

制作:

  • 先从光学模型入手,Phong模型与Lambert模型;
    在这里插入图片描述

  • 对Phong模型做RampTexture那套操作,对normal向量取绿通道做遮罩与菲涅尔相乘;

在这里插入图片描述

  • 将三个模块整合,直接放节点和效果图(突出翅膀那里的感觉),模型来自zbrush里内置文档;

在这里插入图片描述

在这里插入图片描述

2.奇异猴子
效果图:
在这里插入图片描述
在这里插入图片描述因为节点多而杂,且有没删掉的用不到的节点,就简单理解下思路

案例解析:大佬全程没有使用兰伯特模型,用的是Phong模型,环境光模型和阴影还有菲涅尔,比较关键的点:

  • 一个是阴影的衰减做了一个范围限制,从0-1变成0.7-1,使得不会特别暗,猴子的腮红估计就是依托于阴影的关系;
  • 大佬将厚度贴图与AO贴图放在了一张图的不同通道里,在实际工作中属于比较常见的做法;
  • 大佬用厚度贴图整了个power弄出个范围,然后通过lerp,相当于最后给薄的地方染色;

剩下的不多说了,因为无用节点多不好拆解出来…

3.精细的皮卡丘

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

根据节点和面板参数,其实可以发现本质上还是OldSchoolPlus那个模型,但是通过Mask的RGB三通道的贴图,对其不同部分进行划分,如果直接拆开成不同模型,分别用OldSchoolPlus也是差不多的效果;


二.法线贴图

1.连连看

  • 法线贴图承载法线信息,我们烘焙得到的是切线空间下的法线信息,而非世界空间下的法线信息,所以我们要先将
  • 切线空间下的法线转到世界空间,然后再与光向量点乘;
  • 副切线是用来辅助切线和法线向量形成切线空间,三者可以构成TBN矩阵,用切线空间下的法线向量乘该矩阵可得到世界空间下的法线;

节点图如下:

在这里插入图片描述
效果对比,看角的差别;

效果对比

2.代码
在这里插入图片描述

Shader "Unlit/co8-normal-VS"
{
    Properties
    {
        _NormalMap ("法线贴图",2D) = "bump" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
		    Tags { "LightMode"="ForwardBase" }
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_fwdbase_fullshadows
            #include "UnityCG.cginc"

			uniform sampler2D _NormalMap;

            struct appdata
            {
                float4 vertex  : POSITION;
				float3 normal  : NORMAL;
				float4 tangent : TANGENT;
                float2 uv      : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv     : TEXCOORD0;
                float4 vertex : SV_POSITION;
				float3 nDirWS : TEXCOORD1;
				float3 tDirWS : TEXCOORD2;
				float3 bDirWS : TEXCOORD3;
            };


            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
				o.nDirWS = UnityObjectToWorldNormal(v.normal);
				o.tDirWS = normalize(mul(unity_ObjectToWorld,float4(v.tangent.xyz,0.0)));
				o.bDirWS = normalize(cross(o.nDirWS,o.tDirWS)*v.tangent.w);
				o.uv     = v.uv;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
              
                float3 var_Normalmap = UnpackNormal(tex2D(_NormalMap, i.uv)).rgb;
				float3x3  TBN        = float3x3(i.tDirWS,i.bDirWS,i.nDirWS);
				float3 nDir          = normalize(mul(var_Normalmap,TBN));
				float3 lDir          =_WorldSpaceLightPos0;

				float ndotl          =dot(nDir,lDir);
				float lambert       =max(ndotl,0.0);

                return float4(lambert ,lambert ,lambert ,1.0);
            }
            ENDCG
        }
    }
	FallBack "Diffuse"
}

我们尝试将上一次学的OldSchoolPlus的代码结合上法线贴图;

Shader "Unlit/co8-ospnormal-VS"
{
    Properties
    {
        _MainTex ("颜色贴图", 2D) = "white" {}
		_NormalMap("法线贴图",2D)="bump"{}
		_AO ("AO贴图", 2D) = "white" {}
		_LightColor("灯光颜色",color) = (1.0,1.0,1.0,1.0)
		_SpecularPow("高光次幂",range(1,90)) = 30
		_SpecularIns("高光强度",range(0,1)) = 1
		_EnvtopColor("环境上颜色",color) = (1.0,1.0,1.0,1.0)
		_EnvmidColor("环境中颜色",color) = (1.0,1.0,1.0,1.0)
		_EnvdowColor("环境下颜色",color) = (1.0,1.0,1.0,1.0)
		_Envcontrol("环境影响",range(0,1)) = 1
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
		    Tags { "LightMode" = "ForwardBase" }
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"
			#include "AutoLight.cginc"
			#include "Lighting.cginc"
			#pragma multi_compile_fwdbase_fullshadows

			    uniform sampler2D _MainTex;
				uniform sampler2D _NormalMap;
			    uniform sampler2D _AO;
				uniform float3 _LightColor;
				uniform float3 _EnvtopColor;
				uniform float3 _EnvmidColor;
				uniform float3 _EnvdowColor;
				uniform float _SpecularPow;
				uniform float _SpecularIns;
				uniform float _Envcontrol;

            struct appdata
            {
                float4 vertex : POSITION;
				float3 normal : NORMAL;
				float4 tangent:TANGENT;
                float2 uv0 : TEXCOORD0;
				float2 uv1 : TEXCOORD1;
				float2 uv2 : TEXCOORD2;
            };

            struct v2f
            {
                float2 uv0 : TEXCOORD0;
				float2 uv1 : TEXCOORD1;
				float2 uv2 : TEXCOORD8;
                float4 pos : SV_POSITION;
				float3 nDirWS : TEXCOORD2;
				float3 bDirWS : TEXCOORD3;
				float3 tDirWS : TEXCOORD4;
				float4 posWS  : TEXCOORD7;
				LIGHTING_COORDS(5, 6)
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
				o.nDirWS = UnityObjectToWorldNormal(v.normal);
				o.tDirWS = normalize(mul(unity_ObjectToWorld,float4(v.tangent.xyz,0.0)));
				o.bDirWS = normalize(cross(o.nDirWS,o.tDirWS)*v.tangent.w);
				o.posWS  = mul(unity_ObjectToWorld, v.vertex);
                o.uv0 = v.uv0;
				o.uv1 = v.uv1;
				o.uv2 = v.uv2;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
               // float3 nDir = normalize(i.nDirWS);
				float3 lDir = normalize(_WorldSpaceLightPos0.xyz);
				float3 vDir = normalize(_WorldSpaceCameraPos.xyz - i.posWS);

				float3 var_Normalmap = UnpackNormal(tex2D(_NormalMap, i.uv0)).rgb;
				float3 var_MainTex   =tex2D(_MainTex,i.uv1).rgb;
				float3x3  TBN        = float3x3(i.tDirWS,i.bDirWS,i.nDirWS);
				float3 nDir          = normalize(mul(var_Normalmap,TBN));

				float ndotl          =dot(nDir,lDir);
				float topmask = max(nDir.g,0);
				float dowmask = max(-nDir.g, 0);
				float midmsk = 1 - topmask - dowmask;
				float occlusion = tex2D(_AO,i.uv2);
				float shadow = LIGHT_ATTENUATION(i);

				float3 lambert = max(dot(nDir, lDir), 0)* var_MainTex ;
				float Phong = pow(max(dot(reflect(-lDir, nDir), vDir),0), _SpecularPow)* _SpecularIns;
				float3 ambient = (_EnvtopColor * topmask + _EnvmidColor * midmsk + _EnvdowColor * dowmask)*_Envcontrol* var_MainTex * occlusion;

				float3 final = ((lambert + Phong) * _LightColor * shadow) + ambient;

                return float4(final,1.0);
            }
            ENDCG
        }
    }
	FallBack "Diffuse"
}

最后效果如下图的左边,右边为OldSchoolPlus
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值