Cocos Creator Shader入门实战(五):材质的了解、使用和动态构建

news2025/3/26 15:19:20

引擎:3.8.5

您好,我是鹤九日!



回顾


前面的几篇文章,讲述的主要是Cocos引擎对Shader使用的一些固定规则,这里汇总下:

一、Shader实现基础是OpenGL ES可编程渲染管线,开发者只需关注顶点着色器片段着色器

二、Cocos引擎对Shader实现进行了多层封装,用于简化Shader的难度,以及更灵活管理,主要有:

  1. 封装了EffectAsset资源,主要包含CCEffectCCProgram两部分
  2. CCEffect部分, 采用YAML 1.2标准,与JSON兼容,并封装了渲染技术Technique、渲染过程Pass,以及Properties等多种属性配置
  3. CCProgram部分,采用GLSL语言,引擎封装了宏定义常量、函数以及Chunk等多种文件

三、Shader效果的实现,需要借助Effect Asset资源的属性配置和Material材质的数据包装。



简介


此篇文章,主要讲解关于材质Material部分,主要讲述内容:

一、材质的基本使用

二、使用iMaterialInfo动态初始化材质

三、材质的属性设置

四、材质的动态加载

正式开始之前,有两点需要注意:

  1. 材质是依托EffectAsset资源的,没有Effect资源,渲染材质无从谈起。
  2. 材质的作用,可以理解为两个:一、属性检查器的可视化调整; 二、通过脚本进行属性的动态调整

借助Cocos引擎实现Shader效果,简要的说,三个步骤:

一、创建EffectAsset资源,配置CCEffect渲染参数和编写CCProgram着色器片段

二、创建Material材质,设置属性检查器着色器资源,渲染技术、宏定义开关

三、渲染组件设置自定义材质属性



内置Effect

使用之前,首先我们需要有EffectAsset资源,可以通过编译器创建,也可以使用引擎内置的Effect资源。

内置Effect目录:../internal/effects
请添加图片描述

按照官方文档所言:

  • advanced 基于PBR着色器制作的一些高级效果,比如水面、皮肤、头发、玉石等,引擎会持续迭代
  • for2d 2D渲染相关着色器,比如:sprite、spine等
  • internal 引擎内置功能相关着色器,用户无需关注
  • particles 粒子相关特效
  • pipeline 管线着色器,比如延迟光照、后效和抗锯齿等

更多信息,可参考:内置着色器

本篇文章,便以内置的buitin-sprite.effect为例,主要原因有二:

  1. 精灵组件的Grayscale灰度渲染效果是它实现的
  2. CCEffect的属性配置和顶点着色器的片段代码,算是2D渲染中较为通用的。

内容如下:

  • CCEffect部分:
// Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd.
CCEffect %{
  # 渲染技术
  techniques:
  # 渲染过程
  - passes:
    # 顶点、片段着色器的名字和入口,必须参数
    - vert: sprite-vs:vert
      frag: sprite-fs:frag
      # 深度和模板测试
      depthStencilState:
        depthTest: false
        depthWrite: false
      # 混合模式状态
      blendState:
        targets:
        - blend: true
          blendSrc: src_alpha
          blendDst: one_minus_src_alpha
          blendDstAlpha: one_minus_src_alpha
      # 光栅化状态,禁用面剔除,常见参数有:front, back, none
      rasterizerState:
        cullMode: none
      # 属性参数配置,可用于属性检查器的可视化调整或代码的传参
      properties:
        alphaThreshold: { value: 0.5 }
}%
  • CCProgram着色器部分:
// 顶点着色器
CCProgram sprite-vs %{
  // 精度的设置
  precision highp float;
  // 引擎的Chunk和宏定义开关
  #include <builtin/uniforms/cc-global>
  #if USE_LOCAL
    #include <builtin/uniforms/cc-local>
  #endif
  #if SAMPLE_FROM_RT
    #include <common/common-define>
  #endif
  // 应用程序传入的顶点参数,分别是:位置(xyZ), 纹理坐标(uv), 颜色(rgba)
  in vec3 a_position;
  in vec2 a_texCoord;
  in vec4 a_color;
  // 顶点着色器传给片段着色器的数据,颜色会经过光栅化采样,纹理坐标用于纹理采样
  out vec4 color;
  out vec2 uv0;

  vec4 vert () {
    vec4 pos = vec4(a_position, 1);
    // 顶点坐标的坐标转换
    #if USE_LOCAL
      // 从局部坐标系转换到世界坐标系
      pos = cc_matWorld * pos;
    #endif

    #if USE_PIXEL_ALIGNMENT
      // cc_matView 视图矩阵, 将世界坐标系转换到视图坐标系
      pos = cc_matView * pos;
      pos.xyz = floor(pos.xyz);
      // cc_matProj 投影矩阵,将视图坐标转换为裁剪坐标
      pos = cc_matProj * pos;
    #else
      // cc_matViewProj 视图投影矩阵,将世界坐标转换为裁剪坐标
      pos = cc_matViewProj * pos;
    #endif

    uv0 = a_texCoord;
    #if SAMPLE_FROM_RT
      CC_HANDLE_RT_SAMPLE_FLIP(uv0);
    #endif
    color = a_color;

    return pos;
  }
}%

// 片段着色器
CCProgram sprite-fs %{
  precision highp float;
  #include <builtin/internal/embedded-alpha>
  #include <builtin/internal/alpha-test>

  in vec4 color;

  // 纹理采样相关
  #if USE_TEXTURE
    in vec2 uv0;
    #pragma builtin(local)
    layout(set = 2, binding = 12) uniform sampler2D cc_spriteTexture;
  #endif

  vec4 frag () {
    vec4 o = vec4(1, 1, 1, 1);

    #if USE_TEXTURE
      o *= CCSampleWithAlphaSeparated(cc_spriteTexture, uv0);
      // 是否使用灰度测试
      #if IS_GRAY
        float gray  = 0.2126 * o.r + 0.7152 * o.g + 0.0722 * o.b;
        o.r = o.g = o.b = gray;
      #endif
    #endif

    o *= color;
    ALPHA_TEST(o);
    return o;
  }
}%

注: 注释相关在原有的文章中提及过,这里就当是加深印象吧!



基本使用


创建任意Effect资源,将builtin-sprite.effect内容复制粘贴进去。

然后创建Material材质,这里使用编译器直接构建普通材质Material即可。

请添加图片描述

其属性如下:

请添加图片描述

  • Effect :材质使用到的着色器资源EffectAsset,可通过下拉条进行选择。
  • Technique :Effect资源在CCEffect中所包含的渲染技术,可通过下拉条选择,用于设置不同的渲染效果。
  • Pass… :Effect资源在CCEffect中针对于每一个渲染技术所包含的渲染过程
  • USE… :预处理宏定义开关组合,不同宏定义的组合生成不同的代码,进而实现不同的效果。

这里我们只需关注Effect即可,选择我们添加的effect文件,保存。

请添加图片描述

构建任一页面,页面中包含一个Sprite组件,如下图所示:

请添加图片描述

将创建的demo.mtl材质拖拽进去,保存后,打开demo.mtl材质的属性检查器,如下图:

请添加图片描述

标记部分的勾选与否,便可直接预览灰度渲染效果。



自定义材质


Cocos引擎对Shader为开发者默默做了很多的事情。

上图中,我们借助的是Sprite渲染组件下的customMaterial ,即自定义材质。

我们可以这样认为:

一、对于任何持有CustomMaterial属性的UI和2D组件,我们都可以认为设置自定义材质

二、自定义材质属性即使为空,引擎也会进行默认配置

学习shader,customMateiral属性是一个很重要的入口。

注意:2D渲染对象不支持多材质,自定义材质数量最多为一个。

参考:2D渲染对象自定义材质



imaterialInfo初始化


材质的构建,编译器是最为直观、简洁的方式。那么它支持代码初始化吗?答案可以。

代码的动态初始化,与编译器的构建有相似之处。

引擎对于材质构建所需要的参数进行了封装叫做:IMaterialInfo,它的主要结构如下:

// 初始化材质的基本信息
export interface IMaterialInfo {
    // effectAsset资源引用,和effectName至少要指定一个
    effectAsset?: EffectAsset | null;
    // effect资源名,和effectAsset至少要指定一个
    effectName?: string;
    // 使用到的渲染技术,默认0
    technique?: number;
    // 使用到的预处理宏定义组合,默认全为0
    defines?: renderer.MacroRecord | renderer.MacroRecord[];
    // 自定义管线状态
    states?: renderer.PassOverrides | renderer.PassOverrides[];
}

使用的接口是Material下的initialize,代码的构建实例:

@ccclass('demo')
export class demo extends Component {
    @property(Sprite)
    sprite: Sprite = null!;
    @property(EffectAsset)
    effect: EffectAsset = null!;        // Effect资源引用          

    protected onLoad(): void {
        this.initMaterial();
    }
    // 初始化材质
    private initMaterial() {
        const material = new Material();
        const info: IMaterialInfo = {
            effectAsset: this.effect,
            technique: 0,
            defines: {
                USE_TEXTURE: true,      // 宏定义开关,使用纹理开启
                IS_GRAY: true,          // 宏定义开关,置灰开启
            }
        };
        material.initialize(info);
        // 设置精灵的自定义材质
        this.sprite.customMaterial = material;
    };
}

效果如下:

请添加图片描述



动态加载

不管是普通材质Material,还是物理材质Physics Material,它们都属于Asset资源的范畴。

  • 普通材质Material,主要用于渲染
  • 物理材质Physics Material,主要定义物体在物理模拟中的摩擦力、弹性等。

它们的继承结构如下:

Material
Asset
PhysicsMaterial

既然为Asset资源,那便支持动态加载,大概示例如下:

@ccclass('demo')
export class demo extends Component {
    @property(Sprite)
    sprite: Sprite = null!;       

    protected onLoad(): void {
        this.loadMateiral();
    }

    private loadMateiral() {
        // 资源路径,不需要后缀
        const url = "demo/demo";
        resources.load(url, Material, (err: Error, material: Material) => {
            if (err) {
                return console.error(err.message);
            }
            this.sprite.customMaterial = material;
        });
    }
}


总结


今天的文章到这里就结束了!

可能理解有误,欢迎您的指出,如果觉得文章不错,期待您的点赞和留言,感谢!

我是鹤九日,祝你生活快乐!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2320880.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue设置自定义logo跟标题

准备 Logo 图片 将自定义的 Logo 图片&#xff08;如 logo.png&#xff09;放置在项目的 public文件夹下。 使用环境变量设置 Logo 和标题&#xff08;可选&#xff09; 创建或修改 .env 文件 在项目根目录下创建或修改 .env 文件&#xff0c;添加以下内容&#xff1a; VITE_A…

尝试在软考65天前开始成为软件设计师-计算机网络

OSI/RM 七层模型 层次名功能主要协议7应用层实现具体应用功能 FTP(文件传输)、HTTP、Telnet、 POP3(邮件)SMTP(邮件) ------- DHCP、TFTP(小文件)、 SNMP、 DNS(域名) 6表示层数据格式,加密,压缩.....5会话层建立,管理&终止对话4传输层端到端连接TCP,UDP3网络层分组传输&a…

VMware主机换到高配电脑,高版本系统的问题

原来主机是i3 ,windows7系统&#xff0c;vmware 14.0,虚机系统是ubuntu 14.04。目标新机是i7 14700KF,windows11系统。原以为安装虚拟机&#xff0c;将磁盘文件&#xff0c;虚拟机配置文件拷贝过去可以直接用。 新目标主机先安装了vmware 15&#xff0c;运行原理虚机&#xff0…

【Linux内核系列】:动静态库详解

&#x1f525; 本文专栏&#xff1a;Linux &#x1f338;作者主页&#xff1a;努力努力再努力wz &#x1f4aa; 今日博客励志语录&#xff1a; 有些鸟儿是注定是关不住的&#xff0c;因为它们的每一片羽翼都沾满了自由的光辉 ★★★ 本文前置知识&#xff1a; 编译与链接的过程…

windows环境下NER Python项目环境配置(内含真的从头安的perl配置)

注意 本文是基于完整项目的环境配置&#xff0c;即本身可运行项目你拿来用 其中有一些其他问题&#xff0c;知道的忽略即可 导入pycharm基本包怎么下就不说了&#xff08;这个都问&#xff1f;给你一拳o(&#xff40;ω*)o&#xff09; 看perl跳转第5条 1.predict报错多个设备…

IDEA批量替换项目下所有文件中的特定内容

文章目录 1. 问题引入2. 批量替换项目下所有文件中的特定内容2.1 右键项目的根目录&#xff0c;点击在文件中替换2.2 输入要替换的内容 3. 解决替换一整行文本后出现空行的问题4. 增加筛选条件提高匹配的精确度 更多 IDEA 的使用技巧可以查看 IDEA 专栏&#xff1a; IDEA 1. 问…

【蓝桥杯】4535勇闯魔堡(多源BFS + 二分)

思路 k有一个范围&#xff08;0到怪物攻击的最大值&#xff09;&#xff0c;求满足要求的k的最小值。很明显的二分套路。 关键是check函数怎么写&#xff0c;我们需要找到一条从第一行到最后一行的路径&#xff0c;每一次可以从上下左右四个方向前进&#xff0c;那么我么可以用…

HTML图像标签的详细介绍

1. 常用图像格式 格式特点适用场景JPEG有损压缩&#xff0c;文件小&#xff0c;不支持透明适合照片、复杂图像PNG无损压缩&#xff0c;支持透明&#xff08;Alpha通道&#xff09;适合图标、需要透明背景的图片GIF支持动画&#xff0c;最多256色简单动画、低色彩图标WebP谷歌开…

Chapter 4-15. Troubleshooting Congestion in Fibre Channel Fabrics

show zone member: Shows the name of the zone to which a device belongs to. This command can be used to find the victims of a culprit device or vice versa. 显示设备所属的区域名称。该命令可用于查找罪魁祸首设备的受害者,反之亦然。 show zone active: Shows the…

QT三 自定义控件

一 自定义控件 现在的需求是这样&#xff1a; 假设我们要在QWidget 上做定制&#xff0c;这个定制包括了关于 一些事件处理&#xff0c;意味着要重写QWidget的一些代码&#xff0c;这是不实际的&#xff0c;因此我们需要自己写一个MyWidget继承QWidget&#xff0c;然后再MyWi…

在 ASP .NET Core 9.0 中使用 Scalar 创建漂亮的 API 文档

示例代码&#xff1a;https://download.csdn.net/download/hefeng_aspnet/90407900 Scalar 是一款可帮助我们为 API 创建精美文档的工具。与感觉有些过时的默认 Swagger 文档不同&#xff0c;Scalar 为 API 文档提供了全新而现代的 UI。其简洁的设计让开发人员可以轻松找到测试…

用于 RGB-D 显著目标检测的点感知交互和 CNN 诱导的细化网络(问题)

摘要 问题一&#xff1a;但在对自模态和跨模态的全局长距离依赖关系进行建模方面仍显不足。什么意思&#xff1f; 自模态&#xff08;Intra-modal&#xff09;全局依赖&#xff1a;在同一模态内&#xff0c;长距离像素之间的信息交互对于理解全局背景很重要&#xff0c;但 CN…

python3 -m http.sever 8080加载不了解决办法

解决方法很多&#xff0c;本文设置各种处理方法&#xff0c;逻辑上需要根据你的自身情况选择 我会告诉你遇到这种问题怎么做&#xff0c;根据具体症状处理 如需转载&#xff0c;标记出处 背景&#xff1a; 1。如图 2.。域名访问不了 http://www.meiduo.site:8080/register.ht…

Oracle数据库性能优化全攻略:十大关键方向深度解析与实践指南

文章目录 一、SQL查询优化二、索引优化三、内存管理四、I/O优化五、分区表与分区索引六、并行处理七、统计信息管理八、锁与并发控制九、数据库参数调优十、应用设计优化结论 在当今数据驱动的时代&#xff0c;数据库的性能优化成为了确保企业应用高效运行的关键。Oracle作为业…

windows清除电脑开机密码,可保留原本的系统和资料,不重装系统

前言 很久的一台电脑没有使用了&#xff0c;开机密码忘了&#xff0c;进不去系统 方法 1.将一个闲置u盘设置成pe盘&#xff08;注意&#xff0c;这个操作会清空原来u盘的数据&#xff0c;需要在配置前将重要数据转移走&#xff0c;数据无价&#xff0c;别因为配置这个丢了重…

【深度学习】【目标检测】【Ultralytics-YOLO系列】Windows11下YOLOV3人脸检测

【深度学习】【目标检测】【Ultralytics-YOLO系列】Windows11下YOLOV3人脸检测 文章目录 【深度学习】【目标检测】【Ultralytics-YOLO系列】Windows11下YOLOV3人脸检测前言YOLOV3模型运行环境搭建YOLOV3模型运行数据集准备YOLOV3运行模型训练模型验证模型推理导出onnx模型 总结…

html5-qrcode前端打开摄像头扫描二维码功能

实现的效果如图所示&#xff0c;全屏打开并且扫描到二维码后弹窗提醒&#xff0c;主要就是使用html5-qrcode这个依赖库&#xff0c;html5-qrcode开源地址&#xff1a;GitHub - mebjas/html5-qrcode: A cross platform HTML5 QR code reader. See end to end implementation at:…

ui_auto_study(持续更新)

通过where python来找到python解释器的安装目录 如果不适配&#xff0c;谷歌浏览器插件可以在这个地址下载对应的驱动 谷歌浏览器驱动下载地址 下载对应的驱动版本&#xff0c;替换原驱动 替换后&#xff0c;可以执行成功 div代表标签 .开头的代表类# 使用class定位元素 …

【nodejs】爬虫路漫漫,关于nodejs的基操

一.下载安装nodejs 官网地址&#xff1a;Node.js — 在任何地方运行 JavaScript 二.下载安装vscode代码编辑器 官网地址&#xff1a;Download Visual Studio Code - Mac, Linux, Windows 三.修改本地脚本策略 1&#xff0c;windowsi 打开电脑设置 2&#xff0c;输入powersh…

常见中间件漏洞攻略-Jboss篇

一、CVE-2015-7501-Jboss JMXInvokerServlet 反序列化漏洞 第一步&#xff1a;开启靶场 第二步&#xff1a;访问该接口&#xff0c;发现直接下载&#xff0c;说明接⼝开放&#xff0c;此接⼝存在反序列化漏洞 http://47.103.81.25:8080/invoker/JMXInvokerServlet 第三步&…