├── .gitignore
├── screenshots
└── 01.png
├── ScenekitStarter
├── EnvMap.png
├── FringeMap.png
├── EnvMapInterior.png
├── GameView.h
├── CWHLightingView.h
├── main.m
├── GameView.m
├── CWHLightingView.m
├── AppDelegate.h
├── CWHParameterViewProtocol.h
├── CWHHemisphereProgram.h
├── CWHLightingViewController.h
├── CWHParameterViewController.h
├── GameViewController.h
├── CWHBlinnProgram.h
├── CWHThinFilmProgram.h
├── CWHEnvMapProgram.h
├── CWHVelvetProgram.h
├── CWHLambSkinProgram.h
├── CWHPhongPointLightProgram.h
├── CWHGoochProgram.h
├── CWHLUTSkinProgram.h
├── CWHEdgeFuzzProgram.h
├── CWHLightingProgram.h
├── CWHGlossyWetHighlightProgram.h
├── CWHBlinnParameterViewController.h
├── CWHHemisphereParameterViewController.h
├── CWHThinFilmParameterViewController.h
├── CWHLightingModelWindowController.h
├── CWHVelvetParameterViewController.h
├── CWHParameterViewController.m
├── CWHEnvMapParameterViewController.h
├── CWHLambSkinParameterViewController.h
├── Images.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── Info.plist
├── CWHLUTSkinParameterViewController.h
├── AppDelegate.m
├── CWHPhongPointLightParameterViewController.h
├── CWHGoochParameterViewController.h
├── CWHHemisphereParameterViewController.m
├── CWHGlossyWetHighlightParameterViewController.h
├── CWHEdgeFuzzParameterViewController.h
├── CWHBlinnParameterViewController.m
├── Hemisphere.metal
├── CWHThinFilmParameterViewController.m
├── CWHLightingView.xib
├── Blinn.metal
├── Gooch.metal
├── CWHLightingViewController.m
├── LambSkin.metal
├── GameViewController.m
├── CWHVelvetParameterViewController.m
├── Velvet.metal
├── CWHLambSkinParameterViewController.m
├── LUTSkin.metal
├── Phong.metal
├── CWHLightingProgram.m
├── CWHEnvMapParameterViewController.m
├── CWHHemisphereProgram.m
├── CWHPhongPointLightParameterViewController.m
├── EnvMap.metal
├── CWHBlinnProgram.m
├── CWHGoochParameterViewController.m
├── ThinFilm.metal
├── CWHLUTSkinParameterViewController.m
├── HemisphereParameterView.xib
├── BlinnParameterView.xib
├── CWHThinFilmProgram.m
├── EdgeFuzz.metal
├── CWHEnvMapProgram.m
├── CWHEdgeFuzzParameterViewController.m
├── CWHPhongPointLightProgram.m
├── CWHLambSkinProgram.m
├── CWHVelvetProgram.m
├── CWHLUTSkinProgram.m
├── CWHGoochProgram.m
├── ThinFilmParameterView.xib
├── CWHGlossyWetHighlightParameterViewController.m
├── GlossyWetHighlight.metal
├── CWHLightingModelWindowController.m
├── CWHGlossyWetHighlightProgram.m
├── CWHEdgeFuzzProgram.m
├── LambSkinParameterView.xib
├── LightingModelWindow.xib
└── VelvetParameterView.xib
├── ScenekitStarter.xcodeproj
├── xcuserdata
│ └── super.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ ├── xcschememanagement.plist
│ │ └── ScenekitStarter.xcscheme
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── ScenekitStarter.xccheckout
│ └── xcuserdata
│ │ └── super.xcuserdatad
│ │ └── WorkspaceSettings.xcsettings
└── xcshareddata
│ └── xcschemes
│ └── ScenekitStarter.xcscheme
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | xcuserdata
2 |
--------------------------------------------------------------------------------
/screenshots/01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/metal-by-example/scenekit-lighting-models/HEAD/screenshots/01.png
--------------------------------------------------------------------------------
/ScenekitStarter/EnvMap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/metal-by-example/scenekit-lighting-models/HEAD/ScenekitStarter/EnvMap.png
--------------------------------------------------------------------------------
/ScenekitStarter/FringeMap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/metal-by-example/scenekit-lighting-models/HEAD/ScenekitStarter/FringeMap.png
--------------------------------------------------------------------------------
/ScenekitStarter/EnvMapInterior.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/metal-by-example/scenekit-lighting-models/HEAD/ScenekitStarter/EnvMapInterior.png
--------------------------------------------------------------------------------
/ScenekitStarter.xcodeproj/xcuserdata/super.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/ScenekitStarter.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ScenekitStarter/GameView.h:
--------------------------------------------------------------------------------
1 | //
2 | // GameView.h
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 7/24/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface GameView : SCNView
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHLightingView.h:
--------------------------------------------------------------------------------
1 | //
2 | // GameView.h
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 7/24/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface CWHLightingView : SCNView
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/ScenekitStarter.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ScenekitStarter/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 7/24/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | int main(int argc, const char * argv[]) {
12 | return NSApplicationMain(argc, argv);
13 | }
14 |
--------------------------------------------------------------------------------
/ScenekitStarter/GameView.m:
--------------------------------------------------------------------------------
1 | //
2 | // GameView.m
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 7/24/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import "GameView.h"
10 |
11 | @implementation GameView
12 |
13 | -(void)mouseDown:(NSEvent *)theEvent
14 | {
15 |
16 | [super mouseDown:theEvent];
17 | }
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHLightingView.m:
--------------------------------------------------------------------------------
1 | //
2 | // GameView.m
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 7/24/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import "CWHLightingView.h"
10 |
11 | @implementation CWHLightingView
12 |
13 | -(void)mouseDown:(NSEvent *)theEvent
14 | {
15 | [super mouseDown:theEvent];
16 | }
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/ScenekitStarter/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 7/24/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class CWHLightingModelWindowController;
12 |
13 | @interface AppDelegate : NSObject
14 | {
15 | CWHLightingModelWindowController *windowController;
16 | }
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHParameterViewProtocol.h:
--------------------------------------------------------------------------------
1 | //
2 | // ParameterViewProtocol.h
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 8/4/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @protocol CWHParameterViewProtocol
13 | - (void)parameterViewWillClose;
14 | - (void)updateProgram:(SCNProgram *)program shadableProperties:(NSDictionary *)properties;
15 | @end
16 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHHemisphereProgram.h:
--------------------------------------------------------------------------------
1 | //
2 | // CWHHemisphereProgram.h
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 7/31/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CWHLightingProgram.h"
11 |
12 | @interface CWHHemisphereProgram : CWHLightingProgram
13 |
14 | @property (strong) NSColor *skyColor;
15 | @property (strong) NSColor *groundColor;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHLightingViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // GameViewController.h
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 7/24/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "CWHLightingView.h"
12 |
13 | @interface CWHLightingViewController : NSViewController
14 |
15 | @property (weak) IBOutlet CWHLightingView *lightingView;
16 | @property (nonatomic, retain) SCNNode *geometryNode;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHParameterViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // CWHParameterViewController.h
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 8/14/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import "CWHParameterViewProtocol.h"
12 |
13 | @interface CWHParameterViewController : NSViewController
14 | @property (nonatomic, retain) id delegate;
15 | @property (strong) SCNProgram *program;
16 | @end
17 |
--------------------------------------------------------------------------------
/ScenekitStarter/GameViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // GameViewController.h
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 7/24/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "GameView.h"
12 | #import "CWHShadingNode.h"
13 |
14 | @interface GameViewController : NSViewController
15 |
16 | @property (assign) IBOutlet GameView *gameView;
17 | @property (nonatomic, retain) CWHShadingNode *torusNode;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHBlinnProgram.h:
--------------------------------------------------------------------------------
1 | //
2 | // CWHBlinnProgram.h
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 7/29/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CWHLightingProgram.h"
11 |
12 | @interface CWHBlinnProgram : CWHLightingProgram
13 |
14 | @property (nonatomic, strong) NSColor *lightColor;
15 | @property (nonatomic, strong) NSColor *ambientColor;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | scenekit-lighting-models
2 | ========================
3 |
4 | Alternate lighting models using custom SCNProgram for SceneKit
5 |
6 |
7 | A demo app for previewing alternate lighting models using a custom SCNProgram with SceneKit. Based on a Quartz Composer conversion of NVIDIA samples from toneburst([machinesdontcare.wordpress.com](http://machinesdontcare.wordpress.com)).
8 |
9 | A [short video](https://vimeo.com/106634143) of the app in action.
10 |
11 | 
--------------------------------------------------------------------------------
/ScenekitStarter/CWHThinFilmProgram.h:
--------------------------------------------------------------------------------
1 | //
2 | // CWHThinFilmProgram.h
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 8/28/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CWHLightingProgram.h"
11 |
12 | @interface CWHThinFilmProgram : CWHLightingProgram
13 |
14 | @property (assign) double filmDepth;
15 | @property (strong) NSColor *diffuseColor;
16 | @property (strong) NSString *imagePath;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHEnvMapProgram.h:
--------------------------------------------------------------------------------
1 | //
2 | // CWHEnvMapProgram.h
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 8/25/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CWHLightingProgram.h"
11 |
12 | @interface CWHEnvMapProgram : CWHLightingProgram
13 |
14 | @property (strong) NSColor *diffuseColor;
15 | @property (strong) NSColor *ambientColor;
16 | @property (assign) double ratio;
17 | @property (strong) NSString *imagePath;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHVelvetProgram.h:
--------------------------------------------------------------------------------
1 | //
2 | // CWHVelvetProgram.h
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 7/30/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CWHLightingProgram.h"
11 |
12 | @interface CWHVelvetProgram : CWHLightingProgram
13 |
14 | @property (strong) NSColor *underColor;
15 | @property (strong) NSColor *fuzzColor;
16 | @property (assign) double rolloff;
17 | @property (strong) NSColor *primaryColor;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHLambSkinProgram.h:
--------------------------------------------------------------------------------
1 | //
2 | // CWHLambSkinProgram.h
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 7/31/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CWHLightingProgram.h"
11 |
12 | @interface CWHLambSkinProgram : CWHLightingProgram
13 |
14 | @property (strong) NSColor *diffuseColor;
15 | @property (strong) NSColor *ambientColor;
16 | @property (strong) NSColor *subColor;
17 | @property (assign) double rolloff;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHPhongPointLightProgram.h:
--------------------------------------------------------------------------------
1 | //
2 | // CWHBlinnProgram.h
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 7/29/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CWHLightingProgram.h"
11 |
12 | @interface CWHPhongPointLightProgram: CWHLightingProgram
13 |
14 | @property (strong) NSColor *lightColor;
15 | @property (strong) NSColor *ambientColor;
16 |
17 | @property (assign) double shininess;
18 | @property (assign) double materialSpecularity;
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHGoochProgram.h:
--------------------------------------------------------------------------------
1 | //
2 | // CWHBlinnProgram.h
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 7/29/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CWHLightingProgram.h"
11 |
12 | @interface CWHGoochProgram : CWHLightingProgram
13 |
14 | @property (strong) NSColor *surfaceColor;
15 | @property (strong) NSColor *warmColor;
16 | @property (strong) NSColor *coolColor;
17 | @property (assign) double diffuseWarm;
18 | @property (assign) double diffuseCool;
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHLUTSkinProgram.h:
--------------------------------------------------------------------------------
1 | //
2 | // CWHLUTSkinProgram.h
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 7/31/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CWHLightingProgram.h"
11 |
12 | @interface CWHLUTSkinProgram : CWHLightingProgram
13 |
14 | @property (strong) NSColor *diffuseColor;
15 | @property (strong) NSColor *specularColor;
16 | @property (strong) NSColor *scatterColor;
17 | @property (assign) double wrap;
18 | @property (assign) double scatterWidth;
19 | @property (assign) double shininess;
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHEdgeFuzzProgram.h:
--------------------------------------------------------------------------------
1 | //
2 | // CWHEdgeFuzzProgram.h
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 7/31/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CWHLightingProgram.h"
11 |
12 | @interface CWHEdgeFuzzProgram : CWHLightingProgram
13 |
14 | @property (strong) NSColor *surfaceColor;
15 | @property (strong) NSColor *edgeColor;
16 | @property (strong) NSColor *lightColor;
17 | @property (strong) NSColor *ambientColor;
18 | @property (assign) double fuzziness;
19 | @property (assign) double edgeFade;
20 | @property (assign) double specularity;
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHLightingProgram.h:
--------------------------------------------------------------------------------
1 | //
2 | // CWHLightingProgram.h
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 9/9/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface CWHLightingProgram : SCNProgram
12 |
13 | - (id)initWithProgram:(NSString *)program;
14 |
15 | - (instancetype)initWithLibrary:(id)library
16 | vertexFunctionName:(NSString *)vertexFunctionName
17 | fragmentFunctionName:(NSString *)fragmentFunctionName;
18 |
19 | @property (nonatomic, readonly, copy) NSDictionary *shadableProperties;
20 |
21 | @property (nonatomic, assign) SCNVector3 lightPosition;
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/ScenekitStarter.xcodeproj/xcuserdata/super.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | ScenekitStarter.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | BFB813C51981646100E09822
16 |
17 | primary
18 |
19 |
20 | BFB813E01981646200E09822
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHGlossyWetHighlightProgram.h:
--------------------------------------------------------------------------------
1 | //
2 | // CWHGlossyWetHighlightProgram.h
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 7/31/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CWHLightingProgram.h"
11 |
12 | @interface CWHGlossyWetHighlightProgram : CWHLightingProgram
13 |
14 | @property (strong) NSColor *ambientColor;
15 | @property (strong) NSColor *diffuseColor;
16 | @property (strong) NSColor *specularColor;
17 | @property (assign) double specularity;
18 | @property (assign) double specularExponent;
19 | @property (assign) double glossMax;
20 | @property (assign) double glossMin;
21 | @property (assign) double glossDrop;
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHBlinnParameterViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // CWHBlinnParameterViewController.h
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 8/15/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CWHParameterViewProtocol.h"
11 | #import "CWHParameterViewController.h"
12 | #import "CWHBlinnProgram.h"
13 |
14 | @interface CWHBlinnParameterViewController : CWHParameterViewController
15 |
16 | @property (weak) IBOutlet NSColorWell *ambientColorWell;
17 | @property (strong) NSColor *ambientColor;
18 | - (IBAction)updateAmbientColor:(id)sender;
19 |
20 | @property (weak) IBOutlet NSColorWell *lightColorWell;
21 | @property (strong) NSColor *lightColor;
22 | - (IBAction)updateLightColor:(id)sender;
23 |
24 |
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHHemisphereParameterViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // CWHHemisphereParameterViewController.h
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 8/21/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CWHParameterViewProtocol.h"
11 | #import "CWHHemisphereProgram.h"
12 | #import "CWHParameterViewController.h"
13 |
14 | @interface CWHHemisphereParameterViewController : CWHParameterViewController
15 |
16 | @property (weak) IBOutlet NSColorWell *skyColorWell;
17 | @property (strong) NSColor *skyColor;
18 | - (IBAction)updateSkyColor:(id)sender;
19 |
20 | @property (weak) IBOutlet NSColorWell *groundColorWell;
21 | @property (strong) NSColor *groundColor;
22 | - (IBAction)updateGroundColor:(id)sender;
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHThinFilmParameterViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // CWHThinFilmParameterViewController.h
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 9/4/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 |
10 | #import
11 | #import "CWHParameterViewProtocol.h"
12 | #import "CWHThinFilmProgram.h"
13 | #import "CWHParameterViewController.h"
14 |
15 | @interface CWHThinFilmParameterViewController : CWHParameterViewController
16 |
17 | @property (weak) IBOutlet NSSlider *filmDepthSlider;
18 | @property (weak) IBOutlet NSTextField *filmDepthTextField;
19 | @property (weak) IBOutlet NSColorWell *diffuseColorWell;
20 |
21 | @property (assign) double filmDepth;
22 | - (IBAction)updateFilmDepth:(id)sender;
23 |
24 | @property (strong) NSColor *diffuseColor;
25 | - (IBAction)updateDiffuseColor:(id)sender;
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/ScenekitStarter.xcodeproj/project.xcworkspace/xcuserdata/super.xcuserdatad/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildLocationStyle
6 | UseAppPreferences
7 | CustomBuildLocationType
8 | RelativeToDerivedData
9 | DerivedDataLocationStyle
10 | Default
11 | HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges
12 |
13 | IssueFilterStyle
14 | ShowActiveSchemeOnly
15 | LiveSourceIssuesEnabled
16 |
17 | SnapshotAutomaticallyBeforeSignificantChanges
18 |
19 | SnapshotLocationStyle
20 | Default
21 |
22 |
23 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHLightingModelWindowController.h:
--------------------------------------------------------------------------------
1 | //
2 | // CWHLightingModelWindowController.h
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 8/1/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CWHPhongPointLightParameterViewController.h"
11 | @class CWHLightingViewController;
12 |
13 | @interface CWHLightingModelWindowController : NSWindowController
14 | {
15 | __weak IBOutlet NSView *targetView;
16 | }
17 |
18 | @property (weak) IBOutlet NSMenu *lightingModelMenu;
19 | @property (weak) IBOutlet NSPopUpButton *lightingModelPopupButton;
20 | @property (weak) IBOutlet NSToolbarItem *parameterToolbarItem;
21 | -(IBAction)showInputParameters:(id)sender;
22 | -(IBAction)updateLightingModel:(id)sender;
23 |
24 | @property (strong) IBOutlet CWHLightingViewController *lightingViewController;
25 | @property (assign) BOOL lightingParameterState;
26 | @property (strong) NSString *currentLightingModel;
27 | @property (strong) SCNProgram *currentProgram;
28 |
29 | @end
30 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHVelvetParameterViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // CWHVelvetParamterViewController.h
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 8/15/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CWHVelvetProgram.h"
11 | #import "CWHParameterViewController.h"
12 |
13 | @interface CWHVelvetParameterViewController : CWHParameterViewController
14 |
15 | @property (weak) IBOutlet NSTextField *rolloffTextField;
16 | @property (weak) IBOutlet NSSlider *rolloffCircularSlider;
17 | @property (weak) IBOutlet NSColorWell *underColorWell;
18 | @property (weak) IBOutlet NSColorWell *fuzzColorWell;
19 | @property (weak) IBOutlet NSColorWell *primaryColorWell;
20 |
21 | @property (assign) double rolloff;
22 | - (IBAction)updateRolloff:(id)sender;
23 |
24 | @property (strong) NSColor *underColor;
25 | - (IBAction)updateUnderColor:(id)sender;
26 |
27 | @property (strong) NSColor *fuzzColor;
28 | - (IBAction)updateFuzzColor:(id)sender;
29 |
30 | @property (strong) NSColor *primaryColor;
31 | - (IBAction)updatePrimaryColor:(id)sender;
32 |
33 | @end
34 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHParameterViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // CWHParameterViewController.m
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 8/14/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import "CWHParameterViewController.h"
10 |
11 |
12 | @interface CWHParameterViewController ()
13 |
14 | @end
15 |
16 | @implementation CWHParameterViewController
17 |
18 | - (void)viewDidLoad {
19 | [super viewDidLoad];
20 | // Do view setup here.
21 | }
22 |
23 | - (void)popoverWillClose:(NSNotification *)notification
24 | {
25 |
26 | if ([self.delegate respondsToSelector:@selector(parameterViewWillClose)]) {
27 | [self.delegate parameterViewWillClose];
28 | }
29 |
30 | NSString *closeReason = [[notification userInfo] valueForKey:NSPopoverCloseReasonKey];
31 | if (closeReason)
32 | {
33 | // closeReason can be:
34 | // NSPopoverCloseReasonStandard
35 | // NSPopoverCloseReasonDetachToWindow
36 | //
37 | // add new code here if you want to respond "before" the popover closes
38 | //
39 | }
40 | }
41 |
42 | @end
43 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHEnvMapParameterViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // CWHEnvMapParameterViewController.h
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 8/25/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CWHParameterViewProtocol.h"
11 | #import "CWHEnvMapProgram.h"
12 | #import "CWHParameterViewController.h"
13 |
14 | @interface CWHEnvMapParameterViewController : CWHParameterViewController
15 | @property (weak) IBOutlet NSSlider *ratioSlider;
16 | @property (weak) IBOutlet NSTextField *ratioTextField;
17 | @property (weak) IBOutlet NSColorWell *ambientColorWell;
18 | @property (weak) IBOutlet NSColorWell *diffuseColorWell;
19 | @property (weak) IBOutlet NSPopUpButton *envMapMenu;
20 |
21 | @property (assign) double ratio;
22 | - (IBAction)updateRatio:(id)sender;
23 |
24 | @property (strong) NSColor *ambientColor;
25 | - (IBAction)updateAmbientColor:(NSColorWell *)sender;
26 |
27 | @property (strong) NSColor *diffuseColor;
28 | - (IBAction)updateDiffuseColor:(NSColorWell *)sender;
29 |
30 | @property (strong) NSString *imagePath;
31 | - (IBAction)updateEnvMap:(id)sender;
32 | @end
33 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHLambSkinParameterViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // CWHLambSkinParameterViewController.h
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 8/21/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CWHParameterViewProtocol.h"
11 | #import "CWHLambSkinProgram.h"
12 | #import "CWHParameterViewController.h"
13 |
14 | @interface CWHLambSkinParameterViewController : CWHParameterViewController
15 |
16 | @property (assign) double rolloff;
17 | - (IBAction)updateRolloff:(id)sender;
18 | @property (weak) IBOutlet NSSlider *rolloffSlider;
19 | @property (weak) IBOutlet NSTextField *rolloffTextField;
20 |
21 | @property (weak) IBOutlet NSColorWell *ambientColorWell;
22 | @property (strong) NSColor *ambientColor;
23 | - (IBAction)updateAmbientColor:(id)sender;
24 |
25 | @property (weak) IBOutlet NSColorWell *diffuseColorWell;
26 | @property (strong) NSColor *diffuseColor;
27 | - (IBAction)updateDiffuseColor:(id)sender;
28 |
29 |
30 | @property (weak) IBOutlet NSColorWell *subColorWell;
31 | @property (strong) NSColor *subColor;
32 | - (IBAction)updateSubColor:(id)sender;
33 |
34 | @end
35 |
--------------------------------------------------------------------------------
/ScenekitStarter/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "mac",
5 | "size" : "16x16",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "mac",
10 | "size" : "16x16",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "mac",
15 | "size" : "32x32",
16 | "scale" : "1x"
17 | },
18 | {
19 | "idiom" : "mac",
20 | "size" : "32x32",
21 | "scale" : "2x"
22 | },
23 | {
24 | "idiom" : "mac",
25 | "size" : "128x128",
26 | "scale" : "1x"
27 | },
28 | {
29 | "idiom" : "mac",
30 | "size" : "128x128",
31 | "scale" : "2x"
32 | },
33 | {
34 | "idiom" : "mac",
35 | "size" : "256x256",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "mac",
40 | "size" : "256x256",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "mac",
45 | "size" : "512x512",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "mac",
50 | "size" : "512x512",
51 | "scale" : "2x"
52 | }
53 | ],
54 | "info" : {
55 | "version" : 1,
56 | "author" : "xcode"
57 | }
58 | }
--------------------------------------------------------------------------------
/ScenekitStarter/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | ${PRODUCT_NAME}
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1
25 | LSMinimumSystemVersion
26 | ${MACOSX_DEPLOYMENT_TARGET}
27 | NSHumanReadableCopyright
28 | Copyright © 2014 Creative Workflow Hacks. All rights reserved.
29 | NSMainNibFile
30 | MainMenu
31 | NSPrincipalClass
32 | NSApplication
33 |
34 |
35 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHLUTSkinParameterViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // CWHLUTSkinParameterViewController.h
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 9/12/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import "CWHParameterViewController.h"
10 | #import "CWHLUTSkinProgram.h"
11 |
12 | @interface CWHLUTSkinParameterViewController : CWHParameterViewController
13 | @property (weak) IBOutlet NSSlider *wrapSlider;
14 | @property (weak) IBOutlet NSTextField *wrapTextField;
15 | @property (weak) IBOutlet NSSlider *scatterWidthSlider;
16 | @property (weak) IBOutlet NSTextField *scatterWidthTextField;
17 | @property (weak) IBOutlet NSSlider *shininessSlider;
18 | @property (weak) IBOutlet NSTextField *shininessTextField;
19 | @property (weak) IBOutlet NSColorWell *diffuseColorWell;
20 | @property (weak) IBOutlet NSColorWell *specularColorWell;
21 | @property (weak) IBOutlet NSColorWell *scatterColorWell;
22 |
23 |
24 | - (IBAction)updateWrap:(id)sender;
25 | - (IBAction)updateScatterWidth:(id)sender;
26 | - (IBAction)updateShininess:(id)sender;
27 | - (IBAction)updateDiffuseColor:(id)sender;
28 | - (IBAction)updateSpecularColor:(id)sender;
29 | - (IBAction)updateScatterColor:(id)sender;
30 |
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/ScenekitStarter/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 7/24/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 | #import "CWHLightingModelWindowController.h"
11 |
12 | @implementation AppDelegate
13 |
14 | - (IBAction)newDocument:(id)sender
15 | {
16 | if(windowController == nil)
17 | {
18 | windowController = [[CWHLightingModelWindowController alloc] initWithWindowNibName:@"LightingModelWindow"];
19 | }
20 |
21 | [windowController showWindow:self];
22 | }
23 |
24 | - (void)applicationDidFinishLaunching:(NSNotification*)notification
25 | {
26 | [self newDocument:self];
27 | }
28 |
29 | - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender {
30 | return YES;
31 | }
32 |
33 | - (BOOL)validateMenuItem:(NSMenuItem *)theMenuItem
34 | {
35 | BOOL enable = [self respondsToSelector:[theMenuItem action]];
36 |
37 | // disable "New" if the window is already up
38 | if ([theMenuItem action] == @selector(newDocument:))
39 | {
40 | if ([[windowController window] isKeyWindow])
41 | {
42 | enable = NO;
43 | }
44 | }
45 | return enable;
46 | }
47 |
48 |
49 | @end
50 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHPhongPointLightParameterViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // CWHPhongPointLightParameterViewController.h
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 8/1/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CWHParameterViewProtocol.h"
11 | #import "CWHPhongPointLightProgram.h"
12 | #import "CWHParameterViewController.h"
13 |
14 | @interface CWHPhongPointLightParameterViewController : CWHParameterViewController
15 |
16 |
17 | @property (weak) IBOutlet NSSlider *specularitySlider;
18 | @property (weak) IBOutlet NSSlider *shininessSlider;
19 |
20 | @property (weak) IBOutlet NSTextField *specularityTextField;
21 | @property (weak) IBOutlet NSTextField *shininessTextField;
22 |
23 | @property (weak) IBOutlet NSColorWell *ambientColorWell;
24 | @property (weak) IBOutlet NSColorWell *lightColorWell;
25 |
26 | @property (assign) double materialSpecularity;
27 | -(IBAction)updateMaterialSpecularity:(id)sender;
28 |
29 | @property (assign) double shininess;
30 | -(IBAction)updateShininess:(id)sender;
31 |
32 | @property (strong) NSColor *ambientColor;
33 | -(IBAction)updateAmbientColor:(id)sender;
34 |
35 | @property (strong) NSColor *lightColor;
36 | -(IBAction)updateLightColor:(id)sender;
37 |
38 | @end
39 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHGoochParameterViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // CWHGoochParameterViewController.h
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 8/12/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CWHParameterViewProtocol.h"
11 | #import "CWHGoochProgram.h"
12 | #import "CWHParameterViewController.h"
13 |
14 | @interface CWHGoochParameterViewController : CWHParameterViewController
15 |
16 | @property (weak) IBOutlet NSTextField *diffuseWarmTextField;
17 | @property (weak) IBOutlet NSTextField *diffuseCoolTextField;
18 |
19 | @property (weak) IBOutlet NSSlider *diffuseWarmSlider;
20 | @property (weak) IBOutlet NSSlider *diffuseCoolSlider;
21 |
22 | @property (weak) IBOutlet NSColorWell *surfaceColorWell;
23 | @property (weak) IBOutlet NSColorWell *warmColorWell;
24 | @property (weak) IBOutlet NSColorWell *coolColorWell;
25 |
26 | @property (assign) double diffuseWarm;
27 | - (IBAction)updateDiffuseWarm:(id)sender;
28 |
29 | @property (assign) double diffuseCool;
30 | - (IBAction)updateDiffuseCool:(id)sender;
31 |
32 | @property (strong) NSColor *surfaceColor;
33 | - (IBAction)updateSurfaceColor:(id)sender;
34 |
35 | @property (strong) NSColor *warmColor;
36 | - (IBAction)updateWarmColor:(id)sender;
37 |
38 | @property (strong) NSColor *coolColor;
39 | - (IBAction)updateCoolColor:(id)sender;
40 |
41 | @end
42 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHHemisphereParameterViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // CWHHemisphereParameterViewController.m
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 8/21/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import "CWHHemisphereParameterViewController.h"
10 |
11 | @interface CWHHemisphereParameterViewController ()
12 |
13 | @end
14 |
15 | @implementation CWHHemisphereParameterViewController
16 |
17 | - (void)viewDidLoad {
18 | [super viewDidLoad];
19 | // Do view setup here.
20 | if(self.program){
21 | NSColor *skyColor = [self.program valueForKey:@"skyColor"];
22 |
23 | if (skyColor) {
24 | [self.skyColorWell setColor:skyColor];
25 | self.skyColor = skyColor;
26 | }
27 |
28 | NSColor *groundColor = [self.program valueForKey:@"groundColor"];
29 |
30 | if(groundColor){
31 | [self.groundColorWell setColor:groundColor];
32 | self.groundColor = groundColor;
33 | }
34 | }
35 | }
36 |
37 | - (IBAction)updateSkyColor:(id)sender {
38 | self.skyColor = [sender color];
39 | [self updateShaderValues];
40 | }
41 |
42 | - (IBAction)updateGroundColor:(id)sender {
43 | self.groundColor = [sender color];
44 | [self updateShaderValues];
45 | }
46 |
47 | -(void)updateShaderValues
48 | {
49 |
50 | CWHHemisphereProgram *program = (CWHHemisphereProgram *)self.program;
51 |
52 | program.skyColor = self.skyColor;
53 | program.groundColor = self.groundColor;
54 |
55 | [self.delegate updateProgram:program shadableProperties:nil];
56 | }
57 |
58 | @end
59 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHGlossyWetHighlightParameterViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // CWHGlossyWetHighlightParameterViewController.h
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 9/12/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 | #import
9 | #import "CWHGlossyWetHighlightProgram.h"
10 | #import "CWHParameterViewController.h"
11 |
12 |
13 | @interface CWHGlossyWetHighlightParameterViewController : CWHParameterViewController
14 | @property (weak) IBOutlet NSSlider *glossMinSlider;
15 | @property (weak) IBOutlet NSTextField *glossMinTextField;
16 | @property (weak) IBOutlet NSSlider *glossMaxSlider;
17 | @property (weak) IBOutlet NSTextField *glossMaxTextField;
18 | @property (weak) IBOutlet NSSlider *glossDropSlider;
19 | @property (weak) IBOutlet NSTextField *glossDropTextField;
20 | @property (weak) IBOutlet NSSlider *specularExponentSlider;
21 | @property (weak) IBOutlet NSTextField *specularExponentTextField;
22 | @property (weak) IBOutlet NSSlider *specularitySlider;
23 | @property (weak) IBOutlet NSTextField *specularityTextField;
24 | @property (weak) IBOutlet NSColorWell *diffuseColorWell;
25 | @property (weak) IBOutlet NSColorWell *ambientColorWell;
26 | @property (weak) IBOutlet NSColorWell *specularColorWell;
27 |
28 |
29 | - (IBAction)updateGlossMin:(id)sender;
30 | - (IBAction)updateGlossMax:(id)sender;
31 | - (IBAction)updateGlossDrop:(id)sender;
32 | - (IBAction)updateSpecularExponent:(id)sender;
33 | - (IBAction)updateSpecularity:(id)sender;
34 | - (IBAction)updateDiffuseColor:(id)sender;
35 | - (IBAction)updateAmbientColor:(id)sender;
36 | - (IBAction)updateSpecularColor:(id)sender;
37 |
38 | @end
39 |
--------------------------------------------------------------------------------
/ScenekitStarter.xcodeproj/project.xcworkspace/xcshareddata/ScenekitStarter.xccheckout:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDESourceControlProjectFavoriteDictionaryKey
6 |
7 | IDESourceControlProjectIdentifier
8 | 1BD5EB16-086D-4C67-B2FF-E637C53F6FF3
9 | IDESourceControlProjectName
10 | ScenekitStarter
11 | IDESourceControlProjectOriginsDictionary
12 |
13 | A91601920B3F1208C5E892E32836B83870B353A1
14 | ssh://creative-workflow-hacks.com/~/ScenekitStarter.git
15 |
16 | IDESourceControlProjectPath
17 | ScenekitStarter.xcodeproj
18 | IDESourceControlProjectRelativeInstallPathDictionary
19 |
20 | A91601920B3F1208C5E892E32836B83870B353A1
21 | ../..
22 |
23 | IDESourceControlProjectURL
24 | ssh://creative-workflow-hacks.com/~/ScenekitStarter.git
25 | IDESourceControlProjectVersion
26 | 111
27 | IDESourceControlProjectWCCIdentifier
28 | A91601920B3F1208C5E892E32836B83870B353A1
29 | IDESourceControlProjectWCConfigurations
30 |
31 |
32 | IDESourceControlRepositoryExtensionIdentifierKey
33 | public.vcs.git
34 | IDESourceControlWCCIdentifierKey
35 | A91601920B3F1208C5E892E32836B83870B353A1
36 | IDESourceControlWCCName
37 | ScenekitStarter
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHEdgeFuzzParameterViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // CWHEdgeFuzzParameterViewController.h
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 8/15/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CWHParameterViewProtocol.h"
11 | #import "CWHEdgeFuzzProgram.h"
12 | #import "CWHParameterViewController.h"
13 |
14 | @interface CWHEdgeFuzzParameterViewController : CWHParameterViewController
15 |
16 | @property (weak) IBOutlet NSTextField *fuzzinessTextField;
17 | @property (weak) IBOutlet NSSlider *fuzzinessCircularSlider;
18 | @property (weak) IBOutlet NSColorWell *surfaceColorWell;
19 | @property (weak) IBOutlet NSTextField *edgeFadeTextField;
20 | @property (weak) IBOutlet NSSlider *edgeFadeCircularSlider;
21 | @property (weak) IBOutlet NSTextField *specularityTextField;
22 | @property (weak) IBOutlet NSSlider *specularityCircularSlider;
23 | @property (weak) IBOutlet NSColorWell *edgeColorWell;
24 | @property (weak) IBOutlet NSColorWell *lightColorWell;
25 | @property (weak) IBOutlet NSColorWell *ambientColorWell;
26 |
27 | @property (assign) double fuzziness;
28 | - (IBAction)updateFuzziness:(id)sender;
29 |
30 | @property (strong) NSColor *surfaceColor;
31 | - (IBAction)updateSurfaceColor:(id)sender;
32 |
33 | @property (assign) double edgeFade;
34 | - (IBAction)updateEdgeFade:(id)sender;
35 |
36 | @property (assign) double specularity;
37 | - (IBAction)updateSpecularity:(id)sender;
38 |
39 | @property (strong) NSColor *edgeColor;
40 | - (IBAction)updateEdgeColor:(id)sender;
41 |
42 | @property (strong) NSColor *lightColor;
43 | - (IBAction)lightColor:(id)sender;
44 |
45 | @property (strong) NSColor *ambientColor;
46 | - (IBAction)updateAmbientColor:(id)sender;
47 |
48 | @end
49 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHBlinnParameterViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // CWHBlinnParameterViewController.m
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 8/15/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import "CWHBlinnParameterViewController.h"
10 |
11 | @interface CWHBlinnParameterViewController ()
12 |
13 | @end
14 |
15 | @implementation CWHBlinnParameterViewController
16 |
17 | - (void)viewDidLoad {
18 | [super viewDidLoad];
19 | if (self.program) {
20 | NSColor *ambientColor = [self.program valueForKey:@"ambientColor"];
21 |
22 | if (ambientColor) {
23 | [self.ambientColorWell setColor:ambientColor];
24 | self.ambientColor = ambientColor;
25 | }
26 |
27 | NSColor *lightColor = [self.program valueForKey:@"lightColor"];
28 |
29 | if(lightColor){
30 | [self.lightColorWell setColor:lightColor];
31 | self.lightColor = lightColor;
32 | }
33 | }
34 | }
35 |
36 | - (IBAction)updateAmbientColor:(id)sender {
37 |
38 | NSColorWell *colorWell = sender;
39 | NSColor *color = [colorWell color];
40 |
41 | self.ambientColor = color;
42 | [self updateShaderValues];
43 |
44 | }
45 |
46 | - (IBAction)updateLightColor:(id)sender {
47 | NSColorWell *colorWell = sender;
48 | NSColor *color = [colorWell color];
49 |
50 | self.lightColor = color;
51 | [self updateShaderValues];
52 | }
53 |
54 | -(void)updateShaderValues
55 | {
56 | CWHBlinnProgram *program = (CWHBlinnProgram *)self.program;
57 |
58 | program.lightColor = self.lightColor;
59 | program.ambientColor = self.ambientColor;
60 |
61 | [self.delegate updateProgram:program shadableProperties:nil];
62 | }
63 |
64 | @end
65 |
--------------------------------------------------------------------------------
/ScenekitStarter/Hemisphere.metal:
--------------------------------------------------------------------------------
1 |
2 | #include
3 | using namespace metal;
4 |
5 | #include
6 |
7 | struct VertexIn {
8 | float4 position [[attribute(SCNVertexSemanticPosition)]];
9 | float3 normal [[attribute(SCNVertexSemanticNormal)]];
10 | //float2 texCoords [[attribute(SCNVertexSemanticTexcoord0)]];
11 | };
12 |
13 | struct NodeConstants {
14 | float4x4 modelViewTransform;
15 | float4x4 modelViewProjectionTransform;
16 | float4x4 normalTransform;
17 | };
18 |
19 | struct LightConstants {
20 | packed_float3 position;
21 | packed_float3 skyColor;
22 | packed_float3 groundColor;
23 | };
24 |
25 | struct VertexOut {
26 | float4 position [[position]];
27 | float4 color;
28 | };
29 |
30 | /*
31 | From the GLSL Orange Book
32 | Randi J. Rost
33 | */
34 |
35 | vertex VertexOut HemisphereVertex(VertexIn in [[stage_in]],
36 | constant SCNSceneBuffer &scn_frame [[buffer(0)]],
37 | constant NodeConstants &scn_node [[buffer(1)]],
38 | constant LightConstants &light [[buffer(2)]])
39 | {
40 | float4 Nm = scn_node.normalTransform * float4(in.normal, 0.0f);
41 | float3 N = normalize(Nm.xyz);
42 | float3 V = (scn_node.modelViewTransform * in.position).xyz;
43 | float3 lightVec = normalize(light.position.xyz - V);
44 | float costheta = dot(N, lightVec);
45 | float a = 0.5 + 0.5 * costheta;
46 | float3 litColor = mix(light.groundColor, light.skyColor, a);
47 |
48 | VertexOut out;
49 | out.position = scn_node.modelViewProjectionTransform * in.position;
50 | out.color = float4(litColor, 1.0f);
51 | return out;
52 | }
53 |
54 | fragment float4 HemisphereFragment(VertexOut in [[stage_in]])
55 | {
56 | return in.color;
57 | }
58 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHThinFilmParameterViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // CWHThinFilmParameterViewController.m
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 9/4/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import "CWHThinFilmParameterViewController.h"
10 |
11 | @interface CWHThinFilmParameterViewController ()
12 |
13 | @end
14 |
15 | @implementation CWHThinFilmParameterViewController
16 |
17 | - (void)viewDidLoad {
18 | [super viewDidLoad];
19 | if(self.program){
20 | NSColor *diffuseColor = [self.program valueForKey:@"diffuseColor"];
21 |
22 | if (diffuseColor) {
23 | [self.diffuseColorWell setColor:diffuseColor];
24 | self.diffuseColor = diffuseColor;
25 | }
26 |
27 | double filmDepth = [[self.program valueForKey:@"filmDepth"] doubleValue];
28 | if (filmDepth >= 0) {
29 | [self.filmDepthSlider setDoubleValue:filmDepth];
30 | [self.filmDepthTextField setDoubleValue:filmDepth];
31 | self.filmDepth = filmDepth;
32 | }
33 | }
34 | }
35 |
36 | - (IBAction)updateFilmDepth:(id)sender {
37 | self.filmDepth = [sender doubleValue];
38 | if ([sender isKindOfClass:[NSSlider class]]) {
39 | [self.filmDepthTextField setDoubleValue:[sender doubleValue]];
40 | }else{
41 | [self.filmDepthSlider setDoubleValue:[sender doubleValue]];
42 | }
43 | [self updateShaderValues];
44 | }
45 |
46 | - (IBAction)updateDiffuseColor:(id)sender {
47 | NSColorWell *colorWell = sender;
48 | NSColor *color = [colorWell color];
49 |
50 | self.diffuseColor = color;
51 | [self updateShaderValues];
52 | }
53 |
54 | -(void)updateShaderValues
55 | {
56 | CWHThinFilmProgram *program = (CWHThinFilmProgram *)self.program;
57 |
58 | program.filmDepth= self.filmDepth;
59 | program.diffuseColor = self.diffuseColor;
60 |
61 | [self.delegate updateProgram:program shadableProperties:program.shadableProperties];
62 | }
63 |
64 | @end
65 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHLightingView.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/ScenekitStarter/Blinn.metal:
--------------------------------------------------------------------------------
1 | #include
2 | using namespace metal;
3 |
4 | #include
5 |
6 | struct VertexIn {
7 | float4 position [[attribute(SCNVertexSemanticPosition)]];
8 | float3 normal [[attribute(SCNVertexSemanticNormal)]];
9 | float2 texCoords [[attribute(SCNVertexSemanticTexcoord0)]];
10 | };
11 |
12 | struct NodeConstants {
13 | float4x4 modelViewTransform;
14 | float4x4 modelViewProjectionTransform;
15 | float4x4 normalTransform;
16 | };
17 |
18 | struct LightConstants {
19 | packed_float3 diffuseIntensity;
20 | packed_float3 ambientIntensity;
21 | packed_float3 position;
22 | };
23 |
24 | struct VertexOut {
25 | float4 position [[position]];
26 | float3 normal;
27 | float3 lightDir;
28 | };
29 |
30 | vertex VertexOut BlinnVertex(VertexIn in [[stage_in]],
31 | constant SCNSceneBuffer &scn_frame [[buffer(0)]],
32 | constant NodeConstants &scn_node [[buffer(1)]],
33 | constant LightConstants &vertexLight [[buffer(2)]])
34 | {
35 | float4 viewPosition = scn_node.modelViewTransform * in.position;
36 | float3 v = float3(viewPosition.xyz / viewPosition.w);
37 | float4 n = scn_node.normalTransform * float4(in.normal, 0.0f);
38 | float3 normal = normalize(n.xyz);
39 |
40 | VertexOut out;
41 | out.position = scn_node.modelViewProjectionTransform * in.position;
42 | out.normal = normal;
43 | out.lightDir = float3(vertexLight.position.xyz - v);
44 |
45 | return out;
46 | }
47 |
48 | fragment float4 BlinnFragment(VertexOut in [[stage_in]],
49 | constant LightConstants &fragmentLight [[buffer(2)]])
50 | {
51 | const float3 emissionColor(0.0f, 0.0f, 0.0f);
52 | const float3 ambientColor(1.0f, 1.0f, 1.0f);
53 | const float3 diffuseColor(1.0f, 1.0f, 1.0f);
54 |
55 | // Ambient contribution
56 | float3 surfaceColor = emissionColor + ambientColor * fragmentLight.ambientIntensity;
57 | float3 N = normalize(in.normal);
58 | float3 L = normalize(in.lightDir);
59 | float lambertTerm = dot(N,L);
60 | if(lambertTerm > 0.0) {
61 | // Diffuse contribution
62 | surfaceColor += fragmentLight.diffuseIntensity * diffuseColor * lambertTerm;
63 | }
64 | return float4(surfaceColor, 1.0f);
65 | }
66 |
--------------------------------------------------------------------------------
/ScenekitStarter/Gooch.metal:
--------------------------------------------------------------------------------
1 |
2 | #include
3 | using namespace metal;
4 |
5 | #include
6 |
7 | struct VertexIn {
8 | float4 position [[attribute(SCNVertexSemanticPosition)]];
9 | float3 normal [[attribute(SCNVertexSemanticNormal)]];
10 | float2 texCoords [[attribute(SCNVertexSemanticTexcoord0)]];
11 | };
12 |
13 | struct NodeConstants {
14 | float4x4 modelViewTransform;
15 | float4x4 modelViewProjectionTransform;
16 | float4x4 normalTransform;
17 | };
18 |
19 | struct LightConstants {
20 | packed_float3 position;
21 | };
22 |
23 | struct MaterialConstants {
24 | packed_float4 surfaceColor;
25 | packed_float4 warmColor;
26 | packed_float4 coolColor;
27 | float diffuseWarm;
28 | float diffuseCool;
29 | };
30 |
31 | struct VertexOut {
32 | float4 position [[position]];
33 | float3 reflectVec;
34 | float3 viewVec;
35 | float NdotL;
36 | };
37 |
38 | vertex VertexOut GoochVertex(VertexIn in [[stage_in]],
39 | constant SCNSceneBuffer &scn_frame [[buffer(0)]],
40 | constant NodeConstants &scn_node [[buffer(1)]],
41 | constant LightConstants &light [[buffer(2)]])
42 | {
43 | float4 eyePosition = scn_node.modelViewTransform * in.position;
44 | float3 v = eyePosition.xyz / eyePosition.w;
45 | float4 n = scn_node.normalTransform * float4(in.normal, 0.0f);
46 | float3 tnorm = normalize(n.xyz);
47 | float3 lightVec = normalize(light.position - v);
48 |
49 | VertexOut out;
50 | out.reflectVec = normalize(reflect(-lightVec, tnorm));
51 | out.viewVec = normalize(-v);
52 | out.NdotL = (dot(lightVec, tnorm) + 1.0f) * 0.5f;
53 | out.position = scn_node.modelViewProjectionTransform * in.position;
54 | return out;
55 | }
56 |
57 | fragment float4 GoochFragment(VertexOut in [[stage_in]],
58 | constant MaterialConstants &material [[buffer(0)]])
59 | {
60 | float3 kcool = min(material.coolColor.rgb + material.diffuseCool * material.surfaceColor.rgb, 1.0f);
61 | float3 kwarm = min(material.warmColor.rgb + material.diffuseWarm * material.surfaceColor.rgb, 1.0f);
62 | float3 kfinal = mix(kcool, kwarm, in.NdotL);
63 |
64 | float3 nreflect = normalize(in.reflectVec);
65 | float3 nview = normalize(in.viewVec);
66 |
67 | float spec = max(dot(nreflect, nview), 0.0f);
68 | spec = powr(spec, 32.0f);
69 |
70 | return float4(min(kfinal + spec, 1.0), 1.0);
71 | }
72 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHLightingViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // lightingViewController.m
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 7/24/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import "CWHLightingViewController.h"
10 |
11 | @interface CWHLightingViewController ()
12 | @property (strong) SCNNode *lightNode;
13 | @end
14 |
15 | @implementation CWHLightingViewController
16 |
17 | -(void)awakeFromNib
18 | {
19 | // create a new scene
20 | SCNScene *scene = [SCNScene scene];
21 |
22 | // create and add a camera to the scene
23 | SCNNode *cameraNode = [SCNNode node];
24 | cameraNode.camera = [SCNCamera camera];
25 | [scene.rootNode addChildNode:cameraNode];
26 |
27 | // place the camera
28 | cameraNode.position = SCNVector3Make(0, 0, 15);
29 |
30 | // create and add a light to the scene
31 | SCNNode *ambientLightNode = [SCNNode node];
32 | ambientLightNode.name = @"light";
33 | ambientLightNode.light = [SCNLight light];
34 | ambientLightNode.position = SCNVector3Make(0, 10, 10);
35 | ambientLightNode.light.type = SCNLightTypeAmbient;
36 | ambientLightNode.light.color = [NSColor redColor];
37 | [scene.rootNode addChildNode:ambientLightNode];
38 | self.lightNode = ambientLightNode;
39 |
40 | SCNAction *moveByAction = [SCNAction moveBy:SCNVector3Make(20, 30, 10) duration:2];
41 | moveByAction.timingMode = SCNActionTimingModeEaseInEaseOut;
42 | SCNAction *reversed = [moveByAction reversedAction];
43 |
44 | [ambientLightNode runAction:[SCNAction repeatActionForever:[SCNAction sequence:@[moveByAction, reversed]]]];
45 |
46 | SCNTorus *torusShape = [SCNTorus torusWithRingRadius:3 pipeRadius:1];
47 |
48 | SCNNode *torusNode = [SCNNode nodeWithGeometry:torusShape];
49 | torusNode.position = SCNVector3Make(0, 0, 0);
50 | torusNode.scale = SCNVector3Make(1, 1, 1);
51 |
52 | [torusNode runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:2 y:0 z:0 duration:1]]];
53 |
54 | self.geometryNode = torusNode;
55 |
56 | [scene.rootNode addChildNode:self.geometryNode];
57 |
58 | // set the scene to the view
59 | self.lightingView.scene = scene;
60 |
61 | // allows the user to manipulate the camera
62 | self.lightingView.allowsCameraControl = YES;
63 |
64 | // show statistics such as fps and timing information
65 | self.lightingView.showsStatistics = YES;
66 |
67 | // configure the view
68 | self.lightingView.backgroundColor = [NSColor blackColor];
69 | }
70 |
71 | @end
72 |
--------------------------------------------------------------------------------
/ScenekitStarter/LambSkin.metal:
--------------------------------------------------------------------------------
1 |
2 | #include
3 | using namespace metal;
4 |
5 | #include
6 |
7 | struct VertexIn {
8 | float4 position [[attribute(SCNVertexSemanticPosition)]];
9 | float3 normal [[attribute(SCNVertexSemanticNormal)]];
10 | };
11 |
12 | struct NodeConstants {
13 | float4x4 modelViewTransform;
14 | float4x4 modelViewProjectionTransform;
15 | float4x4 normalTransform;
16 | };
17 |
18 | struct LightConstants {
19 | packed_float3 position;
20 | };
21 |
22 | struct MaterialConstants {
23 | packed_float3 ambientColor;
24 | packed_float3 diffuseColor;
25 | packed_float3 subColor;
26 | float rolloff;
27 | };
28 |
29 | struct VertexOut {
30 | float4 position [[position]];
31 | float3 lightVec;
32 | float3 eyeNormal;
33 | };
34 |
35 | /*
36 | Adapted from:
37 | 'lambSkin' shader from NVIDIA shader library
38 | http://developer.download.nvidia.com/shaderlibrary/webpages/shader_library.html
39 |
40 | "A lambertian-like surface with light 'bleed-through'."
41 | */
42 |
43 | vertex VertexOut LambSkinVertex(VertexIn in [[stage_in]],
44 | constant SCNSceneBuffer &scn_frame [[buffer(0)]],
45 | constant NodeConstants &scn_node [[buffer(1)]],
46 | constant LightConstants &light [[buffer(2)]])
47 | {
48 | VertexOut out;
49 |
50 | float4 V = scn_node.modelViewTransform * in.position;
51 | float4 N = normalize(scn_node.normalTransform * float4(in.normal, 0.0f));
52 |
53 | out.lightVec = light.position - V.xyz;
54 | out.eyeNormal = N.xyz;
55 |
56 | out.position = scn_node.modelViewProjectionTransform * in.position;
57 | return out;
58 | }
59 |
60 | fragment float4 LambSkinFragment(VertexOut in [[stage_in]],
61 | constant MaterialConstants &material [[buffer(0)]])
62 | {
63 | // Normalize normal and light vector
64 | float3 Ln = normalize(in.lightVec);
65 | float3 Nn = normalize(in.eyeNormal);
66 |
67 | float ldn = dot(Ln, Nn);
68 |
69 | // Calculate diffuse contribution
70 | float diffComp = max(0.0f, ldn);
71 | float3 diffuse = (diffComp * material.diffuseColor).xyz;
72 |
73 | // Calculate simulated subsurface contribution
74 | float subLamb = smoothstep(-material.rolloff, 1.0f, ldn) - smoothstep(0.0f, 1.0f, ldn);
75 | subLamb = max(0.0f, subLamb);
76 | float3 subsurface = subLamb * material.subColor.xyz;
77 |
78 | float3 surfaceColor = material.ambientColor.xyz + diffuse + subsurface;
79 | return float4(surfaceColor, 1.0f);
80 | }
81 |
--------------------------------------------------------------------------------
/ScenekitStarter/GameViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // GameViewController.m
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 7/24/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import "GameViewController.h"
10 |
11 | @implementation GameViewController
12 |
13 | -(void)awakeFromNib
14 | {
15 | NSLog(@"awakeFromNib");
16 | // create a new scene
17 | SCNScene *scene = [SCNScene scene];
18 |
19 | // create and add a camera to the scene
20 | SCNNode *cameraNode = [SCNNode node];
21 | cameraNode.camera = [SCNCamera camera];
22 | [scene.rootNode addChildNode:cameraNode];
23 |
24 | // place the camera
25 | cameraNode.position = SCNVector3Make(0, 0, 15);
26 |
27 | // create and add a light to the scene
28 | SCNNode *ambientLightNode = [SCNNode node];
29 | ambientLightNode.name = @"light";
30 | ambientLightNode.light = [SCNLight light];
31 | ambientLightNode.position = SCNVector3Make(0, 10, 10);
32 | ambientLightNode.light.type = SCNLightTypeAmbient;
33 | ambientLightNode.light.color = [NSColor redColor];
34 | [scene.rootNode addChildNode:ambientLightNode];
35 |
36 |
37 | SCNAction *moveByAction = [SCNAction moveBy:SCNVector3Make(20, 30, 10) duration:2];
38 | moveByAction.timingMode = SCNActionTimingModeEaseInEaseOut;
39 | SCNAction *reversed = [moveByAction reversedAction];
40 |
41 | [ambientLightNode runAction:[SCNAction repeatActionForever:[SCNAction sequence:@[moveByAction, reversed]]]];
42 |
43 | SCNTorus *torusShape = [SCNTorus torusWithRingRadius:3.
44 | pipeRadius:1.];
45 |
46 |
47 | CWHShadingNode *torusNode = [[CWHShadingNode alloc] initWithGeometry:torusShape
48 | light:ambientLightNode];
49 | torusNode.position = SCNVector3Make(0., 0., 0.);
50 | torusNode.scale = SCNVector3Make(1., 1., 1.);
51 |
52 | [torusNode runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:2 y:0 z:0 duration:1]]];
53 |
54 | self.torusNode = torusNode;
55 |
56 | [scene.rootNode addChildNode:self.torusNode];
57 |
58 |
59 | // set the scene to the view
60 | self.gameView.scene = scene;
61 |
62 | // allows the user to manipulate the camera
63 | self.gameView.allowsCameraControl = YES;
64 |
65 | // show statistics such as fps and timing information
66 | self.gameView.showsStatistics = YES;
67 |
68 | // configure the view
69 | self.gameView.backgroundColor = [NSColor blackColor];
70 | }
71 |
72 | @end
73 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHVelvetParameterViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // CWHVelvetParamterViewController.m
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 8/15/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import "CWHVelvetParameterViewController.h"
10 |
11 | @interface CWHVelvetParameterViewController ()
12 |
13 | @end
14 |
15 | @implementation CWHVelvetParameterViewController
16 |
17 | - (void)viewDidLoad {
18 | [super viewDidLoad];
19 |
20 | if(self.program){
21 | double rolloff = [[self.program valueForKey:@"rolloff"] doubleValue];
22 | if (rolloff >= 0) {
23 | [self.rolloffCircularSlider setDoubleValue:rolloff];
24 | [self.rolloffTextField setDoubleValue:rolloff];
25 | self.rolloff = rolloff;
26 | }
27 |
28 | NSColor *underColor = [self.program valueForKey:@"underColor"];
29 |
30 | if (underColor) {
31 | [self.underColorWell setColor:underColor];
32 | self.underColor = underColor;
33 | }
34 |
35 | NSColor *fuzzColor = [self.program valueForKey:@"fuzzColor"];
36 |
37 | if(fuzzColor){
38 | [self.fuzzColorWell setColor:fuzzColor];
39 | self.fuzzColor= fuzzColor;
40 | }
41 |
42 | NSColor *primaryColor = [self.program valueForKey:@"primaryColor"];
43 |
44 | if(primaryColor){
45 | [self.primaryColorWell setColor:primaryColor];
46 | self.primaryColor = primaryColor;
47 | }
48 | }
49 | }
50 |
51 | - (IBAction)updateRolloff:(id)sender {
52 | self.rolloff = [sender doubleValue];
53 | if ([sender isKindOfClass:[NSSlider class]]) {
54 | [self.rolloffTextField setDoubleValue:[sender doubleValue]];
55 | }
56 |
57 | [self updateShaderValues];
58 | }
59 |
60 | - (IBAction)updateUnderColor:(id)sender {
61 | self.underColor = [sender color];
62 | [self updateShaderValues];
63 | }
64 |
65 | - (IBAction)updateFuzzColor:(id)sender {
66 | self.fuzzColor = [sender color];
67 | [self updateShaderValues];
68 | }
69 |
70 | - (IBAction)updatePrimaryColor:(id)sender {
71 | self.primaryColor = [sender color];
72 | [self updateShaderValues];
73 | }
74 |
75 | -(void)updateShaderValues
76 | {
77 | CWHVelvetProgram *program = (CWHVelvetProgram *)self.program;
78 |
79 | program.rolloff = self.rolloff;
80 | program.underColor = self.underColor;
81 | program.fuzzColor = self.fuzzColor;
82 | program.primaryColor = self.primaryColor;
83 |
84 | [self.delegate updateProgram:program shadableProperties:nil];
85 | }
86 | @end
87 |
--------------------------------------------------------------------------------
/ScenekitStarter/Velvet.metal:
--------------------------------------------------------------------------------
1 |
2 | #include
3 | using namespace metal;
4 |
5 | #include
6 |
7 | struct VertexIn {
8 | float4 position [[attribute(SCNVertexSemanticPosition)]];
9 | float3 normal [[attribute(SCNVertexSemanticNormal)]];
10 | float2 texCoords [[attribute(SCNVertexSemanticTexcoord0)]];
11 | };
12 |
13 | struct NodeConstants {
14 | float4x4 modelViewTransform;
15 | float4x4 modelViewProjectionTransform;
16 | float4x4 normalTransform;
17 | };
18 |
19 | struct LightConstants {
20 | packed_float3 position;
21 | };
22 |
23 | struct MaterialConstants {
24 | packed_float4 primaryColor;
25 | packed_float4 fuzzColor;
26 | packed_float4 underColor;
27 | float rolloff;
28 | };
29 |
30 | struct VertexOut {
31 | float4 position [[position]];
32 | float4 color;
33 | };
34 |
35 | /*
36 | Translated from HLSL shader for VVVV
37 | vNoiseVelvety.fx
38 | by Desaxismundi 2008
39 |
40 | Velvet shader originally by NVIDIA
41 |
42 | GLSL conversion toneburst 2008
43 | */
44 |
45 | vertex VertexOut VelvetVertex(VertexIn in [[stage_in]],
46 | constant SCNSceneBuffer &scn_frame [[buffer(0)]],
47 | constant NodeConstants &scn_node [[buffer(1)]],
48 | constant LightConstants &light [[buffer(2)]],
49 | constant MaterialConstants &material [[buffer(3)]])
50 |
51 | {
52 | // Transform normal into Eye Space
53 | float4 Nm = normalize(scn_node.normalTransform * float4(in.normal, 0.0f));
54 | float3 Nn = Nm.xyz;
55 | // Transform vertex into Eye Space
56 | float4 Po = in.position;
57 | float3 Pe = (scn_node.modelViewTransform * Po).xyz;
58 | float3 Ln = normalize(light.position - Pe);
59 | float ldn = dot(Ln, Nn);
60 | float diffComp = max(0.0f, ldn);
61 | float3 diffContrib = diffComp * material.primaryColor.rgb;
62 | float subLamb = smoothstep(-material.rolloff, 1.0f, ldn) - smoothstep(0.0f, 1.0f, ldn);
63 | subLamb = max(0.0f, subLamb);
64 | float3 subContrib = subLamb * material.underColor.rgb;
65 | float3 cameraPos = float3(0.0f, 0.0f, 1.0f);
66 | float3 Vn = normalize(cameraPos - Pe);
67 | float vdn = 1.0f -dot(Vn, Nn);
68 | float3 vecColor = float3(vdn, vdn, vdn);
69 | float3 diffColor = subContrib + diffContrib;
70 | float3 specColor = vecColor * material.fuzzColor.rgb;
71 | float3 surfaceColor = diffColor + specColor;
72 |
73 | VertexOut out;
74 | out.position = scn_node.modelViewProjectionTransform * in.position;
75 | out.color = float4(surfaceColor, 1.0f);
76 | return out;
77 | }
78 |
79 | fragment float4 VelvetFragment(VertexOut in [[stage_in]])
80 | {
81 | return in.color;
82 | }
83 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHLambSkinParameterViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // CWHLambSkinParameterViewController.m
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 8/21/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import "CWHLambSkinParameterViewController.h"
10 |
11 | @interface CWHLambSkinParameterViewController ()
12 |
13 | @end
14 |
15 | @implementation CWHLambSkinParameterViewController
16 |
17 | - (void)viewDidLoad {
18 | [super viewDidLoad];
19 | // Do view setup here.
20 |
21 | if(self.program){
22 | NSColor *ambientColor = [self.program valueForKey:@"ambientColor"];
23 |
24 | if (ambientColor) {
25 | [self.ambientColorWell setColor:ambientColor];
26 | self.ambientColor = ambientColor;
27 | }
28 |
29 | NSColor *diffuseColor = [self.program valueForKey:@"diffuseColor"];
30 |
31 | if(diffuseColor){
32 | [self.diffuseColorWell setColor:diffuseColor];
33 | self.diffuseColor = diffuseColor;
34 | }
35 |
36 | NSColor *subColor = [self.program valueForKey:@"subColor"];
37 |
38 | if(subColor){
39 | [self.subColorWell setColor:subColor];
40 | self.subColor= subColor;
41 | }
42 |
43 | double rolloff = [[self.program valueForKey:@"rolloff" ] doubleValue];
44 | if (rolloff >= 0) {
45 | [self.rolloffSlider setDoubleValue:rolloff];
46 | [self.rolloffTextField setDoubleValue:rolloff];
47 | self.rolloff = rolloff;
48 | }
49 |
50 | }
51 | }
52 |
53 | - (IBAction)updateRolloff:(id)sender {
54 | self.rolloff = [sender doubleValue];
55 | if ([sender isKindOfClass:[NSSlider class]]) {
56 | [self.rolloffTextField setDoubleValue:[sender doubleValue]];
57 | }else{
58 | [self.rolloffSlider setDoubleValue:[sender doubleValue]];
59 | }
60 |
61 | [self updateShaderValues];
62 | }
63 |
64 | - (IBAction)updateAmbientColor:(id)sender {
65 | self.ambientColor = [sender color];
66 | [self updateShaderValues];
67 | }
68 |
69 | - (IBAction)updateDiffuseColor:(id)sender {
70 | self.diffuseColor = [sender color];
71 | [self updateShaderValues];
72 | }
73 |
74 | - (IBAction)updateSubColor:(id)sender {
75 | self.subColor = [sender color];
76 | [self updateShaderValues];
77 | }
78 |
79 | -(void)updateShaderValues
80 | {
81 |
82 | CWHLambSkinProgram *program = (CWHLambSkinProgram *)self.program;
83 |
84 | program.rolloff = self.rolloff;
85 | program.ambientColor = self.ambientColor;
86 | program.diffuseColor = self.diffuseColor;
87 | program.subColor = self.subColor;
88 |
89 | [self.delegate updateProgram:program shadableProperties:nil];
90 | }
91 | @end
92 |
--------------------------------------------------------------------------------
/ScenekitStarter/LUTSkin.metal:
--------------------------------------------------------------------------------
1 |
2 | #include
3 | using namespace metal;
4 |
5 | #include
6 |
7 | struct VertexIn {
8 | float4 position [[attribute(SCNVertexSemanticPosition)]];
9 | float3 normal [[attribute(SCNVertexSemanticNormal)]];
10 | float2 texCoords [[attribute(SCNVertexSemanticTexcoord0)]];
11 | };
12 |
13 | struct NodeConstants {
14 | float4x4 modelViewTransform;
15 | float4x4 modelViewProjectionTransform;
16 | float4x4 normalTransform;
17 | };
18 |
19 | struct LightConstants {
20 | packed_float3 position;
21 | };
22 |
23 | struct MaterialConstants {
24 | packed_float4 diffuseColor;
25 | packed_float4 specularColor;
26 | };
27 |
28 | struct VertexOut {
29 | float4 position [[position]];
30 | float3 normal;
31 | float3 lightVec;
32 | float3 halfVec;
33 | };
34 |
35 | /*
36 | Subsurface scattering approximation
37 | Adapted from GPU Gems Vol.1
38 | Chapter 16. 'Real-Time Approximations to Subsurface Scattering'
39 | by Simon Green
40 |
41 | Available online at
42 | http://http.developer.nvidia.com/GPUGems/gpugems_ch16.html
43 | */
44 |
45 | vertex VertexOut LUTSkinVertex(VertexIn in [[stage_in]],
46 | constant SCNSceneBuffer &scn_frame [[buffer(0)]],
47 | constant NodeConstants &scn_node [[buffer(1)]],
48 | constant LightConstants &light [[buffer(2)]])
49 | {
50 | const float3 eye(0.0f, 0.0f, 1.0f);
51 | float4 eyeNormal = scn_node.normalTransform * float4(in.normal, 0.0f);
52 |
53 | float4 v = scn_node.modelViewTransform * in.position;
54 | float3 V = v.xyz / v.w;
55 |
56 | VertexOut out;
57 | out.position = scn_node.modelViewProjectionTransform * in.position;
58 | out.normal = normalize(eyeNormal.xyz);
59 | out.lightVec = normalize(light.position.xyz - V.xyz);
60 | out.halfVec = normalize(out.lightVec + eye);
61 | return out;
62 | }
63 |
64 | fragment float4 LUTSkinFragment(VertexOut in [[stage_in]],
65 | texture2d skinLUT [[texture(0)]],
66 | constant MaterialConstants &material [[buffer(0)]])
67 | {
68 | constexpr sampler bilinearClampedSampler(coord::normalized,
69 | min_filter::linear,
70 | mag_filter::linear,
71 | mip_filter::none,
72 | address::clamp_to_edge);
73 | float2 s {
74 | dot(in.normal, in.lightVec),
75 | dot(in.normal, in.halfVec)
76 | };
77 | s = s * 0.5f + 0.5f;
78 | s.x = min(0.996f, s.x);
79 | float4 light = skinLUT.sample(bilinearClampedSampler, s);
80 | return material.diffuseColor * light + material.specularColor * light.a;
81 | }
82 |
--------------------------------------------------------------------------------
/ScenekitStarter/Phong.metal:
--------------------------------------------------------------------------------
1 |
2 | #include
3 | using namespace metal;
4 |
5 | #include
6 |
7 | struct VertexIn {
8 | float4 position [[attribute(SCNVertexSemanticPosition)]];
9 | float3 normal [[attribute(SCNVertexSemanticNormal)]];
10 | float2 texCoords [[attribute(SCNVertexSemanticTexcoord0)]];
11 | };
12 |
13 | struct NodeConstants {
14 | float4x4 modelViewTransform;
15 | float4x4 modelViewProjectionTransform;
16 | float4x4 normalTransform;
17 | };
18 |
19 | struct LightConstants {
20 | packed_float3 position;
21 | packed_float3 diffuseIntensity;
22 | packed_float3 ambientIntensity;
23 | };
24 |
25 | struct MaterialConstants {
26 | packed_float3 specularColor;
27 | float shininess;
28 | };
29 |
30 | struct VertexOut {
31 | float4 position [[position]];
32 | float3 normal;
33 | float3 lightDir;
34 | float3 eyeVec;
35 | };
36 |
37 | vertex VertexOut PhongVertex(VertexIn in [[stage_in]],
38 | constant SCNSceneBuffer &scn_frame [[buffer(0)]],
39 | constant NodeConstants &scn_node [[buffer(1)]],
40 | constant LightConstants &vertexLight [[buffer(2)]])
41 | {
42 | float4 viewPosition = scn_node.modelViewTransform * in.position;
43 | float3 V = viewPosition.xyz / viewPosition.w;
44 | float4 N = scn_node.normalTransform * float4(in.normal, 0.0f);
45 |
46 | VertexOut out;
47 | out.position = scn_node.modelViewProjectionTransform * in.position;
48 | out.normal = normalize(N.xyz);
49 | out.lightDir = vertexLight.position.xyz - V;
50 | out.eyeVec = -V;
51 |
52 | return out;
53 | }
54 |
55 | fragment float4 PhongFragment(VertexOut in [[stage_in]],
56 | constant LightConstants &fragmentLight [[buffer(2)]],
57 | constant MaterialConstants &material [[buffer(3)]])
58 | {
59 | float3 specularIntensity(1.0f, 1.0f, 1.0f);
60 |
61 | float3 emissiveIntensity(0.0f, 0.0f, 0.0f);
62 | float3 ambientColor(1.0f, 1.0f, 1.0f);
63 | float3 diffuseColor(1.0f, 1.0f, 1.0f);
64 | float3 specularColor(material.specularColor.rgb);
65 |
66 | // Ambient contribution
67 | float3 surfaceColor = emissiveIntensity + ambientColor * fragmentLight.ambientIntensity.rgb;
68 |
69 | float3 N = normalize(in.normal);
70 | float3 L = normalize(in.lightDir);
71 | float diffuseFactor = saturate(dot(N,L));
72 | if(diffuseFactor > 0.0)
73 | {
74 | // Diffuse contribution
75 | surfaceColor += fragmentLight.diffuseIntensity.rgb * diffuseColor * diffuseFactor;
76 |
77 | // Specular contribution
78 | float3 E = normalize(in.eyeVec);
79 | float3 R = reflect(-L, N);
80 | float specularFactor = powr(max(dot(R, E), 0.0), material.shininess);
81 | surfaceColor += specularIntensity * specularColor * specularFactor;
82 | }
83 |
84 | return float4(surfaceColor, 1.0f);
85 | }
86 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHLightingProgram.m:
--------------------------------------------------------------------------------
1 | //
2 | // CWHLightingProgram.m
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 9/9/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import "CWHLightingProgram.h"
10 |
11 | @implementation CWHLightingProgram
12 |
13 | - (id)init {
14 | return [self initWithProgram:@"PhongPointLight"];
15 | }
16 |
17 | - (id)initWithProgram:(NSString *)program {
18 | self = [super init];
19 | if (self) {
20 | _lightPosition = SCNVector3Make(0, 10, 10);
21 |
22 | NSURL *vertexShaderURL = [[NSBundle mainBundle] URLForResource:program withExtension:@"vsh"];
23 | NSURL *fragmentShaderURL = [[NSBundle mainBundle] URLForResource:program withExtension:@"fsh"];
24 |
25 | NSString *vertexShader = [[NSString alloc] initWithContentsOfURL:vertexShaderURL
26 | encoding:NSUTF8StringEncoding
27 | error:NULL];
28 | NSString *fragmentShader = [[NSString alloc] initWithContentsOfURL:fragmentShaderURL
29 | encoding:NSUTF8StringEncoding
30 | error:NULL];
31 | //// Assign the shader
32 | self.vertexShader = vertexShader;
33 | self.fragmentShader = fragmentShader;
34 |
35 | // Bind geometry source semantics to the vertex shader attributes
36 | [self setSemantic:SCNGeometrySourceSemanticVertex forSymbol:@"a_srcPos" options:nil];
37 | [self setSemantic:SCNGeometrySourceSemanticNormal forSymbol:@"a_normPos" options:nil];
38 | [self setSemantic:SCNGeometrySourceSemanticTexcoord forSymbol:@"a_texcoord" options:nil];
39 |
40 | // Bind the uniforms that can benefit from "automatic" values, computed and assigned by Scene Kit at each frame
41 | [self setSemantic:SCNModelViewTransform forSymbol:@"u_mv" options:nil];
42 | [self setSemantic:SCNModelViewProjectionTransform forSymbol:@"u_mvproj" options:nil];
43 | [self setSemantic:SCNProjectionTransform forSymbol:@"u_proj" options:nil];
44 | [self setSemantic:SCNNormalTransform forSymbol:@"u_norm" options:nil];
45 |
46 | // Become the program delegate so that you get the binding callback
47 | self.delegate = self;
48 | }
49 | return self;
50 | }
51 |
52 | - (instancetype)initWithLibrary:(id)library
53 | vertexFunctionName:(NSString *)vertexFunctionName
54 | fragmentFunctionName:(NSString *)fragmentFunctionName
55 | {
56 | if ((self = [super init])) {
57 | _lightPosition = SCNVector3Make(0, 10, 10);
58 |
59 | self.library = library;
60 | self.vertexFunctionName = vertexFunctionName;
61 | self.fragmentFunctionName = fragmentFunctionName;
62 |
63 | self.delegate = self;
64 | }
65 | return self;
66 | }
67 |
68 | @end
69 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHEnvMapParameterViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // CWHEnvMapParameterViewController.m
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 8/25/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CWHEnvMapParameterViewController.h"
11 | #import "CWHParameterViewProtocol.h"
12 | #import "CWHEnvMapProgram.h"
13 | #import "CWHParameterViewController.h"
14 |
15 | @interface CWHEnvMapParameterViewController ()
16 |
17 | @end
18 |
19 | @implementation CWHEnvMapParameterViewController
20 |
21 | - (void)viewDidLoad {
22 | [super viewDidLoad];
23 |
24 | double ratio = 0.875;
25 | NSColor *ambientColor = [NSColor colorWithRed:0. green:0. blue:0. alpha:1.];
26 | NSColor *diffuseColor = [NSColor colorWithRed:1. green:1. blue:1. alpha:1.];
27 | NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"EnvMapInterior" ofType:@"png"];
28 |
29 | if (self.program) {
30 | ratio = [[self.program valueForKey:@"ratio"] doubleValue];
31 | ambientColor = [self.program valueForKey:@"ambientColor"];
32 | diffuseColor = [self.program valueForKey:@"diffuseColor"];
33 | imagePath = [self.program valueForKey:@"imagePath"];
34 | }
35 |
36 | if (imagePath == nil) {
37 | imagePath = [[NSBundle mainBundle] pathForResource:@"EnvMapInterior" ofType:@"png"];
38 | }
39 |
40 | NSString *envMapTitle = [[imagePath lastPathComponent] stringByDeletingPathExtension];
41 |
42 | self.ratio = ratio;
43 | [self.ratioTextField setDoubleValue:self.ratio];
44 | [self.ratioSlider setDoubleValue:self.ratio];
45 |
46 | self.ambientColor = ambientColor;
47 | [self.ambientColorWell setColor:ambientColor];
48 |
49 | self.diffuseColor = diffuseColor;
50 | [self.diffuseColorWell setColor:diffuseColor];
51 |
52 | self.imagePath = imagePath;
53 | [self.envMapMenu selectItemWithTitle:envMapTitle];
54 | }
55 |
56 | - (IBAction)updateRatio:(id)sender {
57 | self.ratio = [sender doubleValue];
58 | if ([sender isKindOfClass:[NSSlider class]]) {
59 | [self.ratioTextField setDoubleValue:[sender doubleValue]];
60 | }else{
61 | [self.ratioSlider setDoubleValue:[sender doubleValue]];
62 | }
63 | [self updateShaderValues];
64 | }
65 |
66 | - (IBAction)updateAmbientColor:(NSColorWell *)sender {
67 | self.ambientColor = [sender color];
68 | [self updateShaderValues];
69 | }
70 |
71 | - (IBAction)updateDiffuseColor:(NSColorWell *)sender {
72 | self.diffuseColor = [(NSColorWell *)sender color];
73 | [self updateShaderValues];
74 | }
75 |
76 | - (IBAction)updateEnvMap:(id)sender {
77 | NSString *updatedMap = [sender titleOfSelectedItem];
78 | self.imagePath = [[NSBundle mainBundle] pathForResource:updatedMap ofType:@"png"];
79 |
80 | [self updateShaderValues];
81 | }
82 |
83 | -(void)updateShaderValues
84 | {
85 | CWHEnvMapProgram *program = (CWHEnvMapProgram *)self.program;
86 |
87 | program.ratio = self.ratio;
88 | program.ambientColor = self.ambientColor;
89 | program.diffuseColor = self.diffuseColor;
90 | program.imagePath = self.imagePath;
91 |
92 | [self.delegate updateProgram:program shadableProperties:program.shadableProperties];
93 | }
94 |
95 | @end
96 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHHemisphereProgram.m:
--------------------------------------------------------------------------------
1 | //
2 | // CWHHemisphereProgram
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 7/30/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import "CWHHemisphereProgram.h"
10 |
11 | @implementation CWHHemisphereProgram
12 |
13 | +(BOOL) supportsSecureCoding {
14 | return YES;
15 | }
16 |
17 | -(instancetype)init
18 | {
19 | id device = MTLCreateSystemDefaultDevice();
20 | id library = [device newDefaultLibrary];
21 |
22 | self = [super initWithLibrary:library vertexFunctionName:@"HemisphereVertex" fragmentFunctionName:@"HemisphereFragment"];
23 |
24 | if ( self != nil )
25 | {
26 | self.delegate = self;
27 |
28 | [self bindBuffers];
29 |
30 | NSColor *skyColor = [NSColor colorWithRed:0.0 green:0.7 blue:1.0 alpha:1.0];
31 | self.skyColor = skyColor;
32 | NSColor *groundColor = [NSColor colorWithRed:0.7 green:0.5 blue:0.2 alpha:1.0];
33 | self.groundColor = groundColor;
34 | }
35 |
36 | return self;
37 | }
38 |
39 | - (id)initWithCoder:(NSCoder *)decoder {
40 | id device = MTLCreateSystemDefaultDevice();
41 | id library = [device newDefaultLibrary];
42 |
43 | self = [super initWithLibrary:library vertexFunctionName:@"HemisphereVertex" fragmentFunctionName:@"HemisphereFragment"];
44 |
45 | if ( self != nil )
46 | {
47 | self.delegate = self;
48 |
49 | [self bindBuffers];
50 |
51 | self.skyColor =[decoder decodeObjectOfClass:[NSColor class] forKey:@"skyColor"];
52 | self.groundColor = [decoder decodeObjectOfClass:[NSColor class] forKey:@"groundColor"];
53 |
54 | }
55 | return self;
56 | }
57 |
58 | - (void)encodeWithCoder:(NSCoder *)encoder {
59 | [encoder encodeObject:_skyColor forKey:@"skyColor"];
60 | [encoder encodeObject:_groundColor forKey:@"groundColor"];
61 | }
62 |
63 | - (void)bindBuffers {
64 | SCNBufferBindingBlock lightBlock = ^(id buffer, SCNNode *node, id shadable, SCNRenderer *renderer)
65 | {
66 | struct LightConstants {
67 | float position[3];
68 | float skyColor[3];
69 | float groundColor[3];
70 | } light;
71 |
72 | light.position[0] = self.lightPosition.x;
73 | light.position[1] = self.lightPosition.y;
74 | light.position[2] = self.lightPosition.z;
75 |
76 | if (self.skyColor) {
77 | light.skyColor[0] = self.skyColor.redComponent;
78 | light.skyColor[1] = self.skyColor.greenComponent;
79 | light.skyColor[2] = self.skyColor.blueComponent;
80 | }
81 |
82 | if (self.groundColor) {
83 | light.groundColor[0] = self.groundColor.redComponent;
84 | light.groundColor[1] = self.groundColor.greenComponent;
85 | light.groundColor[2] = self.groundColor.blueComponent;
86 | }
87 |
88 | [buffer writeBytes:&light length:sizeof(light)];
89 | };
90 |
91 | [self handleBindingOfBufferNamed:@"light" frequency:SCNBufferFrequencyPerFrame usingBlock:lightBlock];
92 | }
93 |
94 | #pragma mark - SCNProgramDelegate Protocol Methods
95 |
96 | - (void)program:(SCNProgram*)program handleError:(NSError*)error {
97 | // Log the shader compilation error
98 | NSLog(@"SceneKit compilation error: %@", error);
99 | }
100 |
101 | @end
102 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHPhongPointLightParameterViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // CWHPhongPointLightParameterViewController.m
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 8/1/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import "CWHPhongPointLightParameterViewController.h"
10 |
11 | @interface CWHPhongPointLightParameterViewController ()
12 |
13 | @end
14 |
15 | @implementation CWHPhongPointLightParameterViewController
16 |
17 | - (void)viewDidLoad {
18 | [super viewDidLoad];
19 | // Do view setup here.
20 | if(self.program){
21 | NSColor *ambientColor = [self.program valueForKey:@"ambientColor"];
22 |
23 | if (ambientColor) {
24 | [self.ambientColorWell setColor:ambientColor];
25 | self.ambientColor = ambientColor;
26 | }
27 |
28 | NSColor *lightColor = [self.program valueForKey:@"lightColor"];
29 |
30 | if(lightColor){
31 | [self.lightColorWell setColor:lightColor];
32 | self.lightColor = lightColor;
33 | }
34 |
35 | double shininess = [[self.program valueForKey:@"shininess"] doubleValue];
36 | if (shininess) {
37 | [self.shininessSlider setDoubleValue:shininess];
38 | [self.shininessTextField setDoubleValue:shininess];
39 | self.shininess = shininess;
40 | }
41 |
42 | double materialSpecularity = [[self.program valueForKey:@"materialSpecularity"] doubleValue];
43 | if (materialSpecularity >= 0) {
44 | [self.specularitySlider setDoubleValue:materialSpecularity];
45 | [self.specularityTextField setDoubleValue:materialSpecularity];
46 | self.materialSpecularity = materialSpecularity;
47 | }
48 | }
49 |
50 | }
51 |
52 | - (void)viewDidAppear
53 | {
54 |
55 | }
56 |
57 | -(void)viewWillDisappear
58 | {
59 |
60 | }
61 |
62 | -(IBAction)updateMaterialSpecularity:(id)sender
63 | {
64 | NSSlider *slider = sender;
65 | double value = [slider doubleValue];
66 |
67 | [self.specularityTextField setDoubleValue:value];
68 | self.materialSpecularity = value;
69 |
70 | [self updateShaderValues];
71 | }
72 |
73 | -(IBAction)updateShininess:(id)sender
74 | {
75 | NSSlider *slider = sender;
76 | double value = [slider doubleValue];
77 |
78 | self.shininess = value;
79 | [self.shininessTextField setDoubleValue:value];
80 |
81 | [self updateShaderValues];
82 | }
83 |
84 | -(IBAction)updateAmbientColor:(id)sender
85 | {
86 | NSColorWell *colorWell = sender;
87 | NSColor *color = [colorWell color];
88 |
89 | self.ambientColor = color;
90 | [self updateShaderValues];
91 | }
92 |
93 | -(IBAction)updateLightColor:(id)sender
94 | {
95 | NSColorWell *colorWell = sender;
96 | NSColor *color = [colorWell color];
97 |
98 | self.lightColor = color;
99 | [self updateShaderValues];
100 | }
101 |
102 | -(void)updateShaderValues
103 | {
104 | CWHPhongPointLightProgram *program = (CWHPhongPointLightProgram *)self.program;
105 |
106 | program.lightColor = self.lightColor;
107 | program.ambientColor = self.ambientColor;
108 | program.shininess = self.shininess;
109 | program.materialSpecularity = self.materialSpecularity;
110 |
111 | [self.delegate updateProgram:program shadableProperties:nil];
112 | }
113 |
114 | @end
115 |
--------------------------------------------------------------------------------
/ScenekitStarter/EnvMap.metal:
--------------------------------------------------------------------------------
1 |
2 | #include
3 | using namespace metal;
4 |
5 | #include
6 |
7 | struct VertexIn {
8 | float4 position [[attribute(SCNVertexSemanticPosition)]];
9 | float3 normal [[attribute(SCNVertexSemanticNormal)]];
10 | float2 texCoords [[attribute(SCNVertexSemanticTexcoord0)]];
11 | };
12 |
13 | struct NodeConstants {
14 | float4x4 modelViewTransform;
15 | float4x4 modelViewProjectionTransform;
16 | float4x4 normalTransform;
17 | };
18 |
19 | struct LightConstants {
20 | packed_float3 position;
21 | packed_float3 ambientIntensity;
22 | packed_float3 diffuseIntensity;
23 | };
24 |
25 | struct VertexOut {
26 | float4 position [[position]];
27 | float4 color;
28 | float2 texCoords;
29 | };
30 |
31 | /*
32 | Adapted from:
33 | /Developer/Examples/Quartz Composer/Compositions/GLSL/Environment Map.qtz
34 | More environment maps can be found here
35 | http://www.codemonsters.de/home/content.php?show=spheremaps
36 | */
37 |
38 | void envMapVS(VertexIn in, thread VertexOut &out, constant NodeConstants &scn_node, constant LightConstants &light)
39 | {
40 | // (@warrenm) In spite of the naming of the variables below, they are mostly in eye space.
41 | // I have left the original names for posterity, but there is some confusion in this code
42 | // about which space we're in.
43 |
44 | float4 vWorld = scn_node.modelViewTransform * in.position;
45 | float4 Nm = normalize(scn_node.normalTransform * float4(in.normal, 0.0f));
46 | float3 nWorld = Nm.xyz;
47 |
48 | // Diffuse
49 | float3 vertToLight = normalize(light.position - vWorld.xyz);
50 | float diffuseLight = max(dot(vertToLight, nWorld), 0.0);
51 | out.color = float4(light.ambientIntensity.rgb + (diffuseLight * light.diffuseIntensity.xyz), 1.0f);
52 |
53 | // Environment mapping texture coordinates
54 | float3 vWorldUnit = normalize(vWorld.xyz);
55 | float3 f = reflect(vWorldUnit, nWorld);
56 | float m = 2.0 * sqrt(f.x * f.x + f.y * f.y + (f.z + 1.0) * (f.z + 1.0));
57 | out.texCoords = float2(f.x / m + 0.5, -f.y / m + 0.5);
58 | }
59 |
60 | vertex VertexOut EnvMapVertex(VertexIn in [[stage_in]],
61 | constant SCNSceneBuffer &scn_frame [[buffer(0)]],
62 | constant NodeConstants &scn_node [[buffer(1)]],
63 | constant LightConstants &vertexLights [[buffer(2)]])
64 | {
65 | VertexOut out;
66 | envMapVS(in, out, scn_node, vertexLights);
67 |
68 | out.position = scn_node.modelViewProjectionTransform * in.position;
69 |
70 | return out;
71 | }
72 |
73 | /*
74 | Adapted from:
75 | /Developer/Examples/Quartz Composer/Compositions/GLSL/Environment Map.qtz
76 | */
77 |
78 | fragment float4 EnvMapFragment(VertexOut in [[stage_in]],
79 | texture2d environmentMap [[texture(0)]],
80 | constant float &ratio [[buffer(0)]])
81 | {
82 | constexpr sampler bilinearClampedSampler(coord::normalized,
83 | min_filter::linear,
84 | mag_filter::linear,
85 | mip_filter::none,
86 | address::clamp_to_edge);
87 | float2 tex = in.texCoords;
88 | tex.y = 1.0f - tex.y;
89 | float4 environmentColor = environmentMap.sample(bilinearClampedSampler, tex);
90 | float4 finalColor = mix(in.color, environmentColor, ratio);
91 | return finalColor;
92 | }
93 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHBlinnProgram.m:
--------------------------------------------------------------------------------
1 | //
2 | // CWHBlinnProgram.m
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 7/29/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import "CWHBlinnProgram.h"
10 |
11 | @implementation CWHBlinnProgram
12 |
13 | +(BOOL) supportsSecureCoding {
14 | return YES;
15 | }
16 |
17 | -(instancetype)init
18 | {
19 | id device = MTLCreateSystemDefaultDevice();
20 | id library = [device newDefaultLibrary];
21 |
22 | self = [super initWithLibrary:library vertexFunctionName:@"BlinnVertex" fragmentFunctionName:@"BlinnFragment"];
23 |
24 | if ( self != nil )
25 | {
26 | self.delegate = self;
27 |
28 | [self bindBuffers];
29 |
30 | self.ambientColor = [NSColor colorWithRed:0 green:0 blue:0 alpha:1];
31 | self.lightColor = [NSColor redColor];
32 | }
33 |
34 | return self;
35 | }
36 |
37 | - (id)initWithCoder:(NSCoder *)decoder {
38 | id device = MTLCreateSystemDefaultDevice();
39 | id library = [device newDefaultLibrary];
40 |
41 | self = [super initWithLibrary:library vertexFunctionName:@"BlinnVertex" fragmentFunctionName:@"BlinnFragment"];
42 |
43 | if (self != nil) {
44 | self.ambientColor = [decoder decodeObjectOfClass:[NSColor class] forKey:@"ambientColor"];
45 | self.lightColor = [decoder decodeObjectOfClass:[NSColor class] forKey:@"lightColor"];
46 |
47 | [self bindBuffers];
48 |
49 | self.delegate = self;
50 | }
51 | return self;
52 | }
53 |
54 | - (void)encodeWithCoder:(NSCoder *)encoder {
55 | [encoder encodeObject:_ambientColor forKey:@"ambientColor"];
56 | [encoder encodeObject:_lightColor forKey:@"lightColor"];
57 | }
58 |
59 | - (void)bindBuffers {
60 | SCNBufferBindingBlock lightBlock = ^(id buffer, SCNNode *node, id shadable, SCNRenderer *renderer)
61 | {
62 | struct LightUniforms {
63 | float diffuseIntensity[3];
64 | float ambientIntensity[3];
65 | float position[3];
66 | } lights;
67 |
68 | memset(&lights, 0, sizeof(lights));
69 |
70 | lights.position[0] = self.lightPosition.x;
71 | lights.position[1] = self.lightPosition.y;
72 | lights.position[2] = self.lightPosition.z;
73 |
74 | if (self.lightColor) {
75 | lights.diffuseIntensity[0] = [self.lightColor redComponent];
76 | lights.diffuseIntensity[1] = [self.lightColor greenComponent];
77 | lights.diffuseIntensity[2] = [self.lightColor blueComponent];
78 | }
79 |
80 | if (self.ambientColor) {
81 | lights.ambientIntensity[0] = [self.ambientColor redComponent];
82 | lights.ambientIntensity[1] = [self.ambientColor greenComponent];
83 | lights.ambientIntensity[2] = [self.ambientColor blueComponent];
84 | }
85 |
86 | [buffer writeBytes:&lights length:sizeof(lights)];
87 | };
88 |
89 | [self handleBindingOfBufferNamed:@"vertexLight" frequency:SCNBufferFrequencyPerFrame usingBlock:lightBlock];
90 | [self handleBindingOfBufferNamed:@"fragmentLight" frequency:SCNBufferFrequencyPerFrame usingBlock:lightBlock];
91 | }
92 |
93 | #pragma mark - SCNProgramDelegate Protocol Methods
94 |
95 | - (void)program:(SCNProgram*)program handleError:(NSError*)error {
96 | // Log the shader compilation error
97 | NSLog(@"SceneKit compilation error: %@", error);
98 | }
99 |
100 | @end
101 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHGoochParameterViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // CWHGoochParameterViewController.m
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 8/12/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import "CWHGoochParameterViewController.h"
10 |
11 | @interface CWHGoochParameterViewController ()
12 |
13 | @end
14 |
15 | @implementation CWHGoochParameterViewController
16 |
17 | - (void)viewDidLoad {
18 | [super viewDidLoad];
19 |
20 | if(self.program){
21 | NSColor *surfaceColor = [self.program valueForKey:@"surfaceColor"];
22 | if (surfaceColor) {
23 | [self.surfaceColorWell setColor:surfaceColor];
24 | self.surfaceColor= surfaceColor;
25 | }
26 |
27 | double diffuseWarm= [[self.program valueForKey:@"diffuseWarm"] doubleValue];
28 | if (diffuseWarm) {
29 | [self.diffuseWarmSlider setDoubleValue:diffuseWarm];
30 | [self.diffuseWarmTextField setDoubleValue:diffuseWarm];
31 | self.diffuseWarm = diffuseWarm;
32 | }
33 |
34 | double diffuseCool = [[self.program valueForKey:@"diffuseCool"] doubleValue];
35 |
36 | [self.diffuseCoolSlider setDoubleValue:diffuseCool];
37 | [self.diffuseCoolTextField setDoubleValue:diffuseCool];
38 | self.diffuseCool = diffuseCool;
39 |
40 | NSColor *warmColor = [self.program valueForKey:@"warmColor"];
41 | if (warmColor) {
42 | [self.warmColorWell setColor:warmColor ];
43 | self.warmColor = warmColor ;
44 | }
45 |
46 | NSColor *coolColor = [self.program valueForKey:@"coolColor"];
47 | if (coolColor) {
48 | [self.coolColorWell setColor:coolColor];
49 | self.coolColor = coolColor;
50 | }
51 | }
52 | }
53 |
54 | - (IBAction)updateSurfaceColor:(id)sender {
55 |
56 | NSColorWell *colorWell = sender;
57 | NSColor *color = [colorWell color];
58 |
59 | self.surfaceColor = color;
60 | [self updateShaderValues];
61 | }
62 |
63 | - (IBAction)updateCoolColor:(id)sender {
64 | NSColorWell *colorWell = sender;
65 | NSColor *color = [colorWell color];
66 |
67 | self.coolColor = color;
68 | [self updateShaderValues];
69 | }
70 |
71 | - (IBAction)updateWarmColor:(id)sender {
72 | NSColorWell *colorWell = sender;
73 | NSColor *color = [colorWell color];
74 |
75 | self.warmColor = color;
76 | [self updateShaderValues];
77 | }
78 |
79 | - (IBAction)updateDiffuseCool:(id)sender {
80 |
81 | NSSlider *slider = sender;
82 | double value = [slider doubleValue];
83 |
84 | self.diffuseCool = value;
85 | [self.diffuseCoolTextField setDoubleValue:value];
86 |
87 | [self updateShaderValues];
88 | }
89 |
90 | - (IBAction)updateDiffuseWarm:(id)sender {
91 | NSSlider *slider = sender;
92 | double value = [slider doubleValue];
93 |
94 | self.diffuseWarm = value;
95 | [self.diffuseWarmTextField setDoubleValue:value];
96 |
97 | [self updateShaderValues];
98 | }
99 |
100 | -(void)updateShaderValues
101 | {
102 | CWHGoochProgram *program = (CWHGoochProgram *)self.program;
103 |
104 | program.surfaceColor = self.surfaceColor;
105 | program.warmColor = self.warmColor;
106 | program.coolColor = self.coolColor;
107 | program.diffuseCool = self.diffuseCool;
108 | program.diffuseWarm = self.diffuseWarm;
109 |
110 | [self.delegate updateProgram:program shadableProperties:nil];
111 | }
112 |
113 |
114 | @end
115 |
--------------------------------------------------------------------------------
/ScenekitStarter.xcodeproj/xcshareddata/xcschemes/ScenekitStarter.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
53 |
55 |
61 |
62 |
63 |
64 |
70 |
72 |
78 |
79 |
80 |
81 |
83 |
84 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/ScenekitStarter/ThinFilm.metal:
--------------------------------------------------------------------------------
1 |
2 | #include
3 | using namespace metal;
4 |
5 | #include
6 |
7 | struct VertexIn {
8 | float4 position [[attribute(SCNVertexSemanticPosition)]];
9 | float3 normal [[attribute(SCNVertexSemanticNormal)]];
10 | float2 texCoords [[attribute(SCNVertexSemanticTexcoord0)]];
11 | };
12 |
13 | struct NodeConstants {
14 | float4x4 modelViewTransform;
15 | float4x4 modelViewProjectionTransform;
16 | float4x4 normalTransform;
17 | };
18 |
19 | struct LightConstants {
20 | packed_float3 position;
21 | };
22 |
23 | struct MaterialConstants {
24 | packed_float4 diffuseColor;
25 | float filmDepth;
26 | };
27 |
28 | struct VertexOut {
29 | float4 position [[position]];
30 | float2 texCoords;
31 | float3 diffColor;
32 | float3 specColor;
33 | float2 viewDepth;
34 | };
35 |
36 | /*
37 | Extracted and adapted from NVIDIA 'Thinfilm' demo
38 | ftp://download.nvidia.com/developer/SDK/Individual_Samples/3dgraphics_samples.html
39 | */
40 |
41 | vertex VertexOut ThinFilmVertex(VertexIn in [[stage_in]],
42 | constant SCNSceneBuffer &scn_frame [[buffer(0)]],
43 | constant NodeConstants &scn_node [[buffer(1)]],
44 | constant LightConstants &light [[buffer(2)]],
45 | constant MaterialConstants &vertexMaterial [[buffer(3)]])
46 | {
47 | // Transform normal from model-space to view-space
48 | float4 n = scn_node.normalTransform * float4(in.normal, 0.0f);
49 | float3 normalVec = normalize(n.xyz);
50 |
51 | // Compute the eye->vertex vector
52 | const float3 eyeVector = float3(0.0f, 0.0f, 1.0f);
53 | float3 eyeVec = eyeVector; // Assume infinite viewer
54 | float3 lightVec = normalize(light.position);
55 |
56 | // Calculate half-angle vector
57 | float3 halfAngleVec = normalize(lightVec + eyeVec);
58 |
59 | // Calculate diffuse component
60 | float diffuse = max(dot(normalVec, lightVec), 0.0f);
61 |
62 | // Calculate specular component
63 | float specular = max(dot(normalVec, halfAngleVec), 0.0f);
64 | specular = powr(specular, 32.0f);
65 |
66 | VertexOut out;
67 | out.position = scn_node.modelViewProjectionTransform * in.position;
68 | out.texCoords = in.texCoords;
69 |
70 | // Compute the view depth for the thin film
71 | out.viewDepth = float2((1.0f / dot(normalVec, eyeVec)) * vertexMaterial.filmDepth);
72 |
73 | // Output final lighting results
74 | out.diffColor = diffuse;
75 | out.specColor = specular;
76 |
77 | return out;
78 | }
79 |
80 | fragment float4 ThinFilmFragment(VertexOut in [[stage_in]],
81 | constant MaterialConstants &fragmentMaterial [[buffer(0)]],
82 | /*texture2d diffuseMap [[texture(0)]],*/
83 | texture2d fringeMap [[texture(1)]])
84 | {
85 | constexpr sampler bilinearClampedSampler(coord::normalized,
86 | min_filter::linear,
87 | mag_filter::linear,
88 | mip_filter::none,
89 | address::clamp_to_edge);
90 |
91 | // Diffuse material color
92 | //float3 diffMaterial = diffuseMap.sample(bilinearClampedSampler, in.texCoords).rgb;
93 | float3 diffMaterial = fragmentMaterial.diffuseColor.rgb;
94 |
95 | // Lookup fringe value based on view depth
96 | float3 fringeColor = fringeMap.sample(bilinearClampedSampler, in.viewDepth).rgb;
97 |
98 | // modulate specular lighting by fringe color, combine with regular lighting
99 | return float4(in.diffColor * diffMaterial + fringeColor * in.specColor, 1.0f);
100 | }
101 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHLUTSkinParameterViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // CWHLUTSkinParameterViewController.m
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 9/12/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import "CWHLUTSkinParameterViewController.h"
10 |
11 | @interface CWHLUTSkinParameterViewController ()
12 |
13 | @end
14 |
15 | @implementation CWHLUTSkinParameterViewController
16 |
17 | - (void)viewDidLoad {
18 | [super viewDidLoad];
19 | if(self.program){
20 | NSColor *diffuseColor = [self.program valueForKey:@"diffuseColor"];
21 |
22 | if (diffuseColor) {
23 | [self.diffuseColorWell setColor:diffuseColor];
24 |
25 | }
26 |
27 | NSColor *specularColor = [self.program valueForKey:@"specularColor"];
28 |
29 | if (specularColor) {
30 | [self.diffuseColorWell setColor:specularColor];
31 |
32 | }
33 | NSColor *scatterColor = [self.program valueForKey:@"scatterColor"];
34 |
35 | if (scatterColor) {
36 | [self.diffuseColorWell setColor:scatterColor];
37 |
38 | }
39 |
40 | double wrap = [[self.program valueForKey:@"wrap"] doubleValue];
41 |
42 | if (wrap >= 0) {
43 | [self.wrapSlider setDoubleValue:wrap];
44 | [self.wrapTextField setDoubleValue:wrap];
45 |
46 | }
47 |
48 |
49 | double scatterWidth = [[self.program valueForKey:@"scatterWidth"] doubleValue];
50 | if (scatterWidth >= 0) {
51 | [self.scatterWidthSlider setDoubleValue:scatterWidth];
52 | [self.scatterWidthTextField setDoubleValue:scatterWidth];
53 |
54 | }
55 |
56 | double shininess = [[self.program valueForKey:@"shininess"] doubleValue];
57 | if (shininess) {
58 | [self.shininessSlider setDoubleValue:shininess];
59 | [self.shininessTextField setDoubleValue:shininess];
60 |
61 | }
62 | }
63 | }
64 |
65 | - (IBAction)updateWrap:(id)sender {
66 | if ([sender isKindOfClass:[NSSlider class]]) {
67 | [self.wrapTextField setDoubleValue:[sender doubleValue]];
68 | }else{
69 | [self.wrapSlider setDoubleValue:[sender doubleValue]];
70 | }
71 |
72 | [self updateShaderValues];
73 | }
74 |
75 | - (IBAction)updateScatterWidth:(id)sender {
76 | if ([sender isKindOfClass:[NSSlider class]]) {
77 | [self.scatterWidthTextField setDoubleValue:[sender doubleValue]];
78 | }else{
79 | [self.scatterWidthSlider setDoubleValue:[sender doubleValue]];
80 | }
81 |
82 | [self updateShaderValues];
83 | }
84 |
85 | - (IBAction)updateShininess:(id)sender {
86 | if ([sender isKindOfClass:[NSSlider class]]) {
87 | [self.shininessTextField setDoubleValue:[sender doubleValue]];
88 | }else{
89 | [self.shininessSlider setDoubleValue:[sender doubleValue]];
90 | }
91 | [self updateShaderValues];
92 | }
93 |
94 | - (IBAction)updateDiffuseColor:(id)sender {
95 | [self updateShaderValues];
96 | }
97 |
98 | - (IBAction)updateSpecularColor:(id)sender {
99 | [self updateShaderValues];
100 | }
101 |
102 | - (IBAction)updateScatterColor:(id)sender {
103 | [self updateShaderValues];
104 | }
105 |
106 | -(void)updateShaderValues
107 | {
108 | CWHLUTSkinProgram *program = (CWHLUTSkinProgram *)self.program;
109 |
110 | program.diffuseColor = [self.diffuseColorWell color];
111 | program.specularColor = [self.specularColorWell color];
112 | program.scatterColor = [self.scatterColorWell color];
113 | program.wrap = [self.wrapSlider doubleValue];
114 | program.scatterWidth = [self.scatterWidthSlider doubleValue];
115 | program.shininess = [self.shininessSlider doubleValue];
116 |
117 | [self.delegate updateProgram:program shadableProperties:nil];
118 | }
119 |
120 | @end
121 |
--------------------------------------------------------------------------------
/ScenekitStarter/HemisphereParameterView.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/ScenekitStarter/BlinnParameterView.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/ScenekitStarter.xcodeproj/xcuserdata/super.xcuserdatad/xcschemes/ScenekitStarter.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
49 |
50 |
51 |
52 |
61 |
62 |
68 |
69 |
70 |
71 |
72 |
73 |
79 |
80 |
86 |
87 |
88 |
89 |
91 |
92 |
95 |
96 |
97 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHThinFilmProgram.m:
--------------------------------------------------------------------------------
1 | //
2 | // CWHThinFilmProgram.m
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 8/28/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import "CWHThinFilmProgram.h"
10 |
11 | @implementation CWHThinFilmProgram
12 |
13 | +(BOOL) supportsSecureCoding {
14 | return YES;
15 | }
16 |
17 | - (instancetype)init
18 | {
19 | id device = MTLCreateSystemDefaultDevice();
20 | id library = [device newDefaultLibrary];
21 |
22 | self = [super initWithLibrary:library vertexFunctionName:@"ThinFilmVertex" fragmentFunctionName:@"ThinFilmFragment"];
23 |
24 | if ( self != nil )
25 | {
26 | self.delegate = self;
27 |
28 | self.imagePath = [[NSBundle mainBundle] pathForResource:@"FringeMap" ofType:@"png"];
29 |
30 | [self bindBuffers];
31 |
32 | self.filmDepth = 0.75;
33 | self.diffuseColor = [NSColor grayColor];
34 |
35 | }
36 | return self;
37 | }
38 | - (id)initWithCoder:(NSCoder *)decoder {
39 | id device = MTLCreateSystemDefaultDevice();
40 | id library = [device newDefaultLibrary];
41 |
42 | self = [super initWithLibrary:library vertexFunctionName:@"ThinFilmVertex" fragmentFunctionName:@"ThinFilmFragment"];
43 |
44 | if ( self != nil )
45 | {
46 | self.delegate = self;
47 |
48 | NSString *imagePath =[decoder decodeObjectOfClass:[NSString class] forKey:@"imagePath"];
49 | if (imagePath) {
50 | self.imagePath = imagePath;
51 | } else {
52 | self.imagePath = [[NSBundle mainBundle] pathForResource:@"FringeMap" ofType:@"png"];
53 | }
54 |
55 | [self bindBuffers];
56 |
57 | self.diffuseColor = [decoder decodeObjectOfClass:[NSColor class] forKey:@"diffuseColor"];
58 | self.filmDepth = [decoder decodeDoubleForKey:@"filmDepth"];
59 | }
60 | return self;
61 | }
62 |
63 | - (void)encodeWithCoder:(NSCoder *)encoder {
64 | [encoder encodeObject:_imagePath forKey:@"imagePath"];
65 | [encoder encodeObject:_diffuseColor forKey:@"diffuseColor"];
66 | [encoder encodeDouble:_filmDepth forKey:@"filmDepth"];
67 | }
68 |
69 | - (void)bindBuffers {
70 | SCNBufferBindingBlock lightBlock = ^(id buffer, SCNNode *node, id shadable, SCNRenderer *renderer)
71 | {
72 | struct LightConstants {
73 | float position[3];
74 | } lights;
75 |
76 | lights.position[0] = self.lightPosition.x;
77 | lights.position[1] = self.lightPosition.y;
78 | lights.position[2] = self.lightPosition.z;
79 |
80 | [buffer writeBytes:&lights length:sizeof(lights)];
81 | };
82 |
83 | SCNBufferBindingBlock materialBlock = ^(id buffer, SCNNode *node, id shadable, SCNRenderer *renderer)
84 | {
85 | struct MaterialConstants {
86 | float diffuseColor[4];
87 | float filmDepth;
88 | } material;
89 |
90 | if (self.diffuseColor) {
91 | material.diffuseColor[0] = self.diffuseColor.redComponent;
92 | material.diffuseColor[1] = self.diffuseColor.greenComponent;
93 | material.diffuseColor[2] = self.diffuseColor.blueComponent;
94 | material.diffuseColor[3] = self.diffuseColor.alphaComponent;
95 | }
96 |
97 | material.filmDepth = self.filmDepth;
98 |
99 | [buffer writeBytes:&material length:sizeof(material)];
100 | };
101 |
102 | [self handleBindingOfBufferNamed:@"light" frequency:SCNBufferFrequencyPerFrame usingBlock:lightBlock];
103 | [self handleBindingOfBufferNamed:@"vertexMaterial" frequency:SCNBufferFrequencyPerFrame usingBlock:materialBlock];
104 | [self handleBindingOfBufferNamed:@"fragmentMaterial" frequency:SCNBufferFrequencyPerFrame usingBlock:materialBlock];
105 | }
106 |
107 | - (NSDictionary *)shadableProperties {
108 | NSDictionary *properties = @{
109 | @"fringeMap" : [SCNMaterialProperty materialPropertyWithContents:self.imagePath]
110 | };
111 | return properties;
112 | }
113 |
114 | #pragma mark - SCNProgramDelegate Protocol Methods
115 | - (void)program:(SCNProgram*)program handleError:(NSError*)error {
116 | // Log the shader compilation error
117 | NSLog(@"SceneKit compilation error: %@", error);
118 | }
119 |
120 | @end
121 |
--------------------------------------------------------------------------------
/ScenekitStarter/EdgeFuzz.metal:
--------------------------------------------------------------------------------
1 | #include
2 | using namespace metal;
3 |
4 | #include
5 |
6 | struct VertexIn {
7 | float4 position [[attribute(SCNVertexSemanticPosition)]];
8 | float3 normal [[attribute(SCNVertexSemanticNormal)]];
9 | float2 texCoords [[attribute(SCNVertexSemanticTexcoord0)]];
10 | };
11 |
12 | struct NodeConstants {
13 | float4x4 modelViewTransform;
14 | float4x4 modelViewProjectionTransform;
15 | float4x4 normalTransform;
16 | };
17 |
18 | struct LightConstants {
19 | packed_float3 position;
20 | packed_float3 ambientIntensity;
21 | packed_float3 diffuseIntensity;
22 | };
23 |
24 | struct MaterialConstants {
25 | packed_float4 edgeColor;
26 | packed_float4 surfaceColor;
27 | float specularity;
28 | float fuzziness;
29 | float edgeFade;
30 | };
31 |
32 | struct VertexOut {
33 | float4 position [[position]];
34 | float3 lightVec;
35 | float3 eyeView;
36 | float3 eyeNormal;
37 | };
38 |
39 | /////////////////////////////////////
40 | //// EDGE FUZZ VS ////
41 | /////////////////////////////////////
42 |
43 | /*
44 | Adapted from:
45 | NVIDIA Shader Library effect 'EdgeFuzz.fx'
46 | http://developer.download.nvidia.com/shaderlibrary/webpages/shader_library.html
47 | */
48 |
49 | // Edge Fuzz Vertex Shader function
50 | void edgefuzzVS(constant NodeConstants &scn_node, float4 modelPosition, float4 N, float3 lightPosition, thread VertexOut &out)
51 | {
52 | float4 V = scn_node.modelViewTransform * modelPosition;
53 | float3 v = V.xyz / V.w;
54 | out.lightVec = lightPosition - v.xyz;
55 | out.eyeView = normalize(float3(0.0, 0.0, 2.0) - v.xyz);
56 | float4 n = scn_node.normalTransform * N;
57 | out.eyeNormal = normalize(n.xyz);
58 | }
59 |
60 | vertex VertexOut EdgeFuzzVertex(VertexIn in [[stage_in]],
61 | constant SCNSceneBuffer &scn_frame [[buffer(0)]],
62 | constant NodeConstants &scn_node [[buffer(1)]],
63 | constant LightConstants &vertexLights [[buffer(2)]])
64 | {
65 | float4 n = float4(in.normal, 0.0f);
66 |
67 | VertexOut out;
68 | edgefuzzVS(scn_node, in.position, n, vertexLights.position, out);
69 |
70 | out.position = scn_node.modelViewProjectionTransform * in.position;
71 |
72 | return out;
73 | }
74 |
75 | /////////////////////////////////////
76 | //// EDGE FUZZ FS ////
77 | /////////////////////////////////////
78 |
79 | /*
80 | Adapted from:
81 | NVIDIA Shader Library effect 'EdgeFuzz.fx'
82 | */
83 |
84 | float3 lit (float NdotL, float NdotH, float m)
85 | {
86 | float ambient = 1.0;
87 | float diffuse = max(NdotL, 0.0);
88 | float specular = step(0.0, NdotL) * max(NdotH * m, 1.0);
89 | return float3(ambient, diffuse, specular);
90 | }
91 |
92 | // Edge Fuzz Fragment Shader function
93 | float4 edgefuzzFS(VertexOut vert, constant LightConstants &light, constant MaterialConstants &material)
94 | {
95 | const float4 specularColor = float4(1.0, 1.0, 1.0, 1.0);
96 | float3 Ln = normalize(vert.lightVec);
97 | float3 Vn = normalize(vert.eyeView);
98 | float3 Nn = normalize(vert.eyeNormal);
99 | float3 Hn = normalize(Vn + Ln);
100 | float ldn = dot(Ln, Nn);
101 | float4 lv = float4(lit(ldn, dot(Hn, Nn), material.specularity), 1.0);
102 | float subd = abs(dot(Nn, Vn));
103 | subd = powr(subd, material.fuzziness);
104 | float3 surfColor = mix(material.edgeColor.rgb, material.surfaceColor.rgb, subd);
105 | surfColor = mix(material.surfaceColor.rgb, surfColor, material.edgeFade);
106 | ldn = max(ldn,0.0);
107 | ldn = powr(ldn, material.fuzziness);
108 | float3 incidentColor = mix(material.edgeColor.rgb, light.diffuseIntensity.rgb, ldn);
109 | incidentColor = mix(light.diffuseIntensity.rgb, incidentColor, ldn);
110 | float3 diffContrib = surfColor * (lv.y * incidentColor + light.ambientIntensity.rgb);
111 | float3 specContrib = specularColor.rgb * lv.y * lv.z * incidentColor;
112 |
113 | return float4(diffContrib + specContrib, 1.0);
114 | }
115 |
116 | fragment float4 EdgeFuzzFragment(VertexOut in [[stage_in]],
117 | constant LightConstants &fragmentLights [[buffer(0)]],
118 | constant MaterialConstants &material [[buffer(1)]])
119 | {
120 | return edgefuzzFS(in, fragmentLights, material);
121 | }
122 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHEnvMapProgram.m:
--------------------------------------------------------------------------------
1 | //
2 | // CWHEnvMapProgram.m
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 8/25/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import "CWHEnvMapProgram.h"
10 |
11 | @interface CWHEnvMapProgram ()
12 | @property (nonatomic, readonly) NSDictionary *shadableProperties;
13 | @end
14 |
15 | @implementation CWHEnvMapProgram
16 |
17 | +(BOOL) supportsSecureCoding {
18 | return YES;
19 | }
20 |
21 | - (instancetype)init
22 | {
23 | id device = MTLCreateSystemDefaultDevice();
24 | id library = [device newDefaultLibrary];
25 |
26 | self = [super initWithLibrary:library vertexFunctionName:@"EnvMapVertex" fragmentFunctionName:@"EnvMapFragment"];
27 |
28 | if (self != nil)
29 | {
30 | self.delegate = self;
31 |
32 | [self bindBuffers];
33 |
34 | NSColor *diffuseColor = [NSColor colorWithRed:0.3 green:0.3 blue:0.3 alpha:1.];
35 | self.diffuseColor = diffuseColor;
36 | NSColor *ambientColor = [NSColor colorWithRed:0. green:0. blue:0. alpha:1.];
37 | self.ambientColor = ambientColor;
38 | self.ratio = 0.875;
39 | self.imagePath = [[NSBundle mainBundle] pathForResource:@"EnvMapInterior" ofType:@"png"];
40 | }
41 | return self;
42 | }
43 |
44 | - (id)initWithCoder:(NSCoder *)decoder {
45 | id device = MTLCreateSystemDefaultDevice();
46 | id library = [device newDefaultLibrary];
47 |
48 | self = [super initWithLibrary:library vertexFunctionName:@"EnvMapVertex" fragmentFunctionName:@"EnvMapFragment"];
49 |
50 | if (self != nil) {
51 | self.delegate = self;
52 |
53 | [self bindBuffers];
54 |
55 | self.diffuseColor =[decoder decodeObjectOfClass:[NSColor class] forKey:@"diffuseColor"];
56 | self.ambientColor = [decoder decodeObjectOfClass:[NSColor class] forKey:@"ambientColor"];
57 | self.ratio = [decoder decodeDoubleForKey:@"ratio"];
58 | self.imagePath = [decoder decodeObjectOfClass:[NSString class] forKey:@"imagePath"];
59 | }
60 | return self;
61 | }
62 |
63 | - (void)encodeWithCoder:(NSCoder *)encoder {
64 | [encoder encodeObject:_diffuseColor forKey:@"diffuseColor"];
65 | [encoder encodeObject:_ambientColor forKey:@"ambientColor"];
66 | [encoder encodeDouble:_ratio forKey:@"ratio"];
67 | [encoder encodeObject:_imagePath forKey:@"imagePath"];
68 | }
69 |
70 | - (void)bindBuffers {
71 | SCNBufferBindingBlock lightBlock = ^(id buffer, SCNNode *node, id shadable, SCNRenderer *renderer)
72 | {
73 | struct LightConstants {
74 | float position[3];
75 | float ambientIntensity[3];
76 | float diffuseIntensity[3];
77 | } lights;
78 |
79 | lights.position[0] = self.lightPosition.x;
80 | lights.position[1] = self.lightPosition.y;
81 | lights.position[2] = self.lightPosition.z;
82 |
83 | if (self.diffuseColor) {
84 | lights.diffuseIntensity[0] = [self.diffuseColor redComponent];
85 | lights.diffuseIntensity[1] = [self.diffuseColor greenComponent];
86 | lights.diffuseIntensity[2] = [self.diffuseColor blueComponent];
87 | }
88 |
89 | if (self.ambientColor) {
90 | lights.ambientIntensity[0] = [self.ambientColor redComponent];
91 | lights.ambientIntensity[1] = [self.ambientColor greenComponent];
92 | lights.ambientIntensity[2] = [self.ambientColor blueComponent];
93 | }
94 |
95 | [buffer writeBytes:&lights length:sizeof(lights)];
96 | };
97 |
98 | [self handleBindingOfBufferNamed:@"vertexLights" frequency:SCNBufferFrequencyPerFrame usingBlock:lightBlock];
99 | [self handleBindingOfBufferNamed:@"fragmentLights" frequency:SCNBufferFrequencyPerFrame usingBlock:lightBlock];
100 | [self handleBindingOfBufferNamed:@"ratio" frequency:SCNBufferFrequencyPerFrame usingBlock:
101 | ^(id buffer, SCNNode *node, id shadable, SCNRenderer *renderer)
102 | {
103 | float ratio = self.ratio;
104 | [buffer writeBytes:&ratio length:sizeof(float)];
105 | }];
106 | }
107 |
108 | - (NSDictionary *)shadableProperties {
109 | NSDictionary *properties = @{
110 | @"environmentMap" : [SCNMaterialProperty materialPropertyWithContents:self.imagePath]
111 | };
112 | return properties;
113 | }
114 |
115 | @end
116 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHEdgeFuzzParameterViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // CWHEdgeFuzzParameterViewController.m
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 8/15/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import "CWHEdgeFuzzParameterViewController.h"
10 |
11 | @interface CWHEdgeFuzzParameterViewController ()
12 |
13 | @end
14 |
15 | @implementation CWHEdgeFuzzParameterViewController
16 |
17 | - (void)viewDidLoad {
18 | [super viewDidLoad];
19 | // Do view setup here.
20 |
21 | if(self.program){
22 |
23 | NSColor *surfaceColor = [self.program valueForKey:@"surfaceColor"];
24 | if (surfaceColor) {
25 | [self.surfaceColorWell setColor:surfaceColor];
26 | self.surfaceColor= surfaceColor;
27 | }
28 |
29 |
30 | double fuzziness = [[self.program valueForKey:@"fuzziness"] doubleValue];
31 | if (fuzziness) {
32 | [self.fuzzinessCircularSlider setDoubleValue:fuzziness];
33 | [self.fuzzinessTextField setDoubleValue:fuzziness];
34 | self.fuzziness = fuzziness;
35 | }
36 |
37 | double edgeFade = [[self.program valueForKey:@"edgeFade"] doubleValue];
38 | if (edgeFade) {
39 | [self.edgeFadeCircularSlider setDoubleValue:edgeFade];
40 | [self.edgeFadeTextField setDoubleValue:edgeFade];
41 | self.edgeFade = edgeFade;
42 | }
43 |
44 | double specularity = [[self.program valueForKey:@"specularity"] doubleValue];
45 | if (specularity) {
46 | [self.specularityCircularSlider setDoubleValue:specularity];
47 | [self.specularityTextField setDoubleValue:specularity];
48 | self.specularity = specularity;
49 | }
50 |
51 | NSColor *edgeColor = [self.program valueForKey:@"edgeColor"];
52 | if (edgeColor) {
53 | [self.edgeColorWell setColor:edgeColor];
54 | self.edgeColor= edgeColor;
55 | }
56 |
57 | NSColor *lightColor = [self.program valueForKey:@"lightColor"];
58 | if (lightColor) {
59 | [self.lightColorWell setColor:lightColor];
60 | self.lightColor = lightColor;
61 | }
62 |
63 | NSColor *ambientColor = [self.program valueForKey:@"ambientColor"];
64 | if (ambientColor) {
65 | [self.ambientColorWell setColor:ambientColor];
66 | self.ambientColor = ambientColor;
67 | }
68 | }
69 |
70 | }
71 |
72 | - (IBAction)updateFuzziness:(id)sender {
73 | //NSLog(@" update Fuzziness %f", [sender doubleValue]);
74 | self.fuzziness = [sender doubleValue];
75 | if ([sender isKindOfClass:[NSSlider class]]) {
76 | [self.fuzzinessTextField setDoubleValue:[sender doubleValue]];
77 | }
78 |
79 | [self updateShaderValues];
80 | }
81 |
82 | - (IBAction)updateSurfaceColor:(id)sender {
83 | self.surfaceColor = [sender color];
84 | [self updateShaderValues];
85 | }
86 |
87 | - (IBAction)updateEdgeFade:(id)sender {
88 | self.edgeFade= [sender doubleValue];
89 | if ([sender isKindOfClass:[NSSlider class]]) {
90 | [self.edgeFadeTextField setDoubleValue:[sender doubleValue]];
91 | }
92 | [self updateShaderValues];
93 | }
94 |
95 | - (IBAction)updateSpecularity:(id)sender {
96 | self.specularity = [sender doubleValue];
97 | if ([sender isKindOfClass:[NSSlider class]]) {
98 | [self.specularityTextField setDoubleValue:[sender doubleValue]];
99 | }
100 |
101 | [self updateShaderValues];
102 | }
103 |
104 | - (IBAction)updateEdgeColor:(id)sender {
105 | self.edgeColor = [sender color];
106 | [self updateShaderValues];
107 | }
108 |
109 | - (IBAction)lightColor:(id)sender {
110 | self.lightColor = [sender color];
111 | [self updateShaderValues];
112 | }
113 |
114 | - (IBAction)updateAmbientColor:(id)sender {
115 | self.ambientColor = [sender color];
116 | [self updateShaderValues];
117 | }
118 |
119 | -(void)updateShaderValues
120 | {
121 | CWHEdgeFuzzProgram *program = (CWHEdgeFuzzProgram *)self.program;
122 |
123 | program.fuzziness = self.fuzziness;
124 | program.surfaceColor = self.surfaceColor;
125 | program.edgeFade = self.edgeFade;
126 | program.specularity = self.specularity;
127 | program.edgeColor = self.edgeColor;
128 | program.lightColor = self.lightColor;
129 | program.ambientColor = self.ambientColor;
130 |
131 | [self.delegate updateProgram:program shadableProperties:nil];
132 | }
133 |
134 | @end
135 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHPhongPointLightProgram.m:
--------------------------------------------------------------------------------
1 | //
2 | // CWHBlinnProgram.m
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 7/29/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import "CWHPhongPointLightProgram.h"
10 |
11 | @implementation CWHPhongPointLightProgram
12 |
13 | +(BOOL) supportsSecureCoding {
14 | return YES;
15 | }
16 |
17 | -(instancetype)init
18 | {
19 | id device = MTLCreateSystemDefaultDevice();
20 | id library = [device newDefaultLibrary];
21 |
22 | self = [super initWithLibrary:library vertexFunctionName:@"PhongVertex" fragmentFunctionName:@"PhongFragment"];
23 |
24 | if ( self != nil )
25 | {
26 | self.delegate = self;
27 |
28 | [self bindBuffers];
29 |
30 | self.ambientColor = [NSColor colorWithRed:0. green:0. blue:0. alpha:1.];
31 | self.lightColor = [NSColor redColor];
32 | self.materialSpecularity = 1;
33 | self.shininess = 10.8;
34 |
35 | }
36 |
37 | return self;
38 | }
39 |
40 | - (id)initWithCoder:(NSCoder *)decoder {
41 | id device = MTLCreateSystemDefaultDevice();
42 | id library = [device newDefaultLibrary];
43 |
44 | self = [super initWithLibrary:library vertexFunctionName:@"PhongVertex" fragmentFunctionName:@"PhongFragment"];
45 |
46 | if (self != nil) {
47 | self.ambientColor = [decoder decodeObjectOfClass:[NSColor class] forKey:@"ambientColor"];
48 | self.lightColor = [decoder decodeObjectOfClass:[NSColor class] forKey:@"lightColor"];
49 | self.materialSpecularity = [decoder decodeDoubleForKey:@"materialSpecularity"];
50 | self.shininess = [decoder decodeDoubleForKey:@"shininess"];
51 |
52 | [self bindBuffers];
53 |
54 | self.delegate = self;
55 | }
56 | return self;
57 | }
58 |
59 | - (void)encodeWithCoder:(NSCoder *)encoder {
60 | [encoder encodeObject:_ambientColor forKey:@"ambientColor"];
61 | [encoder encodeObject:_lightColor forKey:@"lightColor"];
62 | [encoder encodeDouble:_materialSpecularity forKey:@"materialSpecularity"];
63 | [encoder encodeDouble:_shininess forKey:@"shininess"];
64 | }
65 |
66 | - (void)bindBuffers {
67 | SCNBufferBindingBlock lightBlock = ^(id buffer, SCNNode *node, id shadable, SCNRenderer *renderer)
68 | {
69 | struct LightConstants {
70 | float position[3];
71 | float diffuseIntensity[3];
72 | float ambientIntensity[3];
73 | } lights;
74 |
75 | lights.position[0] = self.lightPosition.x;
76 | lights.position[1] = self.lightPosition.y;
77 | lights.position[2] = self.lightPosition.z;
78 |
79 | if (self.lightColor) {
80 | lights.diffuseIntensity[0] = [self.lightColor redComponent];
81 | lights.diffuseIntensity[1] = [self.lightColor greenComponent];
82 | lights.diffuseIntensity[2] = [self.lightColor blueComponent];
83 | }
84 |
85 | if (self.ambientColor) {
86 | lights.ambientIntensity[0] = [self.ambientColor redComponent];
87 | lights.ambientIntensity[1] = [self.ambientColor greenComponent];
88 | lights.ambientIntensity[2] = [self.ambientColor blueComponent];
89 | }
90 |
91 | [buffer writeBytes:&lights length:sizeof(lights)];
92 | };
93 |
94 | SCNBufferBindingBlock materialBlock = ^(id buffer, SCNNode *node, id shadable, SCNRenderer *renderer)
95 | {
96 | struct MaterialConstants {
97 | float specularColor[3];
98 | float shininess;
99 | } material;
100 |
101 | material.specularColor[0] = self.materialSpecularity;
102 | material.specularColor[1] = self.materialSpecularity;
103 | material.specularColor[2] = self.materialSpecularity;
104 | material.shininess = self.shininess;
105 |
106 | [buffer writeBytes:&material length:sizeof(material)];
107 | };
108 |
109 | [self handleBindingOfBufferNamed:@"vertexLight" frequency:SCNBufferFrequencyPerFrame usingBlock:lightBlock];
110 | [self handleBindingOfBufferNamed:@"fragmentLight" frequency:SCNBufferFrequencyPerFrame usingBlock:lightBlock];
111 | [self handleBindingOfBufferNamed:@"material" frequency:SCNBufferFrequencyPerShadable usingBlock:materialBlock];
112 | }
113 |
114 | #pragma mark - SCNProgramDelegate Protocol Methods
115 |
116 | - (void)program:(SCNProgram*)program handleError:(NSError*)error {
117 | // Log the shader compilation error
118 | NSLog(@"SceneKit compilation error: %@", error);
119 | }
120 |
121 |
122 |
123 | @end
124 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHLambSkinProgram.m:
--------------------------------------------------------------------------------
1 | //
2 | // CWHLambSkinProgram.m
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 7/31/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import "CWHLambSkinProgram.h"
10 |
11 | @implementation CWHLambSkinProgram
12 |
13 | +(BOOL) supportsSecureCoding {
14 | return YES;
15 | }
16 |
17 | -(instancetype)init
18 | {
19 | id device = MTLCreateSystemDefaultDevice();
20 | id library = [device newDefaultLibrary];
21 |
22 | self = [super initWithLibrary:library vertexFunctionName:@"LambSkinVertex" fragmentFunctionName:@"LambSkinFragment"];
23 |
24 | if (self != nil)
25 | {
26 | self.delegate = self;
27 |
28 | [self bindBuffers];
29 |
30 | NSColor *diffuseColor = [NSColor colorWithRed:0.3 green:0.3 blue:0.3 alpha:1.0];
31 | self.diffuseColor = diffuseColor;
32 | NSColor *ambientColor = [NSColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:1.0];
33 | self.ambientColor = ambientColor;
34 | NSColor *subColor = [NSColor colorWithRed:1. green:0.0 blue:0.0 alpha:1.0];
35 | self.subColor = subColor;
36 | self.rolloff = 0.575;
37 | }
38 |
39 | return self;
40 | }
41 |
42 | - (id)initWithCoder:(NSCoder *)decoder {
43 | id device = MTLCreateSystemDefaultDevice();
44 | id library = [device newDefaultLibrary];
45 |
46 | self = [super initWithLibrary:library vertexFunctionName:@"LambSkinVertex" fragmentFunctionName:@"LambSkinFragment"];
47 |
48 | if (self != nil)
49 | {
50 | self.delegate = self;
51 |
52 | [self bindBuffers];
53 |
54 | self.diffuseColor =[decoder decodeObjectOfClass:[NSColor class] forKey:@"diffuseColor"];
55 | self.ambientColor = [decoder decodeObjectOfClass:[NSColor class] forKey:@"ambientColor"];
56 | self.subColor = [decoder decodeObjectOfClass:[NSColor class] forKey:@"subColor"];
57 | self.rolloff = [decoder decodeDoubleForKey:@"rolloff"];
58 |
59 | }
60 | return self;
61 | }
62 |
63 | - (void)encodeWithCoder:(NSCoder *)encoder {
64 | [encoder encodeObject:_diffuseColor forKey:@"diffuseColor"];
65 | [encoder encodeObject:_ambientColor forKey:@"ambientColor"];
66 | [encoder encodeObject:_subColor forKey:@"subColor"];
67 | [encoder encodeDouble:_rolloff forKey:@"rolloff"];
68 | }
69 |
70 | - (void)bindBuffers {
71 | SCNBufferBindingBlock lightBlock = ^(id buffer, SCNNode *node, id shadable, SCNRenderer *renderer)
72 | {
73 | struct LightConstants {
74 | float position[3];
75 | } lights;
76 |
77 | lights.position[0] = self.lightPosition.x;
78 | lights.position[1] = self.lightPosition.y;
79 | lights.position[2] = self.lightPosition.z;
80 |
81 | [buffer writeBytes:&lights length:sizeof(lights)];
82 | };
83 |
84 | SCNBufferBindingBlock materialBlock = ^(id buffer, SCNNode *node, id shadable, SCNRenderer *renderer)
85 | {
86 | struct MaterialConstants {
87 | float ambientColor[3];
88 | float diffuseColor[3];
89 | float subColor[3];
90 | float rolloff;
91 | } material;
92 |
93 | if (self.ambientColor) {
94 | material.ambientColor[0] = self.ambientColor.redComponent;
95 | material.ambientColor[1] = self.ambientColor.greenComponent;
96 | material.ambientColor[2] = self.ambientColor.blueComponent;
97 | }
98 |
99 | if (self.diffuseColor) {
100 | material.diffuseColor[0] = self.diffuseColor.redComponent;
101 | material.diffuseColor[1] = self.diffuseColor.greenComponent;
102 | material.diffuseColor[2] = self.diffuseColor.blueComponent;
103 | }
104 |
105 | if (self.subColor) {
106 | material.subColor[0] = self.subColor.redComponent;
107 | material.subColor[1] = self.subColor.greenComponent;
108 | material.subColor[2] = self.subColor.blueComponent;
109 | }
110 |
111 | material.rolloff = self.rolloff;
112 |
113 | [buffer writeBytes:&material length:sizeof(material)];
114 | };
115 |
116 | [self handleBindingOfBufferNamed:@"light" frequency:SCNBufferFrequencyPerFrame usingBlock:lightBlock];
117 | [self handleBindingOfBufferNamed:@"material" frequency:SCNBufferFrequencyPerFrame usingBlock:materialBlock];
118 | }
119 |
120 | #pragma mark - SCNProgramDelegate Protocol Methods
121 |
122 | - (void)program:(SCNProgram*)program handleError:(NSError*)error {
123 | // Log the shader compilation error
124 | NSLog(@"SceneKit compilation error: %@", error);
125 | }
126 |
127 | @end
128 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHVelvetProgram.m:
--------------------------------------------------------------------------------
1 | //
2 | // CWHVelvetProgram.m
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 7/30/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import "CWHVelvetProgram.h"
10 |
11 | @implementation CWHVelvetProgram
12 |
13 | +(BOOL) supportsSecureCoding {
14 | return YES;
15 | }
16 |
17 | -(instancetype)init
18 | {
19 | id device = MTLCreateSystemDefaultDevice();
20 | id library = [device newDefaultLibrary];
21 |
22 | self = [super initWithLibrary:library vertexFunctionName:@"VelvetVertex" fragmentFunctionName:@"VelvetFragment"];
23 |
24 | if (self != nil)
25 | {
26 | self.delegate = self;
27 |
28 | [self bindBuffers];
29 |
30 | NSColor *underColor = [NSColor colorWithRed:0.7 green:0.7 blue:0 alpha:1.0];
31 | self.underColor = underColor;
32 | NSColor *fuzzColor = [NSColor colorWithRed:0.9 green:0.7 blue:0.5 alpha:1.0];
33 | self.fuzzColor = fuzzColor;
34 | self.rolloff = 0.528;
35 | }
36 |
37 | return self;
38 | }
39 |
40 | - (id)initWithCoder:(NSCoder *)decoder {
41 | id device = MTLCreateSystemDefaultDevice();
42 | id library = [device newDefaultLibrary];
43 |
44 | self = [super initWithLibrary:library vertexFunctionName:@"VelvetVertex" fragmentFunctionName:@"VelvetFragment"];
45 |
46 | if (self != nil)
47 | {
48 | self.delegate = self;
49 |
50 | [self bindBuffers];
51 |
52 | self.underColor = [decoder decodeObjectOfClass:[NSColor class] forKey:@"underColor"];
53 | self.fuzzColor = [decoder decodeObjectOfClass:[NSColor class] forKey:@"fuzzColor"];
54 | self.primaryColor = [decoder decodeObjectOfClass:[NSColor class] forKey:@"primaryColor"];
55 | self.rolloff = [decoder decodeDoubleForKey:@"rolloff"];
56 | }
57 | return self;
58 | }
59 |
60 | - (void)encodeWithCoder:(NSCoder *)encoder {
61 | [encoder encodeObject:_underColor forKey:@"underColor"];
62 | [encoder encodeObject:_fuzzColor forKey:@"fuzzColor"];
63 | [encoder encodeObject:_primaryColor forKey:@"primaryColor"];
64 | [encoder encodeDouble:_rolloff forKey:@"rolloff"];
65 | }
66 |
67 | - (void)bindBuffers {
68 | SCNBufferBindingBlock lightBlock = ^(id buffer, SCNNode *node, id shadable, SCNRenderer *renderer)
69 | {
70 | struct LightConstants {
71 | float position[3];
72 | } lights;
73 |
74 | lights.position[0] = self.lightPosition.x;
75 | lights.position[1] = self.lightPosition.y;
76 | lights.position[2] = self.lightPosition.z;
77 |
78 | [buffer writeBytes:&lights length:sizeof(lights)];
79 | };
80 |
81 | SCNBufferBindingBlock materialBlock = ^(id buffer, SCNNode *node, id shadable, SCNRenderer *renderer)
82 | {
83 | struct MaterialConstants {
84 | float primaryColor[4];
85 | float fuzzColor[4];
86 | float underColor[4];
87 | float rolloff;
88 | } material;
89 |
90 | if (self.primaryColor) {
91 | material.primaryColor[0] = self.primaryColor.redComponent;
92 | material.primaryColor[1] = self.primaryColor.greenComponent;
93 | material.primaryColor[2] = self.primaryColor.blueComponent;
94 | material.primaryColor[3] = self.primaryColor.alphaComponent;
95 | }
96 |
97 | if (self.fuzzColor) {
98 | material.fuzzColor[0] = self.fuzzColor.redComponent;
99 | material.fuzzColor[1] = self.fuzzColor.greenComponent;
100 | material.fuzzColor[2] = self.fuzzColor.blueComponent;
101 | material.fuzzColor[3] = self.fuzzColor.alphaComponent;
102 | }
103 |
104 | if (self.underColor) {
105 | material.underColor[0] = self.underColor.redComponent;
106 | material.underColor[1] = self.underColor.greenComponent;
107 | material.underColor[2] = self.underColor.blueComponent;
108 | material.underColor[3] = self.underColor.alphaComponent;
109 | }
110 |
111 | material.rolloff = self.rolloff;
112 |
113 | [buffer writeBytes:&material length:sizeof(material)];
114 | };
115 |
116 | [self handleBindingOfBufferNamed:@"light" frequency:SCNBufferFrequencyPerFrame usingBlock:lightBlock];
117 | [self handleBindingOfBufferNamed:@"material" frequency:SCNBufferFrequencyPerFrame usingBlock:materialBlock];
118 | }
119 |
120 | #pragma mark - SCNProgramDelegate Protocol Methods
121 |
122 | - (void)program:(SCNProgram*)program handleError:(NSError*)error {
123 | // Log the shader compilation error
124 | NSLog(@"SceneKit compilation error: %@", error);
125 | }
126 |
127 | @end
128 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHLUTSkinProgram.m:
--------------------------------------------------------------------------------
1 | //
2 | // CWHLUTSkinProgram.m
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 7/31/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import "CWHLUTSkinProgram.h"
10 |
11 | @implementation CWHLUTSkinProgram
12 |
13 | +(BOOL) supportsSecureCoding {
14 | return YES;
15 | }
16 |
17 | -(instancetype)init
18 | {
19 | id device = MTLCreateSystemDefaultDevice();
20 | id library = [device newDefaultLibrary];
21 |
22 | self = [super initWithLibrary:library vertexFunctionName:@"LUTSkinVertex" fragmentFunctionName:@"LUTSkinFragment"];
23 |
24 | if (self != nil)
25 | {
26 | self.delegate = self;
27 |
28 | [self bindBuffers];
29 |
30 | self.diffuseColor = [NSColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:1.0];;
31 | self.specularColor = [NSColor whiteColor];
32 | self.scatterColor = [NSColor redColor];
33 | self.wrap = 0.58;
34 | self.scatterWidth = 0.10;
35 | self.shininess = 0.35;
36 | }
37 |
38 | return self;
39 | }
40 |
41 | - (id)initWithCoder:(NSCoder *)decoder {
42 | id device = MTLCreateSystemDefaultDevice();
43 | id library = [device newDefaultLibrary];
44 |
45 | self = [super initWithLibrary:library vertexFunctionName:@"LUTSkinVertex" fragmentFunctionName:@"LUTSkinFragment"];
46 |
47 | if (self != nil)
48 | {
49 | self.delegate = self;
50 |
51 | [self bindBuffers];
52 |
53 | self.diffuseColor = [decoder decodeObjectOfClass:[NSColor class] forKey:@"diffuseColor"];
54 | self.specularColor = [decoder decodeObjectOfClass:[NSColor class] forKey:@"specularColor"];
55 | self.scatterColor = [decoder decodeObjectOfClass:[NSColor class] forKey:@"scatterColor"];
56 | self.wrap = [decoder decodeDoubleForKey:@"wrap"];
57 | self.scatterWidth = [decoder decodeDoubleForKey:@"scatterWidth"];
58 | self.shininess = [decoder decodeDoubleForKey:@"shininess"];
59 | }
60 | return self;
61 | }
62 |
63 | - (void)encodeWithCoder:(NSCoder *)encoder {
64 | [encoder encodeObject:_diffuseColor forKey:@"diffuseColor"];
65 | [encoder encodeObject:_specularColor forKey:@"specularColor"];
66 | [encoder encodeObject:_scatterColor forKey:@"scatterColor"];
67 | [encoder encodeDouble:_wrap forKey:@"wrap"];
68 | [encoder encodeDouble:_scatterWidth forKey:@"scatterWidth"];
69 | [encoder encodeDouble:_shininess forKey:@"shininess"];
70 | }
71 |
72 | - (void)bindBuffers {
73 | SCNBufferBindingBlock lightBlock = ^(id buffer, SCNNode *node, id shadable, SCNRenderer *renderer)
74 | {
75 | struct LightConstants {
76 | float position[3];
77 | } lights;
78 |
79 | lights.position[0] = self.lightPosition.x;
80 | lights.position[1] = self.lightPosition.y;
81 | lights.position[2] = self.lightPosition.z;
82 |
83 | [buffer writeBytes:&lights length:sizeof(lights)];
84 | };
85 |
86 | SCNBufferBindingBlock materialBlock = ^(id buffer, SCNNode *node, id shadable, SCNRenderer *renderer)
87 | {
88 | struct MaterialConstants {
89 | float diffuseColor[4];
90 | float specularColor[4];
91 | } material;
92 |
93 | if (self.diffuseColor) {
94 | material.diffuseColor[0] = self.diffuseColor.redComponent;
95 | material.diffuseColor[1] = self.diffuseColor.greenComponent;
96 | material.diffuseColor[2] = self.diffuseColor.blueComponent;
97 | material.diffuseColor[3] = self.diffuseColor.alphaComponent;
98 | }
99 |
100 | if (self.specularColor) {
101 | material.specularColor[0] = self.specularColor.redComponent;
102 | material.specularColor[1] = self.specularColor.greenComponent;
103 | material.specularColor[2] = self.specularColor.blueComponent;
104 | material.specularColor[3] = self.specularColor.alphaComponent;
105 | }
106 |
107 | [buffer writeBytes:&material length:sizeof(material)];
108 | };
109 |
110 | [self handleBindingOfBufferNamed:@"light" frequency:SCNBufferFrequencyPerFrame usingBlock:lightBlock];
111 | [self handleBindingOfBufferNamed:@"material" frequency:SCNBufferFrequencyPerShadable usingBlock:materialBlock];
112 | }
113 |
114 | - (NSDictionary *)shadableProperties {
115 | NSDictionary *properties = @{
116 | @"skinLUT" : [SCNMaterialProperty materialPropertyWithContents:@""]
117 | };
118 | return properties;
119 | }
120 |
121 | #pragma mark - SCNProgramDelegate Protocol Methods
122 |
123 | - (void)program:(SCNProgram*)program handleError:(NSError*)error {
124 | // Log the shader compilation error
125 | NSLog(@"SceneKit compilation error: %@", error);
126 | }
127 |
128 | @end
129 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHGoochProgram.m:
--------------------------------------------------------------------------------
1 | //
2 | // CWHBlinnProgram.m
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 7/29/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import "CWHGoochProgram.h"
10 |
11 | @implementation CWHGoochProgram
12 |
13 | +(BOOL) supportsSecureCoding {
14 | return YES;
15 | }
16 |
17 | -(instancetype)init
18 | {
19 | id device = MTLCreateSystemDefaultDevice();
20 | id library = [device newDefaultLibrary];
21 |
22 | self = [super initWithLibrary:library vertexFunctionName:@"GoochVertex" fragmentFunctionName:@"GoochFragment"];
23 |
24 | if ( self != nil )
25 | {
26 | self.delegate = self;
27 |
28 | [self bindBuffers];
29 |
30 | NSColor *surfaceColor = [NSColor redColor];
31 | self.surfaceColor = surfaceColor;
32 |
33 | NSColor *coolColor = [NSColor colorWithRed:0.2 green:1.0 blue:0.2 alpha:1.0];
34 | self.coolColor = coolColor;
35 |
36 | NSColor *warmColor = [NSColor purpleColor];
37 | self.warmColor = warmColor;
38 |
39 | self.diffuseCool = 0.0;
40 | self.diffuseWarm = 1.0;
41 | }
42 |
43 | return self;
44 | }
45 |
46 | - (id)initWithCoder:(NSCoder *)decoder {
47 | id device = MTLCreateSystemDefaultDevice();
48 | id library = [device newDefaultLibrary];
49 |
50 | self = [super initWithLibrary:library vertexFunctionName:@"GoochVertex" fragmentFunctionName:@"GoochFragment"];
51 |
52 | if ( self != nil )
53 | {
54 | self.delegate = self;
55 |
56 | [self bindBuffers];
57 |
58 | self.coolColor = [decoder decodeObjectOfClass:[NSColor class] forKey:@"coolColor"];
59 | self.warmColor = [decoder decodeObjectOfClass:[NSColor class] forKey:@"warmColor"];
60 | self.surfaceColor = [decoder decodeObjectOfClass:[NSColor class] forKey:@"surfaceColor"];
61 | self.diffuseCool = [decoder decodeDoubleForKey:@"diffuseCool"];
62 | self.diffuseWarm = [decoder decodeDoubleForKey:@"diffuseWarm"];
63 | }
64 | return self;
65 | }
66 |
67 | - (void)encodeWithCoder:(NSCoder *)encoder {
68 | [encoder encodeObject:_coolColor forKey:@"coolColor"];
69 | [encoder encodeObject:_warmColor forKey:@"warmColor"];
70 | [encoder encodeObject:_surfaceColor forKey:@"surfaceColor"];
71 | [encoder encodeDouble:_diffuseCool forKey:@"diffuseCool"];
72 | [encoder encodeDouble:_diffuseWarm forKey:@"diffuseWarm"];
73 | }
74 |
75 | - (void)bindBuffers {
76 | SCNBufferBindingBlock lightBlock = ^(id buffer, SCNNode *node, id shadable, SCNRenderer *renderer)
77 | {
78 | struct LightConstants {
79 | float position[3];
80 | } lights;
81 |
82 | lights.position[0] = self.lightPosition.x;
83 | lights.position[1] = self.lightPosition.y;
84 | lights.position[2] = self.lightPosition.z;
85 |
86 | [buffer writeBytes:&lights length:sizeof(lights)];
87 | };
88 |
89 | SCNBufferBindingBlock materialBlock = ^(id buffer, SCNNode *node, id shadable, SCNRenderer *renderer)
90 | {
91 | struct MaterialConstants {
92 | float surfaceColor[4];
93 | float warmColor[4];
94 | float coolColor[4];
95 | float diffuseWarm;
96 | float diffuseCool;
97 | } material;
98 |
99 | if (self.surfaceColor) {
100 | material.surfaceColor[0] = self.surfaceColor.redComponent;
101 | material.surfaceColor[1] = self.surfaceColor.greenComponent;
102 | material.surfaceColor[2] = self.surfaceColor.blueComponent;
103 | material.surfaceColor[3] = self.surfaceColor.alphaComponent;
104 | }
105 |
106 | if (self.warmColor) {
107 | material.warmColor[0] = self.warmColor.redComponent;
108 | material.warmColor[1] = self.warmColor.greenComponent;
109 | material.warmColor[2] = self.warmColor.blueComponent;
110 | material.warmColor[3] = self.warmColor.alphaComponent;
111 | }
112 |
113 | if (self.coolColor) {
114 | material.coolColor[0] = self.coolColor.redComponent;
115 | material.coolColor[1] = self.coolColor.greenComponent;
116 | material.coolColor[2] = self.coolColor.blueComponent;
117 | material.coolColor[3] = self.coolColor.alphaComponent;
118 | }
119 |
120 | material.diffuseWarm = self.diffuseWarm;
121 | material.diffuseCool = self.diffuseCool;
122 |
123 | [buffer writeBytes:&material length:sizeof(material)];
124 | };
125 |
126 | [self handleBindingOfBufferNamed:@"light" frequency:SCNBufferFrequencyPerFrame usingBlock:lightBlock];
127 | [self handleBindingOfBufferNamed:@"material" frequency:SCNBufferFrequencyPerFrame usingBlock:materialBlock];
128 | }
129 |
130 | #pragma mark - SCNProgramDelegate Protocol Methods
131 |
132 | - (void)program:(SCNProgram*)program handleError:(NSError*)error {
133 | // Log the shader compilation error
134 | NSLog(@"SceneKit compilation error: %@", error);
135 | }
136 |
137 | @end
138 |
--------------------------------------------------------------------------------
/ScenekitStarter/ThinFilmParameterView.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHGlossyWetHighlightParameterViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // CWHGlossyWetHighlightParameterViewController.m
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 9/12/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import "CWHGlossyWetHighlightParameterViewController.h"
10 |
11 | @interface CWHGlossyWetHighlightParameterViewController ()
12 | @end
13 |
14 | @implementation CWHGlossyWetHighlightParameterViewController
15 |
16 | - (void)viewDidLoad {
17 | [super viewDidLoad];
18 |
19 | NSColor *ambientColor = [self.program valueForKey:@"ambientColor"];
20 |
21 | if (ambientColor) {
22 | [self.ambientColorWell setColor:ambientColor];
23 | }
24 |
25 | NSColor *diffuseColor = [self.program valueForKey:@"diffuseColor"];
26 |
27 | if (diffuseColor) {
28 | [self.diffuseColorWell setColor:diffuseColor];
29 | }
30 |
31 | NSColor *specularColor = [self.program valueForKey:@"specularColor"];
32 |
33 | if (specularColor) {
34 | [self.specularColorWell setColor:specularColor];
35 | }
36 |
37 | double glossMin = [[self.program valueForKey:@"glossMin"] doubleValue];
38 | if (glossMin >= 0) {
39 | [self.glossMinSlider setDoubleValue:glossMin];
40 | [self.glossMinTextField setDoubleValue:glossMin];
41 |
42 | }
43 |
44 | double glossMax = [[self.program valueForKey:@"glossMax"] doubleValue];
45 | if (glossMax >= 0) {
46 | [self.glossMaxSlider setDoubleValue:glossMax];
47 | [self.glossMaxTextField setDoubleValue:glossMax];
48 | }
49 |
50 | double glossDrop = [[self.program valueForKey:@"glossDrop"] doubleValue];
51 | if (glossDrop >= 0) {
52 | [self.glossDropSlider setDoubleValue:glossDrop];
53 | [self.glossDropTextField setDoubleValue:glossDrop];
54 | }
55 |
56 | double specularity = [[self.program valueForKey:@"specularity"] doubleValue];
57 | if (specularity >= 0) {
58 | [self.specularitySlider setDoubleValue:specularity];
59 | [self.specularityTextField setDoubleValue:specularity];
60 | }
61 |
62 | double specularExponent = [[self.program valueForKey:@"specularExponent"] doubleValue];
63 | if (specularExponent >= 0) {
64 | [self.specularExponentSlider setDoubleValue:specularExponent];
65 | [self.specularExponentTextField setDoubleValue:specularExponent];
66 | }
67 | }
68 |
69 | - (IBAction)updateGlossMin:(id)sender {
70 | if ([sender isKindOfClass:[NSSlider class]]) {
71 | [self.glossMinTextField setDoubleValue:[sender doubleValue]];
72 | }else{
73 | [self.glossMinSlider setDoubleValue:[sender doubleValue]];
74 | }
75 |
76 | [self updateShaderValues];
77 | }
78 |
79 | - (IBAction)updateGlossMax:(id)sender {
80 | if ([sender isKindOfClass:[NSSlider class]]) {
81 | [self.glossMaxTextField setDoubleValue:[sender doubleValue]];
82 | }else{
83 | [self.glossMaxSlider setDoubleValue:[sender doubleValue]];
84 | }
85 |
86 | [self updateShaderValues];
87 | }
88 |
89 | - (IBAction)updateGlossDrop:(id)sender {
90 | if ([sender isKindOfClass:[NSSlider class]]) {
91 | [self.glossDropTextField setDoubleValue:[sender doubleValue]];
92 | }else{
93 | [self.glossDropSlider setDoubleValue:[sender doubleValue]];
94 | }
95 |
96 | [self updateShaderValues];
97 |
98 | }
99 |
100 | - (IBAction)updateSpecularExponent:(id)sender {
101 |
102 | if ([sender isKindOfClass:[NSSlider class]]) {
103 | [self.specularExponentTextField setDoubleValue:[sender doubleValue]];
104 | }else{
105 | [self.specularExponentSlider setDoubleValue:[sender doubleValue]];
106 | }
107 |
108 | [self updateShaderValues];
109 | }
110 |
111 | - (IBAction)updateSpecularity:(id)sender {
112 |
113 | if ([sender isKindOfClass:[NSSlider class]]) {
114 | [self.specularityTextField setDoubleValue:[sender doubleValue]];
115 | }else{
116 | [self.specularitySlider setDoubleValue:[sender doubleValue]];
117 | }
118 |
119 | [self updateShaderValues];
120 | }
121 |
122 | - (IBAction)updateDiffuseColor:(id)sender {
123 | [self updateShaderValues];
124 | }
125 |
126 | - (IBAction)updateAmbientColor:(id)sender {
127 | [self updateShaderValues];
128 | }
129 |
130 | - (IBAction)updateSpecularColor:(id)sender {
131 | [self updateShaderValues];
132 | }
133 |
134 | -(void)updateShaderValues
135 | {
136 | CWHGlossyWetHighlightProgram *program = (CWHGlossyWetHighlightProgram *)self.program;
137 |
138 | program.glossMin = [self.glossMinSlider doubleValue];
139 | program.glossMax = [self.glossMaxSlider doubleValue];
140 | program.glossDrop = [self.glossDropSlider doubleValue];
141 | program.specularExponent = [self.specularExponentSlider doubleValue];
142 | program.specularity = [self.specularitySlider doubleValue];
143 | program.specularColor = [self.specularColorWell color];
144 | program.ambientColor = [self.ambientColorWell color];
145 | program.diffuseColor = [self.diffuseColorWell color];
146 |
147 | [self.delegate updateProgram:program shadableProperties:nil];
148 | }
149 |
150 | @end
151 |
--------------------------------------------------------------------------------
/ScenekitStarter/GlossyWetHighlight.metal:
--------------------------------------------------------------------------------
1 | #include
2 | using namespace metal;
3 |
4 | #include
5 |
6 | struct VertexIn {
7 | float4 position [[attribute(SCNVertexSemanticPosition)]];
8 | float3 normal [[attribute(SCNVertexSemanticNormal)]];
9 | float2 texCoords [[attribute(SCNVertexSemanticTexcoord0)]];
10 | };
11 |
12 | struct NodeConstants {
13 | float4x4 modelViewTransform;
14 | float4x4 modelViewProjectionTransform;
15 | float4x4 normalTransform;
16 | float4x4 inverseProjectionTransform;
17 | };
18 |
19 | struct LightConstants {
20 | packed_float3 position;
21 | packed_float3 ambientIntensity;
22 | packed_float3 diffuseIntensity;
23 | packed_float3 specularIntensity;
24 | };
25 |
26 | struct MaterialConstants {
27 | float specularExponent;
28 | float specularity;
29 | float glossMin;
30 | float glossMax;
31 | float glossDrop;
32 | };
33 |
34 | struct VertexOut {
35 | float4 position [[position]];
36 | //float4 color;
37 | float2 texCoords;
38 | float3 lightVec;
39 | float3 eyeView;
40 | float3 eyeNormal;
41 | };
42 |
43 | /*
44 | Adapted from:
45 | 'glossyWetHilight.fx' from NVIDIA shader library
46 | http://developer.download.nvidia.com/shaderlibrary/HLSL/glossyWetHilight.fx
47 | NDVIDIA Corporation 2007
48 |
49 | HLSL > GLSL conversion and Quartz Composer setup
50 | toneburst 2008
51 | http://machinesdontcare.wordpress.com
52 | */
53 |
54 | // Main Glossy Wet Hilight Vertex Shader function
55 | void glossyWetVS(VertexIn in, thread VertexOut &out, constant NodeConstants &scn_node, constant LightConstants &light)
56 | {
57 | out.lightVec = light.position.xyz - in.position.xyz;
58 | out.eyeView = normalize(scn_node.inverseProjectionTransform[3].xyz - in.position.xyz);
59 | float4 n = scn_node.normalTransform * float4(in.normal, 0.0f);
60 | out.eyeNormal = normalize(n.xyz);
61 | }
62 |
63 | vertex VertexOut GlossyWetHighlightVertex(VertexIn in [[stage_in]],
64 | constant SCNSceneBuffer &scn_frame [[buffer(0)]],
65 | constant NodeConstants &scn_node [[buffer(1)]],
66 | constant LightConstants &vertexLights [[buffer(2)]])
67 | {
68 | VertexOut out;
69 | glossyWetVS(in, out, scn_node, vertexLights);
70 |
71 | out.position = scn_node.modelViewProjectionTransform * in.position;
72 | //out.color = in.color;
73 | out.texCoords = /*gl_TextureMatrix[0] **/ in.texCoords;
74 |
75 | return out;
76 | }
77 |
78 | /*
79 | Adapted from:
80 | 'glossyWetHilight.fx' from NVIDIA shader library
81 | http://developer.download.nvidia.com/shaderlibrary/HLSL/glossyWetHilight.fx
82 | NDVIDIA Corporation 2007
83 |
84 | HLSL > GLSL conversion and Quartz Composer setup
85 | toneburst 2008
86 | http://machinesdontcare.wordpress.com
87 | */
88 |
89 | static float3 lit (float NdotL, float NdotH, float m)
90 | {
91 | float ambient = 1.0;
92 | float diffuse = max(NdotL, 0.0);
93 | float specular = step(0.0, NdotL) * max(NdotH * m, 1.0);
94 | return float3(ambient, diffuse, specular);
95 | }
96 |
97 | // Calculates specular dropoff
98 | float glossy_drop(float v, float gMax, float gMin, float gDrop)
99 | {
100 | return (gDrop + smoothstep(gMin, gMax, v) * (1.0f - gDrop));
101 | }
102 |
103 | // Main Glossy Wet Hilight Fragment Shader function
104 | float4 glossyWetFS(thread VertexOut &in, float4 baseColor, constant LightConstants &light, constant MaterialConstants &material)
105 | {
106 | float3 Ln = normalize(in.lightVec);
107 | float3 Nn = normalize(in.eyeNormal);
108 | float3 Vn = normalize(in.eyeView);
109 | float3 Hn = normalize(Vn + Ln);
110 | // Specular component
111 | float4 litV = float4(lit(dot(Ln, Nn), dot(Hn, Nn), material.specularExponent), 1.0);
112 | float spec = powr(litV.y, litV.z);
113 | spec *= (material.specularity * glossy_drop(spec, material.glossMax, material.glossMin, material.glossDrop));
114 | float3 specularContrib = spec * light.specularIntensity.xyz;
115 | // Diffuse component
116 | float3 diffuseContrib = litV.y * light.diffuseIntensity.xyz + light.ambientIntensity.xyz;
117 | // Combine lighting components and output result
118 | return float4(specularContrib + (baseColor.rgb * diffuseContrib), baseColor.a);
119 | }
120 |
121 | fragment float4 GlossyWetHighlightFragment(VertexOut in [[stage_in]],
122 | /*texture2d tex2d [[texture(0)]],*/
123 | constant LightConstants &fragmentLights [[buffer(0)]],
124 | constant MaterialConstants &material [[buffer(1)]])
125 | {
126 | /*
127 | constexpr sampler bilinearClampedSampler(coord::normalized,
128 | min_filter::linear,
129 | mag_filter::linear,
130 | mip_filter::none,
131 | address::clamp_to_edge);
132 |
133 | float4 baseColor = tex2d.sample(bilinearClampedSampler, in.texCoords);
134 | */
135 | float4 baseColor(1.0f, 1.0f, 1.0f, 1.0f);
136 | return glossyWetFS(in, baseColor, fragmentLights, material);
137 | }
138 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHLightingModelWindowController.m:
--------------------------------------------------------------------------------
1 | //
2 | // CWHLightingModelWindowController.m
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 8/1/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import "CWHLightingModelWindowController.h"
10 | #import "CWHLightingViewController.h"
11 | #import "CWHParameterViewController.h"
12 |
13 | @interface CWHLightingModelWindowController ()
14 | -(void)saveShaderValues;
15 | @end
16 |
17 | @implementation CWHLightingModelWindowController
18 |
19 | - (void)awakeFromNib
20 | {
21 | self.lightingParameterState = FALSE;
22 | [self updateLightingModel:self.lightingModelPopupButton];
23 | }
24 |
25 | -(void)parameterViewWillClose {
26 | self.lightingParameterState = FALSE;
27 | [self saveShaderValues];
28 | }
29 |
30 | -(void)updateProgram:(SCNProgram *)program shadableProperties:(NSDictionary *)properties;
31 | {
32 | self.currentProgram = program;
33 |
34 | SCNNode *shadedNode = self.lightingViewController.geometryNode;
35 |
36 | SCNMaterial *programMaterial = [SCNMaterial material];
37 | programMaterial.program = program;
38 | for (NSString *key in properties) {
39 | [programMaterial setValue:properties[key] forKey:key];
40 | }
41 | shadedNode.geometry.materials = @[programMaterial];
42 | }
43 |
44 | -(CWHParameterViewController *)parameterViewControllerForCurrentProgram
45 | {
46 | NSString *strippedString = [self.currentLightingModel stringByReplacingOccurrencesOfString:@" " withString:@""];
47 | NSString *programString = [NSString stringWithFormat:@"CWH%@ParameterViewController", strippedString];
48 | NSString *nibString = [NSString stringWithFormat:@"%@ParameterView", strippedString];
49 |
50 | Class parameterViewControllerClass = NSClassFromString(programString);
51 | CWHParameterViewController *parameterViewController = nil;
52 | if (parameterViewControllerClass) {
53 | parameterViewController = [[parameterViewControllerClass alloc]
54 | initWithNibName:nibString bundle:nil];
55 | }
56 |
57 | parameterViewController.program = self.currentProgram;
58 |
59 | return parameterViewController;
60 | }
61 |
62 | -(IBAction)showInputParameters:(id)sender
63 | {
64 | if(self.lightingParameterState == FALSE){
65 | CWHParameterViewController *parameterViewController = [self parameterViewControllerForCurrentProgram];
66 |
67 | if (parameterViewController) {
68 | [self.lightingViewController presentViewController:parameterViewController
69 | asPopoverRelativeToRect:self.parameterToolbarItem.view.bounds
70 | ofView:self.parameterToolbarItem.view
71 | preferredEdge:NSMaxYEdge
72 | behavior:NSPopoverBehaviorTransient];
73 |
74 | parameterViewController.delegate = self;
75 | self.lightingParameterState = TRUE;
76 | }
77 |
78 | }else{
79 | self.lightingParameterState = FALSE;
80 | }
81 |
82 | }
83 |
84 | -(void)saveShaderValues
85 | {
86 | NSError *error = nil;
87 | if(self.currentProgram) {
88 | NSString *className = NSStringFromClass([self.currentProgram class]);
89 | NSData *data = [NSKeyedArchiver archivedDataWithRootObject:self.currentProgram requiringSecureCoding:YES error:&error];
90 | if (data) {
91 | [[NSUserDefaults standardUserDefaults] setObject:data forKey:className];
92 | } else {
93 | NSLog(@"Encountered error when serializing shader program: %@", error.localizedDescription);
94 | }
95 | }
96 | }
97 |
98 | -(SCNProgram *)programForLightingModel:(NSString *)lightingModel
99 | {
100 | NSString *strippedString = [lightingModel stringByReplacingOccurrencesOfString:@" " withString:@""];
101 | NSString *programString = [NSString stringWithFormat:@"CWH%@Program", strippedString];
102 | Class programClass = NSClassFromString(programString);
103 |
104 | SCNProgram *program = nil;
105 | //unarchive here if we've changed some parameters
106 | NSData *programData = [[NSUserDefaults standardUserDefaults] objectForKey:programString];
107 | if(programData){
108 | NSError *error = nil;
109 | program = [NSKeyedUnarchiver unarchivedObjectOfClass:programClass fromData:programData error:&error];
110 | if (program == nil) {
111 | NSLog(@"Encountered error when deserializing shader program: %@", error.localizedDescription);
112 | }
113 | } else if (programClass) {
114 | program = (SCNProgram *)[programClass program];
115 | }
116 |
117 | return program;
118 | }
119 |
120 | - (IBAction)updateLightingModel:(id)sender {
121 | NSString *updatedModel = [sender titleOfSelectedItem];
122 |
123 | if(![self.currentLightingModel isEqualToString:updatedModel]){
124 | CWHLightingProgram *program = (CWHLightingProgram *)[self programForLightingModel:updatedModel];
125 | NSAssert([program isKindOfClass:[CWHLightingProgram class]],
126 | @"Program for lighting model is expected to be an instance of a subclass of CWHLightingProgram");
127 | NSDictionary *properties = program.shadableProperties;
128 | [self updateProgram:program shadableProperties:properties];
129 | self.currentLightingModel = updatedModel;
130 | }
131 | }
132 |
133 | @end
134 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHGlossyWetHighlightProgram.m:
--------------------------------------------------------------------------------
1 | //
2 | // CWHGlossyWetHighlightProgram.m
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 7/31/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import "CWHGlossyWetHighlightProgram.h"
10 |
11 | @implementation CWHGlossyWetHighlightProgram
12 |
13 | +(BOOL) supportsSecureCoding {
14 | return YES;
15 | }
16 |
17 | -(instancetype)init
18 | {
19 | id device = MTLCreateSystemDefaultDevice();
20 | id library = [device newDefaultLibrary];
21 |
22 | self = [super initWithLibrary:library vertexFunctionName:@"GlossyWetHighlightVertex" fragmentFunctionName:@"GlossyWetHighlightFragment"];
23 |
24 | if (self != nil)
25 | {
26 | self.delegate = self;
27 |
28 | [self bindBuffers];
29 |
30 | self.ambientColor = [NSColor colorWithRed:0. green:0. blue:0. alpha:1.];
31 | self.diffuseColor = [NSColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:1.];
32 | self.specularColor = [NSColor colorWithRed:1. green:0. blue:0. alpha:1.];
33 | self.specularity = 0.3;
34 | self.specularExponent = 3.0;
35 | self.glossMax = 1.349;
36 | self.glossMin = 1.199;
37 | self.glossDrop = 2.661;
38 | }
39 |
40 | return self;
41 | }
42 |
43 | - (id)initWithCoder:(NSCoder *)decoder {
44 | id device = MTLCreateSystemDefaultDevice();
45 | id library = [device newDefaultLibrary];
46 |
47 | self = [super initWithLibrary:library vertexFunctionName:@"GlossyWetHighlightVertex" fragmentFunctionName:@"GlossyWetHighlightFragment"];
48 |
49 | if (self != nil)
50 | {
51 | self.delegate = self;
52 |
53 | [self bindBuffers];
54 |
55 | self.ambientColor = [decoder decodeObjectOfClass:[NSColor class] forKey:@"ambientColor"];
56 | self.diffuseColor = [decoder decodeObjectOfClass:[NSColor class] forKey:@"diffuseColor"];
57 | self.specularColor = [decoder decodeObjectOfClass:[NSColor class] forKey:@"specularColor"];
58 | self.specularity = [decoder decodeDoubleForKey:@"specularity"];
59 | self.specularExponent= [decoder decodeDoubleForKey:@"specularExponent"];
60 | self.glossMax= [decoder decodeDoubleForKey:@"glossMax"];
61 | self.glossMin= [decoder decodeDoubleForKey:@"glossMin"];
62 | self.glossDrop = [decoder decodeDoubleForKey:@"glossDrop"];
63 |
64 | }
65 | return self;
66 | }
67 |
68 | - (void)encodeWithCoder:(NSCoder *)encoder {
69 | [encoder encodeObject:_ambientColor forKey:@"ambientColor"];
70 | [encoder encodeObject:_diffuseColor forKey:@"diffuseColor"];
71 | [encoder encodeObject:_specularColor forKey:@"specularColor"];
72 | [encoder encodeDouble:_specularity forKey:@"specularity"];
73 | [encoder encodeDouble:_specularExponent forKey:@"specularExponent"];
74 | [encoder encodeDouble:_glossMax forKey:@"glossMax"];
75 | [encoder encodeDouble:_glossMin forKey:@"glossMin"];
76 | [encoder encodeDouble:_glossDrop forKey:@"glossDrop"];
77 | }
78 |
79 | - (void)bindBuffers {
80 | SCNBufferBindingBlock lightBlock = ^(id buffer, SCNNode *node, id shadable, SCNRenderer *renderer)
81 | {
82 | struct LightConstants {
83 | float position[3];
84 | float ambientIntensity[3];
85 | float diffuseIntensity[3];
86 | float specularIntensity[3];
87 | } lights;
88 |
89 | lights.position[0] = self.lightPosition.x;
90 | lights.position[1] = self.lightPosition.y;
91 | lights.position[2] = self.lightPosition.z;
92 |
93 | if (self.ambientColor) {
94 | lights.ambientIntensity[0] = [self.ambientColor redComponent];
95 | lights.ambientIntensity[1] = [self.ambientColor greenComponent];
96 | lights.ambientIntensity[2] = [self.ambientColor blueComponent];
97 | }
98 |
99 | if (self.diffuseColor) {
100 | lights.diffuseIntensity[0] = [self.diffuseColor redComponent];
101 | lights.diffuseIntensity[1] = [self.diffuseColor greenComponent];
102 | lights.diffuseIntensity[2] = [self.diffuseColor blueComponent];
103 | }
104 |
105 | if (self.specularColor) {
106 | lights.specularIntensity[0] = [self.specularColor redComponent];
107 | lights.specularIntensity[1] = [self.specularColor greenComponent];
108 | lights.specularIntensity[2] = [self.specularColor blueComponent];
109 | }
110 |
111 | [buffer writeBytes:&lights length:sizeof(lights)];
112 | };
113 |
114 | SCNBufferBindingBlock materialBlock = ^(id buffer, SCNNode *node, id shadable, SCNRenderer *renderer)
115 | {
116 | struct MaterialConstants {
117 | float specularExponent;
118 | float specularity;
119 | float glossMin;
120 | float glossMax;
121 | float glossDrop;
122 | } material;
123 |
124 | material.specularExponent = self.specularExponent;
125 | material.specularity = self.specularity;
126 | material.glossMin = self.glossMin;
127 | material.glossMax = self.glossMax;
128 | material.glossDrop = self.glossDrop;
129 |
130 | [buffer writeBytes:&material length:sizeof(material)];
131 | };
132 |
133 | [self handleBindingOfBufferNamed:@"vertexLights" frequency:SCNBufferFrequencyPerFrame usingBlock:lightBlock];
134 | [self handleBindingOfBufferNamed:@"fragmentLights" frequency:SCNBufferFrequencyPerFrame usingBlock:lightBlock];
135 | [self handleBindingOfBufferNamed:@"material" frequency:SCNBufferFrequencyPerFrame usingBlock:materialBlock];
136 | }
137 |
138 | #pragma mark - SCNProgramDelegate Protocol Methods
139 |
140 | - (void)program:(SCNProgram*)program handleError:(NSError*)error {
141 | // Log the shader compilation error
142 | NSLog(@"SceneKit compilation error: %@", error);
143 | }
144 |
145 | @end
146 |
--------------------------------------------------------------------------------
/ScenekitStarter/CWHEdgeFuzzProgram.m:
--------------------------------------------------------------------------------
1 | //
2 | // CWHEdgeFuzzProgram.m
3 | // ScenekitStarter
4 | //
5 | // Created by Dale Bradshaw on 7/31/14.
6 | // Copyright (c) 2014 Creative Workflow Hacks. All rights reserved.
7 | //
8 |
9 | #import "CWHEdgeFuzzProgram.h"
10 |
11 | @implementation CWHEdgeFuzzProgram
12 |
13 | +(BOOL) supportsSecureCoding {
14 | return YES;
15 | }
16 |
17 | -(instancetype)init
18 | {
19 | id device = MTLCreateSystemDefaultDevice();
20 | id library = [device newDefaultLibrary];
21 |
22 | self = [super initWithLibrary:library vertexFunctionName:@"EdgeFuzzVertex" fragmentFunctionName:@"EdgeFuzzFragment"];
23 |
24 | if ( self != nil )
25 | {
26 | self.delegate = self;
27 |
28 | [self bindBuffers];
29 |
30 | NSColor *surfaceColor = [NSColor colorWithRed:0.8 green:0.4 blue:0.2 alpha:1.];
31 | self.surfaceColor = surfaceColor;
32 | NSColor *edgeColor = [NSColor colorWithRed:0.4 green:0.8 blue:1. alpha:1.];
33 | self.edgeColor = edgeColor;
34 | NSColor *lightColor = [NSColor colorWithRed:1. green:1. blue:1. alpha:1.];
35 | self.lightColor = lightColor;
36 | NSColor *ambientColor = [NSColor colorWithRed:0. green:0. blue:0. alpha:1.];
37 | self.ambientColor = ambientColor;
38 |
39 | self.fuzziness = 0.166;
40 | self.edgeFade = 3.868;
41 | self.specularity = 0.1488;
42 | }
43 |
44 | return self;
45 | }
46 |
47 | - (id)initWithCoder:(NSCoder *)decoder {
48 |
49 | id device = MTLCreateSystemDefaultDevice();
50 | id library = [device newDefaultLibrary];
51 |
52 | self = [super initWithLibrary:library vertexFunctionName:@"EdgeFuzzVertex" fragmentFunctionName:@"EdgeFuzzFragment"];
53 |
54 | if (self) {
55 | self.surfaceColor =[decoder decodeObjectOfClass:[NSColor class] forKey:@"surfaceColor"];
56 | self.edgeColor = [decoder decodeObjectOfClass:[NSColor class] forKey:@"edgeColor"];
57 | self.lightColor = [decoder decodeObjectOfClass:[NSColor class] forKey:@"lightColor"];
58 | self.ambientColor = [decoder decodeObjectOfClass:[NSColor class] forKey:@"ambientColor"];
59 | self.fuzziness = [decoder decodeDoubleForKey:@"fuzziness"];
60 | self.edgeFade = [decoder decodeDoubleForKey:@"edgeFade"];
61 | self.specularity = [decoder decodeDoubleForKey:@"specularity"];
62 |
63 | self.delegate = self;
64 |
65 | [self bindBuffers];
66 | }
67 |
68 | return self;
69 | }
70 |
71 | - (void)encodeWithCoder:(NSCoder *)encoder {
72 | [encoder encodeObject:_surfaceColor forKey:@"surfaceColor"];
73 | [encoder encodeObject:_edgeColor forKey:@"edgeColor"];
74 | [encoder encodeObject:_lightColor forKey:@"lightColor"];
75 | [encoder encodeObject:_ambientColor forKey:@"ambientColor"];
76 | [encoder encodeDouble:_fuzziness forKey:@"fuzziness"];
77 | [encoder encodeDouble:_edgeFade forKey:@"edgeFade"];
78 | [encoder encodeDouble:_specularity forKey:@"specularity"];
79 | }
80 |
81 | - (void)bindBuffers {
82 | SCNBufferBindingBlock lightBlock = ^(id buffer, SCNNode *node, id shadable, SCNRenderer *renderer)
83 | {
84 | struct LightConstants {
85 | float position[3];
86 | float ambientIntensity[3];
87 | float diffuseIntensity[3];
88 | } lights;
89 |
90 | lights.position[0] = self.lightPosition.x;
91 | lights.position[1] = self.lightPosition.y;
92 | lights.position[2] = self.lightPosition.z;
93 |
94 | if (self.lightColor) {
95 | lights.diffuseIntensity[0] = [self.lightColor redComponent];
96 | lights.diffuseIntensity[1] = [self.lightColor greenComponent];
97 | lights.diffuseIntensity[2] = [self.lightColor blueComponent];
98 | }
99 |
100 | if (self.ambientColor) {
101 | lights.ambientIntensity[0] = [self.ambientColor redComponent];
102 | lights.ambientIntensity[1] = [self.ambientColor greenComponent];
103 | lights.ambientIntensity[2] = [self.ambientColor blueComponent];
104 | }
105 |
106 | [buffer writeBytes:&lights length:sizeof(lights)];
107 | };
108 |
109 | SCNBufferBindingBlock materialBlock = ^(id buffer, SCNNode *node, id shadable, SCNRenderer *renderer)
110 | {
111 | struct MaterialConstants {
112 | float edgeColor[4];
113 | float surfaceColor[4];
114 | float specularity;
115 | float fuzziness;
116 | float edgeFade;
117 | } material;
118 |
119 | if (self.edgeColor) {
120 | material.edgeColor[0] = [self.edgeColor redComponent];
121 | material.edgeColor[1] = [self.edgeColor greenComponent];
122 | material.edgeColor[2] = [self.edgeColor blueComponent];
123 | material.edgeColor[3] = [self.edgeColor alphaComponent];
124 | }
125 |
126 | if (self.surfaceColor) {
127 | material.surfaceColor[0] = [self.surfaceColor redComponent];
128 | material.surfaceColor[1] = [self.surfaceColor greenComponent];
129 | material.surfaceColor[2] = [self.surfaceColor blueComponent];
130 | material.surfaceColor[3] = [self.surfaceColor alphaComponent];
131 | }
132 |
133 | material.specularity = self.specularity;
134 | material.fuzziness = self.fuzziness;
135 | material.edgeFade = self.edgeFade;
136 |
137 | [buffer writeBytes:&material length:sizeof(material)];
138 | };
139 |
140 | [self handleBindingOfBufferNamed:@"vertexLights" frequency:SCNBufferFrequencyPerFrame usingBlock:lightBlock];
141 | [self handleBindingOfBufferNamed:@"fragmentLights" frequency:SCNBufferFrequencyPerFrame usingBlock:lightBlock];
142 | [self handleBindingOfBufferNamed:@"material" frequency:SCNBufferFrequencyPerShadable usingBlock:materialBlock];
143 | }
144 |
145 | #pragma mark - SCNProgramDelegate Protocol Methods
146 |
147 | - (void)program:(SCNProgram*)program handleError:(NSError*)error {
148 | // Log the shader compilation error
149 | NSLog(@"SceneKit compilation error: %@", error);
150 | }
151 |
152 | @end
153 |
--------------------------------------------------------------------------------
/ScenekitStarter/LambSkinParameterView.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
--------------------------------------------------------------------------------
/ScenekitStarter/LightingModelWindow.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
--------------------------------------------------------------------------------
/ScenekitStarter/VelvetParameterView.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
--------------------------------------------------------------------------------