技术标签: OpenGL
2015.09.06 18:06 字数 2901 阅读 4301评论 2喜欢 25
Shader出现在OpenGL ES 2.0中,允许创建自己的Shader。必须同时创建两个Shader,分别是Vertex shader和Fragment shader.
Shader会有很多坑,不过一些工具能够帮助你跳过这些坑
attribute vec4 position;
attribute vec4 inputTextureCoordinate;
varying vec2 textureCoordinate;
void main()
{
gl_position = position;
textureCoordinate = inputTextureCoordinate.xy;
}
直通滤镜
varying highp vec2 textureCoordinate; //highp属性负责变量精度,这个被加入可以提高效率
uniform sampler2D inputImageTexture; //接收一个图片的引用,当做2D的纹理,这个数据类型就是smpler2D。
void main()
{
gl_FragColor = texture2D(inputImageTexture, textureCoordinate); //texture是GLSL(着色语言)特有的方法
}
三个可以赋值给我们的变量的标签
有很多种向量,但是有三种会经常看到
是浮点数组的数组。三个经常处理的矩阵对象
线性代数发挥作用的地方。想知道线性代数如何工作可以看这个资源站:http://betterexplained.com/articles/linear-algebra-guide/
线性代数可以一次在很多值上进行并行操作,so,正好适合需求,GLSL内建了很多函数可以处理庞大的计算转换
GLSL内建的函数可以在Shaderific网站上找到:http://www.shaderific.com/glsl-functions。很多C语言数学库基本数学运算都有对应的函数。
一个饱和度调节的Fragment shader的例子,出自《图形着色器:理论和实践》这本书。
varying highp vec2 textureCoordinate; //
uniform sampler2D inputImageTexture;
uniform lowp float saturation;
const mediump vec3 luminanceWeighting = vec3(0.2125, 0.7154, 0.0721); //光亮度里三个值相加要为1,各个值代表着颜色的百分比,中间是绿色的值,70%的比重会让效果更好点。
void main()
{
lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); //根据坐标取样图片颜色信息
lowp float luminance = dot(textureColor.rgb, luminanceWeighting); //GLSL中的点乘运算,线性代数的点运算符相乘两个数字。点乘计算需要将纹理颜色信息和相对应的亮度权重相乘。然后取出所有的三个值相加到一起计算得到这个像素的中和亮度值。
lowp vec3 greyScaleColor = vec3(luminance); //创建一个三个值都是亮度信息的vec3,如果只指定一个值,编译器会将其它的都设置成这个值
gl_FragColor = vec4(mix(greyScaleColor, textureColor.rgb, saturation), textureColor.w); //用mix函数把计算的灰度值,初识的纹理颜色和得到的饱和度信息结合起来。
}
varying highp vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
uniform highp vec2 center;
uniform highp float radius;
uniform highp float aspectRatio;
uniform highp float refractiveIndex;
void main()
{
highp vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio)); //归一化坐标空间需要考虑屏幕是一个单位宽和一个单位长。
highp float distanceFromCenter = distance(center, textureCoordinateToUse); //计算特定像素点距离球形的中心有多远。使用GLSL内建的distance()函数,用勾股定律计算出中心坐标和长宽比矫正过的纹理坐标的距离
lowp float checkForPresenceWithinSphere = step(distanceFromCenter, radius); //计算片段是否在球体内。
distanceFromCenter = distanceFromCenter / radius; //标准化到球心的距离,重新设置distanceFromCenter
highp float normalizedDepth = radius * sqrt(1.0 - distanceFromCenter * distanceFromCenter); //模拟一个玻璃球,需要计算球的“深度”是多少。
highp vec3 sphereNormal = normalize(vec3(textureCoordinateToUse - center, normalizedDepth)); //归一化
highp vec3 refractedVector = refract(vec3(0.0, 0.0, -1.0), sphereNormal, refractiveIndex); //GLSL的refract()函数以刚才创建的球法线和折射率来计算当光线通过球时从任意一个点看起来如何。
gl_FragColor = texture2D(inputImageTexture, (refractedVector.xy + 1.0) * 0.5) * checkForPresenceWithinSphere; //最后凑齐所有计算需要的颜色信息。
}
使用gl_FragColor调试代码。GPUImage是个开源的资源有些很酷的shader,非常好的学习shader的方式,可以拿一个你觉得很有意思的shader对着源码一点点看下去。GPUImage还有一个shader设计器https://github.com/BradLarson/GPUImage/tree/master/examples/Mac/ShaderDesigner的Mac应用,可以测试shader而不用准备OpenGL代码。
简单的方法达到调优目的,可以用下载Imagination Technologies PowerVR SDKhttp://community.imgtec.com/developers/powervr/这个工具帮助分析shader
基于OpenCV库,不过这些步骤在GPUImage中都有完整的实现
这种操作在滤镜方面比机器视觉方面多。Sobel边界探测用于探测边界的出现位置,边界是由明变暗或者由暗变明的区域。在被处理的图片中一个像素的亮度反映了这个像素周围边界的强度。
-1 0 +1
-2 0 +2
-1 0 +1
-1 -2 -1
0 0 0
+1 +2 +1
precision mediump float;
//varying的都是在Vertex shader上定义了
varying vec2 textureCoordinate;
varying vec2 leftTextureCoordinate;
varying vec2 rightTextureCoordinate;
varying vec2 topTextureCoordinate;
varying vec2 topLeftTextureCoordinate;
varying vec2 topRightTextureCoordinate;
varying vec2 bottomTextureCoordinate;
varying vec2 bottomLeftTextureCoordinate;
varying vec2 bottomRightTextureCoordinate;
uniform sampler2D inputImageTexture;
void main()
{
float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r;
float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r;
float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r;
float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r;
float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r;
float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r;
float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r;
float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r;
float h = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity;
float v = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity;
float mag = length(vec2(h, v)); //length()函数计算出水平和垂直矩阵转化后值的平方和的平方根的值,这个值会被拷贝进输出像素的红绿蓝通道中,这样就可以来代表边界的明显程度了。
gl_FragColor = vec4(vec3(mag), 1.0);
}
Canny探测会比Sobel复杂些,这样做会得到一条物体边界的干净线条。
探测过程:
vec2 gradientDirection;
gradientDirection.x = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity;
gradientDirection.y = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity;
float gradientMagnitude = length(gradientDirection);
vec2 normalizedDirection = normalize(gradientDirection);
normalizedDirection = sign(normalizedDirection) * floor(abs(normalizedDirection) + 0.617316); // Offset by 1-sin(pi/8) to set to 0 if near axis, 1 if away
normalizedDirection = (normalizedDirection + 1.0) * 0.5; // Place -1.0 - 1.0 within 0 - 1.0
gl_FragColor = vec4(gradientMagnitude, normalizedDirection.x, normalizedDirection.y, 1.0);
precision mediump float;
varying highp vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
uniform highp float texelWidth; //要处理的图片中临近像素之间的距离。
uniform highp float texelHeight; //同上
uniform mediump float upperThreshold; //预期边界强度上下限
uniform mediump float lowerThreshold;
void main()
{
vec3 currentGradientAndDirection = texture2D(inputImageTexture, textureCoordinate).rgb;
vec2 gradientDirection = ((currentGradientAndDirection.gb * 2.0) - 1.0) * vec2(texelWidth, texelHeight);
float firstSampledGradientMagnitude = texture2D(inputImageTexture, textureCoordinate + gradientDirection).r;
float secondSampledGradientMagnitude = texture2D(inputImageTexture, textureCoordinate - gradientDirection).r;
float multiplier = step(firstSampledGradientMagnitude, currentGradientAndDirection.r);
multiplier = multiplier * step(secondSampledGradientMagnitude, currentGradientAndDirection.r);
float thresholdCompliance = smoothstep(lowerThreshold, upperThreshold, currentGradientAndDirection.r);
multiplier = multiplier * thresholdCompliance;
gl_FragColor = vec4(multiplier, multiplier, multiplier, 1.0);
}
多步骤的方法来探测场景中的边角。
R = Ix2 × Iy2 − Ixy × Ixy − k × (Ix2 + Iy2)2
Taily老段的微信公众号,欢迎交流学习
https://blog.csdn.net/taily_duan/article/details/81214815
文章浏览阅读307次。ASP.NET MVC 是一个全新的Web应用框架ASP.NET 代表支撑应用框架的技术平台,表明ASP.NET MVC和传统的WebForm应用框架一样,都是建立在ASP.NET平台之上。MVC 表示该框架背后的设计思想,意味着ASP.NET MVC采用了MVC架构模式。MVC在20世纪70年代后期出现,产生于Xerox PARC施乐公司的帕洛阿尔托研究中心的Small..._aspnet mvvm
文章浏览阅读350次。解压压缩包后,打开终端,进入当前chromedriver所在的路径,将chromedriver移动到默认路径(/usr/local/bin/)二、下载对应版本的浏览器驱动器:找到版本一致或最接近的版本的驱动器。若列表中含有selenium则表明安装成功。记得勾选上继承全局包,要不然会报错。_m1 mac selenium配置
文章浏览阅读4.6k次。谨以此片献给各种遇到坑的朋友。官网上的OpenCV 插件,根据github 上的描述 是针对UE4 4.16 版本以下的版本来提供的 OpenCV 采用的是3.0.0 , 也可以使用openCv 3.2.0环境描述:Ue4 4.15 OpenCV 3.2.0固有插件配置步骤:1, 创建一个C++ 的工程,打开后, 关闭即可。2,将OpenCV 的插件文件 解压缩之后, 将里面的文件..._ue4 opencv操作texture
文章浏览阅读1w次,点赞3次,收藏11次。直接在cmd命令行输入:conda install --channel https://conda.anaconda.org/menpo opencv3 接着根据提示按Y即可
文章浏览阅读646次。#include#includestruct mubang{int x;int y;}a[5005];int cmp(const void *a,const void *b){struct mubang *c=(struct mubang *)a;struct mubang *d=(struct mubang *)b;if(c->x!=d->x)re_nyoj 心急的c小加
文章浏览阅读1.7k次。学习JavaEE的你们是不是一头雾水呢? C/S client/server 客户端/服务器 B/C browser/server 浏览器/服务器 通过浏览器访问到对应页面,发送请求(同步请求,异步请求,ajax请求,会读接口文档)---服务器(云服务器:腾讯云服务器 阿里云服务器等等)---应用服务器Tomcat---匹配servlet---service业务处理---dao层 JDBC Hibemate,ORM---数据库---File---servlet(控制器Controller)MVC_javaee基础知识
文章浏览阅读910次,点赞28次,收藏19次。交互性检索是在检索用户不能构建良好的检索式(关键词)的情况下,通过与检索平台交流互动并不断修改检索式,从而获得较准确检索结果的过程。新闻推荐需要:获取用户请求,召回候选新闻,对候选新闻进行排序,最终给用户推出新闻。将用户持续浏览新闻的推荐过程看成一个决策过程,通过强化学习学习每一次推荐的最佳策略,提高用户的点击率。无人驾驶被认为是强化学习短期内能技术落地的一个应用方向,很多公司投入大量资源在无人驾驶上,其中百度的无人巴士“阿波龙”已经在北京、武汉等地展开试运营,自动无人驾驶的行车视野如下图所示。
文章浏览阅读3.5w次,点赞102次,收藏685次。简历是什么找工作之前投递的个人信息和工作能力----不全面应该是:个人当前阶段的价值体现前者:我能卖多少钱;后者:我现在值多少钱建议:每隔半年/一年给自己做总结的时候写一份简历(相当于个人价值总结)面试要刻意、精心准备公司内部晋升答辩,需要精心准备(ppt、演讲基本要精心准备一个月的时间)面试,简历,同样需要精心准备目录面试官如何分析一份简历简历模板和内容个人信息教育经历专业技能工作经历项目经历体现自己的亮点课程总结注意:不要造假学历造假:学信网可查工作经历造假:可_前端简历
文章浏览阅读2.6k次。https://www.dwhd.org/20160724_085212.html_有gcc高版本的yum库
文章浏览阅读320次。1起步依赖原理分析 1.1分析spring-boot-starter-parent 按住Ctrl点击pom.xml中的spring-boot-starter-parent,跳转到了spring-boot-starter-parent的pom.xml,xml配置如下(只摘抄了部分重点配置):<parent> <groupId>org.sp..._springboot 自动配置分析与整合测试
文章浏览阅读9.1k次。最近想要使用Crypto.Cipher 的AES模块,可总是找不到Crypto.Cipher接下来介绍几个坑1.AES是在pyCrypto中而不是crypto中2.这个pyCrypto中间的C一定要大写,不然也不能用接下来介绍正确的安装姿势1.首先需要现在一款编译器Microsoft Visual C++ Compiler for Python 2.7下载地址https://www.m..._python2.7 使用pycrypto
文章浏览阅读2.9k次,点赞4次,收藏7次。递归算法:将正整数n表示成一系列正整数之和,n=n1+n2+...+nk,其中n1>=n2>=n3>=...>=nk>=1,k>=1。正整数n的这种表示称为正整数n的划分。正整数n的不同的划分个数城外正整数n的划分数,记作p(n)。例如,正整数6有如下11种不同的划分,所以p(6)=11。6;5+1;4+2;4+1+1;3+3;3+2+1;3+1+1+1;2+2+2_n的划分种数,其中划分大于等于2非递归算法