Three.js发光效果在形状上呈现不同的效果

时间:2018-11-20 11:37:32

标签: javascript three.js shapes fragment-shader vertex-shader

我正在制作一个涉及钻石展示的动画。我编码的形状很好看,我想添加发光效果。不幸的是,我的着色器知识几乎为零,因此我不得不找到一些不错的教程。我能够应用和修改找到的代码,但结果非常糟糕。发现的发光效果在圆环形状上看起来不错,但是当我将其放置在钻石上时,它看起来根本就不发光。在圆环形状上,您可以看到它的褪色很好,而在钻石上,它恰好是固体。

这是在圆环上施加的光晕: enter image description here

这是带有菱形的实际代码:

let SCENE_WIDTH = window.innerWidth;
let SCENE_HEIGHT = window.innerHeight;

let FIELD_OF_VIEW = 45;
let ASPECT = SCENE_WIDTH / SCENE_HEIGHT;
let NEAR = 0.1;
let FAR = 10000;

let scene = new THREE.Scene();

let renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0x8d8d8d, 1);
renderer.setSize(SCENE_WIDTH, SCENE_HEIGHT);
document.getElementById('webgl-container').appendChild(renderer.domElement);

let camera = new THREE.PerspectiveCamera(FIELD_OF_VIEW, ASPECT, NEAR, FAR);
camera.position.set(-1, 1, 1);
camera.lookAt(new THREE.Vector3(0, 0, 0));  
scene.add(camera);

let light = new THREE.PointLight(0xffffff, 0.8);
light.position.set(30, 100, 50);
scene.add(light);

var geometry = new THREE.Geometry(),
    tmpGeometry = new THREE.CylinderGeometry(0.3, 0.7, 0.3, 6, 1, false),
    tmpMatrix = new THREE.Matrix4().makeTranslation(0, +tmpGeometry.parameters.height/2, 0);
geometry.merge(tmpGeometry, tmpMatrix);

var tmpGeometry = new THREE.CylinderGeometry(0.7, 0, 0.6, 6, 1, false),
    tmpMatrix = new THREE.Matrix4().makeTranslation(0, -tmpGeometry.parameters.height/2, 0);

geometry.merge(tmpGeometry, tmpMatrix);
let material = new THREE.MeshPhongMaterial({color: 0x00ff00});
let object = new THREE.Mesh( geometry, material );

let glowMaterial = new THREE.ShaderMaterial({
	uniforms: {
		glowAlpha: {
			type: "float",
			value: 1
		},
		glowColor: {
			type: "v3",
			value: new THREE.Vector3(0, 1, 0)
		},
		viewVector: {
			type: "v3",
			value: camera.position
		}
	},
	vertexShader: document.getElementById('vertexShaderSun').textContent,
	fragmentShader: document.getElementById('fragmentShaderSun').textContent,
	side: THREE.FrontSide,
	blending: THREE.AdditiveBlending,
	transparent: true
});

var glowGeometry = new THREE.Geometry(),
    tmpGeometry	= new THREE.CylinderGeometry(0.4, 0.8, 0.4, 6, 1, false),
    tmpMatrix	= new THREE.Matrix4().makeTranslation(0, +tmpGeometry.parameters.height/2, 0);
glowGeometry.merge(tmpGeometry, tmpMatrix);

var tmpGeometry	= new THREE.CylinderGeometry(0.8, 0, 0.7, 6, 1, false),
    tmpMatrix	= new THREE.Matrix4().makeTranslation(0, -tmpGeometry.parameters.height/2, 0);
glowGeometry.merge(tmpGeometry, tmpMatrix);

let glowMesh = new THREE.Mesh(glowGeometry, glowMaterial);
object.add(glowMesh);
object.glow = glowMesh;
scene.add(object);

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

function update () {
	let viewVector = new THREE.Vector3().subVectors( camera.position, object.glow.getWorldPosition());
	object.glow.material.uniforms.viewVector.value = viewVector;

	renderer.render(scene, camera);
	requestAnimationFrame(update);
}
requestAnimationFrame(update);
#webgl-container {
	position: absolute;
	left: 0;
	top: 0;
	background-color: aqua;
}
<script src="https://cdn.rawgit.com/mrdoob/three.js/master/build/three.min.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/controls/OrbitControls.js"></script>

<script id="vertexShaderSun" type="x-shader/x-vertex">
	uniform vec3 viewVector;
	varying float intensity;
	void main() {
		gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4( position, 1.0 );
		vec3 actual_normal = vec3(modelMatrix * vec4(normal, 0.0));
		intensity = pow( dot(normalize(viewVector), actual_normal), 6.0 );
	}
</script>

<script id="fragmentShaderSun" type="x-shader/x-vertex">
	uniform float glowAlpha;
	uniform vec3 glowColor;
	varying float intensity;
	void main() {
		vec3 glow = glowColor * intensity;
		gl_FragColor = vec4( glow, glowAlpha );
	}
</script>

<div id="webgl-container"></div>

因此,您可以看到此特定的发光代码根据所使用的形状而有所不同。一个人该如何修改代码,使它在钻石上具有良好的外观(就像圆环上的钻石一样)。

0 个答案:

没有答案