THREE.JS GLSL精灵始终位于相机之前 [英] THREE.JS GLSL sprite always front to camera
问题描述
我正在为停车灯创建发光效果,并找到了可以始终面对相机的着色器:
I'm creating a glow effect for car stop lights and found a shader that makes it possible to always face the camera:
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 );
}
此解决方案非常简单,几乎可以解决.它对相机的移动有反应,效果很好.但是这个元素是汽车的孩子.汽车本身在四处移动,旋转时,物料停止直接指向相机.
This solution is quite simple and almost works. It reacts to camera movement and it would be great. BUT this element is a child of a car. The car itself is moving around and when it rotates the material stops pointing directly at the camera.
我不想使用SpritePlugin或LensFlarePlugin,因为它们会使我的游戏速度降低20fps,因此我将坚持使用这种轻量级的解决方案.
I don't want to use SpritePlugin or LensFlarePlugin because they slow down my game by 20fps so I'll stick to this lightweight solution.
我找到了Direct 3d的解决方案,您必须从转换矩阵中删除旋转数据,但是我不知道如何在THREE.js中做到这一点
I found a solution for Direct 3d that you have to remove rotation data from tranformation matrix, but I don't know how to do this in THREE.js
我猜想,与其通过汽车变换来添加计算,还必须有一种简化此着色器的方法.
I guess that instead of adding calculations with car transformation there must be a way to simplify this shader instead.
如何简化此着色器,使材质始终面对相机?
How to simplify this shader so the material always faces the camera?
从下面的链接:要进行球形广告牌,只需通过设置单位矩阵来消除所有旋转".如何在THREE.js中执行ShaderMaterial? http://www.geeks3d.com/20140807/billboarding-vertex-shader- glsl/
From the link below: "To do spherical billboarding, just remove all rotations by setting the identity matrix". How to do it ShaderMaterial in THREE.js? http://www.geeks3d.com/20140807/billboarding-vertex-shader-glsl/
我认为这里的问题是在传递给着色器之前从ShaderMaterial截取了转换矩阵,但我不确定.
The problem here I think is intercepting transformation matrix from ShaderMaterial before it's passed to the shader, but I'm not sure.
可能无关紧要,但这也是片段着色器:
Probably irrelevant but here's also fragment shader:
uniform vec3 glowColor;
varying float intensity;
void main() {
vec3 glow = glowColor * intensity;
gl_FragColor = vec4( glow, 1.0 );
}
编辑:目前,我找到了一种解决方法,该方法是通过设置相反的四元数来消除父级的旋转影响.不完美,这是在CPU而非GPU中发生的
edit: for now I found a workaround which is eliminating parent's rotation influence by setting opposite quaternion. Not perfect and it's happening in CPU not GPU
this.quaternion._x = -this.parent.quaternion._x;
this.quaternion._y = -this.parent.quaternion._y;
this.quaternion._z = -this.parent.quaternion._z;
this.quaternion._w = -this.parent.quaternion._w;
推荐答案
您是否正在寻找实现广告牌的方法? (使2D精灵始终面向相机)如果是这样,您需要做的是:
Are you looking for an implementation of billboarding? (make a 2D sprite always face camera) If so, all you need to do is this:
"vec3 billboard(vec2 v, mat4 view){",
" vec3 up = vec3(view[0][1], view[1][1], view[2][1]);",
" vec3 right = vec3(view[0][0], view[1][0], view[2][0]);",
" vec3 p = right * v.x + up * v.y;",
" return p;",
"}"
v
是距中心的偏移量,基本上是面向z轴的平面中的4个顶点.例如. (1.0, 1.0), (1.0, -1.0), (-1.0, 1.0), and (-1.0, -1.0).
v
is the offset from the center, basically the 4 vertices in a plane that faces the z-axis. Eg. (1.0, 1.0), (1.0, -1.0), (-1.0, 1.0), and (-1.0, -1.0).
像这样使用它:
"vec3 worldPos = billboard(a_offset, u_view);"
// then do whatever else.
这篇关于THREE.JS GLSL精灵始终位于相机之前的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!