附上Shadertoy官网链接:https://www.shadertoy.com/
1.ShaderMaterial材质中的默认顶点着色器和片元着色器,此时渲染的物体为红色
/* 顶点着色器 */
const vertexShader=`
void main(){
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`;
/* 片元着色器 */
const fragmentShader=`
void main(){
gl_FragColor=vec4(1.0,0.0,0.0,1.0);
}
`;
const uniforms={
};
const shaderMat=new THREE.ShaderMaterial({
vertexShader,
fragmentShader,
uniforms,
//attributes:{}
});
const box=new THREE.Mesh(new THREE.BoxGeometry(10,10,10),shaderMat);
scene.add(box);
2.shadertoy案例的代码(展开“着色器输入”按钮后的图)
和three中着色器代码对比差异:
- 没有顶点着色器和片元着色器;
- 代码中没有main()函数,而有类似的mainImage();
- 没有gl_FragColor,而有类似的fragColor;
- 不是着色器中的gl_FragCoord,而有类似的fragCoord
经过验证修改
- 顶点着色器保持默认;
- 片元着色器使用mainImage()中的代码,不要括号内的out,in声明的变量,但是需要外部变量。
- 把fragColor 换成 gl_FragColor。
- iResolution是设备视口的分辨率(像素),在three中可以通过uniform的方式传入。
- iTime是一个变量(shadertoy自带的变量),着色器播放时间(秒),在three中可以通过uniform的方式传入。
- fragCoord可以改成uv坐标,直接从顶点着色器传递uv坐标给片元着色器。
- 删除无用的变量声明,如iTimeDelta,iTimeDelta等。
/* 顶点着色器 */
const vertexShader=`
varying vec2 vUv;
void main(){
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`;
/* 片元着色器 */
const fragmentShader=`
varying vec2 vUv;
uniform vec3 iResolution; // 视口分辨率(像素)
uniform float iTime; // 着色器播放时间(秒)
const float rings = 5.0; //任何时刻都是完整的白环数
const float velocity=4.; //跳动速率
const float b = 0.003; //平滑边界的大小
void main(){
vec2 position = vUv.xy/iResolution.xy;
float aspect = iResolution.x/iResolution.y;
position.x *= aspect;
float dist = distance(position, vec2(aspect*0.5, 0.5));
float offset=iTime*velocity;
float conv=rings*4.;
float v=dist*conv-offset;
float ringr=floor(v);
float color=smoothstep(-b, b, abs(dist- (ringr+float(fract(v)>0.5)+offset)/conv));
if(mod(ringr,2.)==1.)
color=1.-color;
gl_FragColor = vec4(color, color, color, 1.);
}
`;
const uniforms={
iTime:{value:0},
iResolution: { value: new THREE.Vector3( 1,1,1) },
};
setInterval(()=>{uniforms.iTime.value += 0.01;},10);//定时刷新
const shaderMat=new THREE.ShaderMaterial({
vertexShader,
fragmentShader,
uniforms
});
const box=new THREE.Mesh(new THREE.BoxGeometry(10,10,10),shaderMat);
scene.add(box);
最后实现效果图