Skip to content

Commit

Permalink
Support artificial (point) lights.
Browse files Browse the repository at this point in the history
  • Loading branch information
SamuelTallet committed Nov 21, 2019
1 parent ac61fce commit b76cb7d
Show file tree
Hide file tree
Showing 7 changed files with 264 additions and 45 deletions.
4 changes: 2 additions & 2 deletions source/pbr.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
# PBR plugin namespace.
module PBR

VERSION = '1.5.0'.freeze
VERSION = '1.5.1'.freeze

# Load translation if it's available for current locale.
TRANSLATE = LanguageHandler.new('pbr.strings')
Expand All @@ -48,7 +48,7 @@ module PBR
extension.copyright = "© 2019 #{extension.creator}"

features = [
TRANSLATE['Add reflects and reliefs to your SketchUp models.'],
TRANSLATE['Add reflects, reliefs and lights to your SketchUp models.'],
TRANSLATE['Get a render in seconds.'],
TRANSLATE['Control camera in real-time.'],
TRANSLATE['Export result to image or 3D object.']
Expand Down
4 changes: 2 additions & 2 deletions source/pbr/Resources/fr/pbr.strings
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
// PBR French Translation.
//
// Package: PBR extension for SketchUp
// Translation author: Samuel Tallet-Sabathé
// Translation author: Samuel Tallet
////////////////////////////////////////////

//
// File: pbr.rb
//

"Physically-Based Rendering"="Rendu basé sur la physique";
"Add reflects and reliefs to your SketchUp models."="Ajoutez des reflets et des reliefs à vos modèles SketchUp.";
"Add reflects, reliefs and lights to your SketchUp models."="Ajoutez des reflets, reliefs et lumières à vos modèles SketchUp.";
"Get a render in seconds."="Obtenez un rendu en quelques secondes.";
"Control camera in real-time."="Contrôlez la caméra en temps réel.";
"Export result to image or 3D object."="Exportez le résultat en image ou en objet 3D.";
Expand Down
144 changes: 104 additions & 40 deletions source/pbr/Viewport App/viewport.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,26 @@ PBR = {};
PBR.Viewport = {};

/**
* Translate Viewport app strings.
* Helper function to convert HTML colors.
*
* @see assets/sketchup-locale.json
* @see https://css-tricks.com/converting-color-spaces-in-javascript/
*/
PBR.Viewport.translateStrings = function() {
PBR.Viewport.rgbToHex = function(r, g, b) {

document.title = sketchUpLocale.document_title;
r = r.toString(16);
g = g.toString(16);
b = b.toString(16);

var helpLink = document.getElementById('helpLink');
if ( r.length == 1 )
r = "0" + r;

helpLink.href = sketchUpLocale.help_link_href;
helpLink.textContent = sketchUpLocale.help_link_text;
if ( g.length == 1 )
g = "0" + g;

if ( b.length == 1 )
b = "0" + b;

return "#" + r + g + b;

};

Expand Down Expand Up @@ -79,6 +87,20 @@ PBR.Viewport.cfg.advancedGraphics = {

};

/**
* Viewport natural lights.
*
* @type {object}
*/
PBR.Viewport.naturalLights = {};

/**
* Viewport artificial lights.
*
* @type {object}
*/
PBR.Viewport.artificialLights = [];

/**
* Create a 3D application that will manage the app initialization and loop.
*
Expand All @@ -99,7 +121,7 @@ PBR.Viewport.app = clay.application.create('#app', {
);

// Create a perspective camera.
this._camera = app.createCamera([0, 0, 0], [0, 0, 0]);
this._camera = app.createCamera([0, 2, -5], [0, 0, 0]);

// Plug & use an orbit control.
this._orbitControl = new clay.plugin.OrbitControl({
Expand All @@ -121,58 +143,85 @@ PBR.Viewport.app = clay.application.create('#app', {
self._advancedRenderer.render();
}, self);

// Create a directional light.
this._mainLight = app.createDirectionalLight([-1, -1, -1], '#fff', 0.8);
this._mainLight.shadowResolution = 4096;

// Create an cubemap ambient light and an spherical harmonic ambient light for specular and diffuse
// lighting in PBR rendering.
app.createAmbientCubemapLight('assets/equirectangular.hdr', 1, 0.5, 1)
return app.createAmbientCubemapLight('assets/equirectangular.hdr', 0.8, 0.8)
.then(function (ambientLight){

// Set HDR background.
PBR.Viewport.naturalLights.diffuse = ambientLight.diffuse;
PBR.Viewport.naturalLights.specular = ambientLight.specular;

// Create a directional light.
PBR.Viewport.naturalLights.direct = app.createDirectionalLight([-1, -1, -1], '#fff', 0.8);
PBR.Viewport.naturalLights.direct.shadowResolution = 4096;

// Set HDR background image.
var skybox = new clay.plugin.Skybox({
scene: app.scene,
environmentMap: ambientLight.environmentMap
});

});
// Load a glTF format model.
app.loadModel('assets/sketchup-model.gltf', {
textureConvertToPOT: true
}).then(function (model) {

// Load a glTF format model.
return app.loadModel('assets/sketchup-model.gltf', {
textureConvertToPOT: true
}).then(function (model) {
if ( model.json.extras && model.json.extras.lights ) {

for (var materialIndex = 0; materialIndex < model.materials.length; materialIndex++) {
// Turn off natural lights.
PBR.Viewport.naturalLights.direct.intensity = 0;
PBR.Viewport.naturalLights.diffuse.intensity = 0;
PBR.Viewport.naturalLights.specular.intensity = 0;

var clayMaterial = model.materials[materialIndex];
var glTFMaterial = model.json.materials[materialIndex];
for (var lightIndex in model.json.extras.lights) {

// Enable alpha test.
clayMaterial.define('fragment', 'ALPHA_TEST');
clayMaterial.set('alphaCutoff', 0.8);
var light = model.json.extras.lights[lightIndex];

// Add artificial light.
PBR.Viewport.artificialLights.push(app.createPointLight(

// Set parallax maps.
if ( glTFMaterial.extras && glTFMaterial.extras.parallaxOcclusionTextureURI ) {
// XXX XYZ to XZ-Y
new clay.Vector3(light.position.x, light.position.z, -light.position.y),
100,
PBR.Viewport.rgbToHex(light.color.r, light.color.g, light.color.b),
1
));

app.loadTexture(glTFMaterial.extras.parallaxOcclusionTextureURI, {
convertToPOT: true,
anisotropic: 16,
flipY: false
}).then(function (parallaxOcclusionTexture) {
clayMaterial.set('parallaxOcclusionMap', parallaxOcclusionTexture);
clayMaterial.set('parallaxOcclusionScale', 0.05);
clayMaterial.set('parallaxMinLayers', 50);
clayMaterial.set('parallaxMaxLayers', 50);
});
}

}
}

}
for (var materialIndex = 0; materialIndex < model.materials.length; materialIndex++) {

var clayMaterial = model.materials[materialIndex];
var glTFMaterial = model.json.materials[materialIndex];

// Enable alpha test.
clayMaterial.define('fragment', 'ALPHA_TEST');
clayMaterial.set('alphaCutoff', 0.8);

});
// Set parallax maps.
if ( glTFMaterial.extras && glTFMaterial.extras.parallaxOcclusionTextureURI ) {

app.loadTexture(glTFMaterial.extras.parallaxOcclusionTextureURI, {
convertToPOT: true,
anisotropic: 16,
flipY: false
}).then(function (parallaxOcclusionTexture) {
clayMaterial.set('parallaxOcclusionMap', parallaxOcclusionTexture);
clayMaterial.set('parallaxOcclusionScale', 0.05);
clayMaterial.set('parallaxMinLayers', 50);
clayMaterial.set('parallaxMaxLayers', 50);
});

}

}


});

});

},

Expand All @@ -186,6 +235,21 @@ PBR.Viewport.app = clay.application.create('#app', {

});

/**
* Translate Viewport app strings.
*
* @see assets/sketchup-locale.json
*/
PBR.Viewport.translateStrings = function() {

document.title = sketchUpLocale.document_title;

var helpLink = document.getElementById('helpLink');

helpLink.href = sketchUpLocale.help_link_href;
helpLink.textContent = sketchUpLocale.help_link_text;

};

// When document is ready:
document.addEventListener('DOMContentLoaded', function() {
Expand Down
7 changes: 6 additions & 1 deletion source/pbr/app_observer.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Physically-Based Rendering extension for SketchUp 2017 or newer.
# Copyright: © 2018 Samuel Tallet-Sabathé <samuel.tallet@gmail.com>
# Copyright: © 2019 Samuel Tallet <samuel.tallet arobase gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
Expand All @@ -21,6 +21,7 @@
unless RUBY_VERSION.to_f >= 2.2 # SketchUp 2017 includes Ruby 2.2.4.

require 'sketchup'
require 'pbr/lights'
require 'pbr/viewport'

# PBR plugin namespace.
Expand All @@ -34,13 +35,17 @@ class AppObserver < Sketchup::AppObserver
# When SketchUp user creates a new, empty model.
def onNewModel(_model)

Sketchup.active_model.layers.add(Lights::LAYER_NAME)

Viewport.reopen if Viewport.update_model

end

# When SketchUp user opens an existing model:
def onOpenModel(_model)

Sketchup.active_model.layers.add(Lights::LAYER_NAME)

Viewport.reopen if Viewport.update_model

end
Expand Down
25 changes: 25 additions & 0 deletions source/pbr/gltf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
require 'sketchup'
require 'fileutils'
require 'json'
require 'pbr/lights'

# PBR plugin namespace.
module PBR
Expand Down Expand Up @@ -101,13 +102,20 @@ def json
gltfile = File.join(Sketchup.temp_dir, 'SketchUpModel.gltf')

File.delete(gltfile) if File.exist?(gltfile)

Sketchup.active_model.layers.add(Lights::LAYER_NAME)

# XXX We hide 'PBR Lights' layer to avoid glTF model "pollution".
Sketchup.active_model.layers[Lights::LAYER_NAME].visible = false

Centaur::GltfExporter::GltfExport.new.export(
false, # is_binary
false, # is_microsoft
gltfile # destination
)

Sketchup.active_model.layers[Lights::LAYER_NAME].visible = true

# Store asset as a Hash.
@gltf = JSON.parse(File.read(gltfile))

Expand Down Expand Up @@ -141,6 +149,8 @@ def json

end

add_lights

# Tools that generated this glTF model. Useful for debugging.
@gltf['asset']['generator'] += ", SketchUp PBR plugin v#{VERSION}"

Expand Down Expand Up @@ -333,6 +343,21 @@ def json

end

# Adds extra lights. XXX This isn't in the spec.
#
# @return [void]
private def add_lights

lights = Lights.all

return if lights.empty?

@gltf['extras'] = {} unless @gltf.key?('extras')

@gltf['extras']['lights'] = lights

end

end

end
Loading

0 comments on commit b76cb7d

Please sign in to comment.