unity3d shader缔造金属各向异性效果

各向异性有两种类型,先截个图看看效果

一种是 径向各向异性:

一种是 线性各向异性:

这个shader就类似金属拉丝或者头发上的高光。(线性各向异性)

它能基于法线贴图的蓝色通道混合各向异性与粗糙程度。

支持漫反射(diffuse)、法线(normal)、反射(specular)、光泽贴图(gloss)和透明(transparency)着色器

光泽与反射值也应用于各向异性高光。

高光能增大或减小表面的各向异性高光的偏移值(Offset)。

各向异性高光表面的方向是被一个像下面的方向贴图定义的。

和切线空间的法线贴图效果相同,在表面定义高光。然而他们不应该在unity中转换法线贴图。

也就是这些图不用再转化成法线贴图了(我是这么理解的)。

成员:

各向异性的方向:就是表面高光的方向,和法线贴图的切线空间方向相同。

反射:反射强度是贴图的红色通道定义的。控制了反射高光的亮度。

光泽:光泽强度是贴图的绿色通道定义的。绿色越多反射高光越细越锐利,绿色越少反射高光越宽越模糊。最好把这个值设为一个非零值。

各向异性遮罩:贴图的蓝色通道定义各向异性与blinn高光的混合,蓝色越多各向异性比重越大,蓝色越少blinn比重越大。

各向异性的偏移:能使各向异性离中心点远或近

以下是本次shader需要的贴图:

径向各向异性效果:

线性各向异性效果:

建立一个shader:

先浏览一下变量:

_SpecularColor      高光颜色

_SpecPower           高光强度 

_Specular               高光各向异性的数目

_AnisoDir               各向异性方向贴图

_AnisoOffset          各向异性的偏移

	Properties {
		_MainTex ("Base (RGB)", 2D) = "white" {}
		_MainTint ("Diffuse Tint", Color) = (1,1,1,1)
		_SpecularColor ("Specular Color", Color) = (1,1,1,1)//高光颜色
		_SpecPower ("Specular Power", Range(0,30)) = 2//高光强度
		_Specular ("Specular Amount", Range(0, 1)) = 0.5
		_AnisoDir ("Anisotropic Direction", 2D) = ""{}//各向异性方向法线贴图
		_AnisoOffset("Anisotropic Offset", Range(-1,1)) = -0.2//_AnisoOffset的作用偏移
	}

让着色器加载我们定义的新的函数不是以前的Lambert

#pragma surface surf Anisotropic

告诉使用shader model3.0的渲染模式

#pragma target 3.0

建立一个新的结构体SurfaceAnisoOutput 传值用

Albedo                 对光源的反射率

Normal                 法线方向

Emission             自发光

AnisoDirection   各向异性方向

Specular              高光反射中的指数部分的系数

Gloss                   高光反射中的强度系数

Alpha                   透明度

		struct SurfaceAnisoOutput
		{
			fixed3 Albedo;//对光源的反射率
			fixed3 Normal;//法线方向
			fixed3 Emission;//自发光
			fixed3 AnisoDirection;//各向异性方向
			half Specular;//高光反射中的指数部分的系数
			fixed Gloss;//高光反射中的强度系数
			fixed Alpha;//透明度
		};

重要的执行函数 LightingAnisotropic

先求出半角向量halfVector

再求法线方向与光照方向的点积NdotL

半角向量与各向异性方向点积HdotA

求出各向异性:

sin((半角向量与各向异性方向点积+偏移值)的弧度值 * 180)

再根据各向异性求出反光强度spec

最后与光照颜色等进行整合

		inline fixed4 LightingAnisotropic (SurfaceAnisoOutput s, fixed3 lightDir, half3 viewDir, fixed atten)
		{
			fixed3 halfVector = normalize(normalize(lightDir) + normalize(viewDir));//normalize()函数把向量转化成单位向量

			float NdotL = saturate(dot(s.Normal, lightDir));

			fixed HdotA = dot(normalize(s.Normal + s.AnisoDirection), halfVector);
			float aniso = max(0, sin(radians((HdotA + _AnisoOffset) * 180f)));//radians()函数将角度值转换为弧度值 

			float spec = saturate(pow(aniso, s.Gloss * 128) * s.Specular);//saturate(x)函数	如果x小于0返回 0;如果x大于1返回1;否则返回x;把x限制在0-1

			fixed4 c;
			c.rgb = ((s.Albedo * _LightColor0.rgb * NdotL) + (_LightColor0.rgb * _SpecularColor.rgb * spec)) * (atten * 2);
			c.a = 1.0;
			return c;

		}

在surf函数中接受各向异性法线贴图

转化为输出的各向异性方向

然后就ok了

<span style="font-size:14px;">		void surf (Input IN, inout SurfaceAnisoOutput o) {
			half4 c = tex2D (_MainTex, IN.uv_MainTex) * _MainTint;
			float3 anisoTex = UnpackNormal(tex2D(_AnisoDir, IN.uv_AnisoDir));

			o.AnisoDirection = anisoTex;
			o.Specular = _Specular;
			o.Gloss = _SpecPower;
			o.Albedo = c.rgb;
			o.Alpha = c.a;

		}</span>

这是径向的效果:

这是线性的效果:

全部代码如下:

Shader "Custom/textShader" {
	Properties {
		_MainTex ("Base (RGB)", 2D) = "white" {}
		_MainTint ("Diffuse Tint", Color) = (1,1,1,1)
		_SpecularColor ("Specular Color", Color) = (1,1,1,1)//高光颜色
		_SpecPower ("Specular Power", Range(0,30)) = 2//高光强度
		_Specular ("Specular Amount", Range(0, 1)) = 0.5
		_AnisoDir ("Anisotropic Direction", 2D) = ""{}//各向异性方向法线贴图
		_AnisoOffset("Anisotropic Offset", Range(-1,1)) = -0.2//_AnisoOffset的作用偏移
	}
	SubShader {
		Tags { "RenderType"="Opaque" }
		LOD 200

			CGPROGRAM
#pragma surface surf Anisotropic
#pragma target 3.0

			sampler2D _MainTex;
		sampler2D _AnisoDir;//各向异性的
		float4 _MainTint;
		float4 _SpecularColor;
		float _AnisoOffset;
		float _Specular;
		float _SpecPower;
		struct SurfaceAnisoOutput
		{
			fixed3 Albedo;//对光源的反射率
			fixed3 Normal;//法线方向
			fixed3 Emission;//自发光
			fixed3 AnisoDirection;//各向异性方向
			half Specular;//高光反射中的指数部分的系数
			fixed Gloss;//高光反射中的强度系数
			fixed Alpha;//透明度
		};

		inline fixed4 LightingAnisotropic (SurfaceAnisoOutput s, fixed3 lightDir, half3 viewDir, fixed atten)
		{
			fixed3 halfVector = normalize(normalize(lightDir) + normalize(viewDir));//normalize()函数把向量转化成单位向量

			float NdotL = saturate(dot(s.Normal, lightDir));

			fixed HdotA = dot(normalize(s.Normal + s.AnisoDirection), halfVector);
			float aniso = max(0, sin(radians((HdotA + _AnisoOffset) * 180f)));//radians()函数将角度值转换为弧度值 

			float spec = saturate(pow(aniso, s.Gloss * 128) * s.Specular);//saturate(x)函数	如果x小于0返回 0;如果x大于1返回1;否则返回x;把x限制在0-1

			fixed4 c;
			c.rgb = ((s.Albedo * _LightColor0.rgb * NdotL) + (_LightColor0.rgb * _SpecularColor.rgb * spec)) * (atten * 2);
			c.a = 1.0;
			return c;

		}

		struct Input {
			float2 uv_MainTex;
			float2 uv_AnisoDir;
		};

		void surf (Input IN, inout SurfaceAnisoOutput o) {
			half4 c = tex2D (_MainTex, IN.uv_MainTex) * _MainTint;
			float3 anisoTex = UnpackNormal(tex2D(_AnisoDir, IN.uv_AnisoDir));

			o.AnisoDirection = anisoTex;
			o.Specular = _Specular;
			o.Gloss = _SpecPower;
			o.Albedo = c.rgb;
			o.Alpha = c.a;

		}
		ENDCG
	}
	FallBack "Diffuse"
}

---------  by wolf96

时间: 2024-09-30 02:42:23

unity3d shader缔造金属各向异性效果的相关文章

Unity3D Shader图像扭曲过场效果

把脚本挂在摄像机上 using UnityEngine; using System.Collections; [RequireComponent(typeof(Camera))] public class PostEffectTwist : MonoBehaviour { public Material ma; void OnRenderImage(RenderTexture src, RenderTexture dest) { Graphics.Blit (src, dest, ma); }

【浅墨Unity3D Shader编程】之七 静谧之秋篇: 表面着色器的写法(二)——自定义光照模式

本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://hpw123.net/plus/view.php?aid=183 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 邮箱: [email protected] QQ交流群:330595914 更多文章尽在:http://www.hpw123.net 本文主要讲解了Unity中SurfaceShader的自定义光照模式的写法. 上篇文章中我们已经说到,表面着色器将分为两次讲解,上

【浅墨Unity3D Shader编程】之五 圣诞夜篇: Unity中Shader的三种形态对比&amp;混合操作合辑

本系列文章由@浅墨_毛星云 出品,转载请注明出处.  文章链接:http://hpw123.net/a/C__/kongzhitaichengxu/2014/1222/164.html 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 邮箱: [email protected] QQ交流群:330595914 更多文章尽在:http://www.hpw123.net 本文算是固定功能Shader的最后一篇,下一次更新应该就会开始讲解表面Shader,而

【浅墨Unity3D Shader编程】之十一 深入理解Unity5中的Standard Shader(三)&amp;屏幕像素化特效的实现

本系列文章由@浅墨_毛星云 出品,转载请注明出处.   文章链接:http://blog.csdn.net/poem_qianmo/article/details/50095705 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 本文工程使用的Unity3D版本: 5.2.1  概要:续接上文,本文进一步讲解与分析了上文未讲完的Unity5中Standard Shader正向基础渲染通道源码的片段着色实现部分,以及对屏幕像素化后期特效进行了实现. 同

【淡墨Unity3D Shader计划】五 圣诞用品: Unity在Shader三种形式的控制&amp;amp;混合操作编译

本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/42060963 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 邮箱: [email protected] 文章开头,先给自己诚求个游戏研发实习的好去处. 浅墨今年1月.明年上半年有近半年的空暇时间可供实习. 近5年游戏编程经验,能够胜任全职的游戏开发工作.仅仅拿实习生的工资(性价比非常高有

【浅墨Unity3D Shader编程】之二 雪山飞狐篇:Unity的基本Shader框架写法&amp;颜色、光照与材质

本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/40955607 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 邮箱: [email protected] 本篇文章中,我们学习了Unity Shader的基本写法框架,以及学习了Shader中Properties(属性)的详细写法,光照.材质与颜色的具体写法.写了6个Shader作为本文S

【译】Unity3D Shader 新手教程(1/6)

刚开始接触Unity3D Shader编程时,你会发现有关shader的文档相当散,这也造成初学者对Unity3D Shader编程望而却步.该系列教程的第一篇文章(译者注:即本文,后续还有5篇文章)详细介绍了Unity3D中的表面着色器(Surface Shader)的,为学习更复杂的Shader编程打下基础. 动机 如果你是刚刚接触Shader编程的新手,你可能不知道从何开始踏出Shader编程的第一步.本教程将带你一步步完成一个表面着色器(Surface Shader)和片段着色器(Fra

【浅墨Unity3D Shader编程】之三 光之城堡篇:子着色器、通道与标签的写法 &amp; 纹理混合

本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/41175585 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 邮箱: [email protected] 本文介绍了Unity中子着色器.通道和标签相关的详细概念与写法,以及纹理的设置方法,基本的纹理混合写法,写了5个Shader作为本文Shader讲解的实战内容,最后创建了一个梦幻的光之

Unity3D shader简介

Unity3D shader简介 可以肯定的说Unity3D使得很多开发者开发游戏更容易.毫无疑问,shader(着色器)编码,仍有很长的路要走.shader是一个专门运行在GPU的程序,经常被神秘包围,它最终绘制3D模型的三角形.如果你想给游戏一个特殊的显示,学习如何编写shader是必要的.Unity3D使用shader做后期处理,对2D游戏也是必不可少的.这个系列的文章将逐步介绍shader编程,并面向几乎没有任何shader知识的开发者. 简介 下图大致表示了在Unity3D渲染流程中发