OpenGL Shader实例分析(8)彩色光圈效果

本文实例为大家分享了OpenGL实现彩色光圈效果的具体代码,供大家参考,具体内容如下

研究了一个彩色光圈效果,感觉挺不错的,分享给大家,效果如下:

代码如下:

Shader "shadertoy/TotalNoob" { //https://www.shadertoy.com/view/XdlSDs
 Properties{
 iMouse ("Mouse Pos", Vector) = (100,100,0,0)
 iChannel0("iChannel0", 2D) = "white" {}
 iChannelResolution0 ("iChannelResolution0", Vector) = (100,100,0,0)
 }

 CGINCLUDE
 #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 // mod = sign*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.28318530718
 #define pi 3.14159265358979
 #define halfpi (pi * 0.5)
 #define oneoverpi (1.0 / pi)

 fixed4 iMouse;
 sampler2D iChannel0;
 fixed4 iChannelResolution0;

 struct v2f {
 float4 pos : SV_POSITION;
 float4 srcPos : TEXCOORD0;
 }; 

 // precision highp float;
 v2f vert(appdata_base v){
 v2f o;
 o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
 o.srcPos = ComputeScreenPos(o.pos);
 return o;
 } 

 vec4 main(v2f _iParam);

 fixed4 frag(v2f _iParam) : COLOR0 {
 return main(_iParam);
 } 

 vec4 main(v2f _iParam) {
 vec2 p = (2.0*gl_FragCoord.xy-iResolution.xy)/iResolution.y;
 float tau = 3.1415926535*2.0;
 float a = atan(p.x,p.y);
 float r = length(p)*0.75;
 vec2 uv = vec2(a/tau,r);

 //get the color
 float xCol = (uv.x - (iGlobalTime / 3.0)) * 3.0;
 xCol = sign(xCol)*fmod(xCol, 3.0);
 vec3 horColour = vec3(0.25, 0.25, 0.25);

 if (xCol < 1.0) {
 horColour.r += 1.0 - xCol;
 horColour.g += xCol;
 } else if (xCol < 2.0) {
 xCol -= 1.0;
 horColour.g += 1.0 - xCol;
 horColour.b += xCol;
 } else {
 xCol -= 2.0;
 horColour.b += 1.0 - xCol;
 horColour.r += xCol;
 }

 // draw color beam
 uv = (2.0 * uv) - 1.0;
 float beamWidth = (0.7+0.5*cos(uv.x*10.0*tau*0.15*clamp(floor(5.0 + 10.0*cos(iGlobalTime)), 0.0, 10.0))) * abs(1.0 / (30.0 * uv.y));
 vec3 horBeam = vec3(beamWidth,beamWidth,beamWidth);
 vec4 gl_FragColor = vec4((( horBeam)* horColour ), 1.0);

 return gl_FragColor;
 }

 ENDCG
 SubShader {
 Pass {
 CGPROGRAM
 #pragma vertex vert
 #pragma fragment frag
 #pragma fragmentoption ARB_precision_hint_fastest
 ENDCG
 }
 }
 FallBack Off
}

代码分析

代码分两部分,颜色 * 光圈,如下图:

 *  = 

彩色的算法

代码如下:

vec2 p = (2.0*gl_FragCoord.xy-iResolution.xy)/iResolution.y;
float tau = 3.1415926535*2.0;
float a = atan(p.x,p.y);
float r = length(p)*0.75;
vec2 uv = vec2(a/tau,r);

//get the color
float xCol = (uv.x - (iGlobalTime / 3.0)) * 3.0;
xCol = mod(xCol, 3.0);
vec3 horColour = vec3(0.25, 0.25, 0.25);

if (xCol < 1.0) {
 horColour.r += 1.0 - xCol;
 horColour.g += xCol;
} else if (xCol < 2.0) {
 xCol -= 1.0;
 horColour.g += 1.0 - xCol;
 horColour.b += xCol;
} else {
 xCol -= 2.0;
 horColour.b += 1.0 - xCol;
 horColour.r += xCol;
}

这段代码是写在fragment shader中的,也就是说,每个像素点的渲染都会调用这段代码。

a) vec2 p = (2.0*gl_FragCoord.xy-iResolution.xy)/iResolution.y;

p表示把当前的坐标轴缩小到原来的1/2,原点移动到屏幕中间,并把x,y轴的坐标范围缩小到1左右的值(即p的y轴范围在-1到1之间,x轴的范围也在附近);

b)float a = atan(p.x, p.y);

a表示p点绕原点的角度,范围为[-π,π];所以uv.x = a/tau的范围为[-1/2, 1/2];

float xCol = (uv.x - (iGlobalTime / 3.0)) * 3.0; xCol=mod(xCol, 3)的范围为 [0,3]

c) xCol经过上面处理,其范围为[0,3]; 现在把这个范围平均分成3份,每一份做一个颜色的混合:

[0,1]:Red和Green混合;[1,2]:Green和Blue混合;[2,3]:Blue和Red混合。

光圈的算法

a)画光圈

式子:abs(1.0 / (30.0*uv.y))

知识:在shader中,如果color的值为负数,则认为是0,不显示该颜色。

uv变量中uv.y表示点到原点的距离,值的范围为 [0, ]

a-1) uv = (2.0 * uv) - 1.0;  先把uv缩小到原来的1/2,然后向外移动1单位。uv.y的值为[-1/2, ];由于负值color不被显示,如下图A:

a-2) 1.0/(30.0* uv.y); 缩小到原来的1/30,并做个倒数,如下图B

a-3) abs(1.0/(30.0* uv.y)); 然后做个绝对值,如下图C

=》=》

画光圈的算法和《【OpenGL】Shader实例分析(一)-Wave》中画线的算法很类似。

b)光圈动画

式子:(0.7+0.5*cos(uv.x*10.0*tau*0.15*clamp(floor(5.0 + 10.0*cos(iGlobalTime)), 0.0, 10.0)))

为了方便,把上面的式子分解如下:

式1:float tt = 5.0 + 10.0*cos(iGlobalTime); 
式2:float param = clamp(floor(tt), 0.0, 10.0);
式3:float beamWidth = (0.7+0.5*cos(uv.x*pi*param));

我们把beamWidth作为颜色输出;

先理解式3,如果当param为0,、1、2、3、10时,分别参考下图:

 =》  =》=》 =》

式2的作用,把tt的值做一个包装,使其为0到10之间的整数

式1的作用,起周期作用,值域为[-5,15]; 其值如左下图所示; 又由于式2做了clamp,把大于10和小于0的值去掉,最终的动画如右下图所示:

 ====》

把光圈和颜色整合起来就看到了和文章开头的动画一样的效果了。

最后吧所有的效果整合起来,如下图:

【彩色】 => 【彩色旋转】 =》【彩色旋转+动画】 =》【彩色旋转+动画+光圈】

=》=》=》

本次分析到此结束,欢迎讨论。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • OpenGL Shader实例分析(4)闪光效果

    本文实例为大家分享了OpenGL Shader实例闪光效果的具体代码,供大家参考,具体内容如下 在游戏中,当战斗结束后,对一些获取的宝贝需要进行闪光处理.这篇文章介绍一个进行闪光处理的shader,运行效果如下: 代码如下: Shader "stalendp/imageShine" { Properties{ _image("image", 2D) = "white" {} _percent("_percent", Range

  • OpenGL Shader实例分析(1)Wave效果

    这篇文章主要分析一个Shader,从而感受shader的魅力,并学习相关shader的函数的用法. 先看Shader运行的效果: 下面是代码: Shader "shadertoy/Waves" { //see https://www.shadertoy.com/view/4dsGzH CGINCLUDE #include "UnityCG.cginc" #pragma target 3.0 struct vertOut { float4 pos:SV_POSITIO

  • OpenGL Shader实例分析(3)等待标识效果

    本文实例为大家分享了OpenGL Shader实例,等待标识,不过效率估计不是很高.结果如下: 代码: Shader "stalendp/waitIcons" { CGINCLUDE #include "UnityCG.cginc" #pragma target 3.0 struct v2f { float4 pos:SV_POSITION; float2 uv : TEXCOORD0; }; v2f vert(appdata_base v) { v2f o; o.

  • OpenGL Shader实例分析(2)绘制心脏跳动效果

    本文将介绍怎么用Shader来绘制一个跳动的心脏.这里会涉及到一些数学知识.先看效果图: 源代码如下: // Created by inigo quilez - iq/2013 // License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. // changed by stalendp@gmail.com Shader "shadertoy/Heart" { // see ht

  • OpenGL Shader实例分析(8)彩色光圈效果

    本文实例为大家分享了OpenGL实现彩色光圈效果的具体代码,供大家参考,具体内容如下 研究了一个彩色光圈效果,感觉挺不错的,分享给大家,效果如下: 代码如下: Shader "shadertoy/TotalNoob" { //https://www.shadertoy.com/view/XdlSDs Properties{ iMouse ("Mouse Pos", Vector) = (100,100,0,0) iChannel0("iChannel0&q

  • OpenGL Shader实例分析(7)雪花飘落效果

    研究了一个雪花飘落效果,感觉挺不错的,分享给大家,效果如下: 代码如下: Shader "shadertoy/Flakes" { // https://www.shadertoy.com/view/4d2Xzc Properties{ iMouse ("Mouse Pos", Vector) = (100,100,0,0) iChannel0("iChannel0", 2D) = "white" {} iChannelReso

  • Winform窗体效果实例分析

    本文实例分析了Winform窗体效果.分享给大家供大家参考.具体如下: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace WindowsApplication4 { public partial cl

  • jQuery实现div拖拽效果实例分析

    本文实例分析了jQuery实现div拖拽效果.分享给大家供大家参考,具体如下: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title> New Document </title> <script type=&q

  • jQuery遮罩层效果实例分析

    本文实例分析了jQuery遮罩层效果.分享给大家供大家参考,具体如下: 先来看看示例代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:l

  • OpenGL Shader实现阴影遮罩效果

    目录 smoothstep另一种用法 遮罩效果实现 效果扩展 smoothstep另一种用法 在之前OpenGL Shader-抗锯齿实现文章中所介绍的那样:为了抗锯齿效果可以用smoothstep函数对绘制形状进行平滑过渡来实现.其中也提到了当smoothstep函数中入参a和b范围过大时就会出现渐变效果.如OpenGL Shader-抗锯齿实现中所展示的效果: 遮罩效果实现 看到这个效果后似乎可以利用smoothstep函数中a和b入参取大范围来实现不一样的特效能力.例如可以使用该特点来实现

随机推荐