nicklockwood / Euclid

A Swift library for creating and manipulating 3D geometry

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Prevent material from repeating in stencil

chellem opened this issue · comments

Hello @nicklockwood ,

I've been trying to use the stencil method which works fine except the material keeps on repeating while when seeing the material on the cube, I have one diagram per each side.

Can you help me with this?

@chellem can you post a screenshot so I can better understand the issue?

@nicklockwood ,
I been able to make a stencil on my model but when trying to change its position, am getting repeats.

IMG_0027
IMG_A29993C1AC61-1 3

@chellem that's very curious. Can you share your project? (send it to support@charcoaldesign.co.uk). I'll see if I can work out what's happening.

@nicklockwood, the project is quite big.

The part that am struggling is within the following lines:

let logo = UIImage(named: "logo")
let material = SCNMaterial()
material.diffuse.contents = logo
material.diffuse.wrapS = .repeat
material.diffuse.wrapT = .repeat
material.diffuse.contentsTransform = SCNMatrix4MakeScale(Float(size.x) * 0.2588, Float(size.y) * 0.475, Float(size.z))
let index: Float = 50
let denominator: Float = 1/index
let x = Double((image.size.width - CGFloat(index)) * (CGFloat)(denominator))
let y = Double((image.size.height - CGFloat(index)) * (CGFloat)(denominator))
let size = Vector(x, y, 1)
let cube = Mesh.cube(center: center, size: size, faces: .front, material: material)
let geometry = SCNGeometry(mesh.stencil(cube))
let node = SCNNode(geometry: geometry)
addChildNode(node)

Am trying to play with the material properties. Change the diffuse wrap to .clamp, . mirror, .clampToBorder didn't help much.
I also tries to play with the contentsTransform to get only one image per side, partial image always appears.

I have tried with 2 cases. One is the stencil one (above) and the other is with a combination of subtract and intersect, while constructing a cube to place it into the subtracted area.

In both cases, am getting the material applied to the cube only to continue onto the other model and thus having the repeating pattern.

@chellem I think the repetition is happening because of the contentsTransform that you're applying (you can verify this by just rendering the cube on its own without the T-shirt).

If you just apply the texture directly to the cube without contentsTransform it shouldn't wrap. To reposition the texture on the T-shirt, you can then resize and reposition the cube itself.

Well, when viewing it with merge, it seems to be good but once I replace it with stencil, it repeats

image

Instead of a cube, what if you use an extruded rectangle instead? like this:

let cube = Mesh.extrude(.rectangle(width: x, height: y), material: material)

This should ensure only the front face is textured.

On second thought, I'm not sure this can work actually. Stencil only takes the shape and material of the object, not texture coordinates. I'm not sure it can be used this way since the texture has a transparent background it will just make a cube-shaped hole with the logo floating inside it.

Is there some way you can get the adidas logo as a vector shape, and then extrude that and use it as a stencil? That will work much better for this than a textured cube.

@nicklockwood, can you please give me some code example about what you mean above ? It will help me a lot.

@nicklockwood

let logo = UIImage(named: "logo")
let material = SCNMaterial()
material.diffuse.contents = logo
material.diffuse.wrapS = .clamp
material.diffuse.wrapT = .clamp

let cube = Mesh.cube(center: center, size: size, faces: .front, material: material)

Why does the cube don't follow the material diffuse wrap property ?

I get it as repeated in every case. (clamp, clampToBorder, mirror)

Is there some way you can get the adidas logo as a vector shape, and then extrude that and use it as a stencil? That will work much better for this than a textured cube.

You mean like use a SCNPlane, putting the image in it and then do the stencil ?

You mean like use a SCNPlane, putting the image in it and then do the stencil ?

No. I mean get something like an SVG copy of the logo, create a CGPath from that, create a ShapeScript path from that, and then extrude it, with a plain black material, and use that for the stencil.

Alternatively, if you just want to apply the texture, you might be better off doing that in 2D, by using CoreGraphics to draw the logo onto the shirt texture before it is applied to the shirt model.

Alternatively, if you just want to apply the texture, you might be better off doing that in 2D, by using CoreGraphics to draw the logo onto the shirt texture before it is applied to the shirt model.

If I draw the logo on the texture, it will not be repeated again ?

If I draw the logo on the texture, it will not be repeated again ?

It depends on how the T-shirt texture is mapped onto the T-shirt model, but as long as the T-shirt texture doesn't repeat, the logo won't either.

You mean like use a SCNPlane, putting the image in it and then do the stencil ?

No. I mean get something like an SVG copy of the logo, create a CGPath from that, create a ShapeScript path from that, and then extrude it, with a plain black material, and use that for the stencil.

Am giving a try to the first approach. I got the CGPath from a SVG. Now how to create that shapescript and proceed further ?

You mean like use a SCNPlane, putting the image in it and then do the stencil ?

No. I mean get something like an SVG copy of the logo, create a CGPath from that, create a ShapeScript path from that, and then extrude it, with a plain black material, and use that for the stencil.

Hi @nicklockwood, can you give me you contact details like email, skype or anything as such so that we can further talk about what I want to do ?

@chellem you can use the support@charcoaldesign.co.uk address I posted earlier.

Am giving a try to the first approach. I got the CGPath from a SVG. Now how to create that shapescript and proceed further ?

You can convert the SVG to a 3D shape as follows:

let path = Path(cgPath: logo)
let shape = Mesh.extrude(path, material:  blackMaterial)

Then use stencil to "draw" the shape on the T-shirt, as you were trying to do with the cube before.