使用opengl做的粒子系统有些问题,求大神指教

云络 2018-11-02 03:59:55
下图效果是使用粒子系统生成的,我感觉红框里面的两个红包相互影响了,但是有一些又不会有影响,求大神指出问题所在


红包的原图是这个,除了中间的红包,其余透明度都为0,因为工程需要,所以透明度为0的部分不能裁剪掉

绘制的流程比较简单,就是使用几何着色器去生成顶点和UV,再在片段着色器中绘制,下面是几何着色器的部分代码:
out vec2 UV;
out vec4 color;
//获取相机坐标系中的坐标
vec4 GetLocalCoord(vec3 position)
{
vec4 view_coord = view_matrix * particle_model_matrix * vec4(position, 1);
return view_coord;
}

//DrawRectangle根据当前输入的点的坐标计算矩形的四个顶点坐标以及uv
void DrawRectangle(vec3 center_position, float size, float ratio)
{
color = particle[0].color;
color.a = particle[0].opacity;

float width_half_size = size / 2;
float height_half_size = width_half_size / ratio;
vec4 local_coord = GetLocalCoord(center_position);
local_coord.x = local_coord.x / local_coord.a;
local_coord.y = local_coord.y / local_coord.a;
local_coord.z = local_coord.z / local_coord.a;
local_coord.a = 0;

vec4 top_left = vec4(-width_half_size, height_half_size, 0.0, 1.0);
vec4 top_right = vec4(width_half_size, height_half_size, 0.0, 1.0);
vec4 bottom_left = vec4(-width_half_size, -height_half_size, 0.0, 1.0);
vec4 bottom_right = vec4(width_half_size, -height_half_size, 0.0, 1.0);

vec4 top_left_rotate = particle[0].rotation_matrix * top_left;
vec4 top_right_rotate = particle[0].rotation_matrix * top_right;
vec4 bottom_left_rotate = particle[0].rotation_matrix * bottom_left;
vec4 bottom_right_rotate = particle[0].rotation_matrix * bottom_right;

top_left_rotate = vec4(top_left_rotate.x / top_left_rotate.a, top_left_rotate.y / top_left_rotate.a, 0.0, 1.0) + local_coord;
top_right_rotate = vec4(top_right_rotate.x / top_right_rotate.a, top_right_rotate.y / top_right_rotate.a, 0.0, 1.0) + local_coord;
bottom_left_rotate = vec4(bottom_left_rotate.x / bottom_left_rotate.a, bottom_left_rotate.y / bottom_left_rotate.a, 0.0, 1.0) + local_coord;
bottom_right_rotate = vec4(bottom_right_rotate.x / bottom_right_rotate.a, bottom_right_rotate.y / bottom_right_rotate.a, 0.0, 1.0) + local_coord;

vec4 top_left_screen = projection_matrix * top_left_rotate;
vec4 top_right_screen = projection_matrix * top_right_rotate;
vec4 bottom_left_screen = projection_matrix * bottom_left_rotate;
vec4 bottom_right_screen = projection_matrix * bottom_right_rotate;

UV = vec2(0.0, 1.0);
gl_Position = top_left_screen;
EmitVertex();

UV = vec2(1.0, 1.0);
gl_Position = top_right_screen;
EmitVertex();

UV = vec2(0, 0);
gl_Position = bottom_left_screen;
EmitVertex();

UV = vec2(1.0, 0);
gl_Position = bottom_right_screen;
EmitVertex();
EndPrimitive();
}


下面是片段着色器中的代码:


uniform sampler2D framebuffer_sampler;
uniform sampler2D particle_texture;
uniform int blend_mode;
uniform bool is_use_texture = false;
uniform vec2 resolution = vec2(720, 1080);

in vec2 UV;
in vec4 color;
out vec4 Frag_Color;

void DoBlend()
{
float src_luma = Frag_Color.r * Frag_Color.a;
float src_alpha = Frag_Color.a;

vec2 p = gl_FragCoord.xy / resolution.xy;
vec4 frame_buffer_color = texture(framebuffer_sampler, p);
vec4 src_cor = Frag_Color; //top color
vec4 dst_cor = frame_buffer_color; //base color
vec3 blend_color = vec3(0.0);
float result_alpha = src_cor.a + (1 - src_cor.a)*dst_cor.a;
switch (blend_mode)
{
case 0:
blend_color = src_cor.rgb;
break;
case 1:
blend_color = src_cor.rgb + dst_cor.rgb;
break;
case 19:
blend_color = max(src_cor.rgb, dst_cor.rgb);
break;
case 30:
blend_color = src_cor.rgb + dst_cor.rgb - (src_cor.rgb * dst_cor.rgb);
break;
default:
blend_color = src_cor.rgb;
break;
}
if (result_alpha != 0)
Frag_Color.rgb = (1 - src_cor.a/result_alpha)*dst_cor.rgb + (src_cor.a/result_alpha)*((1 - dst_cor.a)*src_cor.rgb + dst_cor.a * blend_color);
else
Frag_Color.rgb = blend_color;

Frag_Color.a = result_alpha;
}

void main()
{
Frag_Color = texture(particle_texture, UV);
Frag_Color.a = color.a * Frag_Color.a;
DoBlend();
}

如果需要其他代码的话,我后面再贴
...全文
109 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
云络 2018-11-06
  • 打赏
  • 举报
回复
这个问题基本解决了,是混合函数的问题,但是问题很诡异,我使用glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)去进行混合就不会有这样的问题,如果有人知道是什么原因的话还请赐教。后面需要旋转的时候再加上深度检测去绘制。
赵4老师 2018-11-03
  • 打赏
  • 举报
回复
更绝的是还会发生两个红包在3D空间中交叉重叠(侧视图呈“×”字形,前视图和顶视图呈“日”字形。)的情况。
赵4老师 2018-11-03
  • 打赏
  • 举报
回复
比如50%透明,上下两个红包,上边红包的下半边和下边红包的上半边完全重叠,呈“目”字形。,此时点击中间重叠部分,你到底算只点了上边,或者只点了下边,还是两个都点了?三个重叠呢?N(N>3)个重叠呢?
如果不透明,就不会有问题了。
云络 2018-11-03
  • 打赏
  • 举报
回复
引用 8 楼 zhao4zhong1 的回复:
半透明和楼主的需求是矛盾的。
可以具体说说是什么矛盾吗,因为我看到AfterEffect的trapcode插件是支持这样的效果的,所以我觉得应该是有实现的办法的吧,可能是我的思路不对,赵老师能否给些关键字,我去找找资料
赵4老师 2018-11-03
  • 打赏
  • 举报
回复
半透明和楼主的需求是矛盾的。
云络 2018-11-02
  • 打赏
  • 举报
回复
现在渲染的话使用的framebuffer_texture是framebuffer绑定的纹理,就是说从自身读取,然后绘制到自身,如果这样会有问题的话,那要怎么样绘制会比较好
云络 2018-11-02
  • 打赏
  • 举报
回复
引用 5 楼 smwhotjay 的回复:
不搞半透明
半透明是一定要的
smwhotjay 2018-11-02
  • 打赏
  • 举报
回复
不搞半透明
云络 2018-11-02
  • 打赏
  • 举报
回复
看来是混合模式出了问题,下图是我绘制两个半透明的矩形叠加在一起的情况,那我该怎么去解决呢,看图片的话是有一部分像素没有起作用,而另一部分起作用了,可是不应该是每个像素都是执行相同的操作吗
云络 2018-11-02
  • 打赏
  • 举报
回复
引用 2 楼 smwhotjay 的回复:
调试线框模式 看下那里到底是什么图形导致的。
好,我去试试
smwhotjay 2018-11-02
  • 打赏
  • 举报
回复
调试线框模式 看下那里到底是什么图形导致的。
云络 2018-11-02
  • 打赏
  • 举报
回复
我自己想到一个,可能是Z-fighting的问题,不知道是不是

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧