gpt4 book ai didi

java - 渲染激光束 - 如何使其面向相机?

转载 作者:行者123 更新时间:2023-12-01 11:07:24 25 4
gpt4 key购买 nike

(我使用的是 LibGDX 框架,它基本上只是 LWJGL(Java) 和 OpenGL 进行渲染)你好,我正在尝试渲染激光束,到目前为止我已经得到了这个效果,laser beam

它只是一个矩形,然后整个效果在片段着色器中完成。

但是,由于它是激光束,我希望矩形面向相机,因此玩家每次都会看到这条红色透明“线”。这让我发疯。我尝试做一些广告牌的东西,但我想要的并不是真正的广告牌。我只想在 Z 轴上旋转它,以便玩家始终看到整条线,仅此而已。没有 X 和 Y 旋转。

enter image description here

正如你所看到的,这就是我想要的。而且这根本不是广告牌。

如果是广告牌,它看起来像这样:enter image description here

我还尝试绘制圆柱体和基于 gl_FragCoord 的效果,效果很好,但坐标有所不同(有时 UV 为 0 和 1,有时为 0 和 0.7)并且它没有对整个纹理进行采样,因此效果被破坏了。

所以我现在不知道该怎么办。我真的很感激任何帮助。提前致谢。

这是 vertexShader 代码:

attribute vec3 a_position;
attribute vec2 a_texCoord0;

uniform mat4 u_worldTrans; //model matrix
uniform mat4 u_view; //view matrix
uniform mat4 u_proj; // projection matrix

varying vec2 v_texCoord0;

void main() {
v_texCoord0 = a_texCoord0;

vec4 worldTrans = u_worldTrans * vec4(a_position, 1.0);

gl_Position = u_proj * u_view * worldTrans;
}

这里是fragmentShader代码E:

#ifdef GL_ES 
precision mediump float;
#endif

varying vec2 v_texCoord0;

uniform sampler2D tex; //texture I apply the red color onto. It's how I get the smooth(transparent) edges.

void main() {
vec4 texelColor = texture2D( tex, v_texCoord0 ); //sampling the texture
vec4 color = vec4(10.0,0.0,0.0,1.0); //the red color

float r = 0.15; //here I want to make the whole texture be red, so when there's less transparency, I want it to be more red, and on the edges(more transparency) less red.
if (texelColor.a > 0.5) r = 0.1;

gl_FragColor = vec4(mix(color.rgb,texelColor.rgb,texelColor.a * r),texelColor.a); //and here I just mix the two colors into one, depengind on the alpha value of texColor and the r float.
}

纹理只是一条中间不透明的白线,但纹理边缘透明。 (平滑过渡)

最佳答案

如果你使用 DecalBatch 来绘制激光,你可以这样做。它被称为轴向广告牌或圆柱形广告牌,而不是您描述的球形广告牌。

基本思想是,计算 Sprite 用于球形广告牌的方向,然后进行几次叉积以获得垂直于轴的该方向的分量。

假设您的激光 Sprite 已向上和向下对齐。您将对相机或激光移动的每一帧进行这一系列计算。

//reusable calculation vectors
final Vector3 axis = new Vector3();
final Vector3 look = new Vector3();
final Vector3 tmp = new Vector3();

void orientLaserDecal (Decal decal, float beamWidth, Vector3 endA, Vector3 endB, Camera camera) {
axis.set(endB).sub(endA); //the axis direction

decal.setDimensions(beamWidth, axis.len());

axis.scl(0.5f);
tmp.set(endA).add(axis); //the center point of the laser

decal.setPosition(tmp);

look.set(camera.position).sub(tmp); //Laser center to camera. This is
//the look vector you'd use if doing spherical billboarding, so it needs
//to be adjusted.
tmp.set(axis).crs(look); //Axis cross look gives you the
//right vector, the direction the right edge of the sprite should be
//pointing. This is the same for spherical or cylindrical billboarding.
look.set(tmp).crs(axis); //Right cross axis gives you an adjusted
//look vector that is perpendicular to the axis, i.e. cylindrical billboarding.

decal.setRotation(look.nor(), axis); //Note that setRotation method requires
//direction vector to be normalized beforehand.
}

我没有检查以确保方向不会翻转,因为我在关闭背面剔除的情况下绘制它。因此,如果您进行了剔除并且看不到 Sprite ,则最后一个叉积步骤可能需要反转其顺序,以便外观 vector 指向相反的方向。

关于java - 渲染激光束 - 如何使其面向相机?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32802811/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com