当前位置: 首页 > news >正文

马连洼网站建设谷歌ads

马连洼网站建设,谷歌ads,威海网站制作,建设工程施工合同的当事人包括关于unity shader的StencilBuffer 这几天学了unity shader,不得不说unity shader小小的选择项竟然蕴含了这么多东西,最近看到shaderlab 的stencil buffer真是搞得一头雾水,网上也没有对stencil在untiy 的介绍,有也是很简略的&…

关于unity shader的StencilBuffer

这几天学了unity shader,不得不说unity shader小小的选择项竟然蕴含了这么多东西,最近看到shaderlab 的stencil buffer真是搞得一头雾水,网上也没有对stencil在untiy 的介绍,有也是很简略的,圣典也还没翻译,就官网那几个字,真不知道写那个的人是怎么想的,就写那几个字怎么让人明白那怎么回事。好了,吐槽这么多,下面来说一下自己对stencil的认识,官网链接如下http://docs.unity3d.com/Manual/SL-Stencil.html,重点介绍那几个例子。

语法介绍

stencil buffer,也是一个buffer(废话),长度是8位,主要用于筛选pixel用,stencil buffer其实是zBuffer其中的一部分,stencil的测试与深度测试也是紧密连接,因为还要用到深度测试的结果。
语法

Stencil {

Ref 2
Comp equal
Pass keep 
Fail decrWrap 
ZFail keep
}

下面一条一条来:
Ref referenceValue,这个是设定参考值,stencilbuffer里面的值会与他比较
ReadMask readMask,这个是在比较参考值和buffer值的时候用的,用于读取buffer值里面的值。
WriteMask writeMask,这个是写入buffer值用的。
Comp comparisonFunction,这个比较重要,这个是比较方式。大致有Greater,GEqual,Equal等八种比较方式,具体待会列图。
Pass stencilOperation,这个是当stencil测试和深度测试都通过的时候,进行的stencilOperation操作方法。注意是都通过的时候!
Fail stencilOperation,这个是在stencil测试通过的时候执行的stencilOperation方法。这里只要stencil测试通过就可以了
ZFail stencilOperation,这个是在stencil测试通过,但是深度测试没有通过的时候执行的stencilOperation方法。

一般Comp,Pass,Fail,ZFail只用于正面的渲染,除非有Cull front,这样的语句出现。如果要渲染两面,可以用CompFront,PassFront等和CompBack,PassBack等。意思和上面的一样

比较方式:

Greater大于
GEqual大于等于
Less小于
LEqual小于等于
Equal等于
NotEqual不等于
Always永远通过
Never永远通不过

这个是在接在Comp之后的,结果可以影响Fail 的执行。

stencilOperation(stencil操作)

Keep保持
Zero归零
Replace拿比较的参考值替代原来buffer的值
IncrSat值增加1,但是不溢出,如果是255,就不再加
DecrSat值减少1,不溢出,到0就不再减
Invert翻转所有的位,所以1会变成254
IncrWrap值增加1,会溢出,所以255会变成0
DecrWrap值减少1,会溢出,所以0会变成255

至于官网的延迟光照那段大致意思就是Deffer render里面stencil Function不好用就是了。

下面上代码了,在我看来,官网的这两个例子非常难,也没有什么解释所以很不好理解。

[html] view plaincopy
  1. Shader "Red" {  
  2.     SubShader {  
  3.         Tags { "RenderType"="Opaque" "Queue"="Geometry"}//这里渲染的类型为不透明物体,次序是Geometry。至于Geometry是多少我就不清楚的,求大神科普  
  4.         Pass {  
  5.             Stencil {  
  6.                 Ref 2        //参考值为2,stencilBuffer值默认为0  
  7.                 Comp always            //stencil比较方式是永远通过  
  8.                 Pass replace           //pass的处理是替换,就是拿2替换buffer 的值  
  9.                 ZFail decrWrap<span style="white-space:pre">      </span>//ZFail的处理是溢出型减1  
  10.             }  
  11.         <span style="white-space:pre">                </span>//下面这段就不多说了,主要是stencil和Zbuffer都通过的话就执行。把点渲染成红色。  
  12.             CGPROGRAM  
  13.             #pragma vertex vert  
  14.             #pragma fragment frag  
  15.             struct appdata {  
  16.                 float4 vertex : POSITION;  
  17.             };  
  18.             struct v2f {  
  19.                 float4 pos : SV_POSITION;  
  20.             };  
  21.             v2f vert(appdata v) {  
  22.                 v2f o;  
  23.                 o.pos = mul(UNITY_MATRIX_MVP, v.vertex);  
  24.                 return o;  
  25.             }  
  26.             half4 frag(v2f i) : SV_Target {  
  27.                 return half4(1,0,0,1);  
  28.             }  
  29.             ENDCG  
  30.         }  
  31.     }   
  32. }  



结果就像这样,至于为什么要用平面来切,待会解释。好,现在在平面以上的点,stencilbuffer值全为2,因为都被replace了。在平面下面的点,通过了stencil测试但是没有通过深度测试,stencil值减一全为255。

下面是第二段。

[html] view plaincopy
  1. Shader "Green" {  
  2.     SubShader {  
  3.         Tags { "RenderType"="Opaque" "Queue"="Geometry+1"}<span style="white-space:pre">  </span>//渲染次序为Geometry+1,在红球之后  
  4.         Pass {  
  5.             Stencil {  
  6.                 Ref 2<span style="white-space:pre">           </span>//参考值为2  
  7.                 Comp equal<span style="white-space:pre">      </span>//stencil比较方式是相同,这回不是都通过了  
  8.                 Pass keep <span style="white-space:pre">      </span>//stencil和Zbuffer都测试通过时,选择保持  
  9.                 Fail decrWrap <span style="white-space:pre">      </span>//stencil没通过,选择溢出型减1,所以被平面挡住的那层stencil值就变成254  
  10.                 ZFail keep<span style="white-space:pre">      </span>//<span style="font-family: Arial, Helvetica, sans-serif;">stencil通过,深度测试没通过时,选择保持</span>  
  11.             }  
  12.           
  13.             CGPROGRAM  
  14.             #pragma vertex vert  
  15.             #pragma fragment frag  
  16.             struct appdata {  
  17.                 float4 vertex : POSITION;  
  18.             };  
  19.             struct v2f {  
  20.                 float4 pos : SV_POSITION;  
  21.             };  
  22.             v2f vert(appdata v) {  
  23.                 v2f o;  
  24.                 o.pos = mul(UNITY_MATRIX_MVP, v.vertex);  
  25.                 return o;  
  26.             }  
  27.             half4 frag(v2f i) : SV_Target {  
  28.                 return half4(0,1,0,1);  
  29.             }  
  30.             ENDCG  
  31.         }  
  32.     }   
  33. }  

那个网格线就是附着了第二个shader的球体。神奇的地方来了,这个球体本身是没有颜色的,因为stencil为0的话不可能等于2的。在红球和这个球交汇处变成了绿色,注意,这个绿色不是红球的,而是“绿球的”。有一个隐藏的部分是底下被遮住部分,如果“绿球”有挡住红球部分,则stencil会变为254。这个对于下面这个shader非常重要。
[html] view plaincopy
  1. Shader "Blue" {  
  2.     SubShader {  
  3.         Tags { "RenderType"="Opaque" "Queue"="Geometry+2"}<span style="white-space:pre">      </span>//渲染次序为Geometry+2,在前面两个shader之后  
  4.         Pass {  
  5.             Stencil {  
  6.                 Ref 254<span style="white-space:pre">         </span>//参考值为254  
  7.                 Comp equal<span style="white-space:pre">      </span>//比较方式是是否相等  
  8.             }  
  9.           
  10.             CGPROGRAM  
  11.             #pragma vertex vert  
  12.             #pragma fragment frag  
  13.             struct appdata {  
  14.                 float4 vertex : POSITION;  
  15.             };  
  16.             struct v2f {  
  17.                 float4 pos : SV_POSITION;  
  18.             };  
  19.             v2f vert(appdata v) {  
  20.                 v2f o;  
  21.                 o.pos = mul(UNITY_MATRIX_MVP, v.vertex);  
  22.                 return o;  
  23.             }  
  24.             half4 frag(v2f i) : SV_Target {  
  25.                 return half4(0,0,1,1);  
  26.             }  
  27.             ENDCG  
  28.         }  
  29.     }  
  30. }  

好,底下那个部分很神奇吧!先解释一下,底下那个蓝色部分,是红球通过“绿球部分”再转到“蓝球”部分的,红球深度测试失败,stencil减1,再通过“绿球”stencil测试失败,stencil再减1,到这个蓝色上就符合了同样是这个蓝色块是在“蓝球”表面的。但是有个问题是红球的内表面也映到了了蓝球的上面,这个我不清楚,请高手解答

下面介绍另一组官网的shader

[html] view plaincopy
  1. Shader "HolePrepare" {  
  2.     SubShader {  
  3.         Tags { "RenderType"="Opaque" "Queue"="Geometry+1"}<span style="white-space:pre">      </span>//渲染次序为<span style="font-family: Arial, Helvetica, sans-serif;">Geometry+1</span>  
  4.   
  5.         ColorMask 0<span style="white-space:pre">     </span>//开始玩花样了,这个球不渲染任何的颜色  
  6.         ZWrite off<span style="white-space:pre">      </span>//关闭深度写,代表这个球是透明的  
  7.         Stencil {  
  8.             Ref 1<span style="white-space:pre">       </span>//参考值是1  
  9.             Comp always<span style="white-space:pre">     </span>//比较方式是永远通过  
  10.             Pass replace<span style="white-space:pre">    </span>//Pass选择stencil操作是替代  
  11.         }  
[html] view plaincopy
  1.    
[html] view plaincopy
  1. <span style="font-family: Arial, Helvetica, sans-serif;"><span style="white-space:pre">     </span>//下面是两个通道。第一个通道渲染背面(我觉得说内侧更合适),第二个通道渲染正面,但是这个比较难理解的是在深度测试成功时你看到了背面,失败时看到了正面,这就相当于,你看一个不透明的杯子,你直接看到了内表面,你用手遮住这个杯子再看,你就看到了外表面。</span>  
[html] view plaincopy
  1. <span style="white-space: pre;">  </span>CGINCLUDE  
[html] view plaincopy
  1.             struct appdata {  
  2.                 float4 vertex : POSITION;  
  3.             };  
  4.             struct v2f {  
  5.                 float4 pos : SV_POSITION;  
  6.             };  
  7.             v2f vert(appdata v) {  
  8.                 v2f o;  
  9.                 o.pos = mul(UNITY_MATRIX_MVP, v.vertex);  
  10.                 return o;  
  11.             }  
  12.             half4 frag(v2f i) : SV_Target {  
  13.                 return half4(1,1,0,1);  
  14.             }  
  15.         ENDCG  
  16.   
  17.         Pass {  
  18.             Cull Front  
  19.             ZTest Less  
  20.           
  21.             CGPROGRAM  
  22.             #pragma vertex vert  
  23.             #pragma fragment frag  
  24.             ENDCG  
  25.         }  
  26.         Pass {  
  27.             Cull Back  
  28.             ZTest Greater  
  29.           
  30.             CGPROGRAM  
  31.             #pragma vertex vert  
  32.             #pragma fragment frag  
  33.             ENDCG  
  34.         }  
  35.     }   
  36. }  


不过因为Colormask不渲染任何颜色,所以上面这个shader看不出来什么东西。下面添加一段对上面代码的改写。

[html] view plaincopy
  1. Shader "HolePrepare" {  
  2.     SubShader {  
  3.         Tags { "RenderType"="Opaque" "Queue"="Geometry+1"}  
  4.         //ColorMask 0<span style="white-space:pre">       </span>注释掉ColorMask,让他可以显示颜色  
  5.         ZWrite off  
  6.         Stencil {  
  7.             Ref 1  
  8.             Comp always  
  9.             Pass replace  
  10.         }  
  11.   
  12.         CGINCLUDE  
  13.             struct appdata {  
  14.                 float4 vertex : POSITION;  
  15.             };  
  16.             struct v2f {  
  17.                 float4 pos : SV_POSITION;  
  18.             };  
  19.             v2f vert(appdata v) {  
  20.                 v2f o;  
  21.                 o.pos = mul(UNITY_MATRIX_MVP, v.vertex);  
  22.                 return o;  
  23.             }  
  24.             half4 frag(v2f i) : SV_Target {  
  25.                 return half4(1,1,0,1);  
  26.             }  
  27.               
  28.             half4 frag2(v2f i) : SV_Target {<span style="white-space:pre">        </span>//添加一段片段函数以供调用  
  29.                 return half4(1,0,0,1);  
  30.             }  
  31.         ENDCG  
  32.   
  33.         Pass {  
  34.             Cull Front  
  35.             ZTest Less  
  36.           
  37.             CGPROGRAM  
  38.             #pragma vertex vert  
  39.             #pragma fragment frag  
  40.             ENDCG  
  41.         }  
  42.         Pass {  
  43.             Cull Back  
  44.             ZTest Greater  
  45.           
  46.             CGPROGRAM  
  47.             #pragma vertex vert  
  48.             #pragma fragment frag2<span style="white-space:pre">      </span>//渲染正面时,调用frag2函数  
  49.             ENDCG  
  50.         }  
  51.     }   
  52. }  

如上图,主要的改动的是三个方面,效果如下

嗯,所以可以直接被看见部分(内侧)渲染黄色,被挡住部分(外侧)渲染红色,然后中间的部分,挡住了内侧,暴露了外侧,所以不渲染,为什么要对这个shader解释这么多呢,原因就在下面这个shader。

[html] view plaincopy
  1. Shader "Hole" {  
  2.     Properties {  
  3.         _Color ("Main Color", Color) = (1,1,1,0)  
  4.     }  
  5.     SubShader {  
  6.         Tags { "RenderType"="Opaque" "Queue"="Geometry+2"}<span style="white-space:pre">      </span>//渲染次序为Geometry+2  
  7.   
  8.         ColorMask RGB<span style="white-space:pre">       </span>//显示出颜色,这个默认的,写不写都一样  
  9.         Cull Front<span style="white-space:pre">      </span>//只渲染背面,嗯,这个shader开始牛起来了  
  10.         ZTest Always<span style="white-space:pre">        </span>//深度测试永远通过,霸气侧漏!这个意味着不管你怎么挡,这个球始终可以在你眼皮子底下出现  
  11.         Stencil {  
  12.             Ref 1<span style="white-space:pre">       </span>//参考值为1  
  13.             Comp notequal <span style="white-space:pre">  </span>//比较方式为不相等<span style="white-space:pre"> </span>  
  14.         }  
  15.   
  16.         CGPROGRAM  
  17.         #pragma surface surf Lambert  
  18.         float4 _Color;  
  19.         struct Input {  
  20.             float4 color : COLOR;  
  21.         };  
  22.         void surf (Input IN, inout SurfaceOutput o) {  
  23.             o.Albedo = _Color.rgb;  
  24.             o.Normal = half3(0,0,-1);  
  25.             o.Alpha = 1;  
  26.         }  
  27.         ENDCG  
  28.     }   
  29. }  

这个球的样子是这样


没人挡得住它的显示了


这是他被平面切割的情况,根本看不出来啊!好,这个球说,“谁能挡我!!”

然后他就被挡了


好,解释一下,这个透明球先渲染,所以他上面的内表面和下面的外表秒stencil值为1,或许有人会问上面内表面可以赋值是可以理解的,下面外表面的怎么回事?我也想了好久,其实答案就在每个通道的ztest,内表面的为ztest Less,说明这个内表面的只要在物体前面就可以渲染出来,即深度测试成功,stencil赋值为1,而下面的外表面为ztest Greater,说明这个外表面需要在被挡住的时候显示出来,很贱有没有,这个时候深度测试成功。中间那部分因为没有深度测试成功,所以shencil值还是为0,所以还是被这个霸气侧漏的透了出来!

好了,先写到这里,我要去吃饭了,有发现错误的地方求大神指正。

http://www.lbrq.cn/news/2524519.html

相关文章:

  • php动态网站开发 项目教程国际最新十大新闻事件
  • 百度生成手机网站站内优化主要从哪些方面进行
  • 个人网站模板源码论坛排名
  • 手机端网站如何做排名哪家竞价托管专业
  • 吉林省党风廉政建设官方网站重庆做优化的网络公司
  • 贵溪市城乡建设局网站地推推广平台
  • 西安软件开发公司百度seo软件曝光行者seo
  • 做性的网站有哪些哈尔滨seo整站优化
  • 免费网站建设制作视频音乐接单推广app平台
  • 网上学影视后期靠谱吗王通seo教程
  • 可以做设计兼职的网站有哪些工作可免费投放广告的平台
  • 政府网站策划书站长之家seo综合
  • 怎么做游戏和网站漏洞网络营销策划
  • 网站建设不力 被问责游戏代理加盟平台
  • 通州重庆网站建设免费大数据分析网站
  • 网站制作工资企业seo排名有 名
  • 网站设计外包合同百度搜索推广收费标准
  • 电子商务网站建设属性2022十大热点事件及评析
  • 乐清做网站建设公司哪家好seo搜索引擎是什么
  • 创造力网站设计网络推销平台有哪些
  • 嘉定房产网站建设全网推广引流黑科技
  • 做搜狗网站关键词排名网络营销的盈利模式
  • 嘉兴建设网站百度一下官网网址
  • 网站做系统叫什么软件吗佛山网站建设排名
  • 图库 网站 源码各大网站收录入口
  • 未来5年网络规划设计师河南seo优化
  • 郑州app开发 丁河南关键词优化搜索
  • 湖南城乡建设部网站重庆网站外包
  • 网站掉排名淘宝的17种免费推广方法
  • 舌尖上的西安 网站怎么做网站页面设计
  • 服务器与电脑主机的区别,普通电脑可以当作服务器用吗?
  • 《UE教程》第三章第五回——第三人称视角
  • 大语言模型API付费?
  • 【Linux】重生之从零开始学习运维之mysql用户管理
  • 坚鹏:AI智能体培训是知行学成为AI智能体创新应用引领者的基础
  • JAVA:Spring Boot 集成 Protobuf 的技术指南