Estou participando do evento Nuggets Experience sobre o código, detalhes: mostre seus blocos de código criativos
prefácio
Olá a todos, este é o mágico de CSS e WebGL - alphardex. Neste artigo, vamos usar o componente raymarching do kokomi.js para desenhar uma pokeball~
Jogue em Mo e lute contra um ladrão em Tuo!
pintura começa
Primeiro bifurque este modelo
Veja o bloco "Vamos começar aqui~", vamos começar por aí
material
Pokébolas vêm em 3 cores: preto, branco e vermelho
Primeiro defina o material de 3 cores
// 材质
const BLACK_MAT = "1.0";
const WHITE_MAT = "2.0";
const RED_MAT = "3.0";
const mat = new marcher.SDFMaterial();
mat.addColorMaterial(BLACK_MAT, 0, 0, 0);
mat.addColorMaterial(WHITE_MAT, 255, 255, 255);
mat.addColorMaterial(RED_MAT, 255, 0, 0);
mar.setMaterial(mat);
复制代码
Na esfera
O interior da Pokébola é uma pequena bola preta
const sphere = new marcher.SphereSDF({
sdfVarName: "d1",
materialId: BLACK_MAT,
});
layer.addPrimitive(sphere);
复制代码
botão
Há um botão branco no meio, que na verdade é um cilindro
const button = new marcher.CylinderSDF({
sdfVarName: "d2",
materialId: WHITE_MAT,
radius: 0.1,
height: 0.54,
});
button.rotate(90, "x");
layer.addPrimitive(button);
复制代码
Casca esférica superior e inferior
Em raymarching, apenas a esfera inteira pode ser criada, e daí se você quiser apenas metade da esfera?
Crie um bloco temporário, mova-o para metade da esfera e, em seguida, cruze a esfera para obter metade da esfera
// 球壳(上)
const shellUpper = new marcher.SphereSDF({
sdfVarName: "d3",
materialId: "3",
radius: 0.55,
});
const clipBoxUpper = new marcher.BoxSDF({
sdfVarName: "d4",
width: 0.55,
height: 0.55,
depth: 0.55,
});
clipBoxUpper.hide();
clipBoxUpper.translate(0, -0.6, 0);
layer.addPrimitive(clipBoxUpper);
layer.addPrimitive(shellUpper);
shellUpper.intersect(clipBoxUpper);
// 球壳(下)
const shellLower = new marcher.SphereSDF({
sdfVarName: "d6",
materialId: WHITE_MAT,
radius: 0.55,
});
const clipBoxLower = new marcher.BoxSDF({
sdfVarName: "d5",
width: 0.55,
height: 0.55,
depth: 0.55,
});
clipBoxLower.hide();
clipBoxLower.translate(0, 0.6, 0);
layer.addPrimitive(clipBoxLower);
layer.addPrimitive(shellLower);
shellLower.intersect(clipBoxLower);
复制代码
O botão no meio do normal ainda está bloqueado pela casca esférica, então precisamos esvaziar a parte bloqueada
oco médio
Crie 2 cilindros (semelhante ao botão anterior), aumente ligeiramente o raio e a altura e use-os para deduzir as conchas esféricas superior e inferior, respectivamente, para ter o efeito de esvaziar o meio
// 球壳(上):挖除中间镂空部分后
const clipCylinderCenter1 = new marcher.CylinderSDF({
sdfVarName: "d7",
radius: 0.15,
height: 0.6,
materialId: RED_MAT,
});
clipCylinderCenter1.rotate(90, "x");
layer.addPrimitive(clipCylinderCenter1);
clipCylinderCenter1.subtract(shellUpper);
shellUpper.hide();
// 球壳下:挖除中间镂空部分后
const clipCylinderCenter2 = new marcher.CylinderSDF({
sdfVarName: "d8",
radius: 0.15,
height: 0.6,
materialId: WHITE_MAT,
});
clipCylinderCenter2.rotate(90, "x");
layer.addPrimitive(clipCylinderCenter2);
clipCylinderCenter2.subtract(shellLower);
shellLower.hide();
复制代码
embelezar
Aqui você pode jogar livremente, seja iluminação, ângulo da câmera ou material e outros fatores podem ser otimizados
Os resultados otimizados do autor são os seguintes