Unity Shader中使用GLSL创建材质

2023-11-06

Unity Shader格式

Shader "Shader类型/Shader名称" {
 	Properties{//属性 用于ShaderLab与unity界面的通信
 		//_内置变量名 ("unity界面可见的变量名", 属性类型) = 值
 		_Color ("My Color", Color) = (1, 1, 1, .5) 
 	 } 
 	 
 	 //Subshader  shader的解决方案。
 	 //每个shader程序包含至少一个subshader,用于解决硬件性能兼容问题。
 	 //shader的主代码部分都写在这里
 	 Subshader{

 	 }
 }

Properties

可以看作将OpenGL中各个着色器的Uniform做了一次赋值。
即:将外部数据 "unity界面可见的变量名"的值 赋给 _内置变量名
内置变量名需要在GLSL代码内部定义同_内置变量名Uniform参数。

例如:

   Properties{
         _Color("Color",Color) = (1,1,1,1)			//将“Color”定义为Color类型,就可以在Unity界面上以Color类型进行修改
   }
   SubShader{
         Tags{"RenderType" = "Opaque" "Queue" = "Geometry"}
         Pass{
             GLSLPROGRAM

			//.vert代码
             #ifdef VERTEX
				[vert代码...]
             #endif
             
             //.frag代码
             #ifdef FRAGMENT
             
             uniform vec4 _Color;				//在这里定义了_Color
             
             void main() {
                 gl_FragColor = _Color;
             }
             #endif
             
             ENDGLSL
         }
     }

在属性处定义的Color在unity界面上显示
在这里插入图片描述
在Unity界面上修改Color,属性处的定义 就会将该值传递给GPU变量uniform vec4 _Color
在这里插入图片描述
修改后,可以看到界面中的物体材质发生了改变。即:GLSL成功运行并将渲染的结果呈现了出来。

在这里插入图片描述

怎么在脚本中使用类似于glUniform()的功能呢?

Material对象的一系列set方法。比如这里的_Shininess是float,那么,可以写如下一个C#脚本:

public Material mat;
public UISlider slider;
public void OnSliderValueChanged()
{
	mat.SetFloat ("_Shininess", slider.value);//将滑轮的值传给材质
}

void Start()
{
	mat = gameObject.renderer.material;
}

SubShader

Tags

tags可以填写多个命令,可以控制渲染时机。可以通过在unity的asset窗口中点击shader查看tags生效情况。
最常见的Tag就是"RenderType","RenderType" = "Opaque"表明这是一个不透明的物体。而Transparent就表明是透明物体啦。

另外比较有用的标签还有"IgnoreProjector"=“True”(不被Projectors影响),“ForceNoShadowCasting”=“True”(从不产生阴影)以及"Queue"=“xxx”(指定渲染顺序队列)

LOD

细节等级。大家玩吃鸡的时候,从飞机上跳下,这时看到地图上的建筑都是比较粗糙的块,当距离慢慢拉近,建筑模型变得越发精致,这就是LOD技术,根据不同的范围使用不同的模型。shader的LOD也是同样用法,不同细节等级,使用不同的LOD。在Unity的Quality Settings中可以设定最大LOD值,当当前LOD小于shader LOD时,那个sub shader就会失效.

pass

pass是实现着色器具体代码的地方。一个subshader内可以有多个pass。但尽可能用较少的pass实现是对性能的考虑。

pass内的tags说明
pass内的代码段(GLSL)

代码段由GLSLPROGRAM开始,由ENDGLSL结束。
中间使用如下方法定义代码段

#ifdef VERTEX
	[vert代码段]
#endif

#ifdef FRAGMENT
	[frag代码段]
#endif
}
GLSL与CG语言的差异
1. GLSL不可在外部定义结构体
GLSLPROGRAM
      struct a2v {
          vec4 vertex : POSITION;
          vec3 normal : NORMAL;
          vec4 texcoord : TEXCOORD0;
      };
ENDGLSL

报错
error C7557: OpenGL does not allow Cg-style semantics

2. 在UnityShader中Uniform可以写在vert frag外面
uniform vec4 _Color;

#ifdef VERTEX
void main() {
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
#endif
#ifdef FRAGMENT

void main() {
    //gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
    gl_FragColor = _Color;
}
#endif

Shader 内置参数(GLSL)

GLSLSupport.glslinc

摄像机

uniform mat4 unity_ObjectToWorld;
uniform mat4 unity_WorldToObject;
uniform mat4 unity_MatrixVP;
uniform mat4 unity_MatrixV;
uniform mat4 unity_MatrixInvV;
uniform mat4 glstate_matrix_projection;

  


  uniform mat4 gl_ModelViewMatrix;
  uniform mat4 gl_ProjectionMatrix;
  uniform mat4 gl_ModelViewProjectionMatrix;
  uniform mat4 gl_TextureMatrix[gl_MaxTextureCoords];
  uniform mat3 gl_NormalMatrix; 
     // transpose of the inverse of gl_ModelViewMatrix
  uniform mat4 gl_ModelViewMatrixInverse;
  uniform mat4 gl_ProjectionMatrixInverse;
  uniform mat4 gl_ModelViewProjectionMatrixInverse;
  uniform mat4 gl_TextureMatrixInverse[gl_MaxTextureCoords];
  uniform mat4 gl_ModelViewMatrixTranspose;
  uniform mat4 gl_ProjectionMatrixTranspose;
  uniform mat4 gl_ModelViewProjectionMatrixTranspose;
  uniform mat4 gl_TextureMatrixTranspose[gl_MaxTextureCoords];
  uniform mat4 gl_ModelViewMatrixInverseTranspose;
  uniform mat4 gl_ProjectionMatrixInverseTranspose;
  uniform mat4 gl_ModelViewProjectionMatrixInverseTranspose;
  uniform mat4 gl_TextureMatrixInverseTranspose[gl_MaxTextureCoords];

输入数据

在这里插入图片描述

作者:雄关漫道从头越
链接:https://www.jianshu.com/p/7b1294d5bd2c
来源:简书

UnityCG.glslinc

Time

uniform vec4 _Time;
uniform vec4 _SinTime;
uniform vec4 _CosTime;

摄像机和屏幕参数(Unity入门精要 , P88)

projection
uniform vec4 _ProjectionParams;
  • x: 1或-1(-1表示翻转投影)
  • y:near
  • z:far
  • w:1.0 + 1.0/Far
_WorldSpaceCameraPos

摄像机在世界坐标中的位置

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Unity Shader中使用GLSL创建材质 的相关文章

随机推荐

  • springboottest注解

    SpringBoot test 好习惯要坚持下去 CSDN博客 springboot test springboot使用 SpringBootTest注解进行单元测试 灰太狼 CSDN博客 springboot test
  • 如何为模型不同层设置不同的学习率?

    在模型调参中常用的一种方法是针对不同层设置不同的学习率 以此避免因难易程度不一致引起的过拟合等问题 一 模型举例 class Model nn Module def init self input size hidden size outp
  • 【cfengDB】自己实现数据库第0节 ---整体介绍及事务管理层实现

    LearnProj 内容管理 MySQL系统结构 一条SQL执行流程 cfengDB整体结构 事务管理TM模块 TID文件规则定义 文件读写 NIO RandomAccessFile FileChannel ByteBuffer 接口实现
  • 【单调栈】找到左右两边的最近小于元素

    基本概念 从一个问题引出单调栈的这个概念 给定一个数组 对于数组中的每一个元素 分别找到它左边和右边最近的小于它的元素 无重复数组 默认该数组中的元素是无重复的 我们可以维护一个栈 从栈的下方到上方 元素的大小从小到大 对于数组中的每一个元
  • OSI参考模型与TCP/IP参考模型(计算机网络)

    一 1 OSI参考模型有7层 从上到下为 应用层 表示层 会话层 传输层 网络层 数据链路层 物理层 如下图1 2 TCP IP参考模型有4层 自上到下分别为 应用层 传输层 网际层 网络接口层 如下图2 3 常考的5层参考模型是这样的 自
  • 微信小程序生成分享带参数二维码图片 并添加文字功能

    笔者最近接到一个新的任务 不是很难的功能 就是之前没有接触过 后端生成带参数的小程序二维码图片 并在图片下面添加一些文字 想在将代码分享给大家 期望可以给大家提供帮助 一 首先生成小程序的分享二维码有三种方式 接口 A 适用于需要的码数量较
  • 编程报错和问题解决办法【总结篇】

    目录 1 VMware开启虚拟机失败 模块 Disk 启动失败 2 vim 输入时光标键会变成a b c d 3 vim中delete backspace 键不能向左删除 4 conda command not found解决办法 5 进入
  • Leaflet的Vue组件 — Vue2Leaflet

    原文地址 Leaflet的Vue组件 Vue2Leaflet 这两天折腾Vue 在GitHub上发现了一个开源项目Vue2Leaflet Vue2Leaflet是一个Vue框架的JavaScript库 封装了Leaflet 它使构建地图变得
  • element Tree树形控件使用记录

    需求为使用弹窗选择区域 弹窗左侧为待选区 右侧会展示当前已选中项 也是树形控件展示 如果打开弹窗时上次有选中数据 需要展示出来并勾选相应树形节点 1 html及配置项 数据源部分 由于需求中有需要主动设置选中项 所以需要设置node key
  • 【Linux】线程池

    目录 前言 线程池概念 线程池的实现 前言 这篇文章来实现一个线程池 线程池概念 线程池 一种线程使用模式 线程过多会带来调度开销 进而影响缓存局部性和整体性能 而线程池维护着多个线程 等待着监督管理者分配可并发执行的任务 这避免了在处理短
  • Linux_基础知识笔记4

    基础知识 一 Linux目录结构 二 cat 查看文件内容 三 more 查看文件内容 内容多 四 less 查看文件内容 五 head tail 查看文件内容 六 wc 统计文件内容 七 grep 检索和过滤文件内容 八 gzip bzi
  • 利用闭包,在不设置全局变量的情况下,完成再次点击退出功能

    做APP经常会用到的功能就是 第一次点击弹出退出提示 再次点击退出app 以前常规做法 就是立flag 代码如下 var ableToOut null api addEventListener name keyback function r
  • 关于Undefined symbols for architecture x86_64这个错的总结

    最近在Mac上做一个程序 需要调用动态链接库 出现两次Undefined symbols for architecture x86 64的错误 所以总结下 第一个是 Undefined symbols for architecture x8
  • C++ 复制(拷贝)构造函数

    复制构造函数的定义 复制构造函数是一种特殊的构造函数 其形参为本类的对象引用 作用是用一个已经存在的对象去初始化同类型的新对象 复制构造函数被调用的三种情况 1 定义了一个对象 以本类另一个对象作为初始值 发生复制构造 2 如果函数的形参是
  • matlab中input输入多个数_基于MATLAB的PID控制算法仿真

    一 初学者学习目的 1 利用Matlab Simulink实现PID控制算法 2 观察不同PID参数对控制性能的影响 3 掌握PID参数整定的方法 二 实践内容 1 以二阶系统 为被控对象 K 135 在阶跃输入信号的作用下 用simuli
  • keil添加了头文件仍然报找不到头文件的原因

    1 如果工程中有中文路径 keil是无法识别中文路径的 需要修改为英文路径 2 如果工程中的路径存在数字开头 则keil无法识别该路径 需要修改为以英文字符开头 3 如果修改了工程中的文件夹名 则需要重新将文件夹包含到工程中 4 点击魔术棒
  • Datax插件二次开发之HdfsWriter支持parquet

    Datax插件二次开发之HdfsWriter支持parquet Date December 24 2021 1 背景 目前 公司的OLAP和AD HOC组件主要使用impala 而当前我们的impala版本支持parquet textfil
  • 用c++创造编译器(Brainfuck)

    目录 初始化 主算法 思路 完整代码 补充 请先看此文章 大家了解之后 可能会想 这么简单的语言 能不能用代码写出一个Brainfuck呢 哈哈 当然可以 作为第一次发布文章的博主 就来帮帮你吧 初始化 include
  • RocketMq客户端日志参数设置

    使用的RocketMq版本为4 7 1 RocketMq的客户端日志打印 Logger的创建代码在org apache rocketmq client log ClientLogger中 部分代码如下 public static final
  • Unity Shader中使用GLSL创建材质

    目录 Unity Shader格式 Properties 怎么在脚本中使用类似于glUniform 的功能呢 SubShader Tags LOD pass pass内的tags说明 pass内的代码段 GLSL GLSL与CG语言的差异