opengl在不用shader的情况下怎么实现glsl 高斯模糊 shader

温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
算了,还是留几个字吧。
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
SubShader {&&& Pass {&&&&&&& ZTest Always Cull Off ZWrite Off&&&&&&& Fog { Mode off }&&& CGPROGRAM&&& #pragma vertex vert&&& #pragma fragment frag&&& #pragma fragmentoption ARB_precision_hint_fastest &&& #include "UnityCG.cginc"&&& &&& uniform sampler2D _MainT&&& sampler2D _CameraDepthNormalsT&&& uniform float4 _MainTex_TexelS&&& &&&& &&& struct v2f {&&&&&&& float4 pos : POSITION;&&&&&&& float2 uv[2] : TEXCOORD0;&&& };&&& &&& v2f vert( appdata_img v )&&& {&&&&&&& v2&&&&&&& o.pos = mul (UNITY_MATRIX_MVP, v.vertex);&&&&&&& float2 uv = MultiplyUV( UNITY_MATRIX_TEXTURE0, v.texcoord );&&&&&&& o.uv[0] =&&&&&&& &&&&&&&&&& }&&& &&& &&& &&& half4 frag (v2f i) : COLOR&&& {&&&&&&& &&&&&&& float2 uv = i.uv[0];&&&&&&& half4 original = 0;&&&&&&& //original = tex2D(_MainTex, i.uv[0]);&&&&&&& //&&&&&&& float3x3 _smooth_fil = float3x3 (1/16.0 ,2/16.0,1/16.0 ,&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 2/16.0 ,4/16.0,2/16.0 ,&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 1/16.0 ,2/16.0,1/16.0 );&&&&&&& float3x3 _filter_pos_delta_x = float3x3 ( -1 , 0, 1 ,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 0 , 0, 1 ,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 1 , 0, 1 );&&&&&&& float3x3 _filter_pos_delta_y = float3x3 ( -1 ,-1,-1 ,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& -1 , 0, 0 ,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& -1 , 1, 1 );&&&&&& &&&&&& for(int i = 0 ; i & 3 ; i ++ )&&&&&& {&&&&&&&&&& for(int j = 0 ; j & 3 ; j ++)&&&&&&&&&& {&&&&&&&&&&&&&&&&&& float2 _xy_new = float2(uv.x + _filter_pos_delta_x[j]* _MainTex_TexelSize.x ,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& uv.y + _filter_pos_delta_y[j]*_MainTex_TexelSize.y);&&&&&&&&&&&&&&& original += tex2D(_MainTex, _xy_new)*_smooth_fil[j];&&&&&&&&&&&&&&& &&&&&&&&&& } &&&&&& }&&&&&& &&& }&&& ENDCG&&& }}Fallback off}
阅读(1581)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
loftPermalink:'',
id:'fks_',
blogTitle:'unity3d Shader延迟着色高斯模糊',
blogAbstract:'
关于实现这个高斯模糊我想表达一下心中的纠结。Shader error in \'Hidden/Blur Effect\': Program \'frag\', Temporary register limit of 8 9 registers needed to compile program at line 10这条限制让我很郁闷,我不想在每个ps里面重新定义_smooth_fil 等三个三乘三浮点数组。但因为这条限制,没办法。',
blogTag:'',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:0,
publishTime:8,
permalink:'blog/static/',
commentCount:0,
mainCommentCount:0,
recommendCount:0,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'算了,还是留几个字吧。',
hmcon:'0',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}opengl在不用shader的情况下怎么实现高斯模糊?_opengl吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:4,372贴子:
opengl在不用shader的情况下怎么实现高斯模糊?收藏
如题、不要说把纹理取出来再放回去。
挂机一个月得百万,你还蓝瘦香菇么?
你很有想法 跟我学做菜吧
你可以渲染出图像之后再高斯模糊,那就和OpenGL没啥关系了,OpenCV一个函数的事
楼上的是什么先画出图像,再读取已渲染的图像(桢缓存),清屏(glClear),开启混合,然后一次次渲染
场景渲染到一个 framebuffer中的 texture2d中,然后用 gpu实现,高斯混合
再把图像数据绑定到纹理前,你可以写代码修改每个像素的值。效果的话,就看你的数学能力了。
登录百度帐号推荐应用
为兴趣而生,贴吧更懂你。或2015年9月 VC/MFC大版内专家分月排行榜第二2015年7月 硬件/嵌入开发大版内专家分月排行榜第二2014年5月 VC/MFC大版内专家分月排行榜第二2014年3月 VC/MFC大版内专家分月排行榜第二2013年10月 VB大版内专家分月排行榜第二2013年7月 VB大版内专家分月排行榜第二2012年5月 VB大版内专家分月排行榜第二2012年4月 VB大版内专家分月排行榜第二2012年2月 VB大版内专家分月排行榜第二2011年11月 VB大版内专家分月排行榜第二
2015年11月 VC/MFC大版内专家分月排行榜第三2015年6月 VC/MFC大版内专家分月排行榜第三2015年2月 VC/MFC大版内专家分月排行榜第三2014年1月 VC/MFC大版内专家分月排行榜第三2012年3月 VB大版内专家分月排行榜第三2011年12月 VB大版内专家分月排行榜第三2011年10月 VB大版内专家分月排行榜第三
2015年9月 VC/MFC大版内专家分月排行榜第二2015年7月 硬件/嵌入开发大版内专家分月排行榜第二2014年5月 VC/MFC大版内专家分月排行榜第二2014年3月 VC/MFC大版内专家分月排行榜第二2013年10月 VB大版内专家分月排行榜第二2013年7月 VB大版内专家分月排行榜第二2012年5月 VB大版内专家分月排行榜第二2012年4月 VB大版内专家分月排行榜第二2012年2月 VB大版内专家分月排行榜第二2011年11月 VB大版内专家分月排行榜第二
2015年11月 VC/MFC大版内专家分月排行榜第三2015年6月 VC/MFC大版内专家分月排行榜第三2015年2月 VC/MFC大版内专家分月排行榜第三2014年1月 VC/MFC大版内专家分月排行榜第三2012年3月 VB大版内专家分月排行榜第三2011年12月 VB大版内专家分月排行榜第三2011年10月 VB大版内专家分月排行榜第三
2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。20126人阅读
Unity3D(19)
游戏(43)
转发请保持地址:
这篇文章主要分析一个Shader,从而感受shader的魅力,并学习相关shader的函数的用法。
先看Shader运行的效果:
下面是代码:
Shader &shadertoy/Waves& {
//see /view/4dsGzH
#include &UnityCG.cginc&
#pragma target 3.0
struct vertOut {
float4 pos:SV_POSITION;
float4 srcP
vertOut vert(appdata_base v) {
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.srcPos = ComputeScreenPos(o.pos);
fixed4 frag(vertOut i) : COLOR0 {
fixed3 COLOR1 = fixed3(0.0,0.0,0.3);
fixed3 COLOR2 = fixed3(0.5,0.0,0.0);
float BLOCK_WIDTH = 0.03;
float2 uv = (i.srcPos.xy/i.srcPos.w);
// To create the BG pattern
fixed3 final_color = fixed3(1.0);
fixed3 bg_color = fixed3(0.0);
fixed3 wave_color = fixed3(0.0);
float c1 = fmod(uv.x, 2.0* BLOCK_WIDTH);
c1 = step(BLOCK_WIDTH, c1);
float c2 = fmod(uv.y, 2.0* BLOCK_WIDTH);
c2 = step(BLOCK_WIDTH, c2);
bg_color = lerp(uv.x * COLOR1, uv.y * COLOR2, c1*c2);
// TO create the waves
float wave_width = 0.01;
uv = -1.0 + 2.0*
uv.y += 0.1;
for(float i=0.0; i&10.0; i++) {
uv.y += (0.07 * sin(uv.x + i/7.0 +
_Time.y));
wave_width = abs(1.0 / (150.0 * uv.y));
wave_color += fixed3(wave_width * 1.9, wave_width, wave_width * 1.5);
final_color = bg_color + wave_
return fixed4(final_color, 1.0);
SubShader {
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
FallBack Off
下面进行分析:
1.&ComputeScreenPos的解析:
用于把三维的坐标转化为屏幕上的点。有两种方式,请参考
ComputeScreenPos在UnityCG.cginc文件中定义如下:
// Projected screen position helpers
#define V2F_SCREEN_TYPE float4
inline float4 ComputeScreenPos (float4 pos) {
float4 o = pos * 0.5f;
#if defined(UNITY_HALF_TEXEL_OFFSET)
o.xy = float2(o.x, o.y*_ProjectionParams.x) + o.w * _ScreenParams.
o.xy = float2(o.x, o.y*_ProjectionParams.x) + o.w;
#if defined(SHADER_API_FLASH)
o.xy *= unity_NPOTScale.
o.zw = pos.
}原理解析(待续)
2. 背景的绘制
2.1) 用于求余数,比如fmod(1.5, 1.0) 返回0.5;
2.2) step用于大小的比较,step(a,x) : &0 if x&a; 1 if x&=a; 比如: step(1, 1.2), 返回1; step(1, 0.8) 返回0;
2.3) 结合fmod和step可以得到一个虚线的效果。 比如要得到虚线段长度为1的代码如下:
c1 = fmod(x, 2*width); c1=step(width,c1); //其中width为1
那么如果x的范围是[0,1),c1的值为0;范围为[1,2),c1的值为1;2为一个周期;
那么fmod起到了制作周期的作用,step计算周期内的0和1;
2.4)把2.3中的知识运用到2维,就可以计算出方块。
lerp函数的用法:lerp(&a&,&b&,f&),
f为百分数(取值范围[0,1]);如果f为0,则lerp返回a,f为1,则返回b。f为0到1之间,就返回a到b之间的值。
lerp(uv.x&*&COLOR1,&uv.y&*&COLOR2,&c1*c2); 其中c1和c2的取值不是为1,就是为0,所以就可以变成网格的情况。 背景绘制如下:
3. 波纹的绘制
3.1 ) 坐标的转化
uv = -1.0 + 2.0* &// 把原始的uv进行扩展和位移,得到新的uv。我们的操作就是在新的uv上进行的,最终显示时会映射到原来到uv,请参考下图
3.2 ) &画一条直线:
由于上面把y轴移动到屏幕的中心,所以屏幕的上半部分为正的,下半部分为负的,代码如下:
wave_width = abs(1.0 / (50.0 * uv.y));
wave_color = fixed3(wave_width * 1.9, wave_width, wave_width * 1.5);其中50.0是用来控制线的宽度的(数值越大,线越细),效果如下:
3.3)把直线变为曲线,并使其动起来:
uv.y += (0.07 * sin(uv.x*10 + _Time.y));
wave_width = abs(1.0 / (50.0 * uv.y));
wave_color = fixed3(wave_width * 1.9, wave_width, wave_width * 1.5);效果如下:
3.4)多画几条曲线,形成波浪:
for(float i=0.0; i&10.0; i++) {
uv.y += (0.07 * sin(uv.x + i/7.0 +
_Time.y));
wave_width = abs(1.0 / (150.0 * uv.y));
wave_color += fixed3(wave_width * 1.9, wave_width, wave_width * 1.5);
}最终效果请见文章开头。
其实写shader,很多时候都是要通过不断地效果叠加并调试来达到效果。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:372282次
积分:4454
积分:4454
排名:第5065名
原创:87篇
评论:194条
(2)(1)(2)(1)(1)(1)(2)(3)(1)(1)(1)(2)(3)(1)(1)(2)(1)(2)(2)(2)(2)(2)(9)(4)(9)(2)(2)(7)(4)(3)(7)(1)(1)(1)(1)(1)7438人阅读
Unity3D(19)
游戏(43)
转发请保持地址:
研究了一个雪花飘落效果,感觉挺不错的,分享给大家,效果如下:
代码如下:
Shader &shadertoy/Flakes& {
// /view/4d2Xzc
Properties{
iMouse (&Mouse Pos&, Vector) = (100,100,0,0)
iChannel0(&iChannel0&, 2D) = &white& {}
iChannelResolution0 (&iChannelResolution0&, Vector) = (100,100,0,0)
#include &UnityCG.cginc&
#pragma target 3.0
#pragma glsl
#define vec2 float2
#define vec3 float3
#define vec4 float4
#define mat2 float2x2
#define iGlobalTime _Time.y
#define mod fmod
#define mix lerp
#define atan atan2
#define fract frac
#define texture2D tex2D
// 屏幕的尺寸
#define iResolution _ScreenParams
// 屏幕中的坐标,以pixel为单位
#define gl_FragCoord ((_iParam.srcPos.xy/_iParam.srcPos.w)*_ScreenParams.xy)
#define PI2 6.
#define pi 3.79
#define halfpi (pi * 0.5)
#define oneoverpi (1.0 / pi)
sampler2D iChannel0;
fixed4 iChannelResolution0;
struct v2f {
float4 pos : SV_POSITION;
float4 srcPos : TEXCOORD0;
v2f vert(appdata_base v){
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.srcPos = ComputeScreenPos(o.pos);
vec4 main(v2f _iParam);
fixed4 frag(v2f _iParam) : COLOR0 {
return main(_iParam);
vec4 main(v2f _iParam) {
vec2 p = gl_FragCoord.xy/iResolution.
col = vec3(0,0,0);
float dd = 150;
for( int i=0; i& i++ )
float an = 6.2831*float(i)/
of = vec2( cos(an), sin(an) ) * (1.0+0.6*cos(7.0*an+iGlobalTime)) + vec2( 0.0, iGlobalTime );
col = max( col, texture2D( iChannel0, p + 20*of/iResolution.xy ).xyz );
col = max( col, texture2D( iChannel0, p +
5.0*of/iResolution.xy ).xyz );
col = pow( col, vec3(1.0,2.0,3.0) ) * pow( 4.0*p.y*(1.0-p.y), 0.2);
return vec4( col, 1.0 );
SubShader {
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
FallBack Off
代码分析:
1)七边形雪花的绘制算法
具体代码如下:
float dd = 150;
for( int i=0; i& i++ )
float an = 6.2831*float(i)/
of = vec2( cos(an), sin(an) ) * (1.0+0.6*cos(7.0*an+iGlobalTime)) + vec2( 0.0, iGlobalTime );
col = max( col, texture2D( iChannel0, p + 20*of/iResolution.xy ).xyz );
col = max( col, texture2D( iChannel0, p +
5.0*of/iResolution.xy ).xyz );
}在理解这段代码前,先理解怎么画一个圈,代码如下:
float dd = 30;
for( int i=0; i& i++ )
float an = 6.2831*float(i)/
of = vec2( cos(an), sin(an) );
col = max( col, texture2D( iChannel0, p + 20*of/iResolution.xy ).xyz );
}然后再准备一张贴图,图片中间是一个白色像素,周围都是黑色
效果如下:
这段代码处于fragment shader中,意味着屏幕上每个点都会进行上述的算法。具体如下,遍历贴图中该点周围的点(上面的代码中为距离该点为20单位的圆上的点),把周围点中最亮的作为该点的颜色。 上面的贴图有点特殊,只有一个点是白色,其余点都是黑色的。那么只有距离该点正好为20单位的点才会变成亮色,其余的点都是黑色,如上图的结果。一句话总结上面算法的效果:贴图中的每一个“相对亮点”的周围都会产生“相对亮的特定图形”,图形的亮度取决于该点的亮度,越亮越明显。效果可以参考文末的图片。
接下来理解这段代码:
float dd = 150;
for( int i=0; i& i++ )
float an = 6.2831*float(i)/
of = vec2( cos(an), sin(an) ) * (1.0+0.7*cos(7.0*an));
col = max( col, texture2D( iChannel0, p + 20*of/iResolution.xy ).xyz );
// col = max( col, texture2D( iChannel0, p +
5.0*of/iResolution.xy ).xyz );
}输出结果如下:
a) &1.0+0.7*cos(7.0*an)的图像如下:
b)算法中 of 向量的路径为:
结果就很清晰了;其实这里算法和中绘制心形的算法很类似。
最后加上时间就可以实现动画了:
of = vec2( cos(an), sin(an) ) * (1.0+0.6*cos(7.0*an+iGlobalTime)) + vec2( 0.0, iGlobalTime );第一个iGlobalTime,用来控制雪花的旋转,第二个iGlobalTime使雪花下落。
2)后期颜色等处理
这里可以理解为一种postEffect处理,具体是如下的代码贡献的效果:
col = pow( col, vec3(1.0,2.0,3.0) ) * pow( 4.0*p.y*(1.0-p.y), 0.2);
a) &pow(col, vec3(1.0, 2.0, 3.0)) 这句话使得颜色变成暖色调。col值的范围为[0,1],对小数继续pow运算,次数越高,该值越小。比如:0.5的1次方是0.5, 2次方为0.25, 3次方为0.125等;所以这句话的作用很明显:red成份不变,green变小一些,blue变的更小。达到的效果,使得整体颜色会偏向暖色调。
b)pow(4.0*p.y*(1.0-p.y), 0.2) 使得屏幕上下两边变暗。
最后附上shader中用到的贴图:
经过程序处理后,得到如下:
文章完毕,欢迎讨论。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:372284次
积分:4454
积分:4454
排名:第5065名
原创:87篇
评论:194条
(2)(1)(2)(1)(1)(1)(2)(3)(1)(1)(1)(2)(3)(1)(1)(2)(1)(2)(2)(2)(2)(2)(9)(4)(9)(2)(2)(7)(4)(3)(7)(1)(1)(1)(1)(1)

我要回帖

更多关于 opengl es 高斯模糊 的文章

 

随机推荐