如何使用WebGL渲染一簇水晶
水晶体效果
本文示例用随机几何体、光照、纹理贴图、着色器整合起来绘制一个水晶簇。通过调整着色器,可以产生岩浆、蓝宝石等各种效果。
示例效果图:
27个单晶45度随机分布的蓝色水晶簇。
77个单晶180度随机分布的红色水晶簇。
制作随机水晶体生成器
很多三维库的几何体基本都是规则几何体,没有随机的美感,因此捣鼓了一个随机水晶生成器,源码地址:github.com/guoweish/ve…
实现思路如下:
- 生成单个水晶顶点
- 生成水晶簇顶点
实现步骤如下:
- 一个圆周上取多边形点,使用随机角度,形成不同宽度面
...angle = i / faceNumber * PI * 2 + r * angleDithringFactor * angleDithringUnit;px = Math.sin(angle) * polygonCircleRadius;py = Math.cos(angle) * polygonCircleRadius;...
复制代码
- 随机缩放圆半径,圆周上同角度取多边形点,形成不同柱体半径
...pxd = Math.sin(angle) * polygonCircleRadius* (circleRadiusDithringFactor + radiusDithringDistance);pyd = Math.cos(angle) * polygonCircleRadius* (circleRadiusDithringFactor + radiusDithringDistance);...
复制代码
- 形成多边形棱柱的上下两层顶点
...vertexs.topPositions.push(px);vertexs.topPositions.push(py);...
复制代码
- 增加正对圆心的顶点,形成水晶柱顶点
...vertexsCon = [0, cylinderHeight+conHeight, 0];...
复制代码
- 生成一个水晶体几何体
...vertexs = [...vertexsCylinderDown, ...vertexsCylinderTop, ...vertexsCon];...
复制代码
- 矩阵变换缩放、旋转单个水晶体的顶点,并复制顶点
...let scaleMatrix = new Matrix4();scaleMatrix.setScale(scaleFactor, scaleFactor, scaleFactor);let rotateMatrix = new Matrix4();rotateMatrix.setRotate(rotateAngle, rotateCenter.x, rotateCenter.y, rotateCenter.z);...let vScaledRotated = rotateMatrix.multiplyVector4(vScaled);...
复制代码
- 生成水晶簇几何体
...let extendedIndices = extendIndices(cristalTransformed.indices, currentIndicesLength);cluster.indices = cluster.indices.concat(extendedIndices);cluster.positions = cluster.positions.concat(cristalTransformed.positions);cluster.uvs = cluster.uvs.concat(cristal.uvs);...
复制代码
渲染几何体
用纯色shader简单渲染一下是否顶点和索引正确;
- 片元着色器
fragColor = vec4(0.6, 0.6, 0.6, 1.0);
复制代码
添加光照
增加光照,使用Blinn-Phong模型;
- 片元着色器
vec3 diffuse = max(dot(normal, ec_lightDirection), 0.0) * lightColor * lightIntensity * baseColor;vec3 viewDirection = -normalize(ec_position);vec3 halfAngle = normalize(viewDirection + ec_lightDirection);float specularFactor = clamp(dot(normal, halfAngle), 0.0, 1.0);float spec = pow(specularFactor, specularIntensity);vec3 specular = clamp(spec * specularColor, 0.0, 1.0);fragColor = vec4(diffuse + specular + ambient, 1.0);
复制代码
着色器添加渐变的祖母绿效果
为了看上去像祖母绿宝石效果,用纹理做一个渐变;用pow函数使得渐变非线性,用mix函数融合得颜色,看上去效果更自然;
- 片元着色器
...float colorMixFactor = pow(v_uv.y, 3.0);...vec3 baseColor = mix(CRISTAL_COLOR, GEM_COLOR_GREEN, colorMixFactor);...
复制代码
使用贴图增强表面细节
为了表面有石头纹样效果,找一张大理石图片做贴图过滤一下颜色;魔改一下光照模型,贴图过滤diffuse而不过滤specular,这样使得表面反色不受影响而产生表面光滑的效果;
- 片元着色器
...fragColor = vec4(diffuse + diffuse * textureFilter + specular + AMB_COLOR, 1.0);
复制代码
结语
可以使用perlin噪音和fbm让随机几何体的视觉效果自然,比如大小个体比例和空间位置的分布;光照可以改用pbr模型,比Blinn-Phong会更好,计划下一篇更新尝试(希望有空填坑-_-!!)。
关于作者
郭不耐 github.com/guoweish
参考文献
Webgl Programing Guide
OpenGl Shading Language
The Book of Shaders
ShaderToy
转载于:https://juejin.im/post/5c7290b36fb9a049b07dfb98
如何使用WebGL渲染一簇水晶相关推荐
- webgl渲染Yuv420P图像
Yuv420P格式在安防视频中非常常见,因为H264或者H265解码之后,就是这种格式. YUV定义了三个分量:"Y"表示明亮度(Luminance或Luma)也就是灰度值.U和V ...
- WebGL渲染2D图形
WebGL是OpenGL ES 2.0的Web标准,它结合JavaScript在HTML5的<canvas></canvas>上渲染图形.WebGL现在已经是HTML5 Can ...
- PixiJS - 最快、最灵活的 2D WebGL 渲染引擎
最快.最灵活 的 2D 渲染引擎,它能够在我们没有 WebGL 知识的情况下享受硬件加速的力量 优势 通过 WebGL 来调用 GPU 渲染动画,极大的提升了性能 兼容性好* 支持 WebGL 和 c ...
- WebGL渲染错误:GL_INVALID_FRAMEBUFFER_OPERATION: Draw framebuffer is incomplete
出现这个framebuffer is incomplete的错误,一般是由于rendertarget设置有问题,比如缓冲区目标是否有效.使用上有没有冲突以及缓冲的尺寸是否设置非法等.
- webGL、webGPU、封装、渲染引擎 three.js、游戏引擎,定位是游戏开发,在前面的渲染引擎基础上,还提供了骨骼动画、物理引擎、AI、GUI 等功能,以及可视化编辑器来设计关卡,支撑大型游戏
https://zhuanlan.zhihu.com/p/162878354 如何选择 WebGL 框架和引擎? 知道得越多,不知道的就更多了 数据可视化Sugar-百度智能云 cloud.ba ...
- [软件渲染器入门]六-应用纹理、背面剔除以及一些WebGL相关
译者前言: 本文译自MSDN,原作者为David Rousset,文章中如果有我的额外说明,我会加上[译者注:]. 正文开始: 下面是本系列的最后一个章节了.我们将看到如何从Blender中导出贴图和 ...
- Canvas + WebGL中文艺术字渲染
笔者另一篇文章 https://segmentfault.com/a/11... 讲了基于Canvas的文本编辑器"简诗"的实现,其中文字由WebGL渲染艺术效果,这篇文章主要讲述 ...
- 卜若的代码笔记-webgl系列-第三章:几何渲染Rendering Geometry
1 在webgl里面表述几何体最关键的两种数据类型: 顶点和索引(vertices and indices.) 1.1 顶点是什么? 顶点定义了3D对象的角点,每一个顶点由三个元素组成x,y,z. 在 ...
- WebGL树形结构的模型渲染流程
今天和大家分享的是webgl渲染树形结构的流程.用过threejs,babylonjs的同学都知道,一个大模型都是由n个子模型拼装而成的,那么如何依次渲染子模型,以及渲染每个子模型在原生webgl中的 ...
最新文章
- 使用createrepo自建yum源
- python数据模型搭建_python之路(19)django数据库模型(model)
- 计算机争夺战作文,电脑争夺战作文600字
- 自适应移动设备页面的设计
- StudyTonight 中文系列教程【翻译完成】
- Android开发学习笔记---搭建Android开发环境
- TCP层的分段和IP层的分片之间的关系 MTU和MSS之间的关系
- 开关电源matlab仿真文件,基于PI控制方式的7A开关电源的MATLAB仿真.doc
- 百度地图开放平台web api 获取上海市所有小区信息
- table实现radio单选效果
- 【工作日记18】渗透测试之xml注入攻击、CRLF漏洞
- OpenGL纹理叠加基础知识
- java计算机毕业设计青岛地区常见昆虫图鉴与论坛源码+数据库+lw文档+系统
- spaCy 2.1 中文NLP模型
- 华为mate50os鸿蒙,华为Mate50将如期发布,屏下镜头+鸿蒙OS,再见iPhone12
- 移动开发唱衰,iOS 开发者如何涅槃重生?
- java微信小程序的校园外卖点餐平台 uniapp
- homepod怎么设置为中文_HomePod终于能听懂中文了,但它真能搞定智能家居吗?
- C++经典算法题-洗扑克牌(乱数排列)
- sqlserver查询时间范围