【零基础】充分理解WebGL(六)

颜色

在前面几篇的内容里,我们的例子大部分都是黑白的,那是因为我们着重于渲染形状,基本没有考虑渲染成不同的颜色。

我们既然把shader中文翻译成“着色器”,顾名思义,“着色器”本身就是用来在画布上“着色”的,自然和颜色有着密切的关系。

话不多说,我们仍然通过代码由浅入深地来看一看。

我们已经知道了在片段着色器中,FragColor输出颜色,它默认采用的是RGBA色值。

#version 300 es
precision highp float;
out vec4 FragColor;
uniform vec2 resolution;

void main() {FragColor.rgb = vec3(1.0, 0, 0);FragColor.a = 1.0;
} 

我们在第一讲中,就见过,上面的代码将整个canvas画布渲染为红色。

顺便说一下,码上掘金支持了自定义语言功能,所以从这一讲开始,我利用这个功能来写shader,因为我们讲WebGL的重点是渲染管线里的着色器,所以shader代码是核心,利用自定义语言来写,能够让读者浏览语法高亮的shader代码,便于阅读和修改调试。而其他JS部分,我放在Markup的script标签里,不作为重点。你只要切换码上掘金左侧窗口的script标签,就能看到语法高亮的shader代码了。

https://code.juejin.cn/pen/7111156081786617893

同样,在第一讲中,我们还写过一个例子,通过坐标值来绘制渐变颜色:

#version 300 es
precision highp float;
out vec4 FragColor;
uniform vec2 resolution;

void main() {vec2 st = gl_FragCoord.xy / resolution;FragColor.rgb = vec3(st, 0);FragColor.a = 1.0;
} 

https://code.juejin.cn/pen/7111162916430151711

我们可以利用前面学过的距离场来对颜色造型:

#version 300 es
precision highp float;

#pragma include <stdlib>

out vec4 FragColor;
uniform vec2 dd_resolution;
uniform float dd_time;

void main() {vec2 st = gl_FragCoord.xy / dd_resolution;st = mix(vec2(-5), vec2(5), st);st = polar(st, vec2(0));st = fract(st);FragColor.rgb = vec3(st.x, st.y + 0.5 * sin(dd_time), 0);FragColor.a = 1.0;
} 

https://code.juejin.cn/pen/7111163920278093838

在上面的代码里,我悄悄换了一个库,把 gl_render 换成了 glsl_doodle

它们使用上没有太大差别,glsl_doodle 是继承了 gl_renderer,在 gl_renderer 的基础上支持了 #pragma include 指令加载函数库的功能。通过这个功能,我们内置了一些模块,使用它们的方法就是通过#pragma include 加载进来,这和使用C语言进行加载模块非常类似。实际上很大一部分模块我们在前面的章节中都介绍了它们的具体实现。在后续的章节中我们直接将它们加载进来,这样能保持glsl代码的清晰,便于理解。对于未使用过的函数,如有涉及,我再单独介绍。

另外glsl_doodle还内置了一些uniforms,这样我们就不用在JS中去重复定义它们,内置uniforms在命名上以dd_开头,例如上面代码用到的dd_resolution,它和我们前面章节自己定义的resolution没有区别。

渐变造型

在颜色渐变的基础上,我们可以通过造型函数来控制渐变过程,比如下面的代码用三阶贝塞尔曲线来控制渐变过程:

#version 300 es
precision highp float;

#pragma include <stdlib>
#pragma include <graph>
#pragma include <shaper>

out vec4 FragColor;
uniform vec2 dd_resolution;
uniform float dd_time;
uniform vec3 fromColor;
uniform vec3 toColor;
uniform vec4 bezierController;

float cubic_bezier(float x, vec4 p) {return cubic_bezier(x, p.x, p.y, p.z, p.w);
}

float cubic_bezier(float x) {return cubic_bezier(x, bezierController);
}

void main() {vec2 st = gl_FragCoord.xy / dd_resolution;float d = cubic_bezier(st.x);FragColor.rgb = mix(fromColor, toColor, d);float d2 = PLOT(cubic_bezier, st, 0.01);FragColor.rgb += stroke(d2, 0.01, 0.2);FragColor.a = 1.0;
} 

https://code.juejin.cn/pen/7111175676136259621

像前面章节的例子一样,我们也可以把直角坐标映射成极坐标,做出有趣的效果来:

https://code.juejin.cn/pen/7111187775952519181

HSB

就像CSS中有RGB和HSL一样,我们可以将RGB设置转换成极坐标方式,将红、绿、蓝三原色通道映射成色相饱和度亮度三个通道,这就是HSB设置。

HSB和RGB的相互转换公式如下:

vec3 rgb2hsb(vec3 c){vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));float d = q.x - min(q.w, q.y);float e = 1.0e-10;return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}

//Function from Iñigo Quiles
//https://www.shadertoy.com/view/MsS3Wc
vec3 hsb2rgb(vec3 c){vec3 rgb = clamp(abs(mod(c.x*6.0+vec3(0.0,4.0,2.0), 6.0)-3.0)-1.0, 0.0, 1.0);rgb = rgb * rgb * (3.0 - 2.0 * rgb);return c.z * mix(vec3(1.0), rgb, c.y);
} 

有了HSB,我们可以方便做连续的色相渐变,比如我们将上面的例子修改一下:

https://code.juejin.cn/pen/7111193630966022181

简单运用极坐标变换,我们可以看一下HSB色轮,类似CSS的HSL色轮:

#version 300 es
precision highp float;

#define WEBGL2;

#pragma include <stdlib>
#pragma include <graph>
#pragma include <color>

uniform vec2 dd_resolution;
uniform float dd_time;
uniform float fromColor;
uniform float toColor;
uniform vec4 bezierController;

void main() {vec2 st = gl_FragCoord.xy / dd_resolution;st = polar(st);FragColor.rgb = hsb2rgb(vec3(0.5 * st.y / PI +0.5,st.x,1.0));FragColor.a = 1.0;
} 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 学习WebGL需要具备一定的OpenGL基础,因为WebGL是基于OpenGL ES的一个API,它的一些核心概念和方法与OpenGL有很多相似之处。所以,如果你已经掌握了OpenGL的基础知识,那么学习WebGL会更容易一些,但如果你没有OpenGL基础,也可以直接开始学习WebGL,只需要花费更多的时间和精力来理解它的基本原理和运作方式。 ### 回答2: 学习WebGL不一定需要OpenGL基础。WebGL是基于OpenGL ES的,所以对OpenGL基础有一定了解会对学习WebGL有帮助,但并不是必需的。 如果已经有一定的OpenGL基础,那么对于学习WebGL来说会更容易入门。因为WebGL使用了类似于OpenGL的接口和概念,例如着色器程序、顶点缓冲区对象等等。对于已经熟悉OpenGL的人来说,理解和使用这些概念会更加顺利。 然而,即使没有OpenGL基础,也可以学习和使用WebGL。因为WebGL有自己的学习曲线和特定的语法和概念。学习者可以通过详细的文档、教程和示例来理解和掌握这些内容。通过实践和深入学习WebGL,可以逐渐建立起对其原理和用法的理解。 总而言之,虽然有OpenGL基础会对学习WebGL有一定帮助,但并不是必需的。通过系统学习和实践,没有OpenGL基础的人也可以掌握和应用WebGL的技术。对于初学者来说,重要的是掌握WebGL的核心概念和语法,并通过实践项目来深入理解和应用。 ### 回答3: 学习WebGL不一定需要OpenGL基础。WebGL是一种基于OpenGL ES(嵌入式系统)的开放式图形库,用于在网页浏览器中实现快速的3D图形渲染。然而,对于想要深入理解WebGL原理和开发复杂应用程序的人来说,了解OpenGL基础是很有帮助的。 OpenGL是一种跨平台的图形库,用于在计算机上生成和渲染2D和3D图形。它提供了一套功能强大的API,用于控制图形硬件和绘制图形。WebGL是基于OpenGL的一个子集,它使用JavaScript API来处理3D图形。因此,对于那些已经熟悉OpenGL的开发者来说,学习WebGL会更容易,因为它们之间有很多相似之处。 然而,即使没有OpenGL基础,也可以学习WebGL。通过学习WebGL的教程和参考资料,了解WebGL如何工作以及如何使用其API,您可以开始创建简单的3D图形应用程序。可以逐渐扩展知识,并根据需要深入学习OpenGL相关概念,以了解更高级的WebGL编程技术。 总结而言,学习WebGL不一定需要拥有OpenGL基础,但有OpenGL基础对于理解WebGL的原理和开发复杂应用程序是有帮助的。无论您是否已经熟悉OpenGL,通过学习WebGL相关资料和实践,您可以逐渐掌握WebGL编程技术。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值