Skip to content

Commit 1748945

Browse files
committed
Add support for using texture to specify opacity
1 parent 9384d52 commit 1748945

File tree

14 files changed

+91
-31
lines changed

14 files changed

+91
-31
lines changed

ShapeScript/EvaluationContext.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,10 @@ final class EvaluationContext {
6666
}
6767

6868
var random: RandomSequence
69-
var detail = 16
69+
var detail: Int = 16
7070
var smoothing: Angle?
7171
var font: String = ""
72-
var opacity = 1.0
72+
var opacity: Double = 1
7373

7474
var stackDepth = 1
7575

@@ -115,7 +115,7 @@ final class EvaluationContext {
115115
// root-only
116116
self.background = parent.background
117117
// opacity is cumulative
118-
self.opacity = parent.material.opacity
118+
self.opacity = parent.material.opacity?.color?.a ?? parent.opacity
119119
// reset
120120
self.transform = .identity
121121
self.childTransform = .identity

ShapeScript/Geometry.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,12 @@ private extension Geometry {
598598
}
599599
var m = self.material
600600
if let material = material, case let .mesh(mesh) = type {
601-
m.opacity *= material.opacity
601+
if m.opacity?.opacity ?? 1 == 1 {
602+
m.opacity = material.opacity
603+
} else if m.opacity?.texture == nil, material.opacity?.color != nil {
604+
let opacity = (m.opacity?.opacity ?? 1) * (material.opacity?.opacity ?? 1)
605+
m.opacity = .color(.init(opacity, opacity))
606+
}
602607
m.diffuse = material.diffuse ?? m.diffuse
603608
m.glow = material.glow ?? m.glow
604609
m.metallicity = material.metallicity ?? m.metallicity

ShapeScript/Material.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public extension MaterialProperty {
5757
}
5858

5959
public struct Material: Hashable {
60-
public var opacity: Double = 1
60+
public var opacity: Optional<MaterialProperty>
6161
public var diffuse: Optional<MaterialProperty>
6262
public var metallicity: Optional<MaterialProperty>
6363
public var roughness: Optional<MaterialProperty>
@@ -69,6 +69,7 @@ public extension Material {
6969

7070
init(color: Color? = nil) {
7171
self.init(
72+
opacity: nil,
7273
diffuse: color.map { .color($0) },
7374
metallicity: nil,
7475
roughness: nil,
@@ -77,11 +78,12 @@ public extension Material {
7778
}
7879

7980
var isOpaque: Bool {
80-
opacity > 0.999 && (diffuse?.opacity ?? 1) > 0.999
81+
(opacity?.opacity ?? 1) > 0.999 && (diffuse?.opacity ?? 1) > 0.999
8182
}
8283

8384
var isUniform: Bool {
84-
diffuse?.texture == nil
85+
opacity?.texture == nil
86+
&& diffuse?.texture == nil
8587
&& metallicity?.texture == nil
8688
&& roughness?.texture == nil
8789
&& glow?.texture == nil

ShapeScript/Members.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ extension ValueType {
1717
return .object(values)
1818
case .material:
1919
return .material(.init(
20-
opacity: values["opacity"]?.doubleValue ?? 1,
20+
opacity: values["opacity"]?.numberOrTextureValue,
2121
diffuse: (values["color"] ?? values["texture"])?.colorOrTextureValue,
2222
metallicity: values["metallicity"]?.numberOrTextureValue,
2323
roughness: values["roughness"]?.numberOrTextureValue,
@@ -228,7 +228,7 @@ extension Value {
228228
}
229229
case let .material(material):
230230
switch name {
231-
case "opacity": return .number(material.opacity)
231+
case "opacity": return material.opacity.map { .numberOrTexture($0) } ?? .number(1)
232232
case "color": return .color(material.diffuse?.color ?? .white)
233233
case "texture": return .texture(material.diffuse?.texture)
234234
case "metallicity": return material.metallicity.map { .numberOrTexture($0) } ?? .number(0)

ShapeScript/Scene+SceneKit.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public extension SCNMaterial {
4242
convenience init(_ m: Material, isOpaque: Bool) {
4343
self.init()
4444
m.diffuse?.configureProperty(diffuse)
45-
transparency = CGFloat(m.opacity)
45+
m.opacity?.configureProperty(transparent)
4646

4747
isDoubleSided = !isOpaque
4848
transparencyMode = .dualLayer
@@ -339,7 +339,10 @@ private extension MaterialProperty {
339339

340340
public extension Material {
341341
init?(_ scnMaterial: SCNMaterial) {
342-
opacity = Double(scnMaterial.transparency)
342+
opacity = (MaterialProperty(scnMaterial.transparent) ?? .color(.init(
343+
scnMaterial.transparency,
344+
scnMaterial.transparency
345+
)))?.ifNot(.white)
343346
diffuse = MaterialProperty(scnMaterial.diffuse)?.ifNot(.white)
344347
glow = MaterialProperty(scnMaterial.emission)?.ifNot(.black)
345348
switch scnMaterial.lightingModel {

ShapeScript/StandardLibrary.swift

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,26 @@ extension Dictionary where Key == String, Value == Symbol {
8989
]
9090

9191
static let material: Symbols = color + [
92-
"opacity": .property(.number, { parameter, context in
93-
context.material.opacity = parameter.doubleValue * context.opacity
92+
"opacity": .property(.numberOrTexture, { parameter, context in
93+
switch parameter {
94+
case let .number(opacity):
95+
let opacity = opacity * context.opacity
96+
context.material.opacity = .color(.init(opacity, opacity))
97+
case let .texture(texture):
98+
context.material.opacity = texture.map { .texture($0) }
99+
default:
100+
let opacity = context.opacity
101+
context.material.opacity = .color(.init(opacity, opacity))
102+
}
94103
}, { context in
95-
.number(context.material.opacity / context.opacity)
104+
switch context.material.opacity {
105+
case nil:
106+
return .number(1 / context.opacity)
107+
case let .color(color)?:
108+
return .number(color.a / context.opacity)
109+
case let .texture(texture)?:
110+
return .texture(texture)
111+
}
96112
}),
97113
"texture": .property(.texture, { parameter, context in
98114
context.material.diffuse = parameter.colorOrTextureValue

ShapeScript/Value+Logging.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,11 +168,11 @@ extension MaterialProperty: Loggable {
168168
extension Material: Loggable {
169169
public var logDescription: String {
170170
let fields = [
171-
opacity != 1 ? "opacity \(opacity.logDescription)" : nil,
171+
opacity.map { "opacity \(Value.numberOrTexture($0).logDescription)" },
172172
color.map { "color \($0.logDescription)" },
173173
texture.map { "texture \($0.logDescription)" },
174-
metallicity.map { "metallicity \($0.logDescription)" },
175-
roughness.map { "roughness \($0.logDescription)" },
174+
metallicity.map { "metallicity \(Value.numberOrTexture($0).logDescription)" },
175+
roughness.map { "roughness \(Value.numberOrTexture($0).logDescription)" },
176176
glow.map { "glow \($0.logDescription)" },
177177
].compactMap { $0 }
178178

ShapeScript/Values.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -300,12 +300,10 @@ extension Value {
300300
var numberOrTextureValue: MaterialProperty? {
301301
switch self {
302302
case let .number(value):
303-
return .color(.init(value, 1))
304-
case let .color(color):
305-
return .color(.init(color.r, 1))
303+
return .color(.init(value, value))
306304
case let .texture(texture):
307305
return texture.map { .texture($0) }
308-
case .boolean, .vector, .size, .rotation, .range, .tuple,
306+
case .boolean, .vector, .size, .rotation, .range, .tuple, .color,
309307
.radians, .halfturns, .string, .text, .path, .material, .mesh,
310308
.polygon, .point, .bounds, .object:
311309
return nil

ShapeScriptTests/LoggingTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ class LoggingTests: XCTestCase {
229229

230230
func testPBRMaterial() {
231231
let input = Material(
232-
opacity: 0.5,
232+
opacity: .color(.gray),
233233
diffuse: .color(.red),
234234
metallicity: .color(.white),
235235
roughness: nil,
@@ -239,7 +239,7 @@ class LoggingTests: XCTestCase {
239239
material {
240240
opacity 0.5
241241
color 1 0 0
242-
metallicity 1 1 1
242+
metallicity 1
243243
}
244244
""")
245245
XCTAssertEqual(input.nestedLogDescription, "material")

ShapeScriptTests/TypesystemTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -880,9 +880,9 @@ class TypesystemTests: XCTestCase {
880880
let type = ValueType.material
881881
let value = Value.object(["color": .color(.red), "metallicity": .number(0.5)])
882882
XCTAssertEqual(value.as(type), .material(.init(
883-
opacity: 1,
883+
opacity: nil,
884884
diffuse: .color(.red),
885-
metallicity: .color(.gray),
885+
metallicity: .color(.init(0.5, 0.5)),
886886
roughness: nil,
887887
glow: nil
888888
)))

0 commit comments

Comments
 (0)