从0开始的技美实战(十八)

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

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

本篇内容主要包括:赛博小人制作及相关知识点总结;


1.模型准备

首先还是先对顶点着色,以便之后仅对身体产生变换;
在这里插入图片描述

再来导出两份UV,左边是叠加的,右边是整理好的;

在这里插入图片描述

为了得到网格效果,专门渲染一张纯黑白的网格图,然后右边的图则是在Alpha通道里用于UV分块

在这里插入图片描述

2.SD中准备

基于UV1烘焙一张位置信息图;
在这里插入图片描述
然后根据需求制作三张贴图,一张经描边处理再反向的网格图,一张乱序的类似麻袋的面随机灰度遮罩图,一张面坡度遮罩图,然后存到一张RGBA图中;

最后的节点图如下:
在这里插入图片描述
还有一张用位置信息加噪波扰动的图:

在这里插入图片描述

在这里插入图片描述

3.shader编写
在这里插入图片描述在这里插入图片描述在这里插入图片描述
在这里插入图片描述

最后代码:

Shader "Unlit/co18-cyber"
{
    Properties
    {
	[Header(Texture)]
        _MainTex       ("RGB:基础颜色,A:环境遮罩", 2D)     = "white"   {}//这里将AO贴图与颜色贴图整合到了一张图里
		_NormalTex     ("RGB:法线贴图",2D)                 = "bump"    {}
		_SpecTex       ("RGB:高光颜色,A:高光次幂",2D)      = "gray"    {}
		_EmitTex       ("RGB:自发光贴图",2d)                 = "black"   {}
		_Cubemap       ("RGB:环境贴图Cubemap",Cube)        = "_Skybox" {}
	[Header(Diffuse)]
	    _BaseColor     ("基础颜色",color)                  = (1.0,1.0,1.0,1.0)
		_EnvUpColor    ("环境天顶颜色",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)
		_EnvDiffuse    ("环境漫反射强度",range(0,1))       =  0.2
    [Header(Specular)]
	    _SpecularPow   ("高光次幂",range(1,90))            =  25
		_EnvSpecInt    ("高光强度",range(0,5))             =  1
		_FresenlPow    ("菲涅尔次幂",range(0,10))          =  3
		_CubemapMip    ("环境球Mip",range(0,7))            =  0
    [Header(Emission)]
	    _Emitint       ("自发光强度",range(1,10))          =  5 

	[Header(Effect)]
	    _Effmap01      ("特效纹理1",2D)                    = "gray"{}
		_Effmap02      ("特效纹理2",2D)                    = "gray"{}
[HDR]	_Effcol        ("光效颜色",color)                  = (0.0,0.0,0.0,0.0)
		_EffParams     ("X:波密度 Y:波速度 Z:混乱度 W:消散强度",vector)=(0.03,3.0,0.3,2.5)
   
    }
    SubShader
    {
        Tags { "Queue"="Transparent"
		       "RenderType"="Transparent" }

        Pass
        {
		    Tags {"LightMode"="ForwardBase"}
			Blend One OneMinusSrcAlpha
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_fwdbase_fullshadows
			#pragma target 3.0

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


			uniform sampler2D _MainTex;
			uniform sampler2D _NormalTex;
			uniform sampler2D _SpecTex;
			uniform sampler2D _EmitTex;
			uniform samplerCUBE _Cubemap;

			uniform float3 _BaseColor;
			uniform float3 _EnvUpColor;
			uniform float3 _EnvMidColor;
			uniform float3 _EnvDowColor;
			uniform float3 _EnvDiffuse;

			uniform float _SpecularPow;
			uniform float _EnvSpecInt;
			uniform float _FresenlPow;
			uniform float _CubemapMip;
			uniform float _Emitint;

			uniform sampler2D _Effmap01;
			uniform sampler2D _Effmap02;
			uniform float3    _Effcol;
			uniform float4    _EffParams;


            struct appdata
            {
                float4 vertex : POSITION;
				float4 normal : NORMAL;
				float4 tangent:TANGENT;
                float2 uv : TEXCOORD0;
				float2 uv1: TEXCOORD1;
				float4 color : COLOR;
            };

            struct v2f
            {
                float2 uv         : TEXCOORD0;
				float2 uv1        : TEXCOORD1;
				float4 color      : COLOR;
                float4 pos        : SV_POSITION;
				float3 posWS      : TEXCOORD2;
				float3 nDirWS     : TEXCOORD3;
				float3 bDirWS     : TEXCOORD4;
				float3 tDirWS     : TEXCOORD5;
				float4 effectMask : TEXCOORD6;
				LIGHTING_COORDS(7,8)
            };
			float4 CyberpunkAnim(float noise,float mask, float3 normal,inout float3 vertex){
			   float baseMask = abs(frac(vertex.y*_EffParams.x-_Time.x*_EffParams.y)-0.5)*2.0;//锯齿波mask
			   baseMask       = min(1.0,baseMask*2.0);
			   baseMask      += (noise-0.5)*_EffParams.z;//Noise偏移锯齿波
			   float4 effectMask= float4(0.0,0.0,0.0,0.0);
			   effectMask.x   = smoothstep(-0.2,0.9,baseMask);//smoothstep重映射波形平滑
			   effectMask.y   = smoothstep(0.2,0.7,baseMask);
			   effectMask.z   = smoothstep(0.4,0.5,baseMask);
			   effectMask.w   = mask;//顶点色存入EffectMask
			   vertex.xz     += normal.xz*(1.0-effectMask.y)*_EffParams.w*mask;
			  

			   return float4(effectMask); 
			}




            v2f vert (appdata v)
            {
                v2f o;
				float noise =tex2Dlod(_Effmap02,float4(v.uv1,0.0,0.0));//tex2Dlod顶点着色器中采样纹理,也可采样Mipmap
				o.effectMask=CyberpunkAnim(noise,v.color.r,v.normal.xyz,v.vertex.xyz);
                o.uv     = v.uv;
				o.uv1    = v.uv1;
                o.pos    = UnityObjectToClipPos(v.vertex);
				o.posWS  = mul(unity_ObjectToWorld,v.vertex);
				o.nDirWS = UnityObjectToWorldNormal(v.normal);
				o.tDirWS = normalize(mul(unity_ObjectToWorld,float4(v.tangent.xyz,1.0)));
				o.bDirWS = normalize(cross(o.nDirWS,o.tDirWS));
				TRANSFER_VERTEX_TO_FRAGMENT(o)
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
			   float3   nDirTS      = UnpackNormal(tex2D(_NormalTex,i.uv));
               float3x3 TBN         = float3x3(i.tDirWS,i.bDirWS,i.nDirWS);
			   float3   nDirWS      = normalize(mul(nDirTS,TBN));
			   float3   lDir        = _WorldSpaceLightPos0;
			   float3   vDir        = normalize(_WorldSpaceCameraPos-i.posWS.xyz);
			   float3   vrDir       = reflect(-vDir,nDirWS);
			   float3   lrDir       = reflect(-lDir,nDirWS);

			   float3   ndotl       = dot(nDirWS,lDir); //兰伯特
			   float3   ndotv       = dot(nDirWS,vDir); //菲涅尔
			   float3   vdotlr      = dot(vDir,lrDir);  //Phong

			   float4   var_MainTex = tex2D(_MainTex,i.uv);
			   float4   var_SpecTex = tex2D(_SpecTex,i.uv);
			   float3   var_EmitTex = tex2D(_EmitTex,i.uv);
			   float3   var_Cubemap = texCUBElod(_Cubemap,float4(vrDir,lerp(_CubemapMip,1.0,var_SpecTex.a)));//lerp用来表现越光滑反射越清晰

			   float    Lambert     =  max(ndotl,0);
			   float    spect       =  lerp(1,_SpecularPow,var_SpecTex.a);//用lerp做插值
			   float    Phong       =  pow(max(0,vdotlr),spect);
			   float    shadow      =  LIGHT_ATTENUATION(i);
               float3   dirtLight   =  (Lambert*_BaseColor*var_MainTex.rgb + Phong*var_SpecTex.rgb)*shadow*_LightColor0;

			   float    topmask     =  max(nDirWS.g,0.0);
			   float    dowmask     =  max(-nDirWS.g,0.0);
			   float    midmask     =  1.0-topmask-dowmask;
			   float3   col3        =  topmask*_EnvUpColor+midmask*_EnvMidColor+dowmask*_EnvDowColor;

			   float   fresnel      = pow(max(1-ndotv,0.0),_FresenlPow);
			   float   occluision   = var_MainTex.a;
			   float   Envlighting  = (_BaseColor*var_MainTex.rgb*col3*_EnvDiffuse+var_Cubemap*fresnel*_EnvSpecInt)*occluision;
			   float3  emission     = var_EmitTex*_Emitint;
			    
			   float3 _Effmap01_var  = tex2D(_Effmap01,i.uv1).xyz;
			   float   meshMask      = _Effmap01_var.x;
			   float   faceRandomMask= _Effmap01_var.y;
			   float   facesSlopeMask= _Effmap01_var.z;

			   float  smallMask     = i.effectMask.x;
			   float  midMask       = i.effectMask.y;
			   float  bigMask       = i.effectMask.z;
			   float  baseMask      = i.effectMask.w;

			   float midOpacity     =saturate(floor(min(faceRandomMask,0.99999)+midMask));
			   float bigOpacity     =saturate(floor(min(facesSlopeMask,0.99999)+bigMask));
			   float Opacity        =lerp(1.0,min(bigOpacity,midOpacity),baseMask);

			   float meshEmitInt    =(bigMask-smallMask)*meshMask;
			   meshEmitInt         *=meshEmitInt;
			   emission            +=_Effcol*meshEmitInt*baseMask;
			   float3  final       = dirtLight+Envlighting+emission;

			   return float4(final*Opacity,Opacity);
            }
            ENDCG
        }
    }
}

效果展示:

在这里插入图片描述

4.补充

在这里插入图片描述
1.关于锯齿问题:

扰动造成的,可以给扰动的负值做下限制

2.“最后的输出结果模型上应该不透明的地方会有些半透不透的感觉”

因为是在顶点阶段做的 到像素shader会做差值 所以黑白交界的面是有过渡的

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值