Unity Shader 学习之旅之SurfaceShader
Unity Shader 学习之旅之SurfaceShader
如果大地的每个角落都充满了光明 谁还需要星星,谁还会 在夜里凝望 寻找遥远的安慰——江河
一、工作原理
sureface表面着色器相当于unity在顶点片元着色器的基础上进一步的封装。当我们定义一个“surface function”后,可以通过unity已经封装好的的结构体“SurfaceOutput”等直接获取需要的数据,如纹理,法线,光滑度等
二、结构体
2.1标准output结构体
- struct SurfaceOutput
- {
- fixed3 Albedo; // 漫反射颜色
- fixed3 Normal; // 切线空间法线
- fixed3 Emission;
- half Specular; // 高光系数
- fixed Gloss; // 高光强度
- fixed Alpha; // alpha 通道
- };
2.2Unity5 output结构体
unity5中表面着色器使用基于物理的光照模型。内建Standard和StantardSpecular光照模型使用如下两种结构体:
- struct SurfaceOutputStandard
- {
- fixed3 Albedo; // base (diffuse or specular) color
- fixed3 Normal; // tangent space normal, if written
- half3 Emission;
- half Metallic; // 0=non-metal, 1=metal
- half Smoothness; // 0=rough, 1=smooth
- half Occlusion; // occlusion (default 1)
- fixed Alpha; // alpha for transparencies
- };
- struct SurfaceOutputStandardSpecular
- {
- fixed3 Albedo; // diffuse color
- fixed3 Specular; // specular color
- fixed3 Normal; // tangent space normal, if written
- half3 Emission;
- half Smoothness; // 0=rough, 1=smooth
- half Occlusion; // occlusion (default 1)
- fixed Alpha; // alpha for transparencies
- };
三、SurfaceShader编译指令
SurfaceShader被放置在 CGPROGRAM---ENDCG语块之间,需要注意以下两点:
- 必须放置在SubShader语块中,不能在Pass语块中,SurfaceShader会自主编译成多个Pass
- 通过使用 #pragma surface ... 来表明这是一个SurfaceShader
- #pragma surface surfaceFunction lightModel [optionalparams]
3.1必要参数
- surfaceFuncton:这就是我们在编译指令中指定的表面着色器Cg函数。可以通过 void surf (Input IN, inout SurfaceOutput o) 这种形式定义。其中input是我们定义的结构体,包含该函数需要的数据信息。
- lightMode:光照模型可以使用内建的基于物理的 Standard 和StandardSpecular。也可以使用非物理的Lambert BlinnPhong。这几种类型可以直接通过在编译指令中指定,无需在自己实现。
- Standard 光照模型使用SurfaceOutputStandard output结构体
- StandardSpecular 光照模型使用SurfaceOutputStandardSpecular output结构体
- Lambert和BlinnPhong 光照模型使用 SurfaceOutput output结构体
3.2可选参数
通过指定可选参数[optionalparams],可以让surfaceshader表现出更丰富的效果,如雾效,半透明,阴影等。可选参数具体类型可参考文首给出的 官方文档 查阅。
3.3示例
示例1:使用内置Lambert光照模型的表面着色器
- Shader "Example/Rim" {
- Properties {
- _MainTex ("Texture", 2D) = "white" {}
- _BumpMap ("Bumpmap", 2D) = "bump" {}
- _RimColor ("Rim Color", Color) = (0.26,0.19,0.16,0.0)
- _RimPower ("Rim Power", Range(0.5,8.0)) = 3.0
- }
- SubShader {
- Tags { "RenderType" = "Opaque" }
- CGPROGRAM
- #pragma surface surf Lambert
- struct Input {
- float2 uv_MainTex;
- float2 uv_BumpMap;
- float3 viewDir;
- };
- sampler2D _MainTex;
- sampler2D _BumpMap;
- float4 _RimColor;
- float _RimPower;
- void surf (Input IN, inout SurfaceOutput o) {
- o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
- o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap));
- half rim = 1.0 - saturate(dot (normalize(IN.viewDir), o.Normal));
- o.Emission = _RimColor.rgb * pow (rim, _RimPower);
- }
- ENDCG
- }
- Fallback "Diffuse"
- }
示例2:使用可选参数的表面着色器,通过指定decal:blend,该shader会表现出半透明贴画的效果。
- Shader "Example/Decal" {
- Properties {
- _MainTex ("Base (RGB)", 2D) = "white" {}
- }
- SubShader {
- Tags { "RenderType"="Opaque" "Queue"="Geometry+1" "ForceNoShadowCasting"="True" }
- LOD 200
- Offset -1, -1
- CGPROGRAM
- #pragma surface surf Lambert decal:blend
- sampler2D _MainTex;
- struct Input {
- float2 uv_MainTex;
- };
- void surf (Input IN, inout SurfaceOutput o) {
- half4 c = tex2D (_MainTex, IN.uv_MainTex);
- o.Albedo = c.rgb;
- o.Alpha = c.a;
- }
- ENDCG
- }
- }
Unity Shader 学习之旅之SurfaceShader的更多相关文章
- Unity Shader 学习之旅
Unity Shader 学习之旅 unityshader图形图像 纸上学来终觉浅,绝知此事要躬行 美丽的梦和美丽的诗一样 都是可遇而不可求的——席慕蓉 一.渲染流水线 示例图 Tips:什么是 GP ...
- 第四章 开始Unity Shader学习之旅(2)
目录 1. 强大的援手:Unity提供的内置文件和变量 1.1 内置的包含文件 1.2 内置的变量 2. Unity提供的Cg/HLSL语义 2.1 什么是语义 2.2 Unity支持的语义 2.3 ...
- 第四章 开始Unity Shader学习之旅(1)
1. 一个最简单的顶点/片元着色器 现在,我们正式开始学习如何编写Unity Shader,更准确的说是,学习如何编写顶点/片元着色器 2.顶点/片元着色器的基本结构 我们在以前已经讲过了Unity ...
- Unity Shader入门精要学习笔记 - 第5章 开始 Unity Shader 学习之旅
一个顶点/片元 着色器的结构大概如下: Shader "MyShaderName" { Properties { //属性 } SubShader { //针对显卡A的SubSha ...
- 第四章 开始Unity Shader学习之旅(3)
1. 程序员的烦恼:Debug 调试(debug),大概是所有程序员的噩梦.而不幸的是,对一个Shader进行调试更是噩梦中的噩梦.这也是造成Shader难写的原因之一--如果发现得到的效果不对,我们 ...
- [转]Unity Shader 学习总结
1.先来一段单张纹理贴图的shader示例代码: // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClip ...
- Unity Shader学习笔记-1
本篇文章是对Unity Shader入门精要的学习笔记,插图大部分来自冯乐乐女神的github 如果有什么说的不正确的请批评指正 目录 渲染流水线 流程图 Shader作用 屏幕映射 三角形遍历 两大 ...
- 【Unity Shader学习笔记】Unity基础纹理-单张纹理
1 单张纹理 1.1 纹理 使用纹理映射(Texture Mapping)技术,我们把一张图片逐纹素(Texel)地控制模型的颜色. 美术人员建模时,会在建模软件中利用纹理展开技术把纹理映射坐标(Te ...
- Unity shader学习之屏幕后期处理效果之高斯模糊
高斯模糊,见 百度百科. 也使用卷积来实现,每个卷积元素的公式为: 其中б是标准方差,一般取值为1. x和y分别对应当前位置到卷积中心的整数距离. 由于需要对高斯核中的权重进行归一化,即使所有权重相加 ...
随机推荐
- mycat结合双主复制实现读写分离模式
简介:应用程序仅需要连接mycat,后端服务器的读写分离由mycat进行控制,后端服务器数据的同步由MySQL主从同步进行控制. 本次实验环境架构图 服务器主机规划 主机名 IP 功能 备注 lin ...
- ethereumjs/ethereumjs-account-2-test
ethereumjs-account/test/index.js const Account = require('../index.js') const tape = require('tape') ...
- Django提示Unknown database处理方法
cmd.exe运行别人的程序 C:\Python27\Python.exe E:\Django\Guest\Guest\manage.py runserver 提示 django.db.utils.I ...
- 手动安装sublime插件babel-sublime
(一)手动安装babel 在开发reactjs开发使用sublime时,想要代码高亮显示,需要安装babel-sublime插件,在Preferences中的Package Control菜单搜索In ...
- mysql因为服务器异常关机倒是启动不了 找不到mysql.sock
今天mysql服务器突然异常关机,查看云平台发现该vm处于为开机状态切状态是无法启动,经过协调, 服务器启动了.但是进行service mysql start 启动时.提示错误: Starting M ...
- VC++程序运行时间测试函数
0:介绍 我们在衡量一个函数运行时间,或者判断一个算法的时间效率,或者在程序中我们需要一个定时器,定时执行一个特定的操作,比如在多媒体中,比如在游戏中等,都会用到时间函数.还比如我们通过记录函数或者算 ...
- VMware Tools安装方法及解决无法全屏显示问题
环境:VMware8.0虚拟机 ubuntu:12.04 在刚安装完ubuntu后,屏幕不能全屏显示,此时: 1.安装VMware Tools 步骤: 1.1 进入ubuntu系 ...
- 网络编程中的read,write函数
关于TCP/IP协议,建议参考Richard Stevens的<TCP/IP Illustrated,vol1>(TCP/IP详解卷1). 关于第二层面,依然建议Richard Steve ...
- 【LeetCode445】 Add Two Numbers II★★
题目描述: 解题思路: 给定两个链表(代表两个非负数),数字的各位以正序存储,将两个代表数字的链表想加获得一个新的链表(代表两数之和). 如(7->2->4->3)(7243) + ...
- iOS渐变导航栏封装
由于最近开发的几个项目都有渐变导航栏,每次写的时候都要copy一堆关于导航渐变相关的代码,显得类很冗余,所以花了点时间封装了一个渐变类,直接继承就可以满足大部分需求啦,这里简单写一下心路历程: 渐变的 ...