Unity shader教程-第六课:Ramp Texture

本文首发地址:http://98jy.net/article/25

更多文章,请入传送门

----------------------------------------------

Ramp Texture在Valve公司的军团要塞2后开始成为一种控制漫反射的方法。

Ramp Texture是类似下图的一张贴图:

在一般的Blinn/Phong模型中,我们对漫反射的系数是基于入射光和击中的点的法线的角度。在这种情况下,系数的计算代码大致如下:

float DiffuseCoeff(in float3 pos, in float3 normal, in float3 lightPos) {
    float3 lightDir = lightPos - pos;
    lightDir.normalize();

    return max(0.0, Dot(lightDir, normal));
}

使用Ramp texture,可以用一张1D的材质图来做为索引表。用来控制漫反射的系数。虚拟代码如下:

texture1D rampTex;
float DiffuseCoeff(in float3 pos, in float3 normal, in float3 lightPos) {
    float3 lightDir = lightPos - pos;
    lightDir.normalize();

    // Map value from [-1, 1] to [0, 1]
    float rampCoord = Dot(lightDir, normal) * 0.5 + 0.5;
    return tex1D(rampTex, rampCoord);
}

我们这节课来改动原来的shader,自己来观察原来的shader在加入Ramp Texture后能做的事情。

  • 把原来的BaiscDiffuse代码改成如下
	    inline float4 LightingBasicDiffuse(SurfaceOutput s, fixed3 lightDir, fixed atten)
		{
		    float difLight = dot(s.Normal, lightDir);
		    float hLambert = difLight * 0.5 + 0.5;
		    float3 ramp = tex2D(_RampTex, float2(hLambert, hLambert)).rgb;

		    float4 col;
		    col.rgb = s.Albedo * _LightColor0.rgb * (ramp);
		    col.a = s.Alpha;
		    return col;
		}
  • 在Properties中加入
_RampTex("Ramp texture", 2D) = "white"
  • 在SubShader块中加入
sampler2D _RampTex;

为了保证你最后的结果跟我的是一样的,这里是最后的代码:

Shader "myDiffuse"
{
	Properties
	{
		_EmissiveColor ("Emissive Color", Color) = (1, 1, 1, 1)
		_AmbientColor ("Ambient Color", Color) = (1, 1, 1, 1)
		_SomeValue ("Coefficient", Range(0, 10)) = 2.5
		_RampTex("Ramp texture", 2D) = "white"
	}

	SubShader
	{
		Tags { "RenderType"="Opaque" }
		LOD 200

		CGPROGRAM
		#pragma surface surf BasicDiffuse

		float4 _EmissiveColor;
		float4 _AmbientColor;
		float _SomeValue;
	    sampler2D _RampTex;

	    inline float4 LightingBasicDiffuse(SurfaceOutput s, fixed3 lightDir, fixed atten)
		{
		    float difLight = dot(s.Normal, lightDir);
		    float hLambert = difLight * 0.5 + 0.5;
		    float3 ramp = tex2D(_RampTex, float2(hLambert, hLambert)).rgb;

		    float4 col;
		    col.rgb = s.Albedo * _LightColor0.rgb * (ramp);
		    col.a = s.Alpha;
		    return col;
		}

		struct Input
		{
			float2 uv_MainTex;
		};

		void surf (Input IN, inout SurfaceOutput o)
		{
			float4 c = pow((_EmissiveColor + _AmbientColor), _SomeValue);

			o.Albedo = c.rgb;
			o.Alpha = c.a;
		}
		ENDCG
	}
	FallBack "Diffuse"
}
  • 保存,然后我们回到unity。

选中某个材质球,Inspector面板上会出现选择图片的控件,这里我们可以拖入一张图观察结果。

对那些还不会使用绘图工具的读者,你可以用我这里给你准备好的几张图(ramp texture生成方式可以使用photoshop的gradient工具,附录里我们写了这些步骤)

对于Ramp Texture shader来说,我们主要是加入了对送入的Ramp texture的色彩的检索,检索出来的色彩值最后能影响到我们的光照模型的输出。

tex2D()方法是cg的库方法,用来根据第二个参数提供的uv值(类型是float2,分别代码水平方向的u和竖直方向的v),来检索第一个参数代表的图档中的RGBA值。

这里我们给定的uv值有half lambert的值决定,half lambert越大,意味着我们索引到的像素的值的位置在原图中越是偏向于右下角方向。美术可以利用这个特性来控制一个物体表面的漫反射(越是往右,越是往下,意为着物体的法线方向越来越接近于入射光)。

附录:

在Photoshop中,我们可以几个步骤来建立Ramp texture:

  • 打开photoshop,新建一张图
  • 选中工具箱中的渐变工具(一般在橡皮擦的下面一个)
  • 然后在图上从左到右拖动一根线出来
  • 结果就得到一张从photoshop中设置的前景色过渡到背景色的图出来了

98教育原创,转载请注明出处(98jy.net),否则视为侵权。

时间: 2024-08-14 18:48:15

Unity shader教程-第六课:Ramp Texture的相关文章

Unity shader教程-第三课:实践!同一个shader,多个material。

本文首发地址:http://98jy.net/article/18 更多更及时的文章请关于98教育 这节课我们开始利用我们学到的Properties知识来改动代码,用一个shader实现如下图的几个不同的球体: 步骤: 使用MonoDevelop打开shader文件 保证Properties里面是如下内容 _EmissiveColor ("Emissive Color", Color) = (1, 1, 1, 1) _AmbientColor ("Ambient Color&

Unity shader教程-第五课:自定义光照模型之Half Lambert模型

本文首发地址:http://98jy.net/article/24 更多文章,请入传送门 ---------------------------------------------- Half Lambert光照模型是Valve公司在制作"半条命"游戏时发明的,用来给在比较暗的区域显示物体.总体来说,该光照模型提高了物体表面的漫反射光.下图是Valve的示例,左手边是Lambert模型,右手边是Half Lambert模型. 使用我们原来的基础的shader,我们把LightingBa

Unity shader教程-第四课:自定义光照模型(方程)

本文首发地址:http://98jy.net/article/22 更多文章,请入传送门 ---------------------------------------------- 在我们前面的课程中,有一行代码如下 #pragma surface surf Lambert 这行代码指示unity在编译我们的shader代码的时候,选用"Lambert"这个光照模型.它的格式是 #pragma surface surf LightModel 其中LightModel是unity自带的

Unity shader教程-第一课:写shader和应用shader的流程

这是我们Unity shader(着色器)教程的第一课,在这节课中,你会学到怎么样来用程序来编写一个在Unity中能使用的着色器:漫反射着色器.这节课的内容主要让我们熟悉创建shader和应用shader的流程. 准备工作: 安装Unity版本4.6以上 创建一个新的工程 菜单GameObject | 3D Object | Plane创建出一个平面,作为我们的地面 菜单GameObject | 3D Object | Sphere创建出球来,反复多次创建多个 注意: 1. 创建地面后选中该物体

NeHe OpenGL教程 第六课:纹理映射

转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线教程的编写,以及yarn的翻译整理表示感谢. NeHe OpenGL第六课:纹理映射 纹理映射: 在这一课里,我将教会你如何把纹理映射到立方体的六个面. 学习 texture map 纹理映射(贴图)有很多好处.比方说您想让一颗导弹飞过屏幕.根据前几课的知识,我们最可行的办法可能是很多个多边形来构建

[译文]JOAL教程 第六课 高级加载方式与错误处理

[译文]JOAL教程 原文地址:http://jogamp.org/joal-demos/www/devmaster/lesson6.html 原文作者:Athomas Goldberg 译文:三向板砖 转载请保留以上信息. 本次课程对应的学习笔记:http://blog.csdn.net/shuzhe66/article/details/40303739 第六课 高级加载方式与错误处理 本文是DevMaster.net(http://devmaster.net/)的OpenAL教程对应的JOA

Unity shader教程-第二课:Shader的框架和Properties详细介绍

本文首发地址:http://98jy.net/article/17 更多更及时的文章可在上述地址看到 一.Shader的框架 shader由关键字Shader 加上后面的用双引号括起来的字串开始,字串里面可以用上/表示在Inspector中显示出来的分类.整个shader代码都包在这个部分后面的{}中.举例来说,一个典型的shader会是这样 Shader "Name" { } 或者 Shader "Category / Name" { } 二.Shader中的属性

【Mongodb教程 第六课 】MongoDB 插入文档

insert() 方法 要插入数据到 MongoDB 集合,需要使用 MongoDB 的  insert() 或 save() 方法. 语法 insert() 命令的基本语法如下: >db.COLLECTION_NAME.insert(document) 例子 >db.mycol.insert({ _id: ObjectId(7df78ad8902c), title: 'MongoDB Overview', description: 'MongoDB is no sql database',

【Unity Shader】(九) ------ 高级纹理之渲染纹理及镜子与玻璃效果的实现

笔者使用的是 Unity 2018.2.0f2 + VS2017,建议读者使用与 Unity 2018 相近的版本,避免一些因为版本不一致而出现的问题. [Unity Shader](三) ------ 光照模型原理及漫反射和高光反射的实现 [Unity Shader](四) ------ 纹理之法线纹理.单张纹理及遮罩纹理的实现 [Unity Shader](五) ------ 透明效果之半透明效果的实现及原理 [Unity Shader](六) ------ 复杂的光照(上) [Unity