如何保持 json 模型在 three.js 场景中旋转的发光效果?
How to maintain the glow effect of a json model rotating in three.js scene?
我在场景中添加了一个 json 具有发光效果的模型。
如下:
我尝试自动旋转 json 模型。
但是,旋转时看起来很奇怪。
模型的发光效果不起作用。
我假设json模型在旋转时不会改变模型的位置。结果,当这个模型旋转时,ShaderMaterial 的 viewVector.value 是恒定的(我不改变相机的位置)。
if(jsonMesh){
jsonMesh.rotation.y += 0.1;
jsonMesh.material.uniforms.viewVector.value =
new THREE.Vector3().subVectors( camera.position, jsonMesh.position );
}
这是Three.ShaderMaterial。
顶点着色器和片段着色器
<script id="vertexShader" type="x-shader/x-vertex">
uniform vec3 viewVector;
uniform float c;
uniform float p;
varying float intensity;
void main()
{
vec3 vNormal = normalize( normalMatrix * normal );
vec3 vNormel = normalize( normalMatrix * viewVector );
intensity = pow( c - dot(vNormal, vNormel), p );
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
</script>
<script id="fragmentShader" type="x-shader/x-fragment">
uniform vec3 glowColor;
varying float intensity;
void main()
{
vec3 glow = glowColor * intensity;
gl_FragColor = vec4( glow, 1.0 );
}
</script>
Three.ShaderMaterial.
var customMaterial = new THREE.ShaderMaterial(
{
uniforms:
{
"c": { type: "f", value: 1.0 },
"p": { type: "f", value: 1.4 },
glowColor: { type: "c", value: new THREE.Color(0xffff00) },
viewVector: { type: "v3", value: camera.position }
},
vertexShader: document.getElementById( 'vertexShader' ).textContent,
fragmentShader: document.getElementById( 'fragmentShader' ).textContent,
side: THREE.FrontSide,
blending: THREE.AdditiveBlending,
transparent: true
}
);
这种情况下应该如何修改代码?
这里是 Demo and source code.
您可以为此使用内置的 three.js 函数。我没有使用相机位置,而是选择向您展示如何在世界中设置光源位置。这样您就可以将自定义着色器上的光源与您计划稍后添加到 3d 世界的任何光源相匹配。随意将 worldLightPoint 值更改为 camera.position 而不是新的 THREE.Vector3(100,100,100)。在这种情况下,效果将随着相机位置的变化而保持不变。
var v = new THREE.Vector3();
//var worldLightPoint = camera.position;
var worldLightPoint = new THREE.Vector3(100,100,100);
function update()
{
controls.update();
stats.update();
if(jsonMesh){
jsonMesh.rotation.y += 0.1;
jsonMesh.material.uniforms.viewVector.value = jsonMesh.worldToLocal(v.copy(worldLightPoint));
}
}
我在场景中添加了一个 json 具有发光效果的模型。
如下:
我尝试自动旋转 json 模型。
但是,旋转时看起来很奇怪。
模型的发光效果不起作用。
我假设json模型在旋转时不会改变模型的位置。结果,当这个模型旋转时,ShaderMaterial 的 viewVector.value 是恒定的(我不改变相机的位置)。
if(jsonMesh){
jsonMesh.rotation.y += 0.1;
jsonMesh.material.uniforms.viewVector.value =
new THREE.Vector3().subVectors( camera.position, jsonMesh.position );
}
这是Three.ShaderMaterial。
顶点着色器和片段着色器
<script id="vertexShader" type="x-shader/x-vertex">
uniform vec3 viewVector;
uniform float c;
uniform float p;
varying float intensity;
void main()
{
vec3 vNormal = normalize( normalMatrix * normal );
vec3 vNormel = normalize( normalMatrix * viewVector );
intensity = pow( c - dot(vNormal, vNormel), p );
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
</script>
<script id="fragmentShader" type="x-shader/x-fragment">
uniform vec3 glowColor;
varying float intensity;
void main()
{
vec3 glow = glowColor * intensity;
gl_FragColor = vec4( glow, 1.0 );
}
</script>
Three.ShaderMaterial.
var customMaterial = new THREE.ShaderMaterial(
{
uniforms:
{
"c": { type: "f", value: 1.0 },
"p": { type: "f", value: 1.4 },
glowColor: { type: "c", value: new THREE.Color(0xffff00) },
viewVector: { type: "v3", value: camera.position }
},
vertexShader: document.getElementById( 'vertexShader' ).textContent,
fragmentShader: document.getElementById( 'fragmentShader' ).textContent,
side: THREE.FrontSide,
blending: THREE.AdditiveBlending,
transparent: true
}
);
这种情况下应该如何修改代码? 这里是 Demo and source code.
您可以为此使用内置的 three.js 函数。我没有使用相机位置,而是选择向您展示如何在世界中设置光源位置。这样您就可以将自定义着色器上的光源与您计划稍后添加到 3d 世界的任何光源相匹配。随意将 worldLightPoint 值更改为 camera.position 而不是新的 THREE.Vector3(100,100,100)。在这种情况下,效果将随着相机位置的变化而保持不变。
var v = new THREE.Vector3();
//var worldLightPoint = camera.position;
var worldLightPoint = new THREE.Vector3(100,100,100);
function update()
{
controls.update();
stats.update();
if(jsonMesh){
jsonMesh.rotation.y += 0.1;
jsonMesh.material.uniforms.viewVector.value = jsonMesh.worldToLocal(v.copy(worldLightPoint));
}
}