【p5js shader翻译教程】1.2 为什么使用shaders?

该文章为翻译而来,原文链接见:https://itp-xstory.github.io/p5js-shaders/#/./docs/why-use-shaders

该系列翻译文章将不定期更新,将用于学习记录,若有侵权,请联系我。

1.2 为什么使用shaders?

性能

如果你曾经使用过loadPixels()set()updatePixels()函数,甚至在p5.js中做过简单的逐个像素的数学运算,那么你就会意识到以这种方式绘制的局限性。

下面是一个例子,比较了同样的操作(与鼠标的距离)来改变图像中像素亮度,两种不同方式绘制的帧率和渲染速度。首先使用p5中的loadPixels(),然后使用p5中加载的shader

使用loadPixels()时的显示效果与帧率(7~8fps)

使用shader时的显示效果与帧率(150fps)

这种性能上的巨大差异( 7 fps vs 150 fps ,取决于机器)是由于p5js中的loadPixels()函数依次执行填充像素的操作,而shader则是并行执行,更多关于这个问题,请看什么是What are shaders? (下一小节内容)。

视觉上的复杂性

如果你对在浏览器中创建复杂但具有表现力的图形感兴趣,或者是想在p5.js中展现自己的审美,那么shader(和本指南)就是为你准备的!

该案例的代码如下所示。

后续会选取原教程中一部分比较有用的代码放上来,以供大家参考学习。

sketch.js代码如下所示。

// a shader variable
let theShader;

function preload(){
  // load the shader
  theShader = loadShader('shader.vert', 'shader.frag');
}

function setup() {
  // shaders require WEBGL mode to work
  createCanvas(windowWidth, windowHeight, WEBGL);

  pixelDensity(1);
  noStroke();
}

function draw() {  
  // shader() sets the active shader with our shader
  shader(theShader);

  theShader.setUniform("iResolution", [width, height]);
  theShader.setUniform("iFrame", frameCount);
  theShader.setUniform("iMouse", [mouseX, map(mouseY, 0, height, height, 0)]);

  // rect gives us some geometry on the screen
  rect(0,0,width, height);
}

function windowResized(){
  resizeCanvas(windowWidth, windowHeight);
}

shader.frag代码如下所示。

// this is a port of "recursive noise experiment" by ompuco
// https://www.shadertoy.com/view/wllGzr
// casey conchinha - @kcconch ( https://github.com/kcconch )
// more p5.js + shader examples: https://itp-xstory.github.io/p5js-shaders/

#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 iResolution;
uniform int iFrame;
uniform vec2 iMouse;

float hash( float n )
            {
                return fract(sin(n)*43758.5453);
            }

            float noise( vec3 x )
            {
                // The noise function returns a value in the range -1.0f -> 1.0f

                vec3 p = floor(x);
                vec3 f = fract(x);

                f       = f*f*(3.0-2.0*f);
                float n = p.x + p.y*57.0 + 113.0*p.z;

                return mix(mix(mix( hash(n+0.0), hash(n+1.0),f.x),
                               mix( hash(n+57.0), hash(n+58.0),f.x),f.y),
                           mix(mix( hash(n+113.0), hash(n+114.0),f.x),
                               mix( hash(n+170.0), hash(n+171.0),f.x),f.y),f.z)-.5;
            }


void main()
{


    vec3 t = (float(iFrame)*vec3(1.0,2.0,3.0)/1.0)/1000.0;//+iMouse.xyz/1000.0;


    // Normalized pixel coordinates (from 0 to 1)
    vec2 uv = gl_FragCoord.xy/iResolution.xy;
    uv=uv/4.0+.5;
    uv-=iMouse.xy/iResolution.xy/4.0;

    vec3 col = vec3(0.0);



    for(int i = 0; i < 16; i++){
        float i2 = float(i)*1.0;
                    col.r+=noise(uv.xyy*(12.0+i2)+col.rgb+t*sign(sin(i2/3.0)));
                    col.g+=noise(uv.xyx*(12.0+i2)+col.rgb+t*sign(sin(i2/3.0)));
                    col.b+=noise(uv.yyx*(12.0+i2)+col.rgb+t*sign(sin(i2/3.0)));
                }


     for(int i = 0; i < 16; i++){
        float i2 = float(i)*1.0;
                    col.r+=noise(uv.xyy*(32.0)+col.rgb+t*sign(sin(i2/3.0)));
                    col.g+=noise(uv.xyx*(32.0)+col.rgb+t*sign(sin(i2/3.0)));
                    col.b+=noise(uv.yyx*(32.0)+col.rgb+t*sign(sin(i2/3.0)));
                }
                col.rgb/=32.0;
                col.rgb=mix(col.rgb,normalize(col.rgb)*2.0,1.0);
                col.rgb+=.3;



    // Output to screen
    gl_FragColor = vec4(col,1.0);
}

shader.vert代码如下所示。

// vert file and comments from adam ferriss
// https://github.com/aferriss/p5jsShaderExamples

// our vertex data
attribute vec3 aPosition;

// our texcoordinates
attribute vec2 aTexCoord;

void main() {

  // copy the position data into a vec4, using 1.0 as the w component
  vec4 positionVec4 = vec4(aPosition, 1.0);
  positionVec4.xy = positionVec4.xy * 2.0 - 1.0;

  // send the vertex information on to the fragment shader
  gl_Position = positionVec4;
}
  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hzxwonder

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值