




免费预览已结束,剩余1页可下载查看
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Cocos3.8 Tutorial RenderTexture + BlurThis tutorial will help you to understand how you can use shaders and render textures in cocos2d-x 3.0 and will give you some insights in the underlying math. In one of my projects I faced a necessity to make a blurred version of some background landscape, which composition depends on the screen size, that is clouds are sticked to the top of the screen and ground is sticked to the bottom, so its not an option to just put a blurred image in the resource folder. The landscape must be composed, drawn in a RenderTexture, then drawn again with blurring shader, saved to disk and used in consequent launches. The image can be pretty big and the blur radius can be pretty big as well, so we need something fast.This tutorial can be divided into following steps:1. Diving into math and calculating gaussian weights2. Creating blur shader3. Rendering texture and saving it to file4. Using TextureBlur in a sample programLets start. To blur a pixel we just need to calculate a weighted sum of the surrounding pixels, where weights themselves sum up to 1. Another property that would be nice to have is that central weights must be heavier than the side ones. Why Gaussian function is usually picked for making blur effect? Because it has three nice features:1. Its integral equals 12. Its maximum value is in the symmetry point3. It has the following feature:Tow-dimensional Gaussian function can be split into a product of two one-dimensional functions. What it will give us? To calculate the color of the blurred pixel with coordinate (i, j) in a straightforward manner we need to sum up all the pixels in range (i-R, i+R)x(j-R, j+R), where R is a blur radius. This results in a nested loop and nested loop means O(n*n) complexity and we really do not want such a thing in a shader. Keeping in mind the 3rd feature of the Gaussian distribution we can split the nested loop in two consequent loops. At first we will do a horizontal blur and then - vertical, thus having O(n) complexity. The magic is that the final result of such simplification wont differ from the one obtained with slow nested loop.Lets calculate an integral of Gaussian function with sigma = 1/3 and mu = 0 from x = -1 to 1. That will give us 0.9973, almost 1. Lets now use a common technique for numerical integration: we are going to draw 2*R-1 points from -1 to 1, calculate Gaussian function in them, multiple obtained values by 1/(R-1) and sum everything up.The nice fact is that that sum will equal to something near 1 and the precision will grow together with R. The only problem left to solve is that we want coefficients to sum up exactly to 1, otherwise the blurred image will have some problems with opacity (totally opaque images will become a little bit transparent). This can be guaranteed by calculating the central coefficient as 1 - sum of all the others. So, to the codes. The idea is to pre-calculate gaussian coefficients on start, pass them to the shader and do no math other than multiplication inside. Besides the standard v_fragmentColor and v_texCoord we have four additional parameters:1. pixelSize - in GLSL there are no pixels, only decimals, for instance 0 denotes the left or the lower border of the texture and 1 - the right or the upper border. This means we have to know the decimal step to make to the next pixel.2. radius - our blur radius3. weights - array of precalculated gaussian weights4. direction - 2d vector denoting horizontal or vertical blurThe word uniform in front of these values mean that they are not going to change during the run. The rest of the shader body is pretty straightforward: take a pixel, accumulate surrounding pixels with some coefficients and voila. I had to hardcode maximum array size to be 64 as I found no way to use a dynamic array as a uniform in shader.Everything is pretty much self-explanatory here. We create a new GLProgram using the standard vertex shader and our blur shader, pass additional parameters using GLProgramState class and everything is ready to go. One may encounter another way of assigning the shader body to GLchar* variable, something like this:I prefer using String:createWithContentsOfFile because it frees you from necessity to write n at the end of every line which is quite annoying.The only thing left to do is actually blurring a texture. Our strategy here will be as follows:1. Create a sprite from the texture passed as a parameter2. Draw it to a RenderTexture with horizontal blur shader3. Create a sprite from resulting texture4. Draw this sprite to a Render texture with vertical shader5. Save image to file6. Wait until saving is done, clean up and notify the caller Now, to the main method. We need the following things to be passed as arguments: texture to blur, blur radius, resulting picture file name, a callback to invoke when everything is done and step as an optional parameter, well get to it in a matter of seconds.Here I used a lambda variable - one of the coolest features of C+11. Recitation of the stepX, stepY etc. means that we want these variables to be captured by their value. That means that when we use these variables in lambda, we actually use their local copies. Another option is to capture variables be reference, but in our case these variables will be destroyed at the moment when the callback will be executed, thus causing undefined behavior. In Cocos2d-x sources you can find & or = designations. They mean, correspondingly, that all variables should be captured by reference or by value. Some of the C+ safety standards recommend to be as explicit as possible when declaring lambda capturing method, which may be different for every variable.Finally, lets get TextureBlur to work! Some sample drawing in paint, a little bit of additional code to HelloWorld scene and here we go. Thats how initial paysage looks like: And here is its blurred version:Cocos3.8 Tutorial 渲染纹理和虚化这个教程将帮助你理解如何使用cocos2d-x 3.0的着色器和渲染纹理并且给你一些关于数学基础的独特见解。在我的其中一项项目中我需要制造一个根据屏幕大小关于背景和地形的模糊版本。云层固定在屏幕上方,地面固定在底部,所以并不能简单的把一个模糊版本的图像放到资源Resource文件夹中。如果你这么做的话地形图片肯定是静态的,要先经过渲染纹理处理后再进行模糊着色处理,并保存到硬盘上在一系列的应用中使用。图像可能会非常大而且模糊范围也可能会非常大,所以我们需要一些能够运行更为快捷迅速的东西。这篇教程能够分解为以下几个步骤:1. 深入数学研究之中并计算高斯权重。2. 创建模糊材质3. 渲染纹理并保存到文件夹中4. 在样本程序中使用纹理模糊我们开始吧。要模糊一个像素我们需要计算附近的像素的权重,权重总和为1。另一个我们需要的属性是中心点权重必须比周边大。为什么高斯函数经常被用来制作模糊效果?因为他有三个非常好的特性。1. 它的整体为12. 它的最大值在对称点上3. 他有着以下特性:二维高斯方程能够拆开成两个一维函数的乘积。这会给我们带来什么样的便利呢?试想,如果我们直接计算出模糊像素的颜色及坐标(I, j)的方法,我们需要把(i-R, i+R)x(j-R, j+R)这个范围内的像素相加起来,R是模糊半径。这将执行一个嵌套循环。嵌套循环意味着他有着n*n的时间复杂度(译者注:算法的时间复杂度,即该算法对n个数据进行处理所需要的时间是哪个数量级。)而这并不是我们所想要加进着色器shader里的结果。记住这个方程的高斯分布的第三个特性,我们能把嵌套循环分裂成两个相关的循环。首先我们处理水平模糊,而后垂直模糊。因此我们在这里就能获得n的时间复杂度。这个方法的神奇之处在于简化后的结果与之前运行较慢的嵌套循环相比没有差别。 我们开始使用参数sigma = 3 和 mu = 0,以及范围从-1到1的x来计算高斯函数的积分。得到结果0.9973,接近于1。现在我们用一个常用的技术来计算数值积分:我们要画出范围-1 x 1上的2*R 1个点,用高斯方程计算它们,得到的结果乘以1/(R - 1)并相加。 好消息是和接近于1,精度也会随着R值增长。唯一的问题是我们需要让和恰好为1的系数,不然模糊图像在透明度上会出些问题(完全不透明的物体会变得有那么一点透明)。通过计算中央系数1减去其他所有的和来确保这个问题的解决。所以,对于代码。方法就是在开始的时候预先计算高斯系数,把他们的数值传到着色器shader上然后只需在里面做乘法即可。 此外,对于标准的v_fragmentColor, v_texCoord and CC_Texture0我们有四个额外的参数:1. pixelSize 在OpenGL着色语言中并没有像素,只有十进制数,比如,0代表着材质边框的左边或右边1代表着右边框或上边框。这意味着我们需要知道十进制数
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025湖南衡阳耒阳市大学生乡村医生招聘9人备考考试题库附答案解析
- 2025福建省海峡人才报社有限责任公司招聘3人备考考试题库附答案解析
- 工厂安全培训活动计划课件
- 2026年度中国工商银行河南省分行校园招聘580人备考考试题库附答案解析
- 2025广东河源市文化广电旅游体育局选调公务员1人备考考试题库附答案解析
- 2025年湖南怀化沅陵县事业单位招聘35人备考练习题库及答案解析
- 养老服务资本可持续性-洞察及研究
- 2025阿拉尔经济技术开发区招聘(13人)考试参考试题及答案解析
- 掌握艺术鉴赏
- 2026中国水利水电第三工程局有限公司招聘(110人)备考考试题库附答案解析
- 医学基础知识试题及参考答案
- 现浇墩台身轴线偏位、全高竖直度检测记录表
- 合肥市企业退休人员领取养老金资格认证表
- 房屋建筑工程实体质量检查评分表
- 民航安全安全检查员
- 学生伤害事故的责任分析和处理案例
- 隧道防排水检查井技术交底书
- 《历史》中职课件05第五章
- TSS-UT811-001UT-811线路保护测控装置调试说明书V1[1]0.
- (终稿)加油站全流程诊断与优化提量指导手册
- EN779-2012一般通风过滤器——过滤性能测定(中文版)
评论
0/150
提交评论