当前位置:首页 > NFT资讯 > 玩转元宇宙NFT,3个步骤11张图,上架我的蘑菇艺术品

玩转元宇宙NFT,3个步骤11张图,上架我的蘑菇艺术品

admin1个月前 (08-24)NFT资讯18

如何使用Three.js绘制NFT蘑菇窗体顶端

第 1 部分:简介

在本文中,我将尝试简要而完整地概述如何创造艺术并将你的艺术品发布到NFTNon-FungibleToken非同质化代币)网站进行售卖。以及如何在区块链上制作艺术品艺术品蘑菇的设计将会使用到JavaScript以及Three.js本文将告诉大家在虚拟世界如何生成和发布艺术品。

背景

出于兴趣笔者会编写一些寻常的东西。就在新年期间,关于NFT的消息让笔者感到震惊这也是为什么会尝试在这种模式下创造一些有创意的东西。虽说将JPEG上传到区块链的想法并不新奇但是能够将艺术品上链的可能性却让人满怀期待

简而言之,它背后的想法是通过代币生成器,每次你铸造的时候售卖给你一个独特的艺术品(实际上,调用区块链方法花费你购买艺术家创造的艺术品)。毫无疑问,这笔易会产生一个独特的对象,永远存储在区块链中,不可否认这种交易具备一种魔力,不是吗?

由此有一些艺术平台利用了这个想法,其中最著名的是artblocks.io建立在太坊区块链的基础上,它仍然使用proof-of-work(工作量证明)的模式并且Gas(手续费)非常高,于是笔者决定尝试一个更民主、更便宜、环保平台-fxhash.xyz

什么是生成式 NFT 艺术品?

所有的生成NFTNFT,全称为Non-Fungible Token,指非同质化代币,包括jpg和视频剪辑形式是用于表示数字资产的唯一加密货币令牌,可以买卖。NFT的艺术品基本上都网页的方式呈现使用vanillaJavaScript或一些第三方库在画布上绘制艺术品NFT艺术品可以分为3类:抽象数学艺术品、有形程序艺术品和可变手绘艺术品。

如图1所示,

第一类,抽象数学,利用一些数学概念来生成抽象图像:可能有一些分形fractals一种复杂的几何形状、吸引子attractors一个系统有朝某个稳态发展的趋势,这个稳态就叫做吸引子、元胞自动机cellular automata,是一种时间、空间、状态都离散,空间相互作用和时间因果关系为局部的网格动力学模型,具有模拟复杂系统时空演化过程的能力。

等。

第二类,有形程序艺术试图使用参数化的方式来描述一些具体的事物。

第三类,可变手绘艺术品,是对图像预先绘制的部分进行简单随机化处理

1

此外,还有一些实验性和互动性的作品,甚至还有模块化合成器和游戏之类的艺术品不过比较少见。

文章描述一个蘑菇(艺术品)创作过程,并使用事务哈希对其进行随机化。结合艺术视野、构图和风格化等手段创作了这个生成式NFT艺术品

第 2 部分:画蘑菇

Otinium caseubbacula —生殖蘑菇标本之一

在介绍王理论知识之后,让我们进入技术环节。项目完全使用Three.js库,它有一个使用简单的JavaScript在网上很容易查找到它的API使用方式。

生成菌柄

首先要绘制出菌柄样条线(我们称其为基本样条线样条线的作用是辅助生成实体,针对该样条线进行参数化形成菌柄的轮廓。为了创建基本样条线,使用了Three.js中的CatmullRomCurve3类。然后,通过沿基本样条线移动,创造闭合形状来构建对应的几何图形,最后将这些图形连接起来,如图2所示为此使用了Three.js中的BufferGeometry组件

代码入如下:

stipe_vSegments=30;// vertical resolution

stipe_rSegments=20;// angular resolution

stipe_points=[];// vertices

stipe_indices=[];// face indices

stipe_shape=newTHREE.CatmullRomCurve3(...,closed=false);

functionstipe_radius(a,t){...}

for(vart=0;t<1;t+=1/stipe_vSegments){

// stipe profile curve

varcurve=newTHREE.CatmullRomCurve3([

newTHREE.Vector3(0,0,stipe_radius(0,t)),

newTHREE.Vector3(stipe_radius(Math.PI/2,t),0,0),

newTHREE.Vector3(0,0,-stipe_radius(Math.PI,t)),

newTHREE.Vector3(-stipe_radius(Math.PI*1.5,t),0,0),

],closed=true,curveType=catmullrom,tension=0.75);

varprofile_points=curve.getPoints(stipe_rSegments);

for(vari=0;i<profile_points.length;i++){

stipe_points.push(profile_points[i].x,profile_points[i].y,profile_points[i].z);

}

}

//

// and then create a BufferGeometry

varstipe=newTHREE.BufferGeometry();

stipe.setAttribute(position,newTHREE.BufferAttribute(newFloat32Array(stipe_points),3));

stipe.setIndex(stipe_indices);

stipe.computeVertexNormals();

菌柄生成的阶段:样条、顶点、面

2

菌柄噪声

为了菌柄看上去自然,表面随着高度而发生变化,我们定义了噪声函数,该函数对半径进行定义,通过改变基本样条曲线上点的角度和相对高度两个参数的方式生成不一样的半径信息如下代码所示。

base_radius=1;// mean radius

noise_c=2;// higher this - higher the deformations

// stipe radius as a function of angle and relative position

functionstipe_radius(a,t){

returnbase_radius+(1-t)*(1+Math.random())*noise_c;

}

菌柄噪声变化

3

如图3所示,通过半径的噪声函数,根据角度和高度生成不同的半径。

菌帽的生成方式,也可以通过菌柄顶部加入旋转的样条曲线,然后再对曲线进行数化来完成这里可以可以将旋转产生的表面命名为基础表面然后定义基础表面在基础样条上的位置加入围绕菌柄顶部旋转的函数。这种参数化的编程方式方便后面加入噪声函数代码如下:

adial resolution

cap_cSegments=20;// angular resolution

cap_points=[];

cap_indices=[];

// cap surface as a function of polar coordinates

functioncap_surface(a0,t0){

// 1. compute (a,t) from (a0,t0), e.g apply noise

// 2. compute spline value in t

// 3. rotate it by angle a around stipe end

// 4. apply some other noises/transformations

...

returnsurface_point;

}

// spawn surface vertices with resolution

// cap_rSegments * cap_cSegments

for(vari=1;icap_rSegments;i++){

vart0=i/cap_rSegments;

for(varj=0;j<cap_cSegments;j++){

vara0=Math.PI*2/cap_cSegments*j;

varsurface_point=cap_surface(a0,t0);

cap_points.push(surface_point.x,surface_point.y,surface_point.z);

}

}

//

// and then create a BufferGeometry

varcap=newTHREE.BufferGeometry();

cap.setAttribute(position,newTHREE.BufferAttribute(newFloat32Array(cap_points),3));

cap.setIndex(cap_indices);

cap.computeVertexNormals();

帽生成阶段:样条、顶点、面

4

如图4所示,通过基础样条以及顶点生成基础平面,这个平明就是菌帽。

帽噪音

同样为了让艺术品看上去更加真实,需要加入一些噪音。我将帽噪声分为3:径向噪声、角度噪声和法线噪声。径向噪声会影响顶点在基本样条上的相对位置。角噪声改变了围绕柄顶部基本样条旋转的角度。

最后,法线噪声会改变顶点沿基面的位置。在坐标系中定义帽表面时,对扭曲应用2dPerlin噪声,因此这里使用noisejs,来完成上述功能代码如下:

functionradnoise(a,t){

return-Math.abs(NOISE.perlin2(t*Math.cos(a),t*Math.sin(a))*0.5);

}

functionangnoise(a,t){

returnNOISE.perlin2(t*Math.cos(a),t*Math.sin(a))*0.2;

}

functionnormnoise(a,t){

returnNOISE.perlin2(t*Math.cos(a),t*Math.sin(a))*t;

}

functioncap_surface(a0,t0){

// t0 -> t by adding radial noise

vart=t0*(1+radnoise(a,t0));

// compute normal vector in t

varshape_point=cap_shape.getPointAt(t);

vartangent=cap_shape.getTangentAt(t);

varnorm=newTHREE.Vector3(0,0,0);

constz1=newTHREE.Vector3(0,0,1);

norm.crossVectors(z1,tangent);

// a0 -> a by adding angular noise

vara=angnoise(a0,t);

varsurface_point=newTHREE.Vector3(

Math.cos(a)*shape_point.x,

shape_point.y,

Math.sin(a)*shape_point.x

);

// normal noise coefficient

varsurfnoise_val=normnoise(a,t);

// finally surface point

surface_point.x+=norm.x*Math.cos(a)*surfnoise_val;

surface_point.y+=norm.y*surfnoise_val;

surface_point.z+=norm.x*Math.sin(a)*surfnoise_val;

returnsurface_point;

}

从左到右的噪声分量:径向、角度、法线

5

如图5所示,从左到右分别给菌帽径内噪声、角度噪声和法线噪声。

蘑菇的其余部分:鳞片、鳃、环

鳃和环的几何形状与帽的几何形状非常相似。可以在表面上的一些随机锚点周围生成嘈杂的顶点,然后基于它们创建ConvexGeometry代码如下:

bufgeoms=[];

scales_num=20;

n_vertices=10;

scale_radius=2;

for(vari=0;i<scales_num;i++){

varscale_points=[];

// choose a random center of the scale on the cap

vara=Math.random()*Math.PI*2;

vart=Math.random();

varscale_center=cap_surface(a,t);

// spawn a random point cloud around the scale_center

for(varj=0;j<n_vertices;j++){

scale_points.push(newTHREE.Vector3(

scale_center.x+(1-Math.random()*2)*scale_radius,

scale_center.y+(1-Math.random()*2)*scale_radius,

scale_center.z+(1-Math.random()*2)*scale_radius

);

}

// create convex geometry using these points

varscale_geometry=newTHREE.ConvexGeometry(scale_points);

bufgeoms.push(scale_geometry);

}

// join all these geometries into one BufferGeometry

varscales=THREE.BufferGeometryUtils.mergeBufferGeometries(bufgeoms);

鳞片、鳃、环和蘑菇的完整几何形状

6

如图6所示,绘制出鳞片、鳃、环和蘑菇的完整几何形状

碰撞检查

由于在同一个场景中生成多个蘑菇,此时蘑菇之间会产生交叉层叠的情况,所以需要检查它们之间的碰撞关系这里使用一个代码片段来自检测每个网格点的光线投射,从而达到检查蘑菇碰撞的目的

为了减少计算时间,生成了蘑菇的低多边形双胞胎以及蘑菇本身。然后使用这个低多边形模型来检查与其他蘑菇的碰撞。

代码如下:

for(varvertexIndex=0;vertexIndex<Player.geometry.attributes.position.array.length;vertexIndex++)

{

varlocalVertex=newTHREE.Vector3().fromBufferAttribute(Player.geometry.attributes.position,vertexIndex).clone();

varglobalVertex=localVertex.applyMatrix4(Player.matrix);

vardirectionVector=globalVertex.sub(Player.position);

varray=newTHREE.Raycaster(Player.position,directionVector.clone().normalize());

varcollisionResults=ray.intersectObjects(collidableMeshList);

if(collisionResults.length>0&&collisionResults[0].distance<directionVector.length())

{

// a collision occurred... do something...

}

}

用于更快碰撞检查的简化模型

7

如图7所示,检查蘑菇的碰撞效果

渲染和风格化

最初,想实现2d绘图的效果,尽管所有的生成都是用3d制作的。在风格化的背景下,首先想到的是轮廓效果。由于我们不是着色器方面的专家,所以只是从这个例子中获取了轮廓效果,并得到蘑菇轮廓铅笔风格。

三个js轮廓效果

8

如图8所示,显示蘑菇的铅笔画风格。

接着就是着色了,蘑菇的纹理应该有点嘈杂并且有一些柔和的阴影。这里有一个简便的方式就是使用BufferGeometryAPI定义对象的顶点颜色。使用这种方法还可以将顶点的颜色进行参数化也就是加入角度和位置作为参数从而改变颜色,因此噪声纹理的生成变得稍微容易一些

添加一些顶点颜色

9

如图9所示,通过角度和位置给顶点添加颜色。

最后,使用EffectComposer添加了一些全局噪声和类似膜颗粒效果Film Grain是模拟照相膜的随机光学纹理代码如下:

varrenderer=newTHREE.WebGLRenderer({antialias:true});

outline=newTHREE.OutlineEffect(renderer,{thickness:0.01,alpha:1,defaultColor:[0.1,0.1,0.1]});

varcomposer=newTHREE.EffectComposer(outline);

//

varrenderPass=newTHREE.RenderPass(scene,camera);

composer.addPass(renderPass);

varfilmPass=newTHREE.FilmPass(

0.20,// noise intensity

0.025,// scanline intensity

648,// scanline count

false,// grayscale

);

composer.addPass(filmPass);

composer.render();

几乎准备好了,彩色和嘈杂的蘑菇

10

如图10所示,即将要完成的蘑菇。

起个名字

对于起名字这件事,使用了一个简单的马尔可夫链,它接受了1k个蘑菇名称的训练。为了预处理和标记这些名称,使用了pythonYouTokenToMe。有了它,可以将所有名称拆分为200个唯一标记,并将它们的转换概率写入JavaScript典。代码的JS端只读取这些概率并堆叠标记,直到它生成几个单词。

以下是使用这种方法生成的一些蘑菇名称示例:

Stricosphaete cinus

Fusarium sium confsisomyc

Etiformansum poonic

Hellatatum bataticola

Armillanata gossypina mortic

Chosporium anniiffact

Fla po sporthrina

第 3 部分:完成

11

如图11所示,fxhash上铸造的15个蘑菇

准备发布

首先,要准备一个项目在fxhash上发布,只需将代码中的所有随机调用更改为fxrand()方法。主要思想是必须为每个哈希生成唯一的输出,需要对相同的哈希生成完全相同的输出。然后在沙箱中测试令牌,最后在打开铸币时铸币。而已!

这将我们带到了蘑菇地图集(我将这个集合命名为)。您可以在此处查看并查看其变化。虽然它不像笔者之前的一些作品那样售罄,但笔者认为这是他艺术生涯最先进和最具挑战性的作品。希望铸造这个代币的人也能在NFT的世界中享受他们的真菌!

原文地址:https://hackernoon.com/how-to-draw-generative-nft-mushrooms-with-threejs

相关文章

NFT行业下一个风口:音乐NFT

2021年被称为NFT元年,艺术领域掀起了一股NFT热潮并持续至今。由于NFT的核心价值在于数字内容资产化,推动内容资产价值的全面重估,因此NFT技术在音乐、影...

加密社区在一家时髦的长岛酒店度过了“NFT 周末”尴尬地混在一起

上周末,在长岛北叉格林波特的声景酒店,一对夫妇热情地拥抱在一张已经布置了丰盛晚餐的桌子上。起初我很担心——发生了什么事吗?一些坏消息?然后我记得这些是表演者。整...

NFT研究-快速认可NFT

前几年NFT艺术圈子里还光是单纯的区块链圈子里的玩具。2021年,这一NFT在我们艺术环界掀起的狂澜。这一刻里,看看围绕着NFT艺术圈的,看似来可来信,哪些是由...

NFT的诞生及NFT的里程碑

NFT诞生2014年5月3日,由Kevin McCoy和Anil Dash在纽约市新博物馆的会议上现场创建的:第一次通过链上元数据明确地将一个不可替代的、可交易...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。