Apple 推出 metal后,除了新的metal framewrok外,也多了一种新的shader语言,最近工作也做了一些metal移植的测试,主要还是现有引擎如何可以快速支持metal的解决方案。这里也想对边写写自己的心得。
 
  metal shader的语法特性更接近SM5的hlsl,所以sm4或sm5的hlsl转化成metal shader更简单,性能跟GLES3.1相似,提供了Vextrex shader, Fragment Shader和Computer Shader。加上移动端图形API的新特性的支持,所以使得次世代游戏引擎面向移动端的移植成为了可能。
 
  像UE4,CE3这种的大型引擎来说,本身shader代码量就很大,要支持多平台,如果写多套shader,不论是在开发还是测试上都会让工作量成倍增加,所以都是选择转化shader的方式来跨平台。目前常用的shader转化,要么是FXC编译HLSL的字节码转化,要么就是直接源代码之间转化。对HLSL->GLSL而言,用字节码转化更简单。但metal shader不提供字节码的格式,所以字节码转化方式可能是行不通了。UE4在开发时的2年里也搜索过能解决SM5的HLSL转化的跨平台编译器,结果只能自己基于Mesa3D的功能进行扩展,开发了HLSLCC。
  
  目前的几个HLSL->GLSL的方案:
  hlsl2glslfork,由ATI的HLSL2GLSL发展而来,也基于了一部分monoshader的代码(UE3最早就是用的monoshader),shader源代码之间的翻译,问题是只支持DX9风格的HLSL,不支持DX10和DX11的一些语法,也没有geometry shader,tesseliaton shadr和 compute shader,现在Unity3d还是用的这个。
 
  KlayGE的HLSL2GLSL,是从HLSL的字节码转化为GLSL。
 
  UE4的HLSLCC,通过在他们在GDC2014上的ppt来看,也是受到glsl-optimizer的设计的影响,这两个都是参考Mesa3D的,不过Mesa3D只是GLSL的分析和转化为Mesa IR,HLSLCC改成了SM5的HLSL的分析功能,并添加了IR->GLSL的converter。并且在UE4.3后,也加入了metal shader的支持。
 
  接下来也是想结合HLSLCC的ppt,说一些自己的看法,HLSLCC的转化流程,是HLSL->AST->IR->GLSL/Metal + ParameterMap,输出使用了glsl-optimizer一部分功能,但实际运行UE4的HLSLCC的时候,还是会有不少问题的。
 
  1. shader marco,像ue的.usf,ce的.fxc,多少会通过使用宏来做一些shader的条件编译,静态分支处理等等,也就类似uber shader的概念,但基本上没有什么转化工具能搞定那么复杂的工作,而且也经常会有vs,ps的多个Entry函数(Main)写到一个usf文件里的情况,直接整个.usf扔给转化工具也是不现实的,ue和ce的解决方法,还是要经过内部的管理,把每个入口函数的部分独立出来,如UE4就是通过定义Golbalshader子类,自己来设置参数和入口函数名等等。然后独立的shader入口函数进行转化。而#include,#define,#if 一类的宏和分支的处理,进行转化前要通过,只留下runtime必须的部分,转化成不同平台的shader并编译为cache保存。
  
 
  2. OGL通过uniform从每帧从CPU->GPU传递参数,为了减少API调用次数,所以DX11提供了const buffer,而ES3.0和metal也提供了uniform buffer的概念,因为对于大型游戏来说,uniform update调用API的数量也是很大一部分消费,所以需要使用const buffer来根据参数更新频率和顺序进行组织,而在不支持这种概念的DX9上,CE3使用了模拟的const buffer来对参数进行缓存重组再进行更新,而UE4虽然直接支持的DX11,但对移动平台ES2.0的设备,没有uniform buffer的特性,他们使用了模拟的Uniform buffer功能(ppt里叫shadow buffer),基于更新频率打包到uniform array。所以,HLSLCC除了输出GLSL外,也有生成Parameter Map的功能。
  3. shader version方面,如果是DX11 HLSL的转化,对hlslcc进行一些修改定制后就可以,本身hlslcc也支持不同版本GL和metal的输出,如果是DX9 风格HLSL的话,就需要进行一些预处理工作了,dx9和dx11的主要变化在semantic,texture和sample的使用上有些变化。例如:
     
Pixel Shader的input,DX11里改为了SV_Position,output里,COLOR被SV_Target替代
DX9:
 

  1. struct vs2ps
  2. {
  3. float4 Pos : POSITION;
  4. float4 TexCd : TEXCOORD0;
  5. };

DX11:

  1. struct vs2ps
  2. {
  3. float4 Pos: SV_POSITION;
  4. float4 TexCd: TEXCOORD0;
  5. };

DX9:

  1. float4 PS(vs2ps In): COLOR

DX11:

  1. float4 PS(vs2ps In): SV_Target

Texture Sample的定义:

DX9:
  1. texture Tex <string uiname="Texture";>;
  2. sampler Samp = sampler_state //sampler for doing the texture-lookup
  3. {
  4. Texture = (Tex); //apply a texture to the sampler
  5. MipFilter = LINEAR; //sampler states
  6. MinFilter = LINEAR;
  7. MagFilter = LINEAR;
  8. };

DX11:

  1. Texture2D texture;
  2. SamplerState g_samLinear
  3. {
  4. Filter = MIN_MAG_MIP_LINEAR;
  5. AddressU = Wrap;
  6. AddressV = Wrap;
  7. };

如果要Sample Texture:

DX9:
  1. float4 col = tex2D(Samp, In.TexCd.xy);

DX11:

  1. float4 col = texture2d.Sample( g_samLinear, In.TexCd.xy);

DX9:

  1. float4 col = tex2Dlod(Samp, float4(In.TexCd.xy,,level));

DX11:

  1. float4 col = texture2d.SampleLevel( g_samLinear, In.TexCd.xy,level);

DX9:

  1. float4 col = tex2Dproj(Samp,screenProj.xyzw);

DX11:

  1. float4 col = Samp.Sample(g_samLinear, .creenProj.xy / screenProj.w );

4 GLES3.1和metal里都提供了compute shader的功能,metal shader里叫kernel function,很可惜,这部分UE4也还没支持,所以HLSLCC里也还没实现Compute Shader的转化,但相信不久以后也会支持了,拭目以待吧。

总结,自己这方面的工作也是刚开始,所以描述的深度也有限,随着额工作深入,应该会对HLSLCC和各种API如何优化做进一步分析

 

关于Shader的跨平台方案的考虑的更多相关文章

  1. 引擎设计跟踪(九.14.2d) [翻译] shader的跨平台方案之2014

    Origin: http://aras-p.info/blog/2014/03/28/cross-platform-shaders-in-2014/ 简译 translation: 作者在2012年写 ...

  2. 最火移动端跨平台方案盘点:React Native、weex、Flutter

    1.前言 跨平台一直是老生常谈的话题,cordova.ionic.react-native.weex.kotlin-native.flutter等跨平台框架的百花齐放,颇有一股推倒原生开发者的势头. ...

  3. 热门跨平台方案对比:WEEX、React Native、Flutter和PWA

    本文主要对WEEX.React Native.Flutter和PWA几大热门跨平台方案进行简单的介绍和对比.内容选自<WEEX跨平台开发实战> (WEEX项目负责人力荐,从入门到实战,教你 ...

  4. 移动端跨平台方案对比:React Native、weex、Flutter

    跨平台一直是老生常谈的话题,cordova.ionic.react-native.weex.kotlin-native.flutter等跨平台框架百花齐放,颇有一股推倒原生开发者的势头. 为什么我们需 ...

  5. 剖析虚幻渲染体系(08)- Shader体系

    目录 8.1 本篇概述 8.2 Shader基础 8.2.1 FShader 8.2.2 Shader Parameter 8.2.3 Uniform Buffer 8.2.4 Vertex Fact ...

  6. Shader学习笔记

    Shader学习笔记 例子: Shader "SrfShader1"{ //定义显示在Inspector中的变量,并从Inspector中获取值 Properties{ _Colo ...

  7. C#移动跨平台开发(2)Xamarin移动跨平台解决方案是如何工作的?

    概述 上一篇 C#移动跨平台开发(1)环境准备发布之后不久,无独有偶,微软宣布了开放.NET框架源代码并且会为Windows.Mac和Linux开发一个核心运行时(Core CLR),这也是开源的!I ...

  8. 利用C#开发移动跨平台Hybrid App(一):从Native端聊Hybrid的实现

    0x00 前言 前一段时间分别读了两篇博客,分别是叶小钗兄的<浅谈Hybrid技术的设计与实现>以及徐磊哥的<从技术经理的角度算一算,如何可以多快好省的做个app>.受到了很多 ...

  9. 跨平台运行 Rafy 首次部署记录

    一直想在 Linux 上使用 MONO 试试运行 Rafy,最近因为业务需要,总算是真正地试验了一次.下面是本次部署记录的一些要点. Linux 这次部署,我是和两位同事一起来试验的.由于我们对 Li ...

随机推荐

  1. linux编译中的常见问题

    转linux编译中的常见问题 错误提示:Makefile:2: *** 遗漏分隔符 . 停止. 原因makefile中 gcc语句前 缺少一个 tab分割符 错误提示: bash: ./makefil ...

  2. mysql TIMESTAMP详解

    navicat中设置timestamp字段的时间,默认这里填写CURRENT_TIMESTAMP,就是在插入数据的时候按照当前时间插入: 勾选根据当前时间戳更新,表示在UPDATE的时候,会根据当前时 ...

  3. ytu 1998:C语言实验——删除指定字符(水题)

    C语言实验——删除指定字符 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 327  Solved: 211[Submit][Status][Web Boa ...

  4. C#学习笔记——Show()与ShowDialog()的区别

    用Show()调用的窗体不会返回任何值,在使用form.Show()显示form以后,会马上继续执行form.Show()后面的语句.而用ShowDialog()调用的窗体会返回一个DialogRes ...

  5. 电赛总结(二)——AD芯片总结之高速AD9224

    一.特性参数 1.12位高速AD 2.高达40MSPS的高速AD芯片 3.噪声小 二.芯片管脚图 三.管脚功能说明 管脚名称 功能 CLK 参考时钟输入端 BIT12-1 数据输出端(1是低位,12是 ...

  6. JavaScript案例六:简单省市联动(NBA版)

    JavaScript实现简单省市(NBA版)联动 <!DOCTYPE html> <html> <head> <title>JavaScript实现简单 ...

  7. Xamarin Visual Studio提示找不到AssemblyAttributes.cs文件

    Xamarin Visual  Studio提示找不到AssemblyAttributes.cs文件   错误信息:Could not find file ‘C:\Users\[用户名]\AppDat ...

  8. Xamarin Android布局文件没有智能提示

    Xamarin Android布局文件没有智能提示 在Visual Studio 2015中,Android项目的Main.axml文件没有智能提示,不便于布局文件的编写.解决办法:(1)从Xamar ...

  9. DFS POJ 2676 Sudoku

    题目传送门 题意:数独问题,每行每列以及每块都有1~9的数字 分析:一个一个遍历会很慢.先将0的位子用vector存起来,然后用rflag[i][num] = 1 / 0表示在第i行数字num是否出现 ...

  10. POJ2288 Islands and Bridges(TSP:状压DP)

    求一个图的哈密顿路径的最大权及其路径数.显然状态压缩+DP. dp[v][u][S] 表示从v走到当前顶点 u且走过的顶点集合是S的 最大权值和方案数 这题我用记忆化搜索,从终点开始递归进行,感觉这样 ...