OpenGL/WebGL用点绘制有立体感的小球

本文实现一个将网格绘制成一个个球形,并有一定的立体感特效,希望对大家有帮助。

整体效果如下:


正常绘制的网格

球形模式绘制

单个球形最终效果:


单个球形
主要的原理是通过点绘制网格,同时设置点的大小,将非圆形区域的像素丢弃,同时给予颜色的明暗变化看上去有些立体感。

这里主要用的步骤有:

1. 网格绘制成点

这一步很简单,调用drawcall的时候使用点模式GL_POINTS就可以了。如:
glDrawArrays(GL_POINTS, 0, 3);

2. 点画圆

点画圆需要借助两个OpenGL内部变量:gl_PointSize、gl_PointCoord。

  • gl_PointSize:一个点占屏幕多少个像素
  • gl_PointCoord:一个像素在点区域的局部坐标,范围是[0.0~1.0]。

默认一个点只有一个像素,gl_PointSize可改变一个点占几个像素,前提是需要调用启用GL_VERTEX_PROGRAM_POINT_SIZE,调用glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);

启用gl_PointSize需在Vertex Shader中指定,代码类似如下:

#version 330 core
layout (location = 0) in vec3 aPos;
void main()
{
   gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
   gl_PointSize = 100;
}

在这里插入图片描述
当指定点绘制大小之后,一个点会占用长宽是gl_PointSize像素的正方形区域。gl_PointCoord就是像素在这个区域的局部坐标,左上角是(0,0), 中心点是(0.5, 0.5), 右下角是(1.0, 1.0)。要想其变成圆形,需要丢弃一部分像素。这个需要在Fragment Shader中借助gl_PointCoord实现,丢弃方式就是根据像素点到圆心的距离,距离大于半径就丢弃:

vec2 coord = gl_PointCoord * 2.0 - vec2(1.0);
if (dot(coord, coord) > 1.0)
 discard;

在这里插入图片描述

3. 立体感

立体感是通过颜色的明暗变化实现的。可以根据当前像素与圆心的距离确定一个颜色衰减因子,实现颜色的变化。下面代码中fNDotV就是衰减因子。

float dist = distance(gl_PointCoord, vec2(0.5));
float fNDotV = sqrt(1.0 - dist * dist * 4);
FragColor = vec4(vec3(1.0f, 0.5f, 0.2f)* fNDotV, 1.0);

衰减因子可以自己根据距离等规则进行调整。

最终的Fragment Shader的代码如下:

#version 330 core
out vec4 FragColor;
void main()
{
    vec2 coord = gl_PointCoord * 2.0 - vec2(1.0);
    if (dot(coord, coord) > 1.0)
        discard;
    float dist = distance(gl_PointCoord, vec2(0.5));
    float fNDotV = sqrt(1.0 - dist * dist * 4);
    FragColor = vec4(vec3(1.0f, 0.5f, 0.2f)* fNDotV, 1.0);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值