shader画圆
来源:互联网 发布:zipalign优化工具 编辑:程序博客网 时间:2024/05/16 05:14
前言
shaderToy上的效果很是华丽,但是我们一口吃不了大胖子,只能慢慢来,从简单从基本做起,那么率先出场的是圆!
以下是我们在本文要实现的效果图:
Unity实现
首先我们先在unity中新建一个ImageEffectShader.
然后我们直接修改frag函数如下:
fixed4 frag (v2f i) : SV_Target{ return step(length(i.uv),0.3);}
虽然这张图不是我们想要的效果,但是这个方法可以让我们很轻松的实现画圆。
那么我们先来理解下这个方法,也就是 step(length(i.uv),0.3) 这一句的含义.
length(v)
返回一个向量的模,即sqrt(dot(v,v)).
step(a,x)
如果x小于a则返回0,否则返回1.
在上图中我们是直接返回i.uv(屏幕坐标)的模,然后再与0.3(圆的半径,你可以随意定自己想要的半径)进行比较,如果0.3小于此模,则为0(黑色),否则为1(白色)。
那么接下来我们开始修改一些参数来达到我们想要的效果,在修改之前我们先分析一下现在的效果有哪些不对的地方,这样我们才能有针对的去做修改。
- 圆心的位置不对
- 圆看起来不完整
- 圆看起来不是我们想要的正圆
- 圆的颜色和数量不对
那么接下来我们一个个来修改,第1点和第2点其实是一个问题,就是圆心位置,如果我们把圆放在屏幕中间位置,半径小一些就不会出现不完整了。
好,那我们修改一下上代码:
fixed4 frag (v2f i) : SV_Target{ return step(length(i.uv-fixed2(0.5,0.5)),0.2);}
这个问题比较简单,我们只需要自己定义一个fixed2然后让它与i.uv相减即可偏移到我们想要的位置。
那么第3点问题现在更加明显的可以看出来,出现这种问题的主要原因就是因为我们现在的屏幕不管尺寸是多少,左下角坐标永远都是(0,0),右上角坐标永远都是(1,1),这就导致了画出来的圆会被拉伸缩放。
既然找到了原因,那我们就想办法来解决:
fixed4 frag (v2f i) : SV_Target{ fixed2 screenUV=i.uv; screenUV.x*=_ScreenParams.x/_ScreenParams.y; return step(length(screenUV-fixed2(0.5,0.5)),0.2);}
第4点颜色和数量不对,颜色我们可以直接让圆与一个我们想要的颜色进行相乘(白色与任颜色相乘都等于这个颜色),至于数量我们可以多做几个圆进行叠加。
fixed4 frag (v2f i) : SV_Target{ fixed2 screenUV=i.uv; screenUV.x*=_ScreenParams.x/_ScreenParams.y; return step(length(screenUV-fixed2(0.5,0.5)),0.2)*fixed4(1,0,0,1);}
完整代码
最后我们把画圆单独做了个函数,并把代码整理了一下,以下代码就是实现出本文一开始的三原色(三个圆圈)的最终代码。
Shader "Unlit/CircleTest"{ Properties { } SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag // make fog work #pragma multi_compile_fog #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; v2f vert (appdata v) { v2f o; o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); o.uv=v.uv; return o; } fixed DrawCircle(float2 screenUV,float2 pos,float radius) { screenUV-=pos; return step(length(screenUV),radius); } fixed4 frag (v2f i) : SV_Target { fixed2 screenUV=i.uv; screenUV.x*=_ScreenParams.x/_ScreenParams.y; fixed4 _layer0=fixed4(0,0,0,1); fixed4 _c0=DrawCircle(screenUV,fixed2(0.7,0.7),0.2)*fixed4(1,0,0,1); fixed4 _c1=DrawCircle(screenUV,fixed2(0.6,0.5),0.2)*fixed4(0,1,0,1); fixed4 _c2=DrawCircle(screenUV,fixed2(0.8,0.5),0.2)*fixed4(0,0,1,1); return _layer0+_c0+_c1+_c2; } ENDCG } }}
- 【Shader】用 Shader 画圆
- shader画圆
- shader
- shader
- shader
- Shader
- Shader
- shader
- shader
- shader
- Shader
- shader
- Shader
- shader
- Shader
- shader
- Shader
- Shader
- standford自然语言处理第二课“文本处理基础(Basic Text Processing)”
- Mysql 分表分区的区别与联系
- nginx+tomcat+memcache----2 tomcat+nginx负载均衡
- (java)括号匹配(简单)
- C语言如何调用Java语言
- shader画圆
- JavaScript中创建对象的方法
- Java内部类的使用小结
- linux下帮助文档汇总
- Chrome谷歌浏览器下不支持css字体小于12px的解决办法
- GPUImage实现实时滤镜
- 通过递归查询指定目录下的所有文件和子文件夹下的指定文件名
- Linux学习笔记
- 【JZOJ 4799】 我的快乐时代