如何更改此THREE.js演示中的颜色

时间:2017-09-14 21:10:44

标签: three.js shader perlin-noise

我刚刚在codepen上发现了这个漂亮的演示,但我不知道如何改变球体的颜色 - 我的意思是蓝色和紫色的颜色,而不是我知道如何改变颜色的背景颜色!

以下是演示:Link to the demo

JavaScript专家请帮忙! 这是HTML代码:

<canvas></canvas>

<script type="x-shader/x-vertex" id="wrapVertexShader">
uniform float uTime;
varying vec3 vNormal;
attribute float perlin;
varying float vPerlin;
void main() 
{
		vNormal = normal;
		vPerlin = perlin;
		vec3 position = position;
    position.x *= abs(perlin)*0.1+1.0;
    position.y *= abs(perlin)*0.1+1.0;
    position.z *= abs(perlin)*0.1+1.0;
    vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
    gl_PointSize = 3.0;
    gl_Position = projectionMatrix * mvPosition;
}
</script>
<script type="x-shader/x-fragment" id="wrapFragmentShader">
varying float vPerlin;
void main(){
  vec3 outcolor = vec3(abs(vPerlin),vPerlin-1.0,1.0);
  gl_FragColor = vec4(outcolor, 1.0);
}
</script>

这是JS代码:

var ww = window.innerWidth,
    wh = window.innerHeight,
    imgData;

var renderer = new THREE.WebGLRenderer({
  canvas: document.querySelector("canvas")
});
renderer.setClearColor(0xffffff);
renderer.setSize(ww, wh);

var scene = new THREE.Scene();

var camera = new THREE.PerspectiveCamera(50, ww / wh, 1, 10000);
camera.position.set(0, 0, 300);

var controls = new THREE.OrbitControls(camera, renderer.domElement);

var geom = new THREE.SphereBufferGeometry(100,60, 60);
var mat = new THREE.MeshBasicMaterial({color:0xff0000});
var length = geom.attributes.position.count;
var perlins = new Float32Array(length);
geom.addAttribute('perlin', new THREE.BufferAttribute(perlins, 1));
var wrapMatShader = new THREE.ShaderMaterial({
    uniforms: {
        uTime: { type: "f", value: 1.0 },
    },
    vertexShader: document.getElementById("wrapVertexShader").textContent,
    fragmentShader: document.getElementById("wrapFragmentShader").textContent
  });
var sphere = new THREE.Mesh(geom, wrapMatShader);
scene.add(sphere);


// ========  
//RENDER
// ========  
function render(a) {
  requestAnimationFrame(render);
  
  var perlins = new Float32Array(length);
  for(var i=0;i<length;i++){
    var x = geom.attributes.position.array[i*3];
    var y = geom.attributes.position.array[i*3+1];
    var z = geom.attributes.position.array[i*3+2];
    var random = noise.simplex3((x+a*0.02)*0.01, (y+a*0.02)*0.01, (z+a*0.02)*0.01);
    perlins[i] = random;
  }
  geom.addAttribute('perlin', new THREE.BufferAttribute(perlins, 1));
  
  wrapMatShader.uniforms.uTime.value  = a;

  renderer.render(scene, camera);
}


requestAnimationFrame(render);

1 个答案:

答案 0 :(得分:1)

这是设置颜色值的行:

vec3 outcolor = vec3(abs(vPerlin), vPerlin - 1.0, 1.0);

因此,参数vPerlin可以控制颜色的红色和绿色值。蓝色分量固定为1.0。继续玩这些值吧。

现在,perlin-value来自顶点着色器,后者又接收来自这段javascript的值:

var perlins = new Float32Array(length);
for(var i=0;i<length;i++){
    var x = geom.attributes.position.array[i*3];
    var y = geom.attributes.position.array[i*3+1];
    var z = geom.attributes.position.array[i*3+2];
    var random = noise.simplex3((x+a*0.02)*0.01, (y+a*0.02)*0.01, (z+a*0.02)*0.01);
    perlins[i] = random;
}
geom.addAttribute('perlin', new THREE.BufferAttribute(perlins, 1));

它比这复杂一点,涉及顶点和碎片着色器如何协同工作。如果您对此处发生的事情感到好奇,您可能需要阅读此内容:https://webglfundamentals.org/webgl/lessons/webgl-shaders-and-glsl.html