bool and smooth
This commit is contained in:
@ -11,11 +11,11 @@ cmd_marchtoy = on_command("march")
|
|||||||
async def _(args: Message = CommandArg()):
|
async def _(args: Message = CommandArg()):
|
||||||
if cmd := args.extract_plain_text():
|
if cmd := args.extract_plain_text():
|
||||||
try:
|
try:
|
||||||
img = await render.render(cmd, (256, 256))
|
img = await render.render(cmd, (512, 512))
|
||||||
buffer = io.BytesIO()
|
buffer = io.BytesIO()
|
||||||
# img.show()
|
# img.show()
|
||||||
# img.save("/mnt/d/output.png", format="GIF")
|
# img.save("/mnt/d/output.png", format="GIF")
|
||||||
img.save(buffer, format="GIF")
|
img.save(buffer, format="PNG")
|
||||||
buffer.seek(0)
|
buffer.seek(0)
|
||||||
await cmd_marchtoy.send(await UniMessage().image(raw=buffer).export())
|
await cmd_marchtoy.send(await UniMessage().image(raw=buffer).export())
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@ -24,7 +24,10 @@ async def render(command: str, res: tuple[int, int]):
|
|||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise Exception(f"cannot compile glsl: {e}") from e
|
raise Exception(f"cannot compile glsl: {e}") from e
|
||||||
uniform = program["u_resolution"]
|
try:
|
||||||
|
uniform = program["u_resolution"]
|
||||||
|
except Exception as e:
|
||||||
|
raise Exception("无法获取 uniform,可能相机位于物体内部?")
|
||||||
uniform.write(np.array(res, dtype=np.float32))
|
uniform.write(np.array(res, dtype=np.float32))
|
||||||
vertices = np.array([-1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0], dtype=np.float32)
|
vertices = np.array([-1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0], dtype=np.float32)
|
||||||
indices = np.array([0, 1, 2, 1, 2, 3], dtype=np.int32)
|
indices = np.array([0, 1, 2, 1, 2, 3], dtype=np.int32)
|
||||||
|
|||||||
@ -81,6 +81,7 @@ class Object:
|
|||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.transform: Transform = Transform()
|
self.transform: Transform = Transform()
|
||||||
self.texture: Texture = Texture()
|
self.texture: Texture = Texture()
|
||||||
|
self.round_corner: float = 0.0
|
||||||
|
|
||||||
def parse_args(self, args: list[str]):
|
def parse_args(self, args: list[str]):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
@ -172,7 +173,7 @@ class Capsule(Object):
|
|||||||
|
|
||||||
@make_obj("smoothed", "mix")
|
@make_obj("smoothed", "mix")
|
||||||
class Smoothed(Object):
|
class Smoothed(Object):
|
||||||
def __init__(self, _k: float = 0.25):
|
def __init__(self, _k: float = 12.00):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.block_a: str = "INF"
|
self.block_a: str = "INF"
|
||||||
self.block_b: str = "INF"
|
self.block_b: str = "INF"
|
||||||
@ -196,12 +197,56 @@ class Smoothed(Object):
|
|||||||
def sdf_block_glsl(self):
|
def sdf_block_glsl(self):
|
||||||
return f"smin({self.block_a}, {self.block_b}, {self.k})"
|
return f"smin({self.block_a}, {self.block_b}, {self.k})"
|
||||||
|
|
||||||
|
@make_obj("intersect", "bool")
|
||||||
|
class BoolIntersect(Object):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
def parse_args(self, args: list[str]):
|
||||||
|
from konabot.plugins.marchtoy.scene import Scene
|
||||||
|
try:
|
||||||
|
if not len(args) >= 2:
|
||||||
|
raise Exception("expecting at least 2 args")
|
||||||
|
scene_a = Scene(args[0])
|
||||||
|
scene_b = Scene(args[1])
|
||||||
|
self.block_a = scene_a.canvas_objs[0][1]
|
||||||
|
self.block_b = scene_b.canvas_objs[0][1]
|
||||||
|
if len(args) > 2:
|
||||||
|
self.k = ArgParser.as_float(args[2], 0.25)
|
||||||
|
except Exception as e:
|
||||||
|
raise Exception(f"cannot build bool object over {args}: {e}")
|
||||||
|
|
||||||
|
def sdf_block_glsl(self):
|
||||||
|
return f"max({self.block_a}, {self.block_b})"
|
||||||
|
|
||||||
|
@make_obj("substract", "minus")
|
||||||
|
class BoolSubstract(Object):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
def parse_args(self, args: list[str]):
|
||||||
|
from konabot.plugins.marchtoy.scene import Scene
|
||||||
|
try:
|
||||||
|
if not len(args) >= 2:
|
||||||
|
raise Exception("expecting at least 2 args")
|
||||||
|
scene_a = Scene(args[0])
|
||||||
|
scene_b = Scene(args[1])
|
||||||
|
self.block_a = scene_a.canvas_objs[0][1]
|
||||||
|
self.block_b = scene_b.canvas_objs[0][1]
|
||||||
|
if len(args) > 2:
|
||||||
|
self.k = ArgParser.as_float(args[2], 0.25)
|
||||||
|
except Exception as e:
|
||||||
|
raise Exception(f"cannot build bool object over {args}: {e}")
|
||||||
|
|
||||||
|
def sdf_block_glsl(self):
|
||||||
|
return f"max({self.block_a}, -{self.block_b})"
|
||||||
|
|
||||||
@make_obj("camera", "cam")
|
@make_obj("camera", "cam")
|
||||||
class Camera(Object):
|
class Camera(Object):
|
||||||
def __init__(self, _focus: float = 1.0) -> None:
|
def __init__(self, _focus: float = 2.0) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.focus = _focus
|
self.focus = _focus
|
||||||
self.transform.translate(5.0, 5.0, 5.0).lookat(0.0, 0.0, 0.0)
|
self.transform.translate(8.0, 8.0, 8.0).lookat(0.0, 0.0, 0.0)
|
||||||
|
|
||||||
def parse_args(self, args: list[str]):
|
def parse_args(self, args: list[str]):
|
||||||
self.focus = ArgParser.as_float(args)
|
self.focus = ArgParser.as_float(args)
|
||||||
|
|||||||
@ -3,7 +3,7 @@ from konabot.plugins.marchtoy.utilities import ArgParser
|
|||||||
|
|
||||||
OPERATION_ENTRIES = {}
|
OPERATION_ENTRIES = {}
|
||||||
|
|
||||||
def make_operation(*name: str):
|
def make_op(*name: str):
|
||||||
def decorator(op):
|
def decorator(op):
|
||||||
# OPERATION_ENTRIES[name] = op
|
# OPERATION_ENTRIES[name] = op
|
||||||
for alias in [*name]:
|
for alias in [*name]:
|
||||||
@ -13,25 +13,25 @@ def make_operation(*name: str):
|
|||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
@make_operation("pos", "translate", "position", "p")
|
@make_op("pos", "translate", "position", "p")
|
||||||
def translate(obj: Object, args: list[str]):
|
def translate(obj: Object, args: list[str]):
|
||||||
pos = ArgParser.as_vec3(args)
|
pos = ArgParser.as_vec3(args)
|
||||||
obj.transform.translate(pos[0], pos[1], pos[2])
|
obj.transform.translate(pos[0], pos[1], pos[2])
|
||||||
|
|
||||||
|
|
||||||
@make_operation("rot", "rotate", "r")
|
@make_op("rot", "rotate", "r")
|
||||||
def rotate(obj: Object, args: list[str]):
|
def rotate(obj: Object, args: list[str]):
|
||||||
pos = ArgParser.as_vec3(args)
|
pos = ArgParser.as_vec3(args)
|
||||||
obj.transform.rotate(pos[0], pos[1], pos[2])
|
obj.transform.rotate(pos[0], pos[1], pos[2])
|
||||||
|
|
||||||
|
|
||||||
@make_operation("lookat", "look", "l")
|
@make_op("lookat", "look", "l")
|
||||||
def lookat(obj: Object, args: list[str]):
|
def lookat(obj: Object, args: list[str]):
|
||||||
pos = ArgParser.as_vec3(args)
|
pos = ArgParser.as_vec3(args)
|
||||||
obj.transform.lookat(pos[0], pos[1], pos[2])
|
obj.transform.lookat(pos[0], pos[1], pos[2])
|
||||||
|
|
||||||
|
|
||||||
@make_operation("color", "col", "texture")
|
@make_op("color", "col", "texture")
|
||||||
def color(obj: Object, args: list[str]):
|
def color(obj: Object, args: list[str]):
|
||||||
try:
|
try:
|
||||||
if len(args) == 1:
|
if len(args) == 1:
|
||||||
@ -48,3 +48,9 @@ def color(obj: Object, args: list[str]):
|
|||||||
|
|
||||||
except:
|
except:
|
||||||
raise Exception("unknown color")
|
raise Exception("unknown color")
|
||||||
|
|
||||||
|
@make_op("rounded", "round_corner", "corner")
|
||||||
|
def rounded(obj: Object, args: list[str]):
|
||||||
|
if len(args) >= 1:
|
||||||
|
obj.round_corner = ArgParser.as_float(args[0])
|
||||||
|
|
||||||
@ -71,7 +71,9 @@ class Scene:
|
|||||||
obj, sdf_expr = canvas_item
|
obj, sdf_expr = canvas_item
|
||||||
sdf_block += f"float sd{index} = {sdf_expr};"
|
sdf_block += f"float sd{index} = {sdf_expr};"
|
||||||
sdf_block += f"if(sd{index} < qry.value)"
|
sdf_block += f"if(sd{index} < qry.value)"
|
||||||
sdf_block += "{" + f"qry.value = sd{index}; qry.obj_id = {index}; " + "}\n"
|
# 1e-8 最好换成某个 epsilon
|
||||||
|
round_corner = f"- {obj.round_corner}" if obj.round_corner > 1e-8 else ""
|
||||||
|
sdf_block += "{" + f"qry.value = sd{index} {round_corner}; qry.obj_id = {index}; " + "}\n"
|
||||||
color = obj.texture.color
|
color = obj.texture.color
|
||||||
color_block += (
|
color_block += (
|
||||||
f"if(obj_id == {index}) return vec4("
|
f"if(obj_id == {index}) return vec4("
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
#version 330
|
#version 330
|
||||||
const float EPS = 0.001;
|
const float EPS = 0.001;
|
||||||
const int MAX_ITER = 64;
|
const int MAX_ITER = 128;
|
||||||
|
|
||||||
uniform vec2 u_resolution;
|
uniform vec2 u_resolution;
|
||||||
out vec4 fragColor;
|
out vec4 fragColor;
|
||||||
|
|||||||
Reference in New Issue
Block a user