我正在制作一个涉及钻石展示的动画。我编码的形状很好看,我想添加发光效果。不幸的是,我的着色器知识几乎为零,因此我不得不找到一些不错的教程。我能够应用和修改找到的代码,但结果非常糟糕。发现的发光效果在圆环形状上看起来不错,但是当我将其放置在钻石上时,它看起来根本就不发光。在圆环形状上,您可以看到它的褪色很好,而在钻石上,它恰好是固体。
这是带有菱形的实际代码:
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>
因此,您可以看到此特定的发光代码根据所使用的形状而有所不同。一个人该如何修改代码,使它在钻石上具有良好的外观(就像圆环上的钻石一样)。