-
OpenGL和unity 3D
2020-07-01 16:04:05 -
opengl使用unity3d中的lightmap
2015-01-07 17:45:41opengl使用unity3d中的lightmap -
【OpenGL】使用Unity来学习OpenGL-附件资源
2021-03-05 15:17:44【OpenGL】使用Unity来学习OpenGL-附件资源 -
opengl场景代码_实战篇使用Native OpenGL渲染Unity场景
2020-12-06 03:08:0001 前言众所周知,Unity内部集成了OpenGL库,可以在C#脚本中使用GL接口。那为什么还需要Native的方式在渲染呢?原因有如下几点: 1. Unity中提供的GL库开放的功能不是太多,远远不能满足开发者的需要。 2. GL库是...01 前言
众所周知,Unity内部集成了OpenGL库,可以在C#脚本中使用GL接口。那为什么还需要Native的方式在渲染呢?原因有如下几点:
1. Unity中提供的GL库开放的功能不是太多,远远不能满足开发者的需要。
2. GL库是经过封装的,接口、语法等和原生的OpneGL有差距,Unity的shader和OpneGL的shader也是有区别的,对于习惯原生OpenGL操作的人来说显然使用原生OpenGL更为方便。
3. 当要渲染的数据需要复杂的处理时,使用原生OpenGL能更好的实现需求。
4. 对于插件来说,渲染部分代码如果不希望被公开,可以使用原生OpneGL打包成so库来实现。
本文通过实战的方式来讲述在安卓或iOS平台下如何使用OpenGL来渲染Unity场景中的物体。基本思路如下:
由上图可以看出,Unity有自己的渲染线程,它不是unity的的主线程,所以需要在Unity的渲染线程里面执行绘制代码才能正确的渲染。为了原生OpenGL渲染的独立性,在Native层创建单独的渲染线程来实现OpenGL渲染。
下面,我们就来使用原生OenpGL在Unity上的Plane物体上渲染一个三角形。
02 Unity侧配置及代码实现
新建Unity3D工程,切换平台到Android或Ios(本文采用Android平台来实操,iOS和安卓大同小异)。打开ProdectSetting 按需要选择Graphics APIs 为OpenGLES2或OPENGLES3,选择Multithreaded Rendering。创建一个Plane 物体 设置位置角度如下, 我们将使用原生的OpenGL来绘制这个Plane。
给这个Plane创建Render.cs的脚本,开始我们C#部分的代码,C#代码有两种思路:
方式一:unity生成Texture供原生OpenGL使用,此方式比较简单,但是纹理的大小需要unity层决定,不能动态的根据外部的纹理变化。
方式二:原生 OpenGL 生成Texture, 将textureId 回调给Unity使用。这种方式实现起来相对复杂,需要由Native层回调纹理的信息,但是这种方式更加灵活。
如果你绘制的图形大小是固定的,期间不会变化,则可以使用方式一。本文以方式二为例,C#代码:
代码说明:
(1)set_native_callback(new native_texture_callback(receiveNativeTexture));
设置一个回调函数传给native,当native生成好纹理之后将纹理的大小和textureId通过这个回调函数传给unity
(2)GL.IssuePluginEvent(GetRenderEventFunc(), 1);
将unity的渲染线程通过事件发布给Native,Native侧从而获取Unity的OpenGL上下文,为Native创建一组共享上下文的OpenGL环境。注意:两个单独的OpenGL环境是不会产生相互作用的,只有配置了共享上下文的两个OpenGL环境才能相互修改对方的数据。
(3)使用回调回来的纹理,为Plane指定新的纹理
这里有个地方放需要注意一下,因为Native的回调不是Unity的主线程,不能直接设置xxx..mainTexture = nativeTexture,所以需要通过线程的相关方法使之在unity主线程执行,这里采用的是SynchronizationContext发送消息到主线程函数。
以上,Unity侧的配置及代码已全部处理完毕。总结起来讲Unity做了以下两个事情:
1、 将Unity的渲染线程发布给Native,使得Native能获取到Unity的OpenGL上下文参数
2、 将通过原生回调上来的纹理配置给Plane的MainTexture;
关于Unity和Native交互的部分不是文本的要点,这里不做说明。下面我们只需实现原生中的代码即可。
03 Native侧代码实现
创建nativeRender.cpp文件,通过Jni编译成成libnativeRender.so供Unity使用。nativeRender.cpp中实现C#中调用的三个接口
创建OpenGL环境,获取Unity渲染线程的上下文。OnRenderEvent 是运行在Unity渲染线程上的接口,在此接口中获取Unity OpenGL的上下文,然后在另一个线程里面创建Native的OpenGL环境
通过startRender接口触发Native侧OpenGL环境初始化以及渲染
注意:此接口在Unity主线程,里面不可有阻塞线程的操作,不然Unity界面会卡顿,建议重开一个线程单独作为Native的渲染线程,本文例子比较简单,就直接在startRender接口通过调用draw方法绘制一个三角形。
当nantive侧生成texture后通过回调函数传给unity。
以上Native侧的代码已实现完毕,主要流程有以下3步:
1、 通过OnRenderEvent 获取unity的OpenGL上下文
2、 通过第一步获取到的unity的OpenGL上下文创建Native层的OpenGL上下文环境
3、将要绘制的内容绘制到Texture中去,将这个Texture回调给Unity。
最后,运行到安卓手机后效果如下:
04 总结
以上是安卓平台上Unity使用Native OpenGL渲染的所有过程。iOS 在共享上下文上和安卓是有差异的,iOS不需要通过GL.IssuePluginEvent这种方式获取Unity的渲染线程,相对简单一点,其他思路一致,这里不重复阐述。虽然例子中只是绘制了一个简单的三角形,但是我们可以在Native层随意的绘制,解决各种复杂的需求。最后强调一下本方案的核心:利用OpenGL的多线程渲染技术,使得Unity和Native 共用纹理,最终实现native层修改纹理,unity层展示纹理。
作者:陶杰
青榴实验室---超高清视频技术的传播者
-
Android 通过OpenGl更新Unity图片
2020-04-10 17:16:25这个文章是针对Unity 制作的Android程序 java代码部分获取到图片数据,如果要传递到unity,应该怎么做呢? 首先说一下为啥会有这个需求: 如果Unity程序需要外接一些图像设备,例如外接红外摄像头。Unity并不能...这个文章是针对Unity 制作的Android程序
java代码部分获取到图片数据,如果要传递到unity,应该怎么做呢?
首先说一下为啥会有这个需求:
如果Unity程序需要外接一些图像设备,例如外接红外摄像头。Unity并不能直接获取到图像数据,首先需要需要在AndroidStudio中做好设备接入工作(驱动程序之类)。然后设备会通过Usb接口返回图像数据,这个数据然后通过java代码传递到unity。
如何传递这个图片数据:
一、图片肯定是字节数组,可以通过java回调,将字节数组传递到Unity。Unity收到数据,然后更新Texture2D的数据。具体交互方式可以看我之前的文章。
二、直接通过字节传递数据的方式,可以实现。但是大数据传递,加上Texture2D的赋值,这样肯定会造成一定延时。
之前一直想通过OpenGl传递,但是属实不会,看了很多资料也没搞通。今天巧合之下弄好了。
首先在Unity中定义一个Texture2D 或者 RenderTexture(主动调用Create,不然不会在硬件创建纹理)。然后可以通过GetNativeTexturePtr获取到Texture的指针。
将指针传递到java中,然后java就可以通过这个指针修改图片数据了
if (!_update) { return; } int[] imageBuffer = new int[0]; if (_conversionScript != null) { imageBuffer = _conversionScript.getOutputBuffer(); } if (imageBuffer.length > 1) { GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texturePointer); GLES20.glTexSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, _previewSize.getWidth(), _previewSize.getHeight(), GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, IntBuffer.wrap(imageBuffer)); }
通过这段代码修改图片数据后,Unity里面的Texture也就更新了。
unity需要设置GraphicsApi为OpenGl,然后取消多线程渲染。
https://github.com/robsondepaula/unity-android-native-camera
这个工程可以做一个参考。
工程中C++部分,我感觉是没有必要的,因此我去掉了,测试暂时没有遇到问题。
Unity 传递图片到java,参考这篇文章https://blog.csdn.net/hongdameng/article/details/84835032
-
OpenGL与Unity Shader常用基础面试题
2021-03-18 20:21:09OpenGL与Unity Shader常用基础面试题 仓木 生命不息,战斗不止............ 155 人赞同了该文章 搜集了一些面试的时候问的图形学相关的题目,并且整理了下来,后续会不断的完善。 1、三大主流的Shader ...OpenGL与Unity Shader常用基础面试题
生命不息,战斗不止............
155 人赞同了该文章
搜集了一些面试的时候问的图形学相关的题目,并且整理了下来,后续会不断的完善。
1、三大主流的Shader Language?
HLSL、GLSL、CG
2.OpenGL的渲染流程?
(不同的管线流程应该是有去别的,大体上是这样的)
读取顶点数据→执行顶点着色器→组装图元→光栅化图元→执行片段着色器→写入帧缓冲区→显示在屏幕上。
3、Unity Shader的详细流程:
- (1)顶点数据
- (2)几何阶段:顶点着色器→曲面细分着色器→几何着色器→裁剪→屏幕映射(→传递数据给光栅化阶段)
- (3)光栅化阶段:三角形设置→三角形遍历→片元着色器→逐片元操作
- (4)屏幕图像
4、前向渲染、延迟渲染?
a、延迟渲染
- 将着色计算进行延后处理的一种渲染方式。
- 延时光照是有着最高保真度的光照和阴影的渲染路径。如果你有很多实时灯光,最好是使用延时光照。
- 有两个pass:几何处理(G-Buffer Pass)、光照处理(Lighting Pass)
优点:
(1)影响一个物体的光源数量是没有限制的
(2)每一个光源都是逐像素级别的效果,并且可以正确的计算法线贴图以及阴影
(3)高保真,可以还原每一盏灯的效果
缺点:
(1)不支持半透明效果
(2)不支持抗锯齿
(3)内存开销较大
(4)不支持正交相机
b、前向渲染
- 如果物体处在多个逐像素光源影响区域,那么该物体需要执行多个Pass,每个Pass计算一个逐像素光源的光照结果。最后在帧缓冲中(每帧结束数据处理的区域)混合得到最终的显示颜色。
- 前向渲染路径的消耗和实时光的数量成正比。
- 为了减少Pass数目,Unity渲染时会限制物体的逐像素光照数目。
5、光照模型:
a、Lambert(漫反射)
Diffuse = Ambient + Kd * LightColor * max(0,dot(N,L))
- Diffuse: 最终物体上的漫反射光强.
- Ambient: 环境光强度,为了简化计算,环境光强采用一个常数表示.
- Kd: 物体材质对光的反射系数.
- LightColor: 光源的强度.
- N: 顶点的单位法线向量.
- L: 顶点指向光源的单位向量.
b、Phong(高光)
Specular = SpecularColor * Ks * pow(max(0,dot(R,V)), Shininess)
- Specular: 最终物体上的反射高光光强.
- SpecularColor: 反射光的颜色.
- Ks: 反射强度系数.
- R: 反射向量,可使用2 * N * dot(N,L) - L或者reflect (-L,N)获得.
- V: 观察方向.
- N: 顶点的单位法线向量.
- L: 顶点指向光源的单位向量.
- Shininess: 乘方运算来模拟高光的变化.
c、Blinn-Phong(高光)
Specular = SpecularColor * Ks * pow(max(0,dot(N,H)), Shininess)
- Specular: 最终物体上的反射高光光强.
- SpecularColor: 反射光的颜色.
- Ks: 反射强度系数.
- N: 顶点的单位法线向量.
- H: 入射光线L与视线V的中间向量,也称为半角向量H = normalize(L+V).
- Shininess: 乘方运算来模拟高光的变化.
6、你一般使用什么Shader Language?
如果你面试的是Unity岗位,还是以CG语言为主
7、OpenGL中要用到哪几种Buffer?
- (1)帧缓冲(Frame Buffer)
- (2)颜色缓冲(Color Buffer)
- (3)模板缓冲(Stencil Buffer)
- (4)顶点缓冲(Vertice Buffer)
- (5)深度缓冲(Depth Buffer)
8、Unity Shader 中的常用RenderType?
- (1)Opaque: 用于大多数着色器(法线着色器、自发光着色器、反射着色器以及地形的着色器)。
- (2)Transparent:用于半透明着色器(透明着色器、粒子着色器、字体着色器、地形额外通道的着色器)。
- (3)TransparentCutout: 蒙皮透明着色器(Transparent Cutout,两个通道的植被着色器)。
- (4)Background: Skybox shaders. 天空盒着色器。
- (5)Overlay: GUITexture, Halo, Flare shaders. 光晕着色器、闪光着色器。
- (6)TreeOpaque: terrain engine tree bark. 地形引擎中的树皮。
- (7)TreeTransparentCutout: terrain engine tree leaves. 地形引擎中的树叶。
- (8)TreeBillboard: terrain engine billboarded trees. 地形引擎中的广告牌树。
- (9)Grass: terrain engine grass. 地形引擎中的草。
- (10)GrassBillboard: terrain engine billboarded grass. 地形引擎何中的广告牌草。
9、请介绍你所有知道的纹理Alpha混合方式,原理(公式).
假设一种不透明东西的颜色是A,另一种透明的东西的颜色是B,那么透过B去看A,看上去的颜色C就是B和A的混合颜色,可以用这个式子来近似。
设B物体的透明度为alpha(取值为0-1,0为完全透明,1为完全不透明)
R(C)=alpha*R(B)+(1-alpha)*R(A)
G(C)=alpha*G(B)+(1-alpha)*G(A)
B(C)=alpha*B(B)+(1-alpha)*B(A)R(x)、G(x)、B(x)分别指颜色x的RGB分量。看起来这个东西这么简单,可是用它实现的效果绝对不简单,应用alpha混合技术,可以实现出最眩目的火光、烟雾、阴影、动态光源等等一切你可以想象的出来的半透明效果。
10、什么是model,view,project矩阵?
世界矩阵(World Matrix)、视图矩阵(View Matrix)以及投影矩阵(Projection Matirx);
- 世界矩阵确定一个统一的世界坐标,用于组织独立的物体形成一个完整的场景;
- 视图矩阵就是我们能看到的那部分场景,由虚拟摄像机负责拍摄;
- 投影矩阵就是3维物体的平面影射.把三维场景在一个二维的平面上显示.
11、阴影
ShadowMapping
unity引擎里面比较常用的实时阴影的生成方法。
ShadowMap是动态生成的阴影纹理图,在需要时对其进行采样来获取阴影的一种技术手段。
a、接收其他物体的阴影:在shader中对阴影映射纹理进行采样,把采样结果和最后的光照结果相乘产生阴影效果
b、添加"LightMode" = "ShadowCaster"的Pass.
向其他物体投射阴影: 把该物体加入到光源的阴影映射纹理计算中,从而让其他物体在对阴影映射纹理采样时可以得到该物体的相关信息。
12、渲染排序
Tags {"Queue"="XXXXX"}
按照渲染顺序,从先到后进行排序,队列数越小的,越先渲染,队列数越大的,越后渲染。
渲染队列数<=2500的对象都被认为是不透明的物体(从前往后渲染),
>2500的被认为是半透明物体(从后往前渲染)。
"Queue" = "Background"
值为1000,此队列的对象最先进行渲染。
"Queue" = "Geometry"
默认值,值为2000,不透明物体的渲染队列。大多数物体都应该使用该队列进行渲染,也是Unity Shader中默认的渲染队列。"Queue" = "Geometry+1" 可通过在值后加数字的方式来改变队列
"Queue" = "AlphaTest"
值为2450,要么完全透明要么完全不透明,多用于利用贴图来实现边缘透明的效果,也就是美术常说的透贴。
"Queue" = "Transparent"
值为3000,半透物体的渲染队列。一般是不写深度的物体,Alpha Blend等的在该队列渲染,渲染时从后往前进行渲染。
"Queue" = "Overlay"
值为4000,最后被渲染的物体的队列,一般是覆盖效果,比如镜头光晕,屏幕贴片之类的。
Blend Types 常用的几种混合类型:
- Blend SrcAlpha OneMinusSrcAlpha// Traditional transparency
- Blend One OneMinusSrcAlpha// Premultiplied transparency
- Blend One One
- Blend OneMinusDstColor One // Soft Additive
- Blend DstColor Zero // Multiplicative
- Blend DstColor SrcColor // 2x Multiplicative
-
opengl 天空盒_OpenGL与Unity Shader常用基础面试题
2020-12-30 11:07:57HLSL、GLSL、CG2.OpenGL的渲染流程?(不同的管线流程应该是有去别的,大体上是这样的)读取顶点数据→执行顶点着色器→组装图元→光栅化图元→执行片段着色器→写入帧缓冲区→显示在屏幕上。3、Unity Shader的详细... -
以OpenGL方式运行Unity
2016-08-10 09:48:00Unity在Windows上默认以DirextX的方式运行,在MacOS和Linux上默认以OpenGl的方式运行, 如果希望在Windows上以OpenGL的方式运行可以在命令行中输入 -force-opengl启动Unity 转载于:... -
Unity3d OpenGL_pdf
2016-01-27 11:58:46Unity3d OpenGL_pdf -
用opengl方式打开unity
2016-01-11 20:33:49在目标上面加 "C:\Program Files (x86)\Unity\Editor\Unity.exe" -force-opengl -
opengl纹理贴图正方体六个面_OpenGL与Unity Shader常用基础面试题
2020-11-20 07:18:37HLSL、GLSL、CG2.OpenGL的渲染流程?(不同的管线流程应该是有去别的,大体上是这样的)读取顶点数据→执行顶点着色器→组装图元→光栅化图元→执行片段着色器→写入帧缓冲区→显示在屏幕上。3、Unity Shader的详细... -
【OpenGL】使用Unity来学习OpenGL
2017-08-10 10:55:11OpenGL是原理性和实践性比较强的一门技术,在学习的时候,如果能够跟着书中的例子,一边调试一边学习,效果将很好(这属于实验的一种类型吧,能够吧知识形象化,有助于学习兴趣的提高)。市面上有许多深入浅出的书籍... -
使用OpenGL在Unity中画一个框
2015-12-30 21:46:44Unity3D使用的图形引擎是DirectX,OpenGL和自带的APi(Wii) 我们这里使用OpenGL的渲染方式 代码: (使用过OpenGl的应该相对容易理解 另外:代码中使用Shader是因为矩形框中部的透明部分需要) using... -
unity发布成手机app怎么不能被顶_实战篇使用Native OpenGL渲染Unity场景
2021-01-23 16:27:1901 前言众所周知,Unity内部集成了OpenGL库,可以在C#脚本中使用GL接口。那为什么还需要Native的方式在渲染呢?原因有如下几点: 1. Unity中提供的GL库开放的功能不是太多,远远不能满足开发者的需要。 2. GL库是... -
从opengl 测试到unity alphatest
2018-03-25 14:44:38OpenGL Test Opengl中测试共分为几个阶段 裁剪 apha 测试 模板测试 和深度测试,OpenGL可以为像素保存颜色、深度值和模板值,利用混合实现透明时,像素颜色不发生变化,但深度值则会可能变化,模板值受... -
Unity中简单使用Opengl
2019-09-29 20:39:30由于项目特殊需求,需要在unity中使用一些OpenGL的东西来绘制图形(PS:其实就是有一个拖尾算法只有OpenGL版本~~~懒得改了,直接在unity中使用OpenGL算了)。所以琢磨咯下如何在unity中使用OpenGL,刚找到点入门级的... -
Unity3D调用Native OpenGL渲染方式
2015-11-03 11:12:27Unity3D调用Native OpenGL,Unity3D支持调用C++工程的OpenGL渲染,使用RenderingPlugin DLL方式。 -
Unity crashes with force-opengl
2021-01-02 10:11:44<p>When running Unity with wine with the "-force-opengl" argument, Unity crashes. Sometimes the window border is shown, displaying the title with "" on the end, followed soon by the ... -
Unity3D 实操OpenGL函数
2017-06-01 18:12:51今天让大家学习一下Unity3d里面的OpenGL 自带的API ,我们可以通过简单的使用OpenGL来在场景中利用相机渲染绘制图形。官方学习文档:https://docs.unity3d.com/ScriptReference/GL.html 1.第一步:通过相关官方的... -
unity3d opengl d3d显示demo
2013-12-07 09:57:38利用unity3d的plugin实现在unity3d中用opengl、D3d绘制三维几何形体。 该资源同时展示了unity3d的plugin技术,与opengl和d3d的接口等