diff --git a/deploy/cameras.json b/deploy/cameras.json index 5f3699a..a6ad8b0 100644 --- a/deploy/cameras.json +++ b/deploy/cameras.json @@ -121,7 +121,6 @@ "description": "", "sources": [ "https://www.arri.com/en/camera-systems/cameras/alexa-35", - "https://www.arri.com/en/camera-systems/cameras/alexa-35/alexa-35-recording-formats", "https://www.arri.com/resource/blob/296424/88454a5a3dee9fe1d3fd68e75aa3411e/alexa-35-recording-format-poster-data.pdf", "https://www.arri.com/resource/blob/277386/a8ebd70f6105162b541bc39f4ad098b5/2022-05-arri-formatsandresolutionsoverview-4-4-data.pdf" ], @@ -1065,7 +1064,7 @@ "https://en.wikipedia.org/wiki/Canon_EOS-1D_X_Mark_II", "https://en.wikipedia.org/wiki/Canon_EOS-1D_X_Mark_III", "https://www.canon-europe.com/for_home/product_finder/cameras/digital_slr/eos_1dx/specifications/", - "https://github.com/wetadigital/physlight/blob/main/data/Canon_EOS_1DX_Mark_II_380_780_5.json" + "https://github.com/wetadigital/physlight/blob/main/data/Canon_EOS-1D_X_Mark_II_380_780_5.json" ], "tags": ["full frame"] }, @@ -1469,7 +1468,6 @@ "category": ["Mobile"], "description": "", "sources": [ - "https://www.hasselblad.com/collaborations/dji-mavic-2-pro/", "https://forum.dji.com/forum.php?mod=redirect&goto=findpost&ptid=167017&pid=1576410", "https://dl.djicdn.com/downloads/Mavic_2/Mavic_2_Pro_Zoom_User_Manual_v2.2_en.pdf", "https://github.com/wetadigital/physlight/blob/main/data/Hasselblad_L1D-20c_380_780_5.json" @@ -2111,7 +2109,7 @@ "description": "", "sources": [ "https://en.wikipedia.org/wiki/Leica_S-System", - "https://leica-camera.com/en-SG/photography/cameras/s/s3-black/" + "https://leicacamerausa.com/leica-s3.html" ], "tags": ["medium format"] }, diff --git a/deploy/index.html b/deploy/index.html index f9ce07b..c334fad 100644 --- a/deploy/index.html +++ b/deploy/index.html @@ -54,7 +54,7 @@ =12.0" + } + }, "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", diff --git a/package.json b/package.json index 3c659ea..1df54c5 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,8 @@ "scripts": { "http": "http-server -o deploy", "http-v2": "http-server -o deploy/v2", - "image-processor": "node scripts/image-processor.js " + "image-processor": "node scripts/image-processor.js ", + "create-materialx": "node scripts/create-materialx.js " }, "repository": { "type": "git", @@ -18,6 +19,7 @@ }, "homepage": "https://api.physicallybased.info/", "devDependencies": { + "adm-zip": "^0.5.16", "http-server": "^14.1.1", "sharp": "^0.33.5" } diff --git a/deploy/openapi-schema-v2.yaml b/schemas/openapi-schema-v2.yaml similarity index 90% rename from deploy/openapi-schema-v2.yaml rename to schemas/openapi-schema-v2.yaml index 4c18796..7197cbb 100644 --- a/deploy/openapi-schema-v2.yaml +++ b/schemas/openapi-schema-v2.yaml @@ -2,7 +2,7 @@ openapi: 3.1.0 info: version: 2.0-alpha title: Physically Based API - description: "\U0001F6A7 V2.0 IS UNDER DEVELOPMENT. FOR TESTING USE ONLY. \U0001F6A7\n\nThis is a database of physically based values for CG artists.\n\nIt's made available under the [CC0 1.0](https://creativecommons.org/publicdomain/zero/1.0/legalcode) license, which means you are free to use, modify, and distribute its content without any restrictions, even for commercial purposes. \n\nIdeally, the data is to be consumed by DCC applications in the form of plug-ins, or any other form that makes sense. It's also available to browse on the web at https://physicallybased.info\n\nFor additions or changes, feel free to make a Pull Request on Github at https://github.com/AntonPalmqvist/physically-based-api or send me a message through the [contact form.](https://physicallybased.info/about/)\n\nSchema: https://github.com/AntonPalmqvist/physically-based-api/blob/main/deploy/openapi-schema.yaml" + description: "\U0001F6A7 2.0 IS UNDER DEVELOPMENT. FOR TESTING USE ONLY. \U0001F6A7\n\nThis is a database of physically based values for CG artists.\n\nIt's made available under the [CC0 1.0](https://creativecommons.org/publicdomain/zero/1.0/legalcode) license, which means you are free to use, modify, and distribute its content without any restrictions, even for commercial purposes. \n\nIdeally, the data is to be consumed by DCC applications in the form of plug-ins, or any other form that makes sense. It's also available to browse on the web at https://physicallybased.info\n\nFor additions or changes, feel free to make a Pull Request on Github at https://github.com/AntonPalmqvist/physically-based-api or send me a message through the [contact form.](https://physicallybased.info/about/)\n\nSchema: https://github.com/AntonPalmqvist/physically-based-api/blob/main/schemas/openapi-schema-v2.yaml" contact: url: 'https://physicallybased.info/about' name: Form @@ -101,14 +101,35 @@ components: description: Name of the material. default: Name color: - $ref: '#/components/schemas/color' - description: 'Specifies the diffuse or metallic reflectance color, or in the case of a transparent material, transmission color. RGB triplet in decimal format in linear sRGB color space.' + type: array + description: 'Specifies the diffuse or metallic reflectance color, or in the case of a transparent material, transmission color.' + minItems: 1 + uniqueItems: true + items: + $ref: '#/components/schemas/color' metalness: type: number description: Specifies how metallic the material appears (dials the shading model from pure dielectric to pure metal). specularColor: - $ref: '#/components/schemas/color' - description: 'Color of the specular reflection for metals, specified in the "Gulbrandsen edge tint" format. Calculated from spectral data using script from https://github.com/natyh/material-params' + type: array + description: 'Color of the specular reflection for metals, specified in the \"Gulbrandsen edge tint\", and \"F82\" formats. Calculated from spectral data using scripts from https://github.com/natyh/material-params and https://github.com/portsmouth/F82-tint-generator' + minItems: 2 + uniqueItems: true + items: + type: object + properties: + format: + type: string + enum: + - Gulbrandsen + - F82 + color: + type: array + items: + $ref: '#/components/schemas/color' + required: + - format + - color roughness: type: number description: 'The roughness of the specular reflection. Lower numbers produce sharper reflections, higher numbers produce blurrier reflections.' @@ -127,11 +148,23 @@ components: description: 'Abbe number, describing how much the index of refraction varies across wavelengths. For glass and diamonds, this is typically in the range of 10 to 70, with lower numbers giving more dispersion.' complexIor: type: array - description: 'Complex IOR values, n (refractive index), and k (extinction coefficient), for each color channel, in the following order: nR, kR, nG, kG, nB, kB. Calculated from spectral IOR data files.' - minItems: 6 - maxItems: 6 + description: 'Complex IOR values, n (refractive index), and k (extinction coefficient), for each color channel, in the following order: nR, kR, nG, kG, nB, kB. Calculated from spectral IOR data files with script from https://github.com/natyh/material-params' items: - type: number + type: object + properties: + colorSpace: + type: string + description: The color space for which the n and k values have been calculated for. + nk: + type: array + description: 'N and k values for each RGB color channel in the following order: nR, kR, nG, kG, nB, kB.' + minItems: 6 + maxItems: 6 + items: + type: number + required: + - colorSpace + - nk thinFilmThickness: type: array description: 'The thickness of the thin film layer on the base (in nanometers). If there''s no variation, only one value should be specified. A range can be specified with two values. A third value can be added to specify the most common thickness.' @@ -280,12 +313,23 @@ components: '600': 'https://raw.githubusercontent.com/AntonPalmqvist/physically-based-api/main/images/renders/cycles/600/aluminum.avif' format: avif color: - type: array + type: object title: color - minItems: 3 - maxItems: 3 - items: - type: number + properties: + colorSpace: + type: string + description: The color space. + default: srgb-linear + color: + type: array + description: RGB triplet (vec3) in decimal format. + minItems: 3 + maxItems: 3 + items: + type: number + required: + - colorSpace + - color description: type: string title: description diff --git a/deploy/openapi-schema.yaml b/schemas/openapi-schema.yaml similarity index 98% rename from deploy/openapi-schema.yaml rename to schemas/openapi-schema.yaml index 6f81425..52c11f3 100644 --- a/deploy/openapi-schema.yaml +++ b/schemas/openapi-schema.yaml @@ -11,7 +11,9 @@ info: For additions or changes, feel free to make a Pull Request on Github at https://github.com/AntonPalmqvist/physically-based-api or send me a message through the [contact form.](https://physicallybased.info/about/) - Schema: https://github.com/AntonPalmqvist/physically-based-api/blob/main/deploy/openapi-schema.yaml + Schema: https://github.com/AntonPalmqvist/physically-based-api/blob/main/schemas/openapi-schema.yaml + + API v2 available for testing at: https://api.physicallybased.info/v2/ contact: url: 'https://physicallybased.info/about' name: Form @@ -94,7 +96,7 @@ components: default: Name color: $ref: '#/components/schemas/color' - description: 'The albedo of non-metals, or reflection color of metals, RGB triplet in linear decimal format with rec709 primaries.' + description: 'Specifies the diffuse or metallic reflectance color, or in the case of a transparent material, transmission color. RGB triplet (vec3) in linear decimal format in rec709 primaries.' metalness: type: number description: Specifies how metallic the material appears (dials the shading model from pure dielectric to pure metal). @@ -119,7 +121,7 @@ components: description: 'Abbe number, describing how much the index of refraction varies across wavelengths. For glass and diamonds, this is typically in the range of 10 to 70, with lower numbers giving more dispersion.' complexIor: type: array - description: 'Complex IOR values, n (refractive index), and k (extinction coefficient), for each color channel, in the following order: nR, kR, nG, kG, nB, kB. Calculated from spectral IOR data files.' + description: 'Complex IOR values, n (refractive index), and k (extinction coefficient), for each color channel, in the following order: nR, kR, nG, kG, nB, kB. Calculated from spectral IOR data files with script from https://github.com/natyh/material-params' minItems: 6 maxItems: 6 items: diff --git a/schemas/schema-lightsources-v2.json b/schemas/schema-lightsources-v2.json index 228552c..31e9400 100644 --- a/schemas/schema-lightsources-v2.json +++ b/schemas/schema-lightsources-v2.json @@ -14,12 +14,30 @@ "color": { "description": "Color of the light source.", "type": "array", + "minItems": 1, + "uniqueItems": true, "items": { - "type": "number" - }, - "default": [1, 1, 1], - "minItems": 3, - "maxItems": 3 + "additionalProperties": false, + "type": "object", + "properties": { + "colorSpace": { + "description": "The color space.", + "type": "string", + "default": "srgb-linear" + }, + "color": { + "description": "RGB triplet (vec3) in decimal format.", + "type": "array", + "items": { + "type": "number" + }, + "default": [1, 1, 1], + "minItems": 3, + "maxItems": 3 + } + }, + "required": ["colorSpace", "color"] + } }, "temperature": { "description": "The typical range of color temperature in Kelvin, if color lies on the Planckian curve. If there's no variation, only one value should be specified. A range can be specified with two values. A third value can be added to specify the most common temperature.", @@ -56,7 +74,7 @@ "default": 90 }, "sourceSize": { - "description": "The size of the light source in centimeters. [Radius] if point or spot. [Width, Height] if surface. [Length, Radius] if cylinder.", + "description": "The size of the light source in centimeters. [Radius] if point or spot. [Width, Height] if surface. [Radius, Length] if cylinder.", "type": "array", "items": { "type": "number" @@ -96,12 +114,30 @@ "color": { "description": "Color of the light source.", "type": "array", + "minItems": 1, + "uniqueItems": true, "items": { - "type": "number" - }, - "default": [1, 1, 1], - "minItems": 3, - "maxItems": 3 + "additionalProperties": false, + "type": "object", + "properties": { + "colorSpace": { + "description": "The color space.", + "type": "string", + "default": "srgb-linear" + }, + "color": { + "description": "RGB triplet (vec3) in decimal format.", + "type": "array", + "items": { + "type": "number" + }, + "default": [1, 1, 1], + "minItems": 3, + "maxItems": 3 + } + }, + "required": ["colorSpace", "color"] + } }, "temperature": { "description": "Color temperature in Kelvin, if color lies on the Planckian curve.", diff --git a/schemas/schema-materials-v2.json b/schemas/schema-materials-v2.json index 06c67e7..2a42cc9 100644 --- a/schemas/schema-materials-v2.json +++ b/schemas/schema-materials-v2.json @@ -12,14 +12,32 @@ "default": "Name" }, "color": { - "description": "Albedo, or metal color, RGB triplet (vec3) in linear decimal format in rec709 primaries.", + "description": "Specifies the diffuse or metallic reflectance color, or in the case of a transparent material, transmission color.", "type": "array", + "minItems": 1, + "uniqueItems": true, "items": { - "type": "number" - }, - "default": [0.5, 0.5, 0.5], - "minItems": 3, - "maxItems": 3 + "additionalProperties": false, + "type": "object", + "properties": { + "colorSpace": { + "description": "The color space.", + "type": "string", + "default": "srgb-linear" + }, + "color": { + "description": "RGB triplet (vec3) in decimal format.", + "type": "array", + "items": { + "type": "number" + }, + "default": [0.5, 0.5, 0.5], + "minItems": 3, + "maxItems": 3 + } + }, + "required": ["colorSpace", "color"] + } }, "metalness": { "description": "Specifies how metallic the material appears (dials the shading model from pure dielectric to pure metal).", @@ -27,14 +45,52 @@ "default": 0 }, "specularColor": { - "description": "Color of the specular reflection for metals, specified in the \"Gulbrandsen edge tint\" format. Calculated from spectral data using script from https://github.com/natyh/material-params", + "description": "Color of the specular reflection for metals, specified in the \"Gulbrandsen edge tint\", and \"F82\" formats. Calculated from spectral data using scripts from https://github.com/natyh/material-params and https://github.com/portsmouth/F82-tint-generator", "type": "array", + "minItems": 2, + "uniqueItems": true, "items": { - "type": "number" - }, - "default": [1, 1, 1], - "minItems": 3, - "maxItems": 3 + "additionalProperties": false, + "type": "object", + "properties": { + "format": { + "type": "array", + "items": { + "enum": ["Gulbrandsen", "F82"] + }, + "minItems": 1, + "maxItems": 1 + }, + "color": { + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": { + "additionalProperties": false, + "type": "object", + "properties": { + "colorSpace": { + "description": "The color space.", + "type": "string", + "default": "srgb-linear" + }, + "color": { + "description": "RGB triplet (vec3) in decimal format.", + "type": "array", + "items": { + "type": "number" + }, + "default": [0.5, 0.5, 0.5], + "minItems": 3, + "maxItems": 3 + } + }, + "required": ["colorSpace", "color"] + } + } + }, + "required": ["format", "color"] + } }, "roughness": { "description": "The roughness of the specular reflection. Lower numbers produce sharper reflections, higher numbers produce blurrier reflections.", @@ -67,14 +123,32 @@ "default": 0 }, "complexIor": { - "description": "Complex IOR values, n (refractive index), and k (extinction coefficient), for each color channel, in the following order: nR, kR, nG, kG, nB, kB. Calculated from spectral data using script from https://github.com/natyh/material-params", + "description": "Complex IOR values, n (refractive index), and k (extinction coefficient), for each color channel, in the following order: nR, kR, nG, kG, nB, kB. Calculated from spectral IOR data files with script from https://github.com/natyh/material-params", "type": "array", + "minItems": 1, + "uniqueItems": true, "items": { - "type": "number" - }, - "default": [0, 0, 0, 0, 0, 0], - "minItems": 6, - "maxItems": 6 + "additionalProperties": false, + "type": "object", + "properties": { + "colorSpace": { + "description": "The color space for which the n and k values have been calculated for.", + "type": "string", + "default": "srgb-linear" + }, + "nk": { + "description": "N and k values for each RGB color channel in the following order: nR, kR, nG, kG, nB, kB.", + "type": "array", + "items": { + "type": "number" + }, + "default": [0, 0, 0, 0, 0, 0], + "minItems": 6, + "maxItems": 6 + } + }, + "required": ["colorSpace", "nk"] + } }, "thinFilmThickness": { "description": "The thickness of the thin film layer on the base (in nanometers). If there's no variation, only one value should be specified. A range can be specified with two values. A third value can be added to specify the most common thickness.", diff --git a/schemas/schema-materials.json b/schemas/schema-materials.json index 9353cd8..d92f121 100644 --- a/schemas/schema-materials.json +++ b/schemas/schema-materials.json @@ -12,7 +12,7 @@ "default": "Name" }, "color": { - "description": "Albedo, or metal color, RGB triplet (vec3) in linear decimal format in rec709 primaries.", + "description": "Specifies the diffuse or metallic reflectance color, or in the case of a transparent material, transmission color. RGB triplet (vec3) in linear decimal format in rec709 primaries.", "type": "array", "items": { "type": "number" @@ -67,7 +67,7 @@ "default": 0 }, "complexIor": { - "description": "Complex IOR values, n (refractive index), and k (extinction coefficient), for each color channel, in the following order: nR, kR, nG, kG, nB, kB. Calculated from spectral data using script from https://github.com/natyh/material-params", + "description": "Complex IOR values, n (refractive index), and k (extinction coefficient), for each color channel, in the following order: nR, kR, nG, kG, nB, kB. Calculated from spectral IOR data files with script from https://github.com/natyh/material-params", "type": "array", "items": { "type": "number" diff --git a/scripts/create-materialx.js b/scripts/create-materialx.js new file mode 100644 index 0000000..2f240b4 --- /dev/null +++ b/scripts/create-materialx.js @@ -0,0 +1,123 @@ +const fs = require("node:fs"); +const AdmZip = require("adm-zip"); + +const materialxVersion = "1.39"; +const outputFile = "MaterialX-v" + materialxVersion + "_OpenPBR.zip"; +const tempFolder = "./tmp/"; + +function createFiles() { + return new Promise((resolve, reject) => { + fs.readFile("./deploy/v2/materials.json", "utf8", (err, data) => { + if (err) { + console.error(err); + reject(err); + return; + } + + // prettier-ignore + function makeMaterialX( + hit + ) { + const baseColor = JSON.stringify(hit.color[0].color) !== JSON.stringify([0.8, 0.8, 0.8]) && !hit.transmission && !hit.subsurfaceRadius ? ' \n' : ""; + const metalness = hit.metalness > 0 ? ' \n' : ""; + const specularColor = hit.specularColor ? ' \n' : ""; + const roughness = hit.roughness != 0.3 ? ' \n' : ""; + const specularIor = hit.ior && hit.metalness < 1 && hit.ior != 1.5 ? ' \n' : ""; + const transmission = hit.transmission ? ' \n' : ""; + const transmissionColor = hit.transmission && JSON.stringify(hit.color[0].color) !== JSON.stringify([1, 1, 1]) ? ' \n' : ""; + const transmissionDispersion = hit.transmissionDispersion ? ' \n' : ""; + const transmissionDispersionAbbeNumber = hit.transmissionDispersion ? ' \n' : ""; + const subsurface = hit.subsurfaceRadius ? ' \n' : ""; + const subsurfaceColor = hit.subsurfaceRadius ? ' \n' : ""; + const subsurfaceRadiusScale = hit.subsurfaceRadius ? ' \n' : ""; + const thinFilmWeight = hit.thinFilmThickness ? ' \n' : ""; + const thinFilmThickness = hit.thinFilmThickness && hit.thinFilmThickness[2] ? ' \n' : hit.thinFilmThickness && hit.thinFilmThickness[0] ? ' \n' : ""; + const thinFilmIor = hit.thinFilmIor ? ' \n' : ""; + const thinWalled = hit.thinFilmThickness && hit.transmission ? ' \n' : ""; + let xml = + // Commented lines are values that are not used and therefore removed to follow best practices for MaterialX "preset" functionality https://academysoftwarefdn.slack.com/archives/C0230LWBE2X/p1660682953141679?thread_ts=1660168970.997769&cid=C0230LWBE2X + '\n' + + '\n' + + ' \n' + + ' \n' + + ' \n' + + ' \n' + + baseColor + + //' \n' + + metalness + + //' \n' + + specularColor + + roughness + + specularIor + + // ' \n' + + transmission + + transmissionColor + + //' \n' + + //' \n' + + //' \n' + + transmissionDispersion + + transmissionDispersionAbbeNumber + + subsurface + + subsurfaceColor + + //' \n' + + subsurfaceRadiusScale + + //' \n' + + //' \n' + + //' \n' + + //' \n' + + //' \n' + + thinFilmWeight + + thinFilmThickness + + thinFilmIor + + //' \n' + + thinWalled + + ' \n' + + ''; + + return xml; + } + + JSON.parse(data).forEach((element) => { + if (!fs.existsSync(tempFolder)) { + fs.mkdirSync(tempFolder, { recursive: true }); + } + const fileName = + tempFolder + + element.name.replace(/ |-|\./g, "_").replace(/[()]/g, "") + + ".mtlx"; + fs.writeFile(fileName, makeMaterialX(element), (err) => { + if (err) { + console.error(err); + reject(err); + } else { + console.log(fileName + " created"); + resolve(); + } + }); + }); + }); + }); +} + +function zipFiles() { + const zip = new AdmZip(); + zip.addLocalFolder(tempFolder); + zip.writeZip(outputFile); +} + +async function main() { + try { + await createFiles(); + zipFiles(); + console.log("Created " + outputFile + " successfully"); + + if (fs.existsSync(tempFolder)) { + fs.rmSync(tempFolder, { recursive: true, force: true }); + console.log("Deleted " + tempFolder + " folder successfully"); + } + } catch (err) { + console.error("An error occurred:", err); + } +} + +main();