# Welcome

Welcome to the API Access section of the documentation. This API is designed to help developers seamlessly integrate **colormass** into their applications, enabling advanced data management, configurator integration, and exporting functionalities. With our API, you can create custom workflows, automate processes, and build tailored solutions to suit your business needs.

## Jump right in

<table data-card-size="large" data-view="cards" data-full-width="false"><thead><tr><th></th><th></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Configurator</strong></td><td>Integrate configurators into your website.</td><td><a href="/files/QZU091soTqV4il5HJbIt">/files/QZU091soTqV4il5HJbIt</a></td><td></td><td><a href="/pages/W1cri26jmNYwSAYwV31L">/pages/W1cri26jmNYwSAYwV31L</a></td></tr><tr><td><strong>Data Exporter</strong></td><td>Integrate automatic outputs into your website.</td><td><a href="/files/RT6MKOqoLsVl2UKLIudZ">/files/RT6MKOqoLsVl2UKLIudZ</a></td><td></td><td><a href="/pages/YBo8QV1EAmG6LOZOIHc7">/pages/YBo8QV1EAmG6LOZOIHc7</a></td></tr></tbody></table>

## Configurator

In the configurator documentation you can learn about the ways you can integrate colormass configurators into your website. There are various levels of integration, starting from changing basic styling elements of our components until completely using your own UI and only communicating with the 3D viewer through an API.

Just to provide an example you can find the following custom configurators that were integrated using the colormass API.

* [**Designtex DDS**](https://designtex.com/digital-studio/): This custom application empowers users to visualize customized patterns in real time, offering a dynamic and interactive experience. This visualization capability is seamlessly integrated with Designtex's ecommerce platform, streamlining the process of pattern selection and customization for users. Ultimately, this system results in the production of the desired pattern, which is a printed sample.
* [**VADO Vanity Builder**](https://www.vado.com/cameo-vanity-builder)**:** This configurator was assembled utilizing the colormass 3D backend and seamlessly integrated via the colormass API. The frontend of the configurator was created by VADO to ensure perfect alignment with the brand.

Learn more about configurator integrations [here](/dev/configurator/introduction).

## Data Exporter

* [**Designtex Downloads**](https://shop.designtex.com/circulate/): If you visit any of the product pages of Designtex. You can find that the material exports are integrated into the website, eliminating the need to always download and upload files to the CMS.

<figure><img src="/files/7GzljA3HXCegfp3DQ8ud" alt="" width="375"><figcaption></figcaption></figure>

* [**Maharam Downloads**](https://www.maharam.com/maharam/products/flex/colors/005-weaver)**:** Similarly on the Maharam product pages you will also see that material exports are directly integrated into the website.

<figure><img src="/files/3SgQeovKNAK8bUEb9SMa" alt="" width="70"><figcaption></figcaption></figure>

Learn more about data integrations [here](/dev/data-exporter/integration).

{% hint style="info" %}
If you would like to create Configurators or Exports of your material then please head to the [Tutorials](https://docs.colormass.com/) section of the documentation.
{% endhint %}


# Introduction

{% embed url="<https://vimeo.com/458968347>" %}

The colormass Configurator for Businesses, developed on top of colormass' proprietary life-like visualization technology and data management infrastructure, is a simple and cost effective way to display products in a photorealistic way. It works on almost any device, without plugins. To learn more, visit the [colormass Configurator page](https://www.colormass.com/3d-configurator).

This documentation is intended for anyone who would like to integrate the configurator on their website or e-commerce solution. The most basic integration is possible without any coding skills as described in Getting Started . If you are interested in customizing the user interface or connecting the configurator with your existing website's or webshop's logic, visit the Advanced Integration page.

{% hint style="info" %}
If you have any questions, feel free to send an email to <support@colormass.com> or call us at +49 30 6920 6200.
{% endhint %}


# Web Components

**Web Components**

This section provides an overview of integrating the configurator into your website using web components. Unlike iframe integration, web components allow for a more seamless adaptation to your website's design and offer greater control over the configurator programmatically. If your requirement is solely to display the configurator, iframe integration might be simpler, particularly when utilizing a Content Management System (CMS).


# Getting Started

The configurator and its accompanying menu are integrated into your website as web components. Think of a web component as a tailor-made HTML tag that seamlessly integrates into your HTML document or web application. Unlike the previous iframe-based configurator integration, with web components, the menu's placement can be freely adjusted, independent of the configurator. Moreover, you have the flexibility to customize its appearance to align with the overall aesthetics of your website. The simplest integration resembles the following:

{% code lineNumbers="true" fullWidth="false" %}

```html
<!DOCTYPE html>
<html style="height: 100%">
  <head>
    <!-- Load default styles, icons and fonts required by the configurator -->
    <link
      href="https://configurator.colormass.com/styles.css"
      rel="stylesheet"
    />
    <!-- The configurator web components are contained in the following module -->
    <script
      src="https://configurator.colormass.com/cm-configurator.js"
      type="module"
    ></script>
  </head>
  <body style="width: 100%; height: 100%; margin: 0; font-family: Roboto">
    <!-- This is the actual web component, template-uuid specifies the configurator to load -->
    <cm-configurator-main
      template-uuid="8ee95263-fd7c-40fc-b99f-08961594e14e"
    ></cm-configurator-main>
  </body>
</html>
```

{% endcode %}

In this example, we load the required default styles for the configurator and the configurator Javascript module. Note that some parts of the configurator can be [customised through CSS](/dev/configurator/web-components/styling) in order to match your pages style.

The above example shows a standalone html document. The integration into a CMS like wordpress works similar, but usually requires CMS-specific html containers.

## Separate Menu

If you want to use the menu separately, you can load it as additional web component and place it anywhere in your current website. Note that this requires to set the HTML attribute `use-external-menu="true"` on the configurator element to prevent flashing of the configurator's "internal" menu. The example changes to:

{% code lineNumbers="true" %}

```html
<!DOCTYPE html>
<html style="height: 100%">
  <head>
    <link
      href="https://configurator.colormass.com/styles.css"
      rel="stylesheet"
    />
    <script
      src="https://configurator.colormass.com/cm-configurator.js"
      type="module"
    ></script>

    <style>
      .container {
        display: flex;
        height: 100%;
        overflow: hidden;
      }

      .menu {
        justify-content: center;
        width: 20%;
        background-color: #f4f4f4;
        overflow: hidden;
        display: flex;
        flex-direction: column;
        align-items: flex-start;
        min-width: 400px;
      }

      .configurator-container {
        flex-grow: 1;
        box-sizing: border-box;
      }
    </style>
  </head>
  <body style="width: 100%; height: 100%; margin: 0; font-family: Roboto">
    <div class="container">
      <div class="menu">
        <!-- Separate web component for the menu -->
        <cm-configurator-menu style="width: 100%"></cm-configurator-menu>
      </div>
      <div class="configurator-container">
        <cm-configurator-main
          template-uuid="8ee95263-fd7c-40fc-b99f-08961594e14e"
          use-external-menu="true"
        ></cm-configurator-main>
      </div>
    </div>
  </body>
</html>
```

{% endcode %}


# Advanced Integration

The configurator can be controlled programmatically by calling functions on the web component. You can use this API to for example to change configurations or to take a screenshot.

## Basic Example

The following example loads a specific configurator by calling a function on the element instead of specifying the template uuid as html attribute:

{% code lineNumbers="true" %}

```html
<!DOCTYPE html>
<html style="height: 100%">
    <head>
        <link href="https://configurator.colormass.com/styles.css" rel="stylesheet" />
        <script src="https://configurator.colormass.com/cm-configurator.js" type="module" />

        <script>
            customElements.whenDefined("cm-configurator-main").then(() => {
                //get the configurator element
                const cmConfigurator = document.querySelector("cm-configurator-main")
				
                //call a function on the object
                cmConfigurator.loadConfigurator("8ee95263-fd7c-40fc-b99f-08961594e14e")
            })
        </script>
    </head>
    <body style="width: 100%; height: 100%; margin: 0; font-family: Roboto">
        <cm-configurator-main></cm-configurator-main>
    </body>
</html>
```

{% endcode %}

We use the Custom Elements Api here (`customElements.whenDefined`) to make sure the functions are available.

There is a more elaborate example available in the [sample repository](https://github.com/colormass/samples/tree/prod/configurator-webcomponents/api). In the repository, there is also a cm-configurator.d.ts file, which lists all available functions.

A limitation of the web components currently is that they cannot immediately load a specific configuration. In case of the iframe configurator, this can be achieved with query parameters of the url. Should this feature be required, it can be added short-term.

## Listening to Events

In order to get notified when something happens on the configurator, you can register different event listeners. The following code registers a callback that is invoked when the scene has finished loading:

{% code lineNumbers="true" %}

```html
<script>
	customElements.whenDefined("cm-configurator-main").then(() => {
		cmConfigurator = document.querySelector("cm-configurator-main")

		//Register an event listener and print the parameters available for the current configurator
		cmConfigurator.addEventListener("loadingCompleted", (event) => {
			console.log(cmConfigurator.getParameterList())
		})

		cmConfigurator.loadConfigurator("8ee95263-fd7c-40fc-b99f-08961594e14e")
	})
</script>
```

{% endcode %}

The full section of the previous example is contained for context. After the scene provided to loadConfigurator has finished loading, the configurator will print all available parameters on the console. You can use those parameters to change configurations programmatically.

## Changing Configurations

With the API of the web component, it is possible to change configurations dynamically without clicking on an item in the menu. For this purpose, you can use the parameters returned by cmConfigurator.getParameterlist(). Here is the (shortened) list of the parameters that was printed by the previous example:

{% code lineNumbers="true" %}

```json
[
    {
        "id": "0fb20bb9-2284-4a8b-b6e0-db02ebc36742/ced9d80c-7103-43f2-a5ba-2d90e0c823b3",
        "type": "config",
        "name": "Seat",
        "values": [
            {
                "id": "3d7420d9-6117-428f-ba41-890ecd157f8e",
                "name": "Blazer Darthmouth"
            },
            {
                "id": "e6ddc079-8026-4e4f-95ca-6e2be019a0f6",
                "name": "Oceanic Atoll"
            },
            {
                "id": "18479bf9-e393-4da9-9fc9-dfb37077550b",
                "name": "Lucia Tenom"
            },
        ],
        "value": "087612ab-9a50-43e3-8626-b1c37322b499"
    },
    {
        "id": "0fb20bb9-2284-4a8b-b6e0-db02ebc36742/60a5a88a-7701-4c10-819e-deb5f87f15c4",
        "type": "config",
        "name": "Back",
        "values": [
            {
                "id": "c93e318c-88ee-4e8c-9b56-9c7075f53784",
                "name": "Main Line Flax Bayswater"
            },
            {
                "id": "4c190056-bc69-49f5-a081-c82a86658124",
                "name": "Synergy Quilt Chemistry"
            },
        ],
        "value": "42763086-b3e6-48cb-ac63-2172f2245bf9"
    }
]
```

{% endcode %}

The configurator of this example has two configuration groups: *Back \_and \_seat*. Each has multiple variants. This is reflected in the above json array. In order to set those groups programmatically, you can use the following code:

{% code lineNumbers="true" %}

```javascript
<script>
	customElements.whenDefined("cm-configurator-main").then(() => {
		cmConfigurator = document.querySelector("cm-configurator-main")

		cmConfigurator.addEventListener("loadingCompleted", (event) => {
			console.log(cmConfigurator.getParameterList())

			//Switch the seat upholstery to "Velocity Polar"
			cmConfigurator.setParameter(
				"0fb20bb9-2284-4a8b-b6e0-db02ebc36742/ced9d80c-7103-43f2-a5ba-2d90e0c823b3",
				"config",
				"1d9f7d3d-3823-4224-a3f7-62028295080f",
			)
		})
		cmConfigurator.loadConfigurator("8ee95263-fd7c-40fc-b99f-08961594e14e")
	})
</script>
```

{% endcode %}

The full api is illustrated in the [samples repository](https://github.com/colormass/samples/tree/prod/configurator-webcomponents)


# Styling

Web components provided by us can be seamlessly integrated and styled to align with your website's design, utilizing CSS for customization. These components leverage the shadow DOM for encapsulation, which inherently restricts direct access to their CSS classes to avoid styling conflicts with the rest of your website. Nonetheless, to facilitate customization, certain DOM elements within the configurator are exposed, enabling styling through the ::part pseudo-element. In addition to this, several CSS variables are available. The example below illustrates how to style the cm-config-group-title part within the .menu CSS class of the basic menu example:

{% code lineNumbers="true" %}

```css
.menu {
  justify-content: center;
  width: 15%;
  background-color: #f4f4f4;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  min-width: 400px;
}

/* This will change the apprearance of the configuration group titles */
.menu::part(cm-config-group-title) {
  background-color: #d78a5e;
  padding: 10px;
  color: white;
}
```

{% endcode %}

A full example with more styling options can be found in the [samples repository](https://github.com/colormass/samples/tree/configurator-webcomponents/configurator-webcomponents). This example also covers the CSS variables.

Even though the CSS classes are not directly accessible, you can see all the exposed parts in the dev tools of your browser as illustrated in the figure below:

![part-illustration.jpg](/files/dqOX1ve8rfLGkrkwlGlk)

## HTML attributes

In addition to CSS, the following HTML attributes are available, which change the appearance of the menu:

* **ui-style-override**: Changes the operation mode of the menu, available values are default, icons and accordion
* **use-captions**: Displays captions underneath the icons

For example, the following html code displays an accordion menu with captions underneath the icons, the full example is found on [github](https://github.com/colormass/samples/tree/configurator-webcomponents/configurator-webcomponents/styled%20menu).

```html
<cm-configurator-menu ui-style-override="accordion" use-captions="true" style="width: 100%"></cm-configurator-menu>
```

![image.png](/files/Vo902ErWGEOT09SxA9gn)


# Setting Parameters

Parameters let you adjust the settings of a configurator instance in two ways:

1. **Initial Parameters via HTML:** You can set an initial configuration by adding a set of parameters directly to the configurator's HTML tag. This approach is useful for loading a predefined configuration when the configurator first loads.
2. **Dynamic Parameters at Runtime:** You can also modify parameters at runtime by calling `setParameter` on the configurator. This method is helpful when building a custom menu or control interface for the configurator.

Note that colormass typically provides the necessary parameter settings, so you do not need to understand the details of the parameter format beyond those two points. The following example adds an initial parameter to the HTML tag by using the `parameters` attribute:

```html
<cm-configurator-main
	template-uuid="9f867cb8-966f-4736-9106-3cacba50b3b4"
	parameters="param(3d23006d-1eb2-47f1-a616-e357695316b8)=material(2d8709e8-d5b9-4028-86b1-d06e8575011b)"
></cm-configurator-main>
```

The same parameter can also be set at runtime:

```html
<script>
	customElements.whenDefined("cm-configurator-main").then(() => {
		cmConfigurator = document.querySelector("cm-configurator-main")
		cmConfigurator.setParameter("3d23006d-1eb2-47f1-a616-e357695316b8", "material", "2d8709e8-d5b9-4028-86b1-d06e8575011b")
	})
</script>
```

### Parameter Format

A configurator parameter is composed of three parts: `id`, `type` and `value`. Values for those parts are usually provided by colormass, but if you have access to the platform, you can also get and edit the available parameters yourself. This is covered in a separate [section below](#parameter-types-and-associated-values).

* **id:** This is a unique identifier for the parameter. This ID is usually platform-generated but can be customized for readability.
* **type:** Specifies how the configurator interprets and processes the value. Different types, like "material" or "config" determine the behavior and application of the parameter within the configurator.
* **value**: The specific value to be used with the parameter. Depending on the type, this value can also be customized for better readability.

The parameter string used to load a given configuration is usually provided by colormass. If you need to change it, the format is as follows:

```
param(id)=type(value)
```

When multiple parameters should be set, they are separated by `&`:

```
param(id1)=type(value1)&param(id2)=type(value2)
```

### Parameter Types and Associated Values

All parameters originate from input elements that were used to build the configurator on the colormass platform. The type of a parameter defines what the configurator will assign to those elements internally. The following types are available:

#### config

This type controls configurations that are also available in the configurator’s menu. It allows to programmatically load a specific configuration variant displayed there. A config parameter is derived from a config group within the configurator’s template, and the values it accepts are the IDs of that group’s config variants (see figures below). Available variants for a config parameter can also be retrieved via `cmConfigurator.getParameterList()`.

<figure><img src="/files/kEEOEEnvTmeQA3la5qHE" alt="" width="563"><figcaption><p>Config group inside the template editor. The ID of the group is part of the parameter ID.</p></figcaption></figure>

<figure><img src="/files/It5aUgA51hOT1ApyHQxn" alt="" width="563"><figcaption><p>Config variant, whose ID can be used in cmConfigurator.setParameter.</p></figcaption></figure>

#### material

This type assigns a material to the configurator, even if it is not available in the configurator’s menu. The required value is a material ID, which you can retrieve via our GraphQL API. Instructions for accessing the API are available [here](/dev/data-exporter/api-access), and you can build and test queries directly on the [API test page](https://gql.colormass.com/graphql).

**material-article-id**

This type is used to assign a material by specifying your own in-house ID. The ID must be set up on the details page of the material on the colormass platform:

<figure><img src="/files/l4uJuybap6fy5on0Tvcb" alt="" width="161"><figcaption></figcaption></figure>

### Getting Available Parameters

In order to get the currently available parameters, you can use `getParameterList:`

```html
<script>
    customElements.whenDefined("cm-configurator-main").then(() => {
        cmConfigurator = document.querySelector("cm-configurator-main")

        //Parameters are only available after a configurator was loaded. loadingCompleted is emitted after the initial loading completes
        cmConfigurator.addEventListener("loadingCompleted", (event) => console.log("Current parameters", cmConfigurator.getParameterList()))
        //configurationLoaded is emitted after a new configuration selected by the user was loaded
        cmConfigurator.addEventListener("configurationLoaded", (event) => console.log("Current parameters", cmConfigurator.getParameterList()))
    })
</script>
```

### API Limitations

When creating a custom menu or controls for a configurator, be aware that the configurator’s API currently does not provide information on parameter dependencies. In complex configurators, certain configurations are hidden or shown based on the currently selected variant. Consequently, calls to `cmConfigurator.getParameterList()` may not always list every available parameter. After a parameter with dependencies is changed, subsequent calls to `getParameterList()` may return a different set of parameters.


# SDK API Reference

The configurator web component is a custom HTML element. Just as regular elements, it provides HTML attributes and methods, which are described in the following.

## Attributes

<table><thead><tr><th width="224">Name</th><th width="183">Type</th><th width="313">Description</th><th>Default</th></tr></thead><tbody><tr><td><code>parameters</code></td><td>string</td><td><p>Initial list of parameters formatted as query parameters, e.g, param(&#x3C;input-identifier>)=&#x3C;input-type>(&#x3C;input-value>). <em>Example:</em></p><p><em><code>"param(123)=material(123)&#x26;param(987)=number(10)"</code></em><br></p></td><td><code>undefined</code></td></tr><tr><td><code>show-ui</code></td><td>boolean</td><td>Show or hide the action menu UI layer.</td><td><code>true</code></td></tr><tr><td><code>template-uuid</code></td><td>string</td><td>The id (UUID) of the template to load. Mutually exclusive with the <code>organization-uuid</code>/<code>article-id</code> pair (if both are supplied, <code>template-uuid</code> takes precedence).</td><td><code>undefined</code></td></tr><tr><td><code>organization-uuid</code></td><td>string</td><td>The id (UUID) of the organization used together with <code>article-id</code> to resolve a template by its article identifier. Required when <code>article-id</code> is provided and <code>template-uuid</code> is omitted.</td><td><code>undefined</code></td></tr><tr><td><code>article-id</code></td><td>string</td><td>The optional article identifier used (together with <code>organization-uuid</code>) to load a template without knowing its template UUID. If both <code>template-uuid</code> and <code>article-id</code> are present, the component uses <code>template-uuid</code>.</td><td><code>undefined</code></td></tr><tr><td><code>use-external-menu</code></td><td>boolean</td><td>Set to <code>true</code> if a separate menu is being provided.</td><td><code>false</code></td></tr><tr><td><code>pixel-ratio</code></td><td>number</td><td>Override the device pixel ratio used for rendering to trade off image sharpness versus performance. Higher values increase clarity at additional GPU cost.</td><td><code>undefined</code></td></tr></tbody></table>

## Methods

### captureSnapshotInMemory

The asynchronous `captureSnapshotInMemory()` method of the `Configurator` interface creates an image from the rendering and resolves the returned `Promise` with the data URL string that contains the image data. Optional arguments allow choosing the output mime type and quality.

Throws an error if the Canvas 2d context is not available.

#### Signature

```typescript
async captureSnapshotInMemory(mimeType?: "image/png" | "image/jpeg", quality?: number, transparentBackground?: boolean): Promise<string>
```

#### Parameters

`mimeType`

The optional image type. Can be `"image/png"` or `"image/jpeg"`. Defaults to `"image/jpeg"`.

`quality`

Optional numeric quality for the JPEG encoder between 0 and 1. Defaults to `0.95`. Ignored for `"image/png"`.

`transparentBackground`

Optional. Set to `true` to receive a transparent PNG. This ignores any scene background color/image and forces the mime type to `"image/png"` (JPEG cannot be transparent). Defaults to `false`.

#### Return value

Returns a `Promise` which resolves with the data URL `string`

### downloadPdf

The asynchronous `downloadPdf()` method of the `Configurator` interface generates a PDF document of the current configuration and starts a file download. An optional [`PdfDownloadOptions`](#pdfdownloadoptions) object can be passed to customise the PDF title and provide custom table data (headers, rows, column widths, and a total row).

When called without options (or with `options.table` omitted), the PDF table is populated from the internal pricing service. When `options.table` is provided, the caller-supplied data is rendered instead.

#### Signature

```typescript
async downloadPdf(options?: PdfDownloadOptions): Promise<void>
```

#### Parameters

`options`

An optional [`PdfDownloadOptions`](#pdfdownloadoptions) object.

#### Return value

Returns a `Promise` which resolves to `undefined`.

#### Example

```javascript
const configurator = document.querySelector('cm-configurator-main');

configurator.addEventListener('loadingCompleted', async () => {
    await configurator.downloadPdf({
        title: 'YOUR CUSTOM PRODUCT',
        table: {
            headers: ['DESCRIPTION', 'CODE', 'PRICE'],
            rows: [
                ['Acme Deluxe Cabinet - Oak', 'ACME-DLX-001', '€ 1,200'],
                ['Acme Granite Worktop 800mm', 'ACME-GRN-800', '€ 450'],
            ],
            columnWidthPercentages: [45, 30, 25],
            total: { label: 'Total Price', value: '€ 1,650' },
        },
    });
});
```

### generateQrCode

The asynchronous `generateQrCode()` method of the `Configurator` interface creates an QR code image for the provided `url` and resolves the returned `Promise` with the data URL string that contains the image data.

The QR code image can be configured by setting the `errorCorrectionLevel` to `'high'` or `'low'` and by setting the `width` or `margin` `number` parameter.

#### Signature

```typescript
async generateQrCode(url: string, errorCorrectionLevel: "high" | "low", width: number, margin: number): Promise<string>
```

#### Parameters

`url`

The url `string` the QR code should represent.

`errorCorrectionLevel`

The correction level that should be applied to the QR code generation. Can be `'high'` or `'low'`.

`width`

The `number` of the resulting image width in pixels.

`margin`

The `number` of the margin around the QR code in pixels.

#### Return value

Returns a `Promise` which resolves with the data URL `string`

### getParameterList

The `getParameterList()` method of the `Configurator` interface returns a list of the available [`ConfiguratorParameters`](#configuratorparameters) once the configurator is loaded (after the [`configurationLoaded`](#configurationloaded) event was fired).

#### Signature

```typescript
getParameterList(): ConfiguratorParameters[]
```

#### Parameters

*None*

#### Return value

Returns an `Array` of `Object` conforming to the [`ConfiguratorParameters`](#configuratorparameters) type.

### getPricesAsList

The asynchronous `getPricesAsList()` method of the `Configurator` interface fetches a list of item price data, if configured on the platform. The `Promise` resolves with an array of [`PricedItem`](#priceditem).

#### Signature

```typescript
async getPricesAsList(): Promise<PricedItem[]>
```

#### Parameters

*None*

#### Return value

Returns a `Promise` which resolves with an `Array` of `Object` conforming to the [`PricedItem`](#priceditem) type.

### loadConfigurator

The asynchronous `loadConfigurator()` method of the `Configurator` interface loads the template for the supplied template UUID and starts rendering.

#### Signature

```typescript
async loadConfigurator(templatedUuid: string): Promise<void>
```

#### Parameters

`templateUuid`

The id `string` of the template to load.

#### Return value

Returns a `Promise` which resolves to `undefined`.

### loadConfiguratorByArticleId

The asynchronous `loadConfiguratorByArticleId()` method of the `Configurator` interface resolves a template via an organization UUID / article ID pair and then loads it. Use this when you only know a business-level article identifier within an organization instead of a specific template UUID.

#### Signature

```typescript
loadConfiguratorByArticleId(organizationUuid: string, articleId: string): void
```

#### Parameters

`organizationUuid`

The organization id `string` the article identifier belongs to.

`articleId`

The article identifier `string` unique within the organization.

#### Return value

Returns a `Promise` which resolves to `undefined`.

### resetCamera

The `resetCamera()` method of the `Configurator` interface resets the camera angle and zoom level of the visualisation.

#### Signature

```typescript
resetCamera(): void
```

#### Parameters

*None*

#### Return value

Returns `undefined`.

### saveSnapshot

The `saveSnapshot()` method of the `Configurator` interface creates an image from the rendering and starts a file download. Optional arguments allow choosing the output mime type and quality.

#### Signature

```typescript
saveSnapshot(mimeType?: "image/png" | "image/jpeg", quality?: number, transparentBackground?: boolean): void
```

#### Parameters

`mimeType`

The optional image type. Can be `"image/png"` or `"image/jpeg"`. Defaults to `"image/jpeg"`.

`quality`

Optional numeric quality for the JPEG encoder between 0 and 1. Defaults to `0.95`. Ignored for `"image/png"`.

`transparentBackground`

Optional. Set to `true` to download a transparent PNG. This ignores any scene background color/image and forces the mime type to `"image/png"` (JPEG cannot be transparent). Defaults to `false`.

#### Return value

Returns `undefined`.

### setParameter

The asynchronous `setParameter()` method of the `Configurator` interface sets a parameter for the current template and starts rendering.

There is advanced guide on [how to set parameters](/dev/configurator/web-components/setting-parameters).

#### Signature

```typescript
async setParameter(id: string, type: ConfigType, value: number | string | ImageDataParameter | ColorOverlayParameter): Promise<void>
```

#### Parameters

`id`

The parameter identifier `string`.

`type`

The parameter [`ConfigTyp`](#configtype)

`value`

The parameter value as `number` , `string` or `ImageDataParameter`.

#### Return value

Returns a `Promise` which resolves to `undefined`.

### toggleDimensionGuides

The `toggleDimensionGuides()` method of the `Configurator` interface shows or hides dimension guides, if guides are configured for the template.

#### Signature

```typescript
toggleDimensionGuides(): void
```

#### Parameters

*None*

#### Return value

Returns `undefined`.

### toggleFullscreen

The `toggleFullscreen()` method of the `Configurator` interface requests fullscreen view for the configurator and exits fullscreen respectively.

#### Signature

```typescript
toggleFullscreen(): void
```

#### Parameters

*None*

#### Return value

Returns `undefined`.

### viewInAr

The asynchronous `viewInAr()` method of the `Configurator` interface fetches the AR model for the current configuration and opens the native AR view on iOS or Android. For other devices it will generate and display a QR code, which links to the AR view.

#### Signature

```typescript
async viewInAr(): Promise<void>
```

#### Parameters

*None*

#### Return value

Returns a `Promise` which resolves to `undefined`.

### zoomIn

The `zoomIn()` method of the `Configurator` interface increases the zoom. It accepts a value between 0 and 1, where larger values produce larger zoom steps.

#### Signature

```typescript
zoomIn(value: number): void
```

#### Parameters

`value`

The zoom percentage as a `number` between 0 and 1.

#### Return value

Returns `undefined`.

### zoomOut

The `zoomOut()` method of the `Configurator` interface decreases the zoom. It accepts a value between 0 and 1, where larger values produce larger zoom steps.

#### Signature

```typescript
zoomOut(value: number): void
```

#### Parameters

`value`

The zoom percentage as a `number` between 0 and 1.

#### Return value

Returns `undefined`.

## Events

### arUrl

The `arUrl` event fires when the AR model for the current configuration is ready. The URL `string` to open the AR viewer can be accessed via `event.detail`.

#### Syntax

```typescript
addEventListener("arUrl", (event: { detail: string }) => {}): void
```

### changeCompleted

The `changeCompleted` event fires after a parameter was changed using [`setParameter`](#setparameter) and the visualization change is done. The `event.detail` object contains the changed parameter `id` .

#### Syntax

```typescript
addEventListener("changeCompleted", (event: { id: string}) => {}): void
```

### configurationLoaded

The `configurationLoaded` event fires after the configurator finished loading the configuration. It will fire for the initial configuration and on subsequent changes triggered through the menu UI, changes to attributes, calls to [`loadConfigurator`](#loadconfigurator) or [`setParameter`](#setparameter).

#### Syntax

```typescript
addEventListener("configurationLoaded", (event) => {}): void
```

### loadingCompleted

The `loadingCompleted` event fires after the configurator finished loading the template. It will fire for the initial configuration and if the template is changed via the [`template-uuid`](#properties) attribute or a call to [`loadConfigurator`](#loadconfigurator).

#### Syntax

```typescript
addEventListener("loadingCompleted", (event) => {}): void
```

## Types

### ConfigType

```typescript
type ConfigType = "config" | "material" | "material-article-id" | "template" | "image" | "string" | "boolean" | "number" | "object" | "int" | "float"
```

### ConfiguratorParameters

```typescript
type ConfiguratorParameters = {
    id: string
    type: ConfigType
    name: string
    values: {
        id: string
        name: string
    }[]
    value?: unknown
}
```

### PricedItem

```typescript
type PricedItem = {
    description: string
    sku?: string
    price: number
    currency: "EUR" | "USD" | "GBP"
    amount: number
}
```

### ImageDataParameter

```typescript
type ImageDataParameter = {
    contentType: "image/jpeg" | "image/png"
    data: Uint8Array
}
```

### ColorOverlayParameter

```typescript
type ColorOverlayParameter = {
    materialId: string
    size: [number, number]
    overlay:
        | string
        | {
              data: Uint8Array<ArrayBuffer>
              contentType: string
          }
}
```

### PdfDownloadOptions

```typescript
type PdfDownloadOptions = {
    /** Custom title for the PDF. Overrides the default title from the template settings. */
    title?: string
    /** Table configuration. If omitted, the internal pricing service data is used. */
    table?: {
        /** Column headers (e.g., ["DESCRIPTION", "CODE", "PRICE"]) */
        headers: string[]
        /** Data rows; each row is an array of strings matching the headers */
        rows: string[][]
        /** Optional column width percentages. If omitted, columns are distributed equally. */
        columnWidthPercentages?: number[]
        /** Optional total row rendered in bold at the bottom of the table */
        total?: {
            label: string
            value: string
        }
    }
}
```


# Examples


# Custom Menu

### Goal

A common use case is the integration of the configurator into a shop system or an existing website. As the design options of the built-in menu are limited, it is often necessary to create a separate menu to control the parameters of the configurator.

#### Examples

The following image shows the customised menu from the sample project. The options are generated dynamically based on the available config parameters and control the rendering of the configurator.

<figure><img src="/files/oNeIfyx94R6ST9FQFeLb" alt=""><figcaption><p>Sample configurator with a custom menu UI.</p></figcaption></figure>

### Setting the scene

For this example, we set up a test scene on the colormass platform. It consists of a chair and a configuration node to select from a list of materials for the front and back of the chair.

<figure><img src="/files/It5aUgA51hOT1ApyHQxn" alt=""><figcaption><p>Config group and variants for the material applied to the seat.</p></figcaption></figure>

### Adding the markup

Once the scene has been prepared, the configurator component can be added to the page.

```html
<cm-configurator-main ui-style="default" template-uuid="fb825772-66cd-4001-ae46-d537f194d6a2" use-external-menu="true"></cm-configurator-main>
```

We also add an element that functions as a container for the menu options.

```html
<div class="menu-controls" id="menu-container">
    <!-- Container holds the dynamically rendered menu elements -->
</div>
```

### Adding the scripts

We use the `getParameterList` API to get all available configuration parameters for the current template. For each parameter, we cycle through the available configuration `values` and create a button element. The button uses `setParameter` to update the rendering.

Note: we use a small helper function `htmlToNode` to create the elements to prevent repetition.

```javascript
async function initializeMenu() {
    // clear the menu container
    menuContainer.innerHTML = ""
    // load all available parameters
    parameterList = cmConfigurator.getParameterList()
    for (const parameter of parameterList) {
        // create a container element for each parameter
        const parameterContainer = htmlToNode(`
            <div class="menu-section">
                <h3>${parameter.name}</h3>
                <div class="parameter-flex" id="menu-parameter-values-container"></div>
            </div>
        `)

        for (const parameterValue of parameter.values) {
            // create a button for each possible parameter value
            const parameterValueButton = htmlToNode(`
                <button class="${parameterValue.id === parameter.value ? "active" : ""}">
                    ${parameterValue.name}
                </button>
            `)
            parameterValueButton.onclick = async (event) => {
                updateParameterMenuActiveStates(event.currentTarget)
                await cmConfigurator.setParameter(parameter.id, parameter.parameterType, parameterValue.id)
            }
            parameterContainer.querySelector("#menu-parameter-values-container").appendChild(parameterValueButton)
        }

        menuContainer.appendChild(parameterContainer)
    }
}
```

As soon as the configurator element has finished loading, we add two event listeners to call the above defined render function `initializeMenu`. The `loadingCompleted` event is triggered when the first loading of the configurator is complete. The `changeCompleted` event is triggered when the render parameters have changed.

```javascript
let cmConfigurator, menuContainer, parameterList

customElements.whenDefined("cm-configurator-main").then(() => {
    cmConfigurator = document.querySelector("cm-configurator-main")
    // Initialize UI elements
    menuContainer = document.getElementById("menu-container")
    // Once the configurator has loaded, the menu can be rendered based on the available parameters
    cmConfigurator.addEventListener("loadingCompleted", initializeMenu)
    // Update the menu when available parameter values changed.
    cmConfigurator.addEventListener("configurationLoaded", initializeMenu)
    // Update the menu when available parameter values changed through the setParameter API
    cmConfigurator.addEventListener("changeCompleted", initializeMenu)
})
```

### Putting it all together

The complete example code can also be found in our [sample repository](https://github.com/colormass/samples/tree/prod/configurator-webcomponents/custom-menu/index.html).

```html
<!DOCTYPE html>
<html style="height: 100%">
    <head>
        <link rel="preconnect" href="https://configurator.colormass.com" />
        <!-- Load the colormass configurator styles -->
        <link href="https://configurator.colormass.com/styles.css" rel="stylesheet" />
        <!-- Load the colormass configurator web components -->
        <script src="https://configurator.colormass.com/cm-configurator.js" type="module"></script>

        <link rel="stylesheet" href="../styles/sample.css" />
        <link rel="stylesheet" href="../styles/ui.css" />

        <title>Custom Menu | Example</title>
        <meta charset="UTF-8" />
 
        <script>
            let cmConfigurator, menuContainer, parameterList

            customElements.whenDefined("cm-configurator-main").then(() => {
                cmConfigurator = document.querySelector("cm-configurator-main")
                // Initialize UI elements
                menuContainer = document.getElementById("menu-container")
                // Once the configurator has loaded, the menu can be rendered based on the available parameters
                cmConfigurator.addEventListener("loadingCompleted", initializeMenu)
                // Update the menu when available parameter values changed.
                cmConfigurator.addEventListener("configurationLoaded", initializeMenu)
                // Update the menu when available parameter values changed.
                cmConfigurator.addEventListener("changeCompleted", initializeMenu)
            })

            async function initializeMenu() {
                // clear the menu container
                menuContainer.innerHTML = ""
                // load all available parameters
                parameterList = cmConfigurator.getParameterList()
                for (const parameter of parameterList) {
                    // create a container element for each parameter
                    const parameterContainer = htmlToNode(`
                        <div class="menu-section">
                            <h3>${parameter.name}</h3>
                            <div class="parameter-flex" id="menu-parameter-values-container"></div>
                        </div>
                    `)

                    for (const parameterValue of parameter.values) {
                        // create a button for each possible parameter value
                        const parameterValueButton = htmlToNode(`
                            <button class="${parameterValue.id === parameter.value ? "active" : ""}">
                                ${parameterValue.name}
                            </button>
                        `)
                        parameterValueButton.onclick = async (event) => {
                            updateParameterMenuActiveStates(event.currentTarget)
                            await cmConfigurator.setParameter(parameter.id, parameter.parameterType, parameterValue.id)
                        }
                        parameterContainer.querySelector("#menu-parameter-values-container").appendChild(parameterValueButton)
                    }

                    menuContainer.appendChild(parameterContainer)
                }
            }

            function updateParameterMenuActiveStates(element) {
                // remove active class from all siblings
                const siblings = element.parentElement.children
                for (const sibling of siblings) {
                    sibling.classList.remove("active")
                }
                // set active class for clicked element
                element.classList.add("active")
            }

            function htmlToNode(html) {
                const template = document.createElement("template")
                template.innerHTML = html.trim()
                return template.content.firstChild
            }
        </script>
    </head>
    <body>
        <div class="container">
            <div class="menu">
                <div class="menu-controls" id="menu-container">
                    <!-- Container holds the dynamically rendered menu elements -->
                </div>
            </div>
            <div class="configurator-container">
                <cm-configurator-main ui-style="default" template-uuid="fb825772-66cd-4001-ae46-d537f194d6a2" use-external-menu="true"></cm-configurator-main>
            </div>
        </div>
    </body>
</html>

```


# Overlay Material Color

### Goal

The colormass configurator can be used to render custom fabric designs, which are provided as color images. Internally, the configuator embeds those images into a scanned, high-quality base material. This material contributes to the overall appearance and makes your design look like wool, cotton or linen.

#### Examples

The following images were created using this sample code and these two images as input:

<div><figure><img src="/files/A3LlZ3X7RdjeRCMpP8EN" alt="" width="200"><figcaption><p>A colorful pattern</p></figcaption></figure> <figure><img src="/files/P6pflxFgZnSb6UGAzwkH" alt="" width="191"><figcaption><p>A checkered pattern</p></figcaption></figure></div>

<div><figure><img src="/files/4GoczZu1HQtxrZOclTk5" alt=""><figcaption><p>Colorful dots image, width and height 100cm</p></figcaption></figure> <figure><img src="/files/BHU4Z9u5cS1v7XGMfBRe" alt=""><figcaption><p>Checkered pattern, width and height 10cm</p></figcaption></figure> <figure><img src="/files/WhO3uMKM7HkXnwxQ2gO4" alt=""><figcaption><p>Checkered pattern, width and height 100cm</p></figcaption></figure></div>

### Setting the scene

For this example, we set up a test scene on the colormass platform. It consists of a chair and uses a wool-like base material. The *Overlay Material Color* node takes care of replacing the color information of this material and scales your pattern to the desired width and height.

<figure><img src="/files/B1jMI58NwqRjnTmlPHsA" alt="" width="304"><figcaption><p>Detail settings for the Overlay Material Color node</p></figcaption></figure>

While the base material is fixed, the overlay image as well as the width and height are transferred to the configurator via the corresponding input node (image input and number input).

<div><figure><img src="/files/XKKa2Sr7r1paz00Hgzll" alt="" width="288"><figcaption><p>Detail settings for the overlay image input node.</p></figcaption></figure> <figure><img src="/files/rfGgtOITXAvYP3kaFN2s" alt="" width="288"><figcaption><p>Detail settings for the width number input node.</p></figcaption></figure> <figure><img src="/files/96qNAlnzfWxooZuZyTGJ" alt="" width="288"><figcaption><p>Detail settings for the width number input node.</p></figcaption></figure></div>

### Adding the markup

Once the scene has been prepared, the configurator component can be added to the page.

<pre class="language-html"><code class="lang-html"><strong>&#x3C;cm-configurator-main template-uuid="60ec3a3a-9e92-4d2a-a6e5-16595d34686e">&#x3C;/cm-configurator-main>
</strong></code></pre>

To change the color pattern used programmatically, we add three simple input elements.

```html
<input id="widthInput" type="number" value="10" onchange="updateWidth(this.value)"/>
<input id="heightInput" type="number" value="10" onchange="updateHeight(this.value)"/>
<input type="file" id="overlayImageInput" accept="image/jpeg, image/png" onchange="updateOverlayImage(this.files)" />
```

### Adding the scripts

We use the ‘setParameters’ API, which is provided by the configurator component, to transfer the input data to the renderer. You can find a detailed explanation in our guide on [setting parameters](/dev/configurator/web-components/setting-parameters).

```javascript
// wait for the configurator component to be available
customElements.whenDefined("cm-configurator-main").then(() => {
    cmConfigurator = document.querySelector("cm-configurator-main")
})

// pass the width input to the configurator
async function updateWidth(width) {
    cmConfigurator.setParameter("width", "number", Number(width))
}

// pass the height input to the configurator
async function updateHeight(height) {
    cmConfigurator.setParameter("height", "number", Number(height))
}

// pass the image input to the configurator as an object URL
// note: the image parameter supports passing an image via 
//        - URL
//        - data URL (inlined base64)
//        - raw data (Uint8Array)
async function updateOverlayImage(files) {
    const file = files[0]
    const image = await fetch(file)
    const imageBlob = await image.blob()
    const imageUrl = URL.createObjectURL(imageBlob)
    await cmConfigurator.setParameter("overlayImage", "image", imageUrl)
}
```

### Putting it all together

The complete example code can also be found in our [sample repository](https://github.com/colormass/samples/blob/prod/configurator-webcomponents/overlay-material-color/index.html).

```html
<!DOCTYPE html>
<html style="height: 100%">
    <head>
        <link rel="preconnect" href="https://configurator.colormass.com" />
        <!-- Load the colormass configurator styles -->
        <link href="https://configurator.colormass.com/styles.css" rel="stylesheet" />
        <!-- Load the colormass configurator web components -->
        <script src="https://configurator.colormass.com/cm-configurator.js" type="module"></script>

        <title>Overlay Material Color | Example</title>
        <meta charset="UTF-8" />
        <style>
            body {
                width: 100%;
                height: 100%;
                margin: 0;
            }

            :root {
                --cm-menu-max-num-cols: 8;
                --cm-menu-icon-size: 40px;
                --cm-menu-background-color: rgba(255, 255, 255, 0);
                font-family: "Roboto";
            }

            .container {
                display: flex;
                height: 100%;
                overflow: hidden;
            }

            .menu {
                display: flex;
                flex-direction: column;
                align-items: flex-start;
                gap: 10px;
                padding: 20px;
                width: 300px;
                background-color: #f4f4f4;
                overflow: hidden;
            }

            .menu-item {
                display: flex;
                flex-direction: row;
                justify-content: space-between;
                gap: 10px;
                width: 100%;
            }

            #overlayImageInput {
                display: none;
            }

            .configurator-container {
                flex-grow: 1;
                box-sizing: border-box;
            }

            img {
                width: 100%;
                height: auto;
            }
        </style>

        <script>
            let cmConfigurator,
                overlayImageInput,
                widthInput,
                heightInput,
                overlayImagePreview, 
                snapshotImagePreview;
            
            customElements.whenDefined("cm-configurator-main").then(() => {
                cmConfigurator = document.querySelector("cm-configurator-main")

                // Initialize UI elements
                overlayImageInput = document.getElementById("overlayImageInput")
                widthInput = document.getElementById("widthInput")
                heightInput = document.getElementById("heightInput")
                overlayImagePreview = document.getElementById("overlay-image-preview")
                snapshotImagePreview = document.getElementById("snapshot-image-preview")

                // Reset inputs
                overlayImageInput.value = ""
                widthInput.value = 10
                heightInput.value = 10
            })

            function inMemorySnapshot() {
                cmConfigurator
                    .captureSnapshotInMemory()
                    .then((snapshot) => {
                        snapshotImagePreview.src = snapshot
                    })
                    .catch((error) => {
                        console.log("Could not capture snapshot in memory.", error)
                    })
            }

            async function updateWidth(width) {
                await cmConfigurator.setParameter("width", "number", Number(width))
            }

            async function updateHeight(height) {
                await cmConfigurator.setParameter("height", "number", Number(height))
            }

            async function updateOverlayImage(files) {
                const file = files[0]
                
                const image = await fetch(file)
                const imageBlob = await image.blob()
                const imageUrl = URL.createObjectURL(imageBlob)
                // update image parameter
                await cmConfigurator.setParameter("overlayImage", "image", imageUrl)
                // set image preview
                overlayImagePreview.src = imageUrl

                // Alternative implementation using data URL
                // const dataUrlReader = new FileReader()
                // dataUrlReader.onload = async function (e) {
                //     overlayImagePreview.src = e.target.result
                //     await cmConfigurator.setParameter("overlayImage", "image", e.target.result)
                // }
                // dataUrlReader.readAsDataURL(files[0])
            
                // Alternative implementation using array buffer
                // const byteLoader = new FileReader()
                // byteLoader.onload = async function (e) {
                //     const buffer = new Uint8Array(e.target.result)
                //     const imageParamData = {
                //         contentType: file.type,
                //         data: buffer,
                //     }
                //     await cmConfigurator.setParameter("overlayImage", "image", imageParamData)
                // }
                // byteLoader.readAsArrayBuffer(files[0])
            }
        </script>
    </head>
    <body>
        <div class="container">
            <div class="menu">
                <!-- Pattern width -->
                <div class="menu-item">
                    <label for="widthInput">Width: </label>
                    <input id="widthInput" type="number" value="10" onchange="updateWidth(this.value)"/>
                </div>

                <!-- Pattern height -->
                <div class="menu-item">
                    <label for="heightInput">Height: </label>
                    <input id="heightInput" type="number" value="10" onchange="updateHeight(this.value)"/>
                </div>

                <!-- Overlay image -->
                <div class="menu-item">
                    <label for="overlayImageInput">Overlay image</label>
                    <button onclick="overlayImageInput.click()">Select Image</button>
                    <input type="file" id="overlayImageInput" accept="image/jpeg, image/png" onchange="updateOverlayImage(this.files)" />
                </div>
                <img id="overlay-image-preview" />                    

                <!-- Take in memory snapshot -->
                 <div class="menu-item">
                    <button onclick="inMemorySnapshot()">Take a snapshot</button>
                 </div>
                 <img id="snapshot-image-preview" /> 
            </div>
            <div class="configurator-container">
                <cm-configurator-main ui-style="default" template-uuid="60ec3a3a-9e92-4d2a-a6e5-16595d34686e"></cm-configurator-main>
            </div>
        </div>
    </body>
</html>
```


# Iframe Integration

This section outlines integration of the configurator by means of an iframe. This is straightforward, especially when using a content mangement system (CMS). However, the iframe API is deprecated, and we recommend its use only for displaying the configurator with the standard menu or for a single configuration without a menu. For more customization, please consider web components integration.


# Getting Started

The colormass Configurator is very easy to integrate regardless of the content management system (CMS) or e-commerce solution of your choice. The following example should be up and running on your website in less than 2 minutes!

The integration of the 3D configurator works the same way as embedding a YouTube video in a webpage. If you are familiar with that workflow, you know that it can be done without any programming experience. It uses an *inline frame element*, also called [iframe](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe). To give it a quick try, copy/paste the following code snippet into your webpage:

{% code lineNumbers="true" %}

```html
<iframe
  src="https://configurator.colormass.com/?apiVersion=2&sceneId=955"
  style="width: 100%; height:100%; border:0"
  allowfullscreen=""
></iframe>
```

{% endcode %}

After reloading the page you should see the following interactive configurator (below you can see a screenshot only):

<figure><img src="/files/C3wP6H49y7UFCpUrLAxM" alt=""><figcaption></figcaption></figure>

The only thing you'll have to change now in order to show your own content is the `sceneId` query parameter in the `src` attribute of the iframe. We'll make sure to share it with you once we finished preparing your configurator.

{% hint style="info" %}
Please mind that using the iframe technology, all the data is directly loaded from the colormass hosting infrastructure, so other than being able to copy/paste the iframe snippet into you page, there are no further requirements.
{% endhint %}

The above quick-start guide covered a very basic integration of a configurator to get you started. If you would like to learn more about customizing the user interface or programmatically controlling the configurator, visit the ﻿[Advanced Integration](/dev/configurator/iframe-integration/advanced-integration) page.


# Advanced Integration

The colormass configurator comes with a default user interface, so it is quick and easy to get started as described in Getting Started . However, if it is required to customize the UI or control the configurator's behavior programmatically, there is an API to do so.

The configurator is served from the <https://configurator.colormass.com> domain. When it is embedded into a webpage via an iframe, script access to the frame's content is subject to the [same-origin policy](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy). Because of this, it is not possible to simply call the configurator's functions. Safe cross-origin communication is only enabled over the `window.postMessage()` method. Further information can be found [here](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage).

## **Basic Setup**

To begin with, create an HTML file and copy paste the following code:

{% code title="configurator-example.html" lineNumbers="true" %}

```html
<!DOCTYPE html>
<html style="height: 100%">
<head>
    <title>Configurator iframe Example</title>
    <meta charset="UTF-8">
    <script type="text/javascript">
        let cmConfigurator;
        window.onload = () => {
            cmConfigurator = document.getElementById("cmConfigurator").contentWindow;
        }
    </script>
</head>
<body style="width: 100%; height: 100%; margin: 0;">
<iframe id="cmConfigurator"
        src="https://configurator.colormass.com?sceneId=990"
        style="width: 100%; height: 100%; border: none"
        allowfullscreen>
</iframe>
</body>
</html>
```

{% endcode %}

There is no need to serve the file through a server, it can be opened directly in the browser and the example configurator should load as expected. The above code snippet does two important things:

1. It embeds the configurator using an iframe element.
2. Accessing the [contentWindow](https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement/contentWindow) property, it gets hold of the Window object of the iframe, which will be used to communicate with the configurator through messages.

## **Calling Methods**

The configurator expects messages in the following format:

{% code lineNumbers="true" %}

```json
{
    data: {
        method: string,
        parameters: {}
    },
    type: "colormass"
}
```

{% endcode %}

When using the `postMessage()` method, make sure to pass the `targetOrigin` parameter as shown below, otherwise the messages won't be dispatched.

{% code lineNumbers="true" %}

```javascript
const message = {
    data: {
        method: "showUi",
        parameters: {value: false}
    },
    type: "colormass"
}
cmConfigurator.postMessage(message, "https://configurator.colormass.com");
```

{% endcode %}

The above method call hides the default user interface including the panels both on the left and on the right side. As a next step, let's print the configuration options in order to see the available variants. This is done via the `options` method. The message should look as follows:

{% code lineNumbers="true" %}

```javascript
const message = {
    data: {
        method: "options"
    },
    type: "colormass"
}
```

{% endcode %}

If you post this message the same way as we did for the `showUi` method, you will notice that the printed array is empty. The reason for this is that the loading of the configurator is not finished yet at the point in time when the message arrives. You will have to make sure to wait for the `loadingComplete` event first.

## **Listening to Events**

Up till now we only used the messaging to communicate towards the configurator (iframe window). Event are implemented using the same mechanism, the configurator sends messages back to the parent window. In order to receive those, we have to initialize an event listener as follows:

{% code lineNumbers="true" %}

```javascript
window.onload = () => {
    cmConfigurator = document.getElementById("cmConfigurator").contentWindow;
    window.addEventListener("message", receiveMessage, false);
}

function receiveMessage(message) {
    if (message.data.type === "colormass" && message.data.data.method === "loadingCompleted") {
        let optionsMessage = {
            data: {
                method: "options"
            },
            type: "colormass"
        }
        cmConfigurator.postMessage(optionsMessage, "https://configurator.colormass.com");
    }
}
```

{% endcode %}

If you run the above code, you should see the following options printed to the console:

{% code lineNumbers="true" %}

```javascript
[
    {
        id: "ced9d80c-7103-43f2-a5ba-2d90e0c823b3",
        name: "Seat",
        variants: [
            {id: '3d7420d9-6117-428f-ba41-890ecd157f8e', name: 'Blazer Darthmouth'}
            {id: 'e6ddc079-8026-4e4f-95ca-6e2be019a0f6', name: 'Oceanic Atoll'}
            {id: '18479bf9-e393-4da9-9fc9-dfb37077550b', name: 'Lucia Tenom'}
            {id: '1d9f7d3d-3823-4224-a3f7-62028295080f', name: 'Velocity Polar'}
            {id: 'ec17fd8c-6131-46d8-8bdd-a2ac0f9d29a6', name: 'Main Line flax Farring'}
            {id: '27d9baf3-84fb-476b-8312-e348b46c1e40', name: 'Steam PDY'}
            {id: '087612ab-9a50-43e3-8626-b1c37322b499', name: 'Leather'}
        ]
    },
    {
        id: "60a5a88a-7701-4c10-819e-deb5f87f15c4",
        name: "Back",
        variants: [
            {id: 'c93e318c-88ee-4e8c-9b56-9c7075f53784', name: 'Main Line Flax Bayswater'}
            {id: '4c190056-bc69-49f5-a081-c82a86658124', name: 'Synergy Quilt Chemistry'}
            {id: '42763086-b3e6-48cb-ac63-2172f2245bf9', name: 'Synergy Quilt Group'}
            {id: '918f01a2-a890-42e7-94a8-fb0c821ab3b5', name: 'Carlow Callan'}
            {id: '931d70b6-a156-4fa8-bf3d-f8b817f28516', name: 'Main Line Flax Lambeth'}
        ]
    }
]
```

{% endcode %}

For this specific configurator there are two configuration groups, the \_Seat \_and the \_Back. \_Both of them have multiple variants. In this case those are different fabric options.

{% hint style="info" %}
Please mind that the configuration options could look very different for your specific configurator based on how it was set up on the back end. However, it always has the same structure: configuration groups containing variants.
{% endhint %}

## **Setting Configurations**

As a next step, let's add a button to our example which changes the current configuration to a different fabric on the seat of the chair. The method to be used here is called `option`. It expects a `groupId` and a `variantId`. Given that we would like to change the fabric on the seat, we are going to use the group ID `ced9d80c-7103-43f2-a5ba-2d90e0c823b3`. For the variant we pick the one called *Oceanic Atoll*.

{% code lineNumbers="true" %}

```javascript
let message = {
    data: {
        method: "option",
        parameters: {
            groupId: "ced9d80c-7103-43f2-a5ba-2d90e0c823b3",
            variantId: "e6ddc079-8026-4e4f-95ca-6e2be019a0f6"
        }
    },
    type: "colormass"
}
cmConfigurator.postMessage(message, "https://configurator.colormass.com");
```

{% endcode %}

Make sure the above message gets posted only after the configurator finished loading, otherwise you are going to get an error. One way to achieve this is to execute the above code only after the `loadingCompleted` event fired. Alternatively, you can assign the action to a button and only press it after the default version of the chair loads. If you did everything correctly, you should see the following variation of the chair:

<figure><img src="/files/PXYsGJDYOSqjbbQb6oq8" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
Changing the configuration triggers the `loadingCompleted` event once it finished loading. Make sure not to include the above changing logic within the event listener function, because it will lead to an infinite loop.
{% endhint %}

Having gone through this advanced integration guide, now you should have a good understanding of how the communication between the main window and the iframe is implemented. If you would like to see all the features the API offers, make sure to check out the API Reference .


# API Reference

The configurator expects messages in the following format:

{% code lineNumbers="true" %}

```javascript
const message = {
  data: {
    method: string,
    parameters: {},
  },
  type: "colormass",
};
```

{% endcode %}

Sending a message can be done as follows:

{% code lineNumbers="true" %}

```javascript
window.onload = () => {
  cmConfigurator = document.getElementById("cmConfigurator").contentWindow;
  cmConfigurator.postMessage(message, "https://configurator.colormass.com");
};
```

{% endcode %}

| **Method name** | **Description and Parameters**                                                                                                                                                                                                                           |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| *showUi*        | <p>Shows or hides the default user interface.<br>- <code>value: boolean</code></p>                                                                                                                                                                       |
| *saveSnapshot*  | Initiates the download of a JPG file of the currently rendered view of the configurator.                                                                                                                                                                 |
| *options*       | Prints all the possible configuration options with their IDs to the console.                                                                                                                                                                             |
| *option*        | <p>Sets a specific configuration based on the parameters below.<br>- <code>groupId: string</code><br>- <code>variantId: string</code></p>                                                                                                                |
| *setMaterial*   | <p>Sets the material of the specific <code>variantId</code> to the <code>materialId</code> provided. This is only possible if the variant contains an overridable material.<br>- <code>materialId: string</code><br>- <code>variantId: string</code></p> |

## **Events**

In order to receive events from the iframe window, you have to initialize an event listener on the main window as follows:

{% code lineNumbers="true" %}

```javascript
window.onload = () => {
    window.addEventListener("message", receiveMessage, false);
}

function receiveMessage(message) {
    if (message.origin !== "https://configurator.colormass.com" ||
        message.data.type !== "colormass") return;
    const data = message.data.data;
    const methodName = data.method;
    const parameters = data.parameters;
    // Handle event based on the method's name and parameters
}
```

{% endcode %}

| **Event name**             | **Description and Parameters**                                                                                                                                                                                         |
| -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| *loadingCompleted*         | Triggered when the configurator finished loading.                                                                                                                                                                      |
| *keydown*                  | <p>Triggered on the keydown event. Given that the main window cannot access the keydown event of the iframe directly, this makes it possible to capture a subset of those events.<br>- <code>parameters: {}</code></p> |
| *settingMaterialCompleted* | Triggered when setting a specific material using the *setMaterial* method finished.                                                                                                                                    |


# Default Configurations

Before diving into the ways of setting default configurations there are a few things that need some introduction.

## IDs

In the Template Editor elements that are not an atomic level elements (e.g. a material or a mesh) have IDs. See the area circled in red below.

<figure><img src="/files/IPhG2SMekqlGABNAImPC" alt="" width="375"><figcaption></figcaption></figure>

These IDs are generated automatically but they can also be set/changed by you. Whenever there is a need to use IDs it is always recommended to change them to a human readable format.

This is also the case when you want to control default configurations through the API because these IDs have to be set through the API.

## Example

Here is an example of a code where default configurations of a product is set.

We will only show the link that is used in the configurator and not the complete \*\*iframe \*\*code so that it is easier to read.

```javascript
https://configurator.colormass.com/?apiVersion=2&sceneId=2268&param(combined%2Fcategory)=id(taps)&param(combined%2Ftaps%2Ftaps)=id(OMI-133-C-P)&param(combined%2Ftaps%2Ffinishes%2Ffinishes)=id(polished-black)
```

This might look a bit complicated at first, so lets break it down step by step. You will notice that the URL parts are separated with `&` symbols, and there are two types of elements in the URL above.

```javascript
sceneId = 2268;
```

This is responsible for the viewer where a specific light settings (which you should be familiar with from the previous articles in the documentation) are used and our product is added.

```javascript
param(combined%2Fcategory)=id(taps)
```

These are the ones that set a specific configuration to selected default. You will see a strange character combination: `%2F` . Whenever you see those just think of them as `/` Using slash in the URL has a special meaning so it is recommended to use these special characters instead of the slash. We read the above text inside the `param` as `combined/category=taps`

So to take the above scene as an example you will see that inside this scene the product is called `combined` and the template that is used inside is `Combined (Omika)`.

<figure><img src="/files/UrVOFeHitJOfYkqGgAOt" alt=""><figcaption></figcaption></figure>

Let's say we want to set the default category of the above product. To be able to set a specific configuration we have to set the path in the template using the IDs. So in this specific case the path will be `combined/category`.

{% hint style="info" %}
Explanation: the ID of the main product is `combined` and the config group inside has an ID called `category`. See screenshot below.
{% endhint %}

<figure><img src="/files/UZXrLeky2PzJev4mEIIs" alt="" width="375"><figcaption></figcaption></figure>

Once you have identified the path to the configuration group and added it to the param part of the URL like so:

```javascript
param(combined%2Fcategory)
```

you will also need to set it to a specific Configuration Variant, which in this case will be Taps, see screenshot below.

<figure><img src="/files/aKK2iNq4ZbrxqFQshqht" alt="" width="375"><figcaption></figcaption></figure>

and that is how we arrive to the final segment of our URL:

```javascript
param(combined%2Fcategory)=id(taps)
```


# Generating Exports

## Types

<figure><img src="/files/Lo0p7J5jYkiD6On7w3tv" alt=""><figcaption></figcaption></figure>

For fall materials that have an online revision, various outputs can be generated:

* **Flat thumbnails** are images that are generated with a fixed dimension that is visible on the image. On the platform the following predefined sizes are available to be generated:

<figure><img src="https://colormass.slite.com/api/files/BeulSUdc4Ok0g7/image.png" alt="image.png" width="188"><figcaption></figcaption></figure>

* **Tileable image** is an image that can be placed next to itself (above, below, or side-by-side) without creating an obvious seam. The size of the repeat (and hence the physical size visible on the image) is included in the name of the file.
* **Map exports** are the PBR exports where the maps can be exported based on the last material revision or texture set.

{% hint style="info" %}
It is sometimes easy to confuse *Flat thumbnails* and *Tileable image* because they are both flat. But there is a very important difference: *Flat thumbnails* have a fixed size (e.g. 7 in x 7 in or 9 in x 9 in) no matter what their repeat size is and the *Tileable images* don't (their size is the same as the size of the repeat). *Flat thumbnails* are best to be used where a certain area of the material needs to be visible (e.g. on the website). The *Tileable image* is fitted for a more technical use: either when a larger size has to be covered where the pattern repeat is visible multiple times or if in a certain application the main way to create digital materials is through uploading tileable images (e.g. CET designer).
{% endhint %}

## Generating Outputs

In order to generate an output all you have to do is to go to a specific output you would like to generate and press start (see an example of submitting a 7 in x 7 in flat thumbnail):

<figure><img src="https://colormass.slite.com/api/files/N36-FIIrwLFd5u/image.png" alt="image.png" width="188"><figcaption></figcaption></figure>

Once you submitted the render, you should receive the following message:

<figure><img src="https://colormass.slite.com/api/files/eyJ1hkpbbWGmLJ/image.png" alt="image.png" width="375"><figcaption></figcaption></figure>

After this the image is submitted to the colormass servers for generating and if you check back after some time you should find that there is now a download icon next to the "7in" and that the *Flat thumbnail* text now has a (1) letter next to it, meaning that there is now 1 thumbnail available for download.

<figure><img src="https://colormass.slite.com/api/files/YNhslyiApNdohz/image.png" alt="image.png" width="188"><figcaption></figcaption></figure>

Once you click on the download button you will see an option pop-up that lets you select the format for the material download.

## Re-Generating Outputs

In order to re-generate outputs you would need to remove the existing output using the remove button. See this button for both Tileable and Thumbnail below:

<figure><img src="https://colormass.slite.com/api/files/1rX048EhXKcD2J/image.png" alt="image.png" width="188"><figcaption></figcaption></figure>

<figure><img src="https://colormass.slite.com/api/files/JIzviVlMVyLE5s/image.png" alt="image.png" width="188"><figcaption></figcaption></figure>

Once you removed the image, you will need to refresh the page because this part of the UI at the moment is not refreshed automatically.

Once you don't see the download option anymore that means that the output was removed and you can follow the [Generating Outputs](#generating-outputs) steps.


# Integration

The colormass Exports feature can be used through a web component called `cm-material-download`. This enables you to directly use the download functionality without having to download or upload these assets that are defined in the previous page (Generating Exports ).

## Steps

### 1. Add an Import in the site's header

In order to be able to use the exports component you need to add an import into the `<header>` HTML element, like so:

{% code lineNumbers="true" %}

```html
<head>
    ...
    <script type="module" src="https://material-download.colormass.com"></script>
    ...
</head>
```

{% endcode %}

This only needs to be done once.

### 2. Add a button

Now add a download button to your page. This must be an `a` tag. You can add arbitrary content, CSS classes and attributes to make this appear like any other button on your page. Your existing CSS rules will continue to apply. The `href` attribute can be either omitted or set to an arbitrary value.

```javascript
<a class="you-can-add-your-own-classes-here">Download</a>
```

### 3. Wrap the link

Now wrap the `a` tag in a `cm-material-download` tag, providing the attributes described below. The link's `href` tag will be set automatically. If the required export cannot be found, the CSS class `disabled` will be set on the link.

{% code lineNumbers="true" %}

```html
<cm-material-download organization-id="1f6d7f93-4e0k-4400-b937-1ce73576f570" article-id="9999" type="pbr">
  <a class="you-can-add-your-own-classes-here">Download</a>
</cm-material-download>
```

{% endcode %}

You need to define the following attributes:

* `organization-id`: This is a fixed `UUID` for your account (please ask your contact person if you are not sure).
* `article-id`: This is the article ID `string` of the material. Since these are added on the platform manually, please ask the colormass staff if the corresponding range has the correct article IDs added before integrating them.
* `type`: This is the type of the download. It has the following options: `pbr`, `tile`, `thumbnail`.
* `file-type`: The desired file extension: `jpg` or `tiff`.
* `resolution (PBR)` : `low` (72 DPI) or `high` (Original DPI)
* `resolution`: The desired resolution, one of `low` (1000x1000px), `medium` (2000x2000px) or `high` (original size). Must be `high` unless the file type is `jpg`. Defaults to `high`.
* `dimensions`: One of `7x7in`, `8x8in`, `9x9in`, `13_5x13_5in`, `16x16in`, `27x27in`, `32x32in`, `10x10cm`, `15x15cm`, `20x20cm`, `30x30cm`. Only provide if type is `thumbnail`. Defaults to `7x7in`.

{% hint style="info" %}
If you are not sure what these types above mean, please check the previous [Generating Exports](/dev/data-exporter/generating-exports) page.
{% endhint %}

## Styling

This component doesn't add any styling rules. The wrapped `a` tag can be styled freely. In most cases, it should automatically pick up any existing styling rules on the page, so that no extra steps are necessary. If you do want to customize the appearance of the link, you can simply add CSS classes or inline styles. See the following example:

{% code lineNumbers="true" %}

```html
<cm-material-download organization-id="9999" article-id="9999" type="pbr">
    <a style="text-decoration: none; color: white; background: black; padding: 4px; cursor: pointer;">
        <i class="fancy-icon" />Styled Download Button
    </a>
</cm-material-download>
```

{% endcode %}

## Example

{% code lineNumbers="true" fullWidth="false" %}

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <script type="module" src="https://material-download.colormass.com"></script>
    <meta charset="UTF-8">
    <title>Material Download Example</title>
</head>
<body>
<ul>
  <li>
    <cm-material-download organization-id="1f0d7f93-4e0d-4400-b937-1ce75576f570" article-id="3106702" type="pbr" file-type="tiff" resolution="high">
      <a>Download PBR (TIFF)</a>
    </cm-material-download>
  </li>
  <li>
    <cm-material-download organization-id="1f0d7f93-4e0d-4400-b937-1ce75576f570" article-id="3106702" type="pbr" file-type="tiff" resolution="low">
      <a>Download PBR (JPG)</a>
    </cm-material-download>
  </li>
  <li>
    <cm-material-download organization-id="1f0d7f93-4e0d-4400-b937-1ce75576f570" article-id="3106702" type="tile" file-type="jpg" resolution="low">
      <a>Download Tile (JPG, low res)</a>
    </cm-material-download>
  </li>
  <li>
    <cm-material-download organization-id="1f0d7f93-4e0d-4400-b937-1ce75576f570" article-id="3106702" type="thumbnail" file-type="jpg" dimensions="7x7in">
      <a>Download Thumbnail (7 in x 7 in, JPG, high-res)</a>
    </cm-material-download>
  </li>
  <li>
    <cm-material-download organization-id="1f0d7f93-4e0d-4400-b937-1ce75576f570" article-id="3106702" type="thumbnail" file-type="jpg" dimensions="7x7in">
      <a>Download Thumbnail (7 in x 7 in, JPG, medium-res)</a>
    </cm-material-download>
  </li>
  <li>
    <cm-material-download organization-id="1f0d7f93-4e0d-4400-b937-1ce75576f570" article-id="3106702" type="thumbnail" file-type="jpg" dimensions="30x30cm">
      <a>Download Thumbnail (30 cm x 30 cm, JPG, low-res) - not available</a>
    </cm-material-download>
  </li>
</ul>
</body>
</html>
```

{% endcode %}

If it's needed you can also set the attributes programmatically like you would with any HTML attribute. Just as an example using in pure Javascript:

{% code lineNumbers="true" %}

```javascript
var exampleElements = document.querySelectorAll('cm-material-download');
exampleElements.forEach(function(item, i){
  item.setAttribute('article-id', '9999999');
});
```

{% endcode %}

{% hint style="info" %}
The above example is just an example if you use frameworks or libraries this example would probably look different.
{% endhint %}

The HTML component lets you define any values, so you have to make sure that:

* The **output** you are requesting is **available** on the colormass platform
* The **article ID** is added to the material on the platform and uniquely identifies a material

![](/files/Ihe2ysHV9OpUwXu5lAkp)

For example, if you request the download of Article ID 9999 with the following attributes:

{% code lineNumbers="true" %}

```html
<cm-material-download organization-id="9999" article-id="9999" type="thumbnail" dimensions="9x9in">
    <a>Download Thumbnail (9" x 9")</a>
</cm-material-download>
```

{% endcode %}

The download will not start because it doesn't have a 9in x 9in output. The `a` tag will additionally have the CSS class `disabled`, which you can use to provide feedback to the user.

{% code lineNumbers="true" %}

```css
a.disabled {
  cursor: not-allowed;
}
```

{% endcode %}

As an alternative to the `cm-material-download` web component, you can also generate download links directly using the colormass [GraphQL API](/dev/data-exporter/api-access).


# API Access

The colormass API is available at <https://gql.colormass.com/graphql>

## Authentication

In the Headers tab, enter the demo API key to authenticate to the backend:

{% code lineNumbers="true" %}

```json
{
 "X-Api-Key": "0ecff5f6-5b65-42bf-84d1-facf9ed37c7avf"
}
```

{% endcode %}

The following query will return download URLs for thumbnails/tileable images:

{% code lineNumbers="true" %}

```graphql
query GetMaterialDownloadLink($articleId: String!, $organizationId: ID!, $assignmentType: DataObjectAssignmentType!, $resolution: DownloadResolution, $fileType: DownloadFileType) {
  materials(filter: {articleId: {equals: $articleId}, organizationId: {equals: $organizationId}}) {
    dataObjectAssignments(filter: {assignmentType: [$assignmentType]}) {
      dataObject {
        downloadUrl(resolution: $resolution, fileType: $fileType)
        mediaType
      }
    }
  }
}
```

{% endcode %}

For PBR maps, use this query:

{% code lineNumbers="true" %}

```graphql
query GetPbrMaterialDownloadLink($articleId: ID!, $organizationId: String!, $resolution: DownloadResolution, $fileType: DownloadFileType) {
  materials(filter: {articleId: {equals: $articleId}, organizationId: {equals: $organizationId}}) {
    jsonFileAssignments(filter: {jsonFileContent: [{resolution: $resolution, fileType: $fileType, state: "done", default: true}]}) {
      jsonFile {
        outputDataObject {
          downloadUrl
        }
      }
    }
  }
}
```

{% endcode %}

Follow [this link](https://gql.colormass.com/graphql?query=query+GetMaterialDownloadLink%28%24articleId%3A+String%21%2C+%24organizationId%3A+String%21%2C+%24assignmentType%3A+DataObjectAssignmentType%21%2C+%24resolution%3A+DownloadResolution%2C+%24fileType%3A+DownloadFileType%29+%7B%0A++++materials%28filter%3A+%7BarticleId%3A+%7Bequals%3A+%24articleId%7D%2C+organizationId%3A+%7Bequals%3A+%24organizationId%7D%7D%29+%7B%0A++++++++dataObjectAssignments%28filter%3A+%7BassignmentType%3A+%5B%24assignmentType%5D%7D%29+%7B%0A++++++++++++dataObject+%7B%0A++++++++++++++++downloadUrl%28resolution%3A+%24resolution%2C+fileType%3A+%24fileType%29%0A++++++++++++++++mediaType%0A++++++++++++%7D%0A++++++++%7D%0A++++%7D%0A%7D%0A%0Aquery+GetPbrMaterialDownloadLink%28%24articleId%3A+String%21%2C+%24organizationId%3A+String%21%2C+%24resolution%3A+DownloadResolution%2C+%24fileType%3A+DownloadFileType%29+%7B%0A++++materials%28filter%3A+%7BarticleId%3A+%7Bequals%3A+%24articleId%7D%2C+organizationId%3A+%7Bequals%3A+%24organizationId%7D%7D%29+%7B%0A++++++++jsonFileAssignments%28filter%3A+%7BjsonFileContent%3A+%5B%7Bresolution%3A+%24resolution%2C+fileType%3A+%24fileType%2C+state%3A+%22done%22%2C+default%3A+true%7D%5D%7D%29+%7B%0A++++++++++++jsonFile+%7B%0A++++++++++++++++outputDataObject+%7B%0A++++++++++++++++++++downloadUrl%0A++++++++++++++++%7D%0A++++++++++++%7D%0A++++++++%7D%0A++++%7D%0A%7D) to try the queries on live data. You will need to provide variables in this format:

{% code lineNumbers="true" %}

```json
{
 "organizationId": "<your organization id>",
 "articleId": "<article id>",
 "resolution": "High",
 "fileType": "exr",
 "assignmentType": "MaterialThumbnail_20x20"
}
```

{% endcode %}

The required link is the `downloadUrl` field of the first `dataObject` of the first `dataObjectAsssignment` returned, unless additional filter criteria apply (for example, you might want to filter by `mediaType` to exclude zip files and only offer download links to images).


# Welcome

colormass is the first robust 3D Content Management System that can be operated **entirely from your browser**. Here, you will find the documentation for the colormass platform. Whether you want to upload data, set up a 3D configurator, render images, tile materials, or integrate components into your website, this guide will provide all the information you need to get started and make the most of our online 3D CMS.

The tutorials are divided into the following two main chapters.

**Building Blocks:**

* [Products](/building-blocks/products): combinations of 3D geometry and materials
* [Materials](/building-blocks/materials): 3D materials
* [Scenes](/building-blocks/scenes): setups where 3D assets, cameras, and lights come together

These are **reusable building blocks**, not outputs themselves. You don’t generate final results (such as images or configurators) from these directly. Instead, they exist to be reused across multiple outputs.

If reuse is not required, you can skip building blocks and create outputs directly from scratch. However, anything created this way will not be reusable later.

**Outputs:**

* [Configurator](/configurator/introduction): interactive 3D views built from the building blocks that you can integrate into any website
* [Rendering Platform](/rendering-platform/introduction): images generated from the building blocks

<figure><img src="/files/rsfpEYgn40HK8JNlI284" alt="" width="375"><figcaption></figcaption></figure>

And additionally there is a chapter about scanning and tiling materials:

* [Scanning and Tiling](/scanning-and-tiling/scanning): Digitize and process scans.

Please watch the video to get an initial impression of the platform.

{% embed url="<https://vimeo.com/1160187010/33bcc76691?byline=0&portrait=0&title=0>" %}

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Upload and Manage Data</strong></td><td>3D CMS</td><td></td><td><a href="/files/bp568V9foHiKcEgqvOuj">/files/bp568V9foHiKcEgqvOuj</a></td><td><a href="/pages/PpvIoLVJ8ZOEBwPTxDxm">/pages/PpvIoLVJ8ZOEBwPTxDxm</a></td></tr><tr><td><strong>Set-up 3D Viewers</strong></td><td>Configurator</td><td></td><td><a href="/files/4pOdpcKPDkOSw7oK5QjL">/files/4pOdpcKPDkOSw7oK5QjL</a></td><td><a href="/pages/JBzdfOW885T0hFYg67TQ">/pages/JBzdfOW885T0hFYg67TQ</a></td></tr><tr><td><strong>Render Images</strong></td><td>Rendering Platform</td><td></td><td><a href="/files/XzrqRuqvNfA8YXV7i1u5">/files/XzrqRuqvNfA8YXV7i1u5</a></td><td><a href="/pages/ZdzgPpeyqjyTJ4VMJcA9">/pages/ZdzgPpeyqjyTJ4VMJcA9</a></td></tr><tr><td><strong>Scan Materials</strong></td><td>Scanning &#x26; Tiling</td><td></td><td><a href="/files/TWTwwNPrFx7Evl78cfmx">/files/TWTwwNPrFx7Evl78cfmx</a></td><td><a href="/pages/xwbzaM7zgR0AdB7h0k4S">/pages/xwbzaM7zgR0AdB7h0k4S</a></td></tr><tr><td><strong>Developer Docs</strong></td><td>Integrations</td><td></td><td><a href="/files/TnnVXBEFIZpbzKrDZtJb">/files/TnnVXBEFIZpbzKrDZtJb</a></td><td><a href="/spaces/upRNMrLmfdavpTEehRQn">/spaces/upRNMrLmfdavpTEehRQn</a></td></tr></tbody></table>


# Products

{% embed url="<https://vimeo.com/1160782213/66286984a4?fe=ci&fl=sv&share=copy>" %}

Products are a powerful way to store 3D assets online. This does not have an offline analog so it is a somewhat new concept that you will have to familiarize yourself with. Offline tools like Maya, 3ds Max, Blender etc. are very limited when it comes to storing and using product logic/variations, because these tools are not really meant for that. At colormass we refer to this as Content Engine (or Templates) which refers to the way how atomic data (meshes and materials) can be used and combined in a smart way. Templates are the backbone of storing 3D assets online.

## Introduction - What is a Product?

{% embed url="<https://vimeo.com/1205732135/8ecce7a3a0>" %}

## Adding a Product

The video below shows how to upload products from your 3D software.

{% embed url="<https://vimeo.com/1205732137/dea64bea6d>" %}

Find more details on the following pages: [Upload to Existing Product](/building-blocks/products/add-a-product/upload-to-existing-product).

## Assigning Materials

In the video below, you can see how to assign materials to your uploaded products.

{% embed url="<https://vimeo.com/1205732136/559947de0b>" %}

Find more details about assigning materials here: [Assign Materials](/building-blocks/products/assign-materials) and about inputs here: [Inputs and Outputs](/building-blocks/products/advanced/inputs-and-outputs).

## Creating Variants

Watch the video below to learn how to create simple variants of your products.

{% embed url="<https://vimeo.com/1205732134/85eea95e7e>" %}

Find more details on the following pages: [Create Variants](/building-blocks/products/create-variants) and [Create Material Variants](/building-blocks/products/create-material-variants).

## Creating Your First Configurator

Once you have created your first product, you are ready to create your first configurator as well, go to [Create Your First Configurator](/configurator/create-your-first-configurator).


# Add a Product

Press the *+Create* button and then click on *Product*:

<figure><img src="/files/srVBVI509yx72m5kPBRL" alt="" width="241"><figcaption></figcaption></figure>

Next there will be a prompt that will ask for the name of the product:

<figure><img src="/files/ZPcpBrLdmYivaFnVnP3D" alt="" width="303"><figcaption></figcaption></figure>

Furthermore you can choose between uploading a file, or starting from scratch.&#x20;

If you would like to upload a file you can upload a model by using one of the following supported formats:

* .obj
* .ply
* .fbx

{% hint style="info" %}
Looking to upload a **CAD** file? Check out this page: [Upload CAD File](/building-blocks/products/add-a-product/upload-cad-file).
{% endhint %}

{% hint style="warning" %}
If you upload a file, make sure to select the scale of your file correctly, and in case the UV is not World Space UV then we would also strongly recommend setting that.
{% endhint %}

Once you hit *Create* you should be navigated to an empty Product editor (or if you uploaded a file then the elements of your file should be available there).


# Upload CAD File

To upload CAD file to the platform please follow the steps below. For these steps you would need to download and use [**Rhino 3D**](https://www.rhino3d.com/)**.**&#x20;

## 1. Document Unit Setup

Make sure that Rhino’s units are set to *cm*.

To do this, click on the *Properties/Options* button to open up the options.&#x20;

<figure><img src="/files/nvQGvpJC3TXIxLdDtmsF" alt="" width="553"><figcaption></figcaption></figure>

Select *Units* under the *Document Properties*. If needed, you can open up the drop-down menu for *Model units* and select *cm*. Hit enter to close the window.

<figure><img src="/files/rb9fHGi65uk3xeRGCrhX" alt="" width="563"><figcaption></figcaption></figure>

## 2. Import

Import the CAD file into Rhino by navigating to *File > Import* and selecting your&#x20;reference file.

To set the correct unit settings for your model within the import options, ideally you would need to know what unit settings were used during the export of the model’s file. You can also try different values and measure the resulting model’s scale to check if it’s correct.

<figure><img src="/files/rE6hG2vupQHSVSCX4LOd" alt="" width="401"><figcaption></figcaption></figure>

With this particular example we set the units to mm.

### Warnings

The warnings displayed below can commonly appear during importing. For the first warning click *Yes:*

<figure><img src="/files/DTMIguTOJrsWkwmjUmWg" alt="" width="563"><figcaption></figcaption></figure>

And for the second warning click *Ok*:

<figure><img src="/files/XDJkTGu1UgsSBACwJ45I" alt="" width="512"><figcaption></figcaption></figure>

## 3. Positioning (as needed)

After the import is finished, check if the model is centered to the origin. If yes, then you don't need to do anything in this step.

If the views look empty at this point, that could mean that the model is placed far off from the center, and out of view. To find the model hit *CTRL + A*, then click on the zoom to selected tool. This will zoom in on the object on the viewport which is active.

<figure><img src="/files/OCYE7lZSyOrPO146XdAI" alt="" width="553"><figcaption></figcaption></figure>

{% hint style="info" %}
Tip: If you like, you can repeat the above command on the rest of the views, to center  the object, by simply right clicking inside the area of each of the remaining views
{% endhint %}

Selected objects will be highlighted with bright yellow wireframe.

When you located your object, you can group the individual parts together by pressing *CTRL + G* (For ungroup hit *CTRL + Shift + G*). This will keep the parts of your model holding their position relative to each other during transforms.

Finally, while the model is grouped and selected, look for the align tool on the left side toolbar, click on the small triangle on the bottom right corner of the tool to make all the align options visible, and activate the align center option by clicking on it.

<figure><img src="/files/1WccCHZEu1je38IkE5LY" alt="" width="405"><figcaption></figcaption></figure>

You can see that the tool is active when the model starts to follow the position of your cursor. To center the object to the world origo, hit the 0 on your keyboard or numpad, and then enter. The model is still selected. If it disappears from your view you can use zoom to selected tool again to locate it.

## 4. Remove Unnecessary Parts

In order to make the resulting file size more manageable, it is recommended to remove some parts of the product that are not visible from the outside (e.g. bolts, drawer rails).

To better see if there are any such parts within the model, you can click to the dropdown icon next to the Perspective viewport, and change the mode to *ghosted*. (edited) <br>

<figure><img src="/files/9MwCi5YLruRbqKJ8XoZl" alt="" width="563"><figcaption></figcaption></figure>

To select the smaller parts inside the model, you can click and drag a selection box (starting from an empty area outside the object), dragging from Right to Left. This way the selection will only apply to parts that are completely included in the selected area.&#x20;

<figure><img src="/files/1Qdk1cDkiPG1mKvGDmSg" alt="" width="563"><figcaption></figcaption></figure>

<figure><img src="/files/NGSIaFJZuEPpdUea5O70" alt="" width="563"><figcaption></figcaption></figure>

When you have the unwanted parts selected, press DEL to delete them from the scene.

## 5. Meshing

To create a mesh, select the object, type “Mesh”&#x20;in the upper command&#x20;line, and press Enter.

<figure><img src="/files/4ubjYaWXUtsGsu8TjNJQ" alt="" width="365"><figcaption></figcaption></figure>

The dialog box appears. You can choose between&#x20;two types of dialog boxes:&#x20;simplified or detailed.

<figure><img src="/files/M2qpU8MCgo40hfiE3NDE" alt="" width="563"><figcaption><p>Simplified view</p></figcaption></figure>

Most of the time, the simple&#x20;mesh options are enough to create the mesh model. Press&#x20;Enter to generate the mesh&#x20;model.

If you press the *Detailed Controls* you can also see the more detailed dialog:

<figure><img src="/files/SIJIyNBBP80I53tC8p3q" alt="" width="563"><figcaption><p>Detailed view</p></figcaption></figure>

The detailed mesh option is an advanced meshing dialog. You can define various&#x20;parameters before meshing, such as density, simple planes, and jagged seams.

The resulting mesh would look something like this:

<figure><img src="/files/sJjLFgbR9UqhtrpZQ6G3" alt="" width="563"><figcaption></figcaption></figure>

## 6. Export

In this case, the mesh and the&#x20;NURBS model are in the same&#x20;position. Go to the Selection&#x20;menu and choose the “Mesh Select” tool

<figure><img src="/files/kcWJ72oZdmZDhnlOuSRn" alt=""><figcaption></figcaption></figure>

Then go to the *File menu > Export Selected* option, and export the model&#x20;in your preferred file format. In order to make the file work on the platform please make sure to select *.obj* or *.fbx.*

## 7. Upload

When uploading to the colormass platform, make sure to select *Convert to World Space UVs* on the dialog that appears after upload:

<figure><img src="/files/fSXdlwltcJc6C00kjZLI" alt="" width="559"><figcaption></figcaption></figure>

This will make sure to correct the mapping issues the CAD file has.


# Upload to Existing Product

In the product editor you can simply select&#x20;

<figure><img src="/files/fJwkzpEgWSH7voL2HhEI" alt="" width="563"><figcaption></figcaption></figure>

Once you selected your .obj, .fbx or .cmm file you should see the uploads starting and then also a folder where your meshes are now grouped. If you press the *Edit* and then the *Dissolve group* option you should see all the elements listed in the main tree.

<figure><img src="/files/RT0rEd4JN8z4SDxNrIxk" alt="" width="318"><figcaption></figcaption></figure>


# Assign Materials

First you have to add the material to your template editor. You can do that clicking on the *Materials* button in the top bar:

<figure><img src="/files/nnObuTsRD2GWA4eCEM82" alt="" width="563"><figcaption><p>Add a material</p></figcaption></figure>

Once its added to your product tree, you can assign the material in two simple steps:

1. Selecting the mesh where you want to apply your material
2. And then dragging & dropping our material to a slot

like so:

<figure><img src="/files/p9geg8UnqLG70H6w4Rda" alt=""><figcaption><p>Assign a material</p></figcaption></figure>

Alternatively you can also directly drag the material into the 3D viewer onto the part of the mesh that you would like to assign it to:

<figure><img src="/files/Qg8ANEYBhJ2sOVcma0RL" alt=""><figcaption><p>Alternative option to assign a material</p></figcaption></figure>

## Remove Assignment

To remove the assignment simply click on the bin icon on the top left corner of the material assignment:

<figure><img src="/files/arVSw42pEN2xm07eHgXT" alt=""><figcaption><p>Remove material assignment</p></figcaption></figure>


# Pattern Placement

When a material is assigned, you can easily adjust the pattern placement. You can move the material along both the **X** and **Y** axes, and you can also **rotate** it.

To  change the placement you would need to click on the arrow button in the top right corner and change the values in the dialog window that appears:

<figure><img src="/files/zrDgeMgFwMAFPdd4MLM1" alt=""><figcaption><p>Move the pattern placement</p></figcaption></figure>


# Create Variants

Configuration Groups are used to define variations (any kind of variation: product feature, finish or fabric variations) within a template.&#x20;

In order to show you how it works lets add a variation to the ***chair for showing and hiding the seating pad***.

First you need to add a new *Config(uration) Group*:

<figure><img src="/files/SU83OJokkxn6l76AZeyB" alt=""><figcaption><p>Add a Config Group</p></figcaption></figure>

This will add a new *Config Group* to the product tree on the left. If you expand it you will see two options: *Add variant* and *Add switch*. In order to add more variants to the product we need to press the *Add variant* button, as many times as many variations you need. In this case we will add two and name them:

* With seating pad
* Without seating pad

Once the variants are done we only need to drag & drop the seating mesh into the *With seating pad* option, so that when that variant is selected the mesh is shown and when the other option (*Without seating pad*) is selected then nothing is shown. You can see all these steps in the little screenrecording below:

<figure><img src="/files/UYhVkjy6OYnMdcUB89Rt" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
You can think of config variants as options that can be activated. The options you see below config group are possible options to active and every option that is not selected is deactivated (i.e. hidden/removed).
{% endhint %}


# Create Material Variants

## Simple Material Variants

To better demonstrate how to add material variations to your product, we'll walk through the process of adding two fabrics to our seating pad.

The first step is to add a new *Config Group* with two options to our product (if you're unsure how to do this, refer to the first step in the [Create Variants](/building-blocks/products/create-variants) page) and then add your two fabrics as well. The first steps would look something like this (assuming  you would only want to add two fabric options):

<figure><img src="/files/ERc0k8orGlOM5e3UefgB" alt=""><figcaption><p>Add the Config Group and the two materials</p></figcaption></figure>

Once these initial steps are done you, you'll need to do three additional steps:

* Move the right materials to the corresponding *Config Variant*
* Create a *Material Switch* (this will be the item that will act as a combined material)
* Select the materials under your *Config Variants* and add them to the switch

You can see these same steps below in the screenrecording.

<figure><img src="/files/KaQpwqwPYXjbAH8SlLop" alt=""><figcaption><p>Creating a Material Switch</p></figcaption></figure>

Now you can use the *Material Switch* that you created in the step above as a regular material and assign it to whichever mesh you would like.

<figure><img src="/files/LfwUbHPvmMR0a5DRAGF3" alt=""><figcaption><p>Assign the Material Switch to a mesh</p></figcaption></figure>

You can create as many separate Material Variants as you want. You can create a group of options for the leg (finish options) and for seating pad (fabric options) but you can of course create even more depending on your real life product. These&#x20;

## Advanced Material Variants

In some cases it is necessary to change the finish *in the same time* as you would change the fabric, meaning that a specific fabric option comes with a specific leg finish (and they are not independent options).

To illustrate this, let's assume that the two fabric options we created initially each have a corresponding wood finish. *Fabric 01* should always be paired with *Wood 01*, and *Fabric 02* should always be paired with *Wood 02* finish. To do this, we need to:

* Add the two wood options
* Move them under the original variants
* Create a new *Material Switch*&#x20;
* Add the selected wood finishes under the new *Material Switch*

<figure><img src="/files/t2egZkdPNgKFxfu4t76o" alt=""><figcaption><p>Adding a new Material Switch</p></figcaption></figure>

At the end of the video you can see that the fabric and the finish changes in the same time and what is displayed when an option is selected is determined by what is listed under that option.


# Copy a Product

To  copy a product you simply need to hover over the card of the product and then press *Copy:*

<figure><img src="/files/6JMjQKT7Uix4z0DBCDg3" alt="" width="247"><figcaption><p>Copy a product</p></figcaption></figure>


# Advanced


# Decals

## Adding a Decal

First of all, we would need to add the decal. Go to the *Other* button in the top bar and select Mesh Decal.

<figure><img src="/files/fClqOgIES1wG1gDOY5A4" alt="" width="563"><figcaption><p>Add a Decal</p></figcaption></figure>

Once the *Decal* appears in your product tree, you will need to select an overlay image. To do this simply click on the *Overlay Image* area:

<figure><img src="/files/m1Qas49zrXskSb2ScWUv" alt=""><figcaption><p>Upload decal</p></figcaption></figure>

Once you have uploaded your decal you would need to do three important steps:

* Assign the base mesh (by dragging and dropping it into the *Base Mesh* field): this is the mesh where the decal will be applied.
* Assign a base material (by dragging and dropping it into the *Material* field): this serves as the substrate material for applying the image.
* Choose a point: Select a point on the mesh where the decal should be placed.

You can see all these three points in the screenrecording below.

<figure><img src="/files/UosgPls6pGjRadXm4Ngb" alt=""><figcaption><p>Assign the base mesh and the base material</p></figcaption></figure>

## Move the Decal

Once you uploaded your decal, you also have various options to&#x20;

* Change the size of the decal with *Size U* and *Size V,* just make sure to keep your aspect ratio match to your original image (to avoid distortion)
* Change the exact position of the decal with *Offset U* and *Offset V*
* Rotate your decal with the *Rotation* field

<figure><img src="/files/m85O3yHGCnzRy1axGfAn" alt=""><figcaption></figcaption></figure>

## Overview

Below you can see a small overview of the Decal options.

<figure><img src="/files/cv8SymUic0xBPmWAIdKU" alt=""><figcaption><p>Settings of the Decal</p></figcaption></figure>


# LOD Management

In general the colormass system handles dynamic compression (on the server side) and decompression (on the client side) so that you don't have to absolutely minimize your 3D assets. But in some cases it is good to have an extra tool to manually adjust LOD details and decide what to show where. The colormass platform offers three distinct usecases:

* **Web**: displaying the asset in a configurator
* **AR**: displaying the asset in app-less AR way
* **Path-traced**: using assets in path-traced image rendering

In practice it is usually the best to define two: **Web** and **Path-traced**. To set these first add a group to your product:

<figure><img src="/files/sPSuzdClANfRZX9zLaUE" alt="" width="563"><figcaption><p>Add groups</p></figcaption></figure>

and name then based on what use case will be inside that folder. Move the elements that you would only like to display for that use case under this folder, like so:

<figure><img src="/files/WGkJlfRbhUbyJIi5Uem2" alt="" width="213"><figcaption><p>Group with stitching inside</p></figcaption></figure>

Once all this is done we only have to do one more step, click on the *Other* button and select *LOD Type*:

<figure><img src="/files/5M0M35Rmun5E7WIAP9H2" alt="" width="563"><figcaption><p>LOD Type</p></figcaption></figure>

Then select the use case that you would like to set for your folder:

<figure><img src="/files/z7JTrlnUrfFnJANZkj0X" alt="" width="563"><figcaption><p>Type selection</p></figcaption></figure>

and assign it the *Active* field of your folder:&#x20;

<figure><img src="/files/K6MHcJJWgsDWtuZ0F3Oe" alt="" width="563"><figcaption><p>Assign LOD Type</p></figcaption></figure>

this will make the folder active (visible) during image rendering and inactive (hidden) for any other use case (web, AR).

You can confirm if this is the case if you click on the bottom right corner (in the viewer settings) and switch between the toggle buttons at the very top. You will see that the items which were moved under a folder called *Path-traced* is only shown during *Path-traced* use case:&#x20;

<figure><img src="/files/bu32kLC6hKTOaoMAWRHE" alt=""><figcaption><p>Reviewing the use case</p></figcaption></figure>


# Review Products

Once a product is prepared you have the possibility to review the final product using wireframe and UV tools. To bring up these tools you simply have to click on the bottom right corner (viewer settings) and click on one of the three options:

* Wireframe
* UV
* UV2

<figure><img src="/files/IsHRUEhWRxdO8scffFrh" alt="" width="563"><figcaption><p>Review options</p></figcaption></figure>

{% hint style="info" %}
It is not part of the current tutorial series to describe how you can use these tools to review a model but in case you are interested please write to your contact person at colormass.
{% endhint %}


# Review Products - Performance

On the colormass platform, you can also review a product’s performance by clicking *Performance* under *View*:

<figure><img src="/files/IXvNBzzC81u5AnY7cdQC" alt="" width="563"><figcaption></figcaption></figure>

This allows you to evaluate your product’s performance across several key metrics. You can review the following for your 3D scene:

* Memory usage
* Download size
* Number of triangles

<figure><img src="/files/NmzSOHXuVAE543iIDkOc" alt="" width="563"><figcaption></figcaption></figure>

Next to each item, you can view its individual footprint based on the selected performance factor.

<figure><img src="/files/OvgbT1cf1uiDJiRK9LyC" alt="" width="540"><figcaption></figcaption></figure>


# Create Template from Selection

In some instances you already have a product created but you realize that maybe a small part needs to be saved out as a reusable 3D element to be used in other products as well.

In this case you would need to first select part of the templates that you would like to save out, like the seat is selected in the screenshot below:

<figure><img src="/files/Olk393f93VMili6QbPqN" alt=""><figcaption><p>Selection</p></figcaption></figure>

then press Create Template from Selection using the *Other* menu:

<figure><img src="/files/eA1hVLqXh2FQlIXW44wI" alt=""><figcaption><p>Create Template from Selection</p></figcaption></figure>

then you would need to name the product.

<figure><img src="/files/eDHEWnCtK3eXYSsMNmgT" alt="" width="342"><figcaption><p>Name</p></figcaption></figure>

This creates an internal template, but after you click *Edit* you can promote it to a reusable element that appears in the library.

<figure><img src="/files/BsrvxOjiMlY1EePZ9WV9" alt="" width="375"><figcaption></figcaption></figure>


# Inputs and Outputs

*Inputs* and *Outputs* are very powerful features of the platform. When you create a product they are basically black boxes when they are used in other products or scenes. Meaning, that if you include them in a scene you basically can not change anything about them - unless you add *Inputs*.  This design ensures that when you embed multiple product layers within each other, they update correctly without overwriting existing modifications or causing errors.

{% hint style="warning" %}
Inputs and Outputs are a bit more advanced 3D editing features of the platform, therefore we recommend only starting to explore this section if in general you are familiar with the other 3D management concepts of the colormass platform.
{% endhint %}


# Inputs

Inside a product you can add an input using the *Other* button:

<figure><img src="/files/XLXaeQATEnbOzMBRtrt1" alt="" width="563"><figcaption><p>Adding an input</p></figcaption></figure>

You have various options for the type of input you want to add (depending on what kind of influence you want to give to the scene where this product will be included).

For example you can add a *Material Input,* which will allow the parent scene (the scene where it will be included) to assign material to this input that we you have just created. This material input you can use as a regular material and assign the areas of the product that you want to allow to override in any parent scene.

When you now add your product to the a scene, you will see a new input appear:

<figure><img src="/files/1Wo979ziLAWjZpRx4Lyz" alt="" width="563"><figcaption><p>Material input</p></figcaption></figure>

where you can now use to drag and drop a regular material to override:

<figure><img src="/files/nsFLqTPHaU7zjURhKQDu" alt=""><figcaption><p>Assigning material to an input</p></figcaption></figure>

Notice that in the parent scene you re not able to edit anything else other than assigning a material to the input.

An input always contains a *Default* field:

<figure><img src="/files/CUjoy1qlaM5gUVDw8og8" alt="" width="251"><figcaption><p>Default field</p></figcaption></figure>

This is the value that will be used if nothing is assigned to the input in the parent template.

{% hint style="info" %}
The color of inputs is always blue and the color of outputs is always red. This way you can always quickly see what fields you can assign values to (*Inputs*) and what fields you can use as values that you can assign to other areas (*Outputs*).
{% endhint %}


# Outputs

*Outputs* are the opposite of *Inputs*: these fields can be created to supply values to the parent scene, rather than being used to override elements within the product itself.

Inside a product you can add an output using the *Other* button:

<figure><img src="/files/fozuNTZu00qZCQfF8lZT" alt="" width="563"><figcaption><p>Add an output</p></figcaption></figure>

To demonstrate one way to use outputs, lets say that you want to create a group of finish options that can be reused inside many products. For this we first create a new product and add the options as described in the [Create Material Variants](/building-blocks/products/create-material-variants)page. Then we add a new *Material Output.* Once we have both the options and the *Output* then we need to simply assign the *Switch (this is the combined material)* of the material options to the *Output.*

<figure><img src="/files/pHG2E29fkA4yFFYO1TIQ" alt="" width="563"><figcaption><p>Assign the material switch to the output</p></figcaption></figure>

This way, wherever this product is included, the output (the finish options) can be used by the parent scene. This makes it possible to create dedicated finish-option-products that are specifically designed to be used in products and assigned as finish options. As a result, you can avoid duplicating finish options and simply create reusable configurations.

You can see how this new *finish-option-product* can be used inside another product below:

<figure><img src="/files/aPPpgdBbBsHUfgyT1sUo" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
The color of outputs is always red and the color of inputs is always blue. This way you can always quickly see what fields you can assign values to (*Inputs*) and what fields you can use as values that you can assign to other areas (*Outputs*).
{% endhint %}


# Convert Element to a Reusable Template

At any time during your work, you may want to turn part of an existing scene or product into a reusable element. To do this, simply select the elements you want to reuse - just the top-level elements are enough; there's no need to dig into folders or config groups to select the children - like this:

<figure><img src="/files/E5f64gCkKncqtssXDbuI" alt=""><figcaption><p>Create a template</p></figcaption></figure>

This only created a template in your local editor. You can duplicate the instance (the item with the blue icon) as many times as you like. However, to make this template available in your library, you also need to publish it. You can do this by clicking on the template that you just created and press *Promote to library*:

<figure><img src="/files/n0uaouV027TXbNEKcnL1" alt="" width="334"><figcaption></figcaption></figure>


# Remove a Product

On the platform, products that are in use or have associated data cannot be removed easily by design. This prevents users from accidentally deleting work that may have taken days to create with a single click. Additionally, if a product is already used in a scene, the system restricts its removal to avoid errors when the scene is opened later.

To remove a product, you need to that the product doesn't have any revisions (see [#remove-product-revisions](#remove-product-revisions "mention")).

## Remove Product Revisions

In order to remove a product first you would need to remove all of its revisions. You can do this by clicking on the *Show version history* and removing each history item, or you can also just simply click on *Discard last revision* until there is no revision left.

<figure><img src="/files/CCni4RH1CzpC3H1FdgRn" alt=""><figcaption></figcaption></figure>

If you see that a product revision cannot be removed, it means that it is currently referenced in a scene or in another product. At this point, removing the product becomes intentionally more restricted, because it has already been used in one or more scenes. If the product was removed, those scenes would produce an error every time they were opened. You can view the list of scenes where the product is used in the following section in the dialog window:

<figure><img src="/files/7USEdI3OcN99ecXwi5Jw" alt=""><figcaption></figcaption></figure>

You would need to open each scene and manually remove the product. The system will not remove it automatically, since doing so could potentially damage the many scenes at once.  Once you removed it from the scenes, you should be able to remove the product revision as well.

## Remove Product

To delete the product once there are no associated revision, you just have to click on the three dots and press *Delete product.*

<figure><img src="/files/ETpFgZo5F1rc6eT1ZExb" alt=""><figcaption></figcaption></figure>


# Documentation Review

Using the [Products](/building-blocks/products) documentation please create a new product in the *Products* tab named *\[YOUR NAME] – Test*.

After opening the editor, upload the file below:

{% file src="/files/uWtIe4tGba4iVXSiuQn4" %}

Using this 3D file, please complete the following tasks:

* Following the [Create Variants](/building-blocks/products/create-variants) page create two configuration variations:
  * One where the seating pad is visible
  * One where the seating pad is hidden
* Following the [Create Material Variants](/building-blocks/products/create-material-variants) create two wood finish variations and apply it to all parts except the seating pad
* Assign a fabric (any selection from the library) to the seating pad

Once the product setup is complete, create a render (following the [Render Your First Image](/rendering-platform/render-your-first-image) page) by selecting a 3D scene from the library and placing your newly created chair into the scene. You will need to create a new folder (Project) and sub-folder (Set) please use your own name for the folder (Project) and for the sub-folder (Set).

Once all of this is done, create a new picture and batch render (following the [Batch Rendering](/rendering-platform/batch-rendering) page) all the variations of the product (4 in total).


# Materials

{% embed url="<https://vimeo.com/1160795433/d1855e0db2?byline=0&portrait=0>" %}

## Intro

In the **Materials** tab, you can manage and process your existing scans or upload new materials. The video below provides a quick introduction to creating and working with different types of materials on the platform.

{% embed url="<https://player.vimeo.com/video/1198708258?h=eef8a9b894>" %}

{% hint style="info" %}
The tiling of materials is discussed in a separate chapter: [Scanning and Tiling](/scanning-and-tiling/scanning)
{% endhint %}


# Add a Material

Press the *+Create* button and then click on *Material*:

<figure><img src="/files/ng6DnlKQrog1LMPzc7cV" alt="" width="241"><figcaption></figcaption></figure>

Next there will be a prompt that will ask for the name of the material:

<figure><img src="/files/ofA7q8xAsJqJFJtvq9RF" alt="" width="293"><figcaption></figcaption></figure>

Next you should select how you would like to create a new material:

* **Blank:** Choose this if you are scanning with the colormass scanner (see [Scanning](/scanning-and-tiling/scanning))
* **From Image:** Choose this if you would like to create the material using a single image (see [Upload Image as a Material](/building-blocks/materials/add-a-material/upload-image-as-a-material))
* **From Image (AI):** Choose this if you would like to create the material using a single image but would like to enhance it with the colormass AI material creation (see [Upload Image as a Material (AI)](/building-blocks/materials/add-a-material/upload-image-as-a-material-ai)). Please note that this AI technology is still experimental. Check <https://www.colormass.com/products/material-ai> for more details about the technology.
* **From PBR Files:** Choose this if you would like to upload your own maps (see [Upload PBR Materials (Custom)](/building-blocks/materials/add-a-material/upload-pbr-materials-custom))


# Upload Image as a Material

To create a new material from an image follow the [Add a Material](/building-blocks/materials/add-a-material)page and select the *From Image* option.

In the dialog drag and drop your image that you would like to use like so and type in the width and height (in cm) like so:

<figure><img src="/files/I4ioIEdlIn2TyS2o1Bqu" alt="" width="294"><figcaption></figcaption></figure>

The click on *Create*. Tis should now prepare the basis of your material and the last step to do is to click on *New material:*

<figure><img src="/files/zT1PrnpCxk24cskS4GmB" alt="" width="563"><figcaption></figcaption></figure>

and then *Save* the material, like so:

<figure><img src="/files/sMic0egH7mOd1lhUxnr2" alt=""><figcaption></figcaption></figure>


# Upload Image as a Material (AI)

When you click on the [Add a Material](/building-blocks/materials/add-a-material) button please select *From Image (AI):*

<figure><img src="/files/SJJunj7k60YakmuR14yO" alt="" width="295"><figcaption></figcaption></figure>

Here, you’ll need to fill out:

* The name
* The size (please make sure it is accurate)
* Any relevant tags you find applicable (these help the AI algorithm categorize the material more effectively)

Once you press *Create*, the algorithm will start processing and will take approximately 10–15 minutes to complete. After the process is finished, you will find the maps listed under your item, like this:

<figure><img src="/files/8rje2HXG37eHLt0lJKZu" alt="" width="563"><figcaption></figcaption></figure>


# Upload PBR Materials (Vizoo, AXF)

{% hint style="info" %}
colormass offers an automated solution for integrating **Vizoo** and **AXF** scans into the system. Currently, this conversion is handled by colormass staff, but if your team needs to perform individual conversions rather than processing a large batch at once, please contact your colormass account manager to see how this can be added to your account as an individual feature.
{% endhint %}


# Upload PBR Materials (Custom)

To create a new material from an image follow the [Add a Material](/building-blocks/materials/add-a-material)page and select the *From PBR Files* option.

<figure><img src="/files/CqCMypJ8rAt0xfMjnFRn" alt="" width="293"><figcaption></figcaption></figure>

The click on *Create*.&#x20;

This will open a new material dialog, where the texture set, with the placeholder maps are already created, where you will be able to drag and drop your maps:

<figure><img src="/files/OwXKvRBW6wSte0pwViJf" alt="" width="563"><figcaption></figcaption></figure>

Drag and drop your maps to the slots that best describe the map you are trying to upload and then also enter the **physical size** of the maps, like so:

<figure><img src="/files/PSbCtRspunUothKrKCeB" alt="" width="563"><figcaption></figcaption></figure>

then click on *Save*. After these steps now there is only one step left to do, which is to click on *New material:*

<figure><img src="/files/Mwf4LtZH9l4tyhybUook" alt="" width="563"><figcaption></figcaption></figure>

and then save the material:

<figure><img src="/files/YQVNRvIRjXxxl5HRc8uY" alt=""><figcaption></figcaption></figure>


# Copy a Material

To  copy a material you simply need to hover over the card of the material and then press *Copy:*

<figure><img src="/files/0hDMqWB1aDC8JLbJnOj9" alt="" width="261"><figcaption><p>Copy a material</p></figcaption></figure>

Once you press the icon the new material with the exact same material graph will be created. The name will be the same as the original material with a "(Copy)" added to the end of the title.

<figure><img src="/files/A4TvVlkWS69UCg0weF88" alt=""><figcaption></figcaption></figure>


# Recolor a Material

It happens often that you want to use an existing scan or material and copy it multiple times (see [Copy a Material](/building-blocks/materials/copy-a-material)) and then recolor it or that you need to simply adjust the color of an existing scan. In either case as a first step we would need go to your copied or original material and open the material editor by clicking on the *Edit material* button.

<figure><img src="/files/6kq9xmDnKCfK37mzOYtN" alt=""><figcaption><p>Edit material copy</p></figcaption></figure>

This will open up the material editor. In the material editor the Base color is simply taken from the scan or uploaded image and plugged in to the material definition (node on the right), so to change the color we would need to break this line and add an adjustment node.

<figure><img src="/files/ZxrVGSTU8KzcpXTTpsxo" alt=""><figcaption><p>Base color</p></figcaption></figure>

In the recording below you can see how you can add a [RGB Curve](/building-blocks/materials/recolor-a-material/rgb-curves) node that you can then use to adjust the color. Just as in Photoshop, you can add multiple different adjustment nodes RGB Curve is just one option you can also use [HSV](/building-blocks/materials/recolor-a-material/hue-saturation-value) node.

<figure><img src="/files/59yH9nHwVFcDMz92XP2r" alt=""><figcaption><p>Adding an RGB Curve node</p></figcaption></figure>

The only step left to do is to adjust the curve (or HSV values) depending on which node you chose in the end, like so:

<figure><img src="/files/0vJAhRhV61rW7Y03NRx6" alt=""><figcaption></figcaption></figure>

Once you are done do **not** forget to *Save* your material.


# RGB Curves

The RGB Curves Node allows color corrections for each color channel and levels adjustments in the compositing context.

<figure><img src="/files/sv94bZWpROahusA6tjk9" alt="" width="188"><figcaption><p>RGB Curve Node</p></figcaption></figure>

Clicking on one of the channels displays the curve for each.

* RGB (Combined RGB)
* R (Red)
* G (Green)
* B (Blue)


# Hue Saturation Value

The Hue Saturation Value Node applies a color transformation in the [HSV Color Model](https://en.wikipedia.org/wiki/HSL_and_HSV).

<figure><img src="/files/CAq0zN4PEwqSTcTgFqNB" alt="" width="194"><figcaption><p>HSV Node</p></figcaption></figure>

### Hue

Specifies the hue rotation of the image. 360° are mapped to (0 to 1). The hue shifts of 0 (-180°) and 1 (+180°) have the same result.

### Saturation

A saturation of 0 removes hues from the image, resulting in a grayscale image. A shift greater than 1.0 increases saturation.

### Value

Value is the overall brightness of the image. De/Increasing values shift an image darker/lighter.


# Adjust Reflectivity

In order to adjust the reflectivity of a material on the platform you would first need to navigate to the specific material that you would like to change and click on the *Edit material* button.

<figure><img src="/files/sEyqFdBrBm5ZzZV1eg5c" alt=""><figcaption><p>Edit material</p></figcaption></figure>

This will open up the material editor. In the material editor the reflectivity is mostly controlled by the Roughness map, so to change the reflectivity we would need to break this line and add an adjustment node.

<figure><img src="/files/4NQ8KyQZ2yxk5DPSo9g1" alt=""><figcaption><p>Roughness map</p></figcaption></figure>

In the recording below you can see how you can add a [RGB Curve](/building-blocks/materials/recolor-a-material/rgb-curves) node that you can then use to adjust the reflectivity.&#x20;

<figure><img src="/files/YA69dbuovM4rRvrqYtLJ" alt=""><figcaption><p>Reducing roughness</p></figcaption></figure>

The [RGB Curve ](/building-blocks/materials/recolor-a-material/rgb-curves)works the same way as in photoshop. The RGB Curve in this case simply adjusts the brightness of the roughness (the brighter it becomes the less reflective, the darker it becomes the more reflective). So in order to decrease the reflectivity simply drag the bottom left point more to the top, like so:

<figure><img src="/files/UTakKfZY2gUNDYp3jWNB" alt=""><figcaption><p>Decrease reflectivity</p></figcaption></figure>

or drag the top-right point and drag it down, like so:

<figure><img src="/files/9ZhmidblSaVDJsl4iGr0" alt=""><figcaption><p>Increase reflectivity</p></figcaption></figure>


# Adjust Opacity


# Materials with Transmission

You can determine if a material belongs to this category by checking for a node called Scanned Transmission.&#x20;

To adjust the opacity, simply modify the *Opaque Threshold* (see below).

<figure><img src="/files/pbigHJRr31U0a5okU5HQ" alt=""><figcaption></figcaption></figure>

If you decrease this value then the material becomes more and more see through, see below:

<figure><img src="/files/Nl2vzegxNeiVWiK0YfyR" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/eCU1v1qbHeozMtzDLI6c" alt=""><figcaption></figcaption></figure>


# Materials without Transmission

In order to adjust the reflectivity of a material on the platform you would first need to navigate to the specific material that you would like to change and click on the *Edit material* button.

<figure><img src="/files/sEyqFdBrBm5ZzZV1eg5c" alt=""><figcaption><p>Edit material</p></figcaption></figure>

This will open up the material editor. In the material editor the reflectivity is mostly controlled by the Alpha map, so to change the opacity we would need to break this line (see highlighted in red below) and add an adjustment node.

<figure><img src="/files/4pSNE6gFSQR6ZMvH3mzE" alt=""><figcaption></figcaption></figure>

In the recording below you can see how you can add a [RGB Curve](/building-blocks/materials/recolor-a-material/rgb-curves) node that you can then use to adjust the opacity.&#x20;

<figure><img src="/files/xAZYC1kMngXYnk7d9TIn" alt=""><figcaption><p>Reducing opacity</p></figcaption></figure>

The [RGB Curve ](/building-blocks/materials/recolor-a-material/rgb-curves)works the same way as in photoshop. The RGB Curve in this case simply adjusts the brightness of the alpha (the brighter it becomes the less see-through, the darker it becomes the more see-through it becomes). So in order to decrease the see-through simply drag the bottom left point more to the top, like so:

<figure><img src="/files/g1bIAhUdYoqLtZ2qejRo" alt=""><figcaption><p>Decrease see-through</p></figcaption></figure>

or drag the top-right point and drag it down, like so:

<figure><img src="/files/WnqsU29Hx3cdd4B7gfEU" alt=""><figcaption><p>Increase see-through</p></figcaption></figure>


# Change a Map (Substrate)

In some cases, it’s necessary to replace a map of a scanned or finished material. Most often, this involves swapping the diffuse map to introduce a new pattern while preserving the other captured reflection details.

{% hint style="warning" %}
Please note that this is an advanced change. If you are not sure what this option does, we recommend not using it.
{% endhint %}

The best way to start is by copying an existing material, such as a substrate scan (see [Copy a Material](/building-blocks/materials/copy-a-material)). Once you open the copied material, you will see the original set of textures displayed.

Next you would need to add a new Texture Set:

<figure><img src="/files/4gfzZNlgt94QzQkGb7wa" alt=""><figcaption></figcaption></figure>

Inside the new Texture Set, upload your new map (in this case, the Diffuse Map) by simply dragging and dropping it, as shown below:

<figure><img src="/files/tlQ8gPHqhyhEGKJRfmrP" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
Do not upload the texture into the existing Texture Set, because the system will interpret the newly uploaded texture set as an updated version of the original and overwrite it.
{% endhint %}

You will also need to specify the size of the new map. Make sure the physical dimensions match the real-world size represented by the newly uploaded texture:

<figure><img src="/files/RAI4GWuYr3LkwRpO5Avd" alt=""><figcaption></figcaption></figure>

and then press *Save*.

Once it is saved, copy or remember the Texture Set ID (in this case 61012) and navigate to *Edit Material:*

<figure><img src="/files/Ag1mAjf0ZYjtiSXqJy9Z" alt=""><figcaption></figcaption></figure>

Then click *+ Add a new node* and select a new *Texture Set* from the menu.

<figure><img src="/files/A3sEMzmes0RHLb1jSOqY" alt=""><figcaption></figcaption></figure>

and add the *Texture Set* ID here:

<figure><img src="/files/lr1oQ2a5BOZGoa60rPQs" alt=""><figcaption></figcaption></figure>

As a final step, connect the UV output to the X-Y-Z input, and plug the Base Color into the Base Color input of the Principled BSDF node like so:

<figure><img src="/files/aeseDrNIysdPNBzkF0YS" alt=""><figcaption></figcaption></figure>

Once you are finished, save the material.


# Material Explorer

The *Material Explorer* is a tool that you can use to explore how your graphics (regular images) would look on furniture pieces, without having to manufacture the fabric or patter.&#x20;

To use the *Material Explorer*, first navigate to the *Materials* tab:

<figure><img src="/files/PbWYYu15uwjJdZAVBEw9" alt="" width="563"><figcaption></figcaption></figure>

{% hint style="info" %}
In case you don't see this button that means your account doesn't have this feature turned on, please contact colormass staff to enable this feature.
{% endhint %}

Once you click on the button it will bring up a dialog window that should look something like this:

<figure><img src="/files/FNazrHINiyzJcuHkm4lW" alt=""><figcaption><p>Material Explorer dialog</p></figcaption></figure>

Click on folder icon in the bottom right corner and select your image. Next you will be asked to enter the dimensions of the uploaded image:

<figure><img src="/files/CPB4wx0pXqOOV0GrmrJi" alt="" width="256"><figcaption><p>Dimensions</p></figcaption></figure>

These are basically the physical size of the picture you just uploaded, these are important to make sure that the graphic is applied to the furniture pieces in the right size (if you get it wrong don't worry, you can change this later as well).

Once your image is uploaded you can start adjusting the size and the rotation of the material, just like in this screenrecording below:

<figure><img src="/files/68cMXqfUIXcRycvyRCQ7" alt=""><figcaption><p>Changing width and height of the pattern</p></figcaption></figure>

Furthermore in the bottom left corner you will be able to select furniture pieces to try for your pattern. &#x20;

{% hint style="info" %}
Please ignore the *Material Explorer Material* button on the left (just above the furniture selection). That button is meant for a specific use case that most probably will not be used in your account. If you are unsure please ask your contact person at colormass.
{% endhint %}


# Rotate Material

{% hint style="warning" %}
Before rotating a material, make sure you understand whether the issue is limited to a **single material** with incorrect orientation or if **all materials** appear incorrectly on the mesh. If it’s the latter, you should adjust the [Pattern Placement](/building-blocks/products/pattern-placement) not the material itself.

The easiest way to determine this is to open the texture editor (see below) and check whether the orientation shown there is the same as you would expect the orientation to be.
{% endhint %}

Navigate to the Materials tab and click on the material that you would like to change, and then click on the texture of the material:

<figure><img src="/files/Q0qwlWvh5246TOFTQKEE" alt="" width="563"><figcaption></figcaption></figure>

Then in the operators add the *Rotate* operator to rotate:

<figure><img src="/files/KGq0YPikR64Z4DJjR6mD" alt="" width="316"><figcaption></figcaption></figure>

{% hint style="info" %}
In case you only see a Tiling operator, then please click on Tiling operator first (without modifications and then apply the Rotate operator).
{% endhint %}

If you don't see a way to add an operator then please follow the [I Can't Add an Operator](/scanning-and-tiling/texture-editor/i-cant-add-an-operator) page apply your rotation after the copy and then update your material.

In case you are looking to edit the textures more, please look at the [Texture Editor](/scanning-and-tiling/texture-editor) section.

{% hint style="info" %}
Although materials can also be rotated directly in the material editor, we recommend performing rotations only in the texture editor. Some maps (such as normal maps) require additional adjustments when rotated, and rotating them solely in the material node editor can lead to incorrect visual results.
{% endhint %}


# Displacement

It happens often that you want to increase the intensity of the surface geometry of a scanned sample.&#x20;

The first step we would need go to your copied or original material and open the material editor by clicking on the *Edit material* button.

<figure><img src="/files/6kq9xmDnKCfK37mzOYtN" alt=""><figcaption><p>Edit material</p></figcaption></figure>

Once you’re editing the material, you simply need to enable Displacement and save a new revision, as shown below.

<figure><img src="/files/9oUCRCVbDXEHebvCkbec" alt=""><figcaption></figcaption></figure>

This will enable a default strength for the surface geometry. If you want to increase the intensity of the surface detail, go to the Texture Editor by clicking on any texture in the scanned set, then select Adjust size and set a value between 0 and 2 cm, as shown below.

<figure><img src="/files/X3iDM2NqD8G5Al6Ww6Sb" alt=""><figcaption></figcaption></figure>

To increase the intensity, simply raise the value above the default setting and press *Ok*.


# Scan Materials

This is described in detail in the [Scanning and Tiling](/scanning-and-tiling/scanning) chapter.


# Remove a Material

On the platform, materials that are in use or have associated data cannot be removed easily by design. This prevents users from accidentally deleting work that may have taken days to create with a single click. Additionally, if a material or texture is already used in a scene, the system restricts its removal to avoid errors when the scene is opened later.

To remove a material, you need to ensure two things:

* The material doesn't have any revisions (see [#remove-material-revisions](#remove-material-revisions "mention"))
* The material doesn't have any textures (see [#remove-textures](#remove-textures "mention"))

## Remove Material Revisions

{% hint style="info" %}
If you don't see any revisions under your material (and you only see a *New Material* button), then you can skip this step.
{% endhint %}

In order to remove the materail revisions, you would need to click on *Show version history*

<figure><img src="/files/UytGPRTvmS4mW0mPy4qM" alt=""><figcaption></figcaption></figure>

And then on the bin icon to remove each revision:

<figure><img src="/files/brGDLUcoTb8cvwUOUuX5" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/rgFvLbC3juhr7ah1BHEd" alt=""><figcaption></figcaption></figure>

If you see that a material revision cannot be removed, it means that it is currently referenced in a scene. At this point, removing the material becomes intentionally more restricted, because it has already been used in one or more scenes. If the material were removed, those scenes would produce an error every time they were opened. You can view the list of scenes where the material is used in the following section in the dialog window:

<figure><img src="/files/DjnaWa3jSBxSHVQQLdNM" alt=""><figcaption></figcaption></figure>

You would need to open each scene and manually remove the material. The system will not remove it automatically, since doing so could potentially damage the scene.

## Remove Textures

{% hint style="info" %}
If you don't see any textures under your material, you can skip this step.
{% endhint %}

Removing revisions is only one part of the process. You also need to explicitly remove the textures associated with the material under *Texture Sets.* Click on any of your textures:

<figure><img src="/files/167WlJKdXJmvSH1fqCsG" alt=""><figcaption></figcaption></figure>

Once you are in the texture editor, you can remove all of your texture revisions like so:

<figure><img src="/files/qJGDjjx1LsfI69yZhPf0" alt="" width="540"><figcaption></figcaption></figure>

And once those are removed, you still need to go back to the material and remove the complete *Texture Set* by clicking on the bin icon:

<figure><img src="/files/jxvNWFojQZko9l7rWBhB" alt=""><figcaption></figcaption></figure>

## Remove Material

To delete the material once there are no associated data, you just have to click on the three dots and press *Delete material.*

<figure><img src="/files/tWJb8l99yYMLToH3wQoz" alt=""><figcaption></figcaption></figure>


# Download PBR Materials

In order to download the PBR maps of the material first navigate to the publicly available list, so go to *Materials* and then to *Public Library*.

<figure><img src="/files/DgBSp0Dcv18KAdJqzvod" alt="" width="396"><figcaption></figcaption></figure>

There click on the material of your choice. In the dialog if you see an Upgrade to Download button that means that you would need to upgrade your plan before being able to download the material.

{% hint style="info" %}
You can only download a material with a paid account. If you see a "Upgrade to Download" button, that means that you will need to upgrade your account before being able to download a material.
{% endhint %}

If you see a download icon, then just click on that and your material should begin downloading.


# Scenes


# Camera

## Add a Camera

You can add a camera by clicking on the *Camera* *& Lights* button and then clicking on *Camera.*

<figure><img src="/files/TXn3lYxpLMf7wZWlkYqc" alt="" width="563"><figcaption><p>Adding a camera</p></figcaption></figure>

When you click on the camera, you'll see various options in the inspector area (middle column). Among these, you'll notice the Preview section. Furthermore a blue rectangle will appear in the 3D editor, which represents the focus plane.

<figure><img src="/files/kUIXT38OyXVkslbe91Pp" alt=""><figcaption></figcaption></figure>

## Changing the Target and Focus

If you click on the camera target (or if you click on the camera again while it is selected) you can also move the target of the camera around.

<figure><img src="/files/Ff99vYEkqsYPN0zHoZ6M" alt=""><figcaption><p>Moving the target</p></figcaption></figure>

You will notice that the blue rectangle is changing while you are changing the target. This is because by default there is an *Autofocus* set and the camera is adjusting the focus depending on what you select as the target. But it is possible to **turn off** the *Autofocus* and set it manually. To do this press the  *Autofocus* toggle and then either:

* Choose a point or
* Set the focus plane distance manually in the *Focal distance* field

as you can see in the recording below:

<figure><img src="/files/xJBV0PfFFqaDCgEGEt5v" alt=""><figcaption><p>Changing the focus</p></figcaption></figure>

{% hint style="danger" %}
Please always make sure the focus plane intersect the area where you want your camera to focus, otherwise the image will be blurry.
{% endhint %}

## Focal Length

<figure><img src="/files/iCee8qPSelmQHS3vGbQW" alt=""><figcaption><p>Settings</p></figcaption></figure>

The focal length controls the level of zoom, determining how much of the scene is visible at once. A longer focal length results in a narrower field of view (more zoom), while a shorter focal length provides a wider field of view, allowing more of the scene to be visible at once (less zoom).

## Set Depth of Field

To achieve a DOF,  you have to set your *Focal distance* to the right point and then increase or decrease the *F-stop* (see the second arrow on the top screenshot). The lower *F-stop* is the narrower the depth of field will be and the higher the *F-stop* the larger the depth of field will be.

Therefore if you would like your image to be sharp everywhere set it to a high number (like 500) and if you would like your image to be blurry except&#x20;

<figure><img src="/files/a0AcT9f1i26hVHTwdJ9V" alt=""><figcaption><p>DOF</p></figcaption></figure>


# Light

## Add a Light

At the moment there are two ways to add a light source in the editor:&#x20;

* Area light&#x20;
* HDRI light

You can add an area light by clicking on the *Camera* *& Lights* button and then clicking on *Lights* and then *Area Light.*&#x20;

<figure><img src="/files/j0mElsYrYWf7XQQdBgYc" alt="" width="563"><figcaption><p>Add a light</p></figcaption></figure>

Which will add a rectangle like object in the middle:

<figure><img src="/files/LRhX6QFX4LngX7UEmBi0" alt="" width="375"><figcaption><p>Area light</p></figcaption></figure>

## Targeted vs Non-Targeted

If you click on the target you can also adjust where the target of the light is. The light by default will move around a fixed point in space:

<figure><img src="/files/eCDPEkBJyo594pi5fB5F" alt=""><figcaption><p>Targeted light</p></figcaption></figure>

If you change the *Targeted* toggl&#x65;*:*

<figure><img src="/files/MmhaNl4nEn3govyG3ZnM" alt="" width="563"><figcaption><p>Targeted toggle</p></figcaption></figure>

&#x20;you will have a *Non-Targeted Light* that is not fixated on any point in space.

<figure><img src="/files/0UBeVPRQsLliFAWeFnER" alt=""><figcaption><p>Non-targeted light</p></figcaption></figure>

## Width and Height

You can change the width and height of the light:

<figure><img src="/files/wIVckngVCky15x1v73AM" alt=""><figcaption></figcaption></figure>

## Intentisty and Color

furthermore you can also adjust the intensity and the color of the light. If you change the intensity it is good to keep in mind that the intensity of the light will depend on which type of light you chose.

<figure><img src="/files/WUwxonR62ApKlmGCt8oH" alt="" width="563"><figcaption></figcaption></figure>

You can choose between the two types of *Area Light*:

* Blender: The luminous flux (the intensity of the whole light) remains constant, meaning that increasing the surface area (width and height) will not affect the overall intensity.
* Corona: The luminance of the light (the intensity in a given unit area) is constant so if you increase the size of the light it will increase the intensity of the whole light as well

To change the color of the light, you simply have to pick a color from the color picker.

<figure><img src="/files/rIexaahaleU2V0e4yrtM" alt=""><figcaption><p>Choosing the color of the light</p></figcaption></figure>

## Visibility

In some cases it is important to adjust whether the light is visible to the camera or various reflections, and this you can change in the visiblity settings:

<figure><img src="/files/V1ybNl2LO2FCp3o2mGAb" alt="" width="176"><figcaption><p>Visibility</p></figcaption></figure>


# HDRI

In 3D design and rendering, HDRI is a technique that uses a special 360-degree panoramic photograph to light a virtual scene. HDRI stores a massive amount of real-world light data.

Imagine taking your 3D object and placing it inside a giant, glowing sphere that is painted with a real-world environment. Wherever there is a light source painted on that sphere, actual light shines down onto your object from that exact direction.

## Changing HDRI Lighting

When you are working in the platform, you have the ability to rotate this HDRI environment in three different directions (the X, Y, and Z axes).

Because the HDRI is a full 360-degree map of light and color, adjusting these rotations changes exactly where the light sources and shadows fall on your object. By simply tweaking these three rotation values, you essentially produce completely new light settings from the exact same file, without ever having to manually add or adjust artificial lamps. See the recording below.

<figure><img src="/files/VDanhVviNJ7NsK9VbrFU" alt=""><figcaption></figcaption></figure>


# Render Node

In the render node you are able to set the resolution and the rendering accuracy.

<figure><img src="/files/ypkXeKeUNdJWeHHVt1qy" alt="" width="322"><figcaption><p>Render node</p></figcaption></figure>

* W: width of the image in pixels
* H: height of the image in pixels
* Samples: The number of paths traced for each pixel in the final render. Increasing the number of samples reduces noise and improves accuracy. Usually for a regular white background image you can set 50-100 for a quick preview and set 100-300 for room images or for a less noisy white background image. Please note that increasing the number will take the image a longer time to finish rendering.


# Post Processing

If you already generated an image you can adjust the final look by applying various affects. All these effects can be controlled in the *Post Processing* node. If you click on the *Post Processing* node and the *Render Image* button:

<figure><img src="/files/ARaiybs0YQzjGRSvW71Q" alt="" width="136"><figcaption><p>Render button</p></figcaption></figure>

then you can see how the changes that you apply to the *Post Processing* node will affect your image. You can see a quick overview of the various options and their effect on the final render below.

<figure><img src="/files/JO7gikb7cgn5tJUWUM0B" alt=""><figcaption><p>Post processing options</p></figcaption></figure>

The main options of post processing are:

* **Exposure**: Adjusts the exposure (brightness) of the image, with negative values making the image darker and positive values making it brighter.
* **White Balance (White B.)**: Adjusts the color temperature of the image to achieve accurate colors, where lower values make the image cooler and higher values make it warmer.
* **Tone Mapping**:
  * **Tone Mapping Type**: You can select the algorithm to use when adjusting the tonal values of an image.
  * **LUT (Look-Up Table)**: Applies a specific color grading to the image for visual style.&#x20;
* **Background**:
  * **Transparent**: Makes the background of the image transparent.
  * **Composite**: Adds a background color to the image.
  * **Background Color**: Here you can select the background color that is used in compositing.


# Process Shadows

In some cases it can happen that shadows continue for way to long until the edge of the picture. Especially if you need the shadows to be uniform on many images (i.e. you would need a way to consistently cut the shadow for all images).

To easily change this without having to change the light and the camera, there is a *Post Processing* option called *Process Shadows*.

With it you can control how quickly the shadows disappear as they approach the edge of the image. Options:

<table data-full-width="false"><thead><tr><th width="155.333251953125">Option</th><th width="395">Description</th><th width="89.333251953125">Range</th><th width="100.666748046875">Default</th></tr></thead><tbody><tr><td><strong>Shadow Inner</strong></td><td>Mostly you will not need to use option, but this option pulls away shadows from the object. Unless you need something specific (e.g. increase the strength of the shadow that extends under the product) please skip this option.</td><td>0-1</td><td>0</td></tr><tr><td><strong>Shadow Outer</strong></td><td>Controls how far from the object the shadow disappears. The higher the value the more it tries to suppress the shadows that are not directly under the product.</td><td>0-1</td><td>0</td></tr><tr><td><strong>Shadow Falloff</strong></td><td>Controls the falloff of the shadow (how quickly, how soft the shadow gets). The lower the value quicker it gets softer away from the product.</td><td>0-1</td><td>1</td></tr><tr><td><strong>Shadow Opacity</strong></td><td>Controls the transparency and overall darkness of the generated shadows. The higher the value the less transparent it is.</td><td>0-1</td><td>1</td></tr></tbody></table>

Take for example the following image:

<figure><img src="/files/L4KxfabVvNUOWeae7tta" alt="" width="563"><figcaption><p>Original image</p></figcaption></figure>

When turning on the option we can see already that with the default values we see that much of the shadow disappears around the product:

<figure><img src="/files/AXCIlf9dV26yQzYBGKCo" alt="" width="563"><figcaption><p>Default values</p></figcaption></figure>

If we increase the **Shadow Outer** to 1 it will not let any shadow be casted away from the product (other than the shadow right under the product):

<figure><img src="/files/rbIru5YeDFCgFxSxRTGo" alt="" width="563"><figcaption><p>Shadow Outer </p></figcaption></figure>

If we decrease the **Falloff** to 0 it will make the shadows much softer much quicker away from the product. So you see the bit stronger shadow right under the product but going away the shadow gets much softer.

<figure><img src="/files/pVDRLDSpPC8IohcyT2X4" alt="" width="563"><figcaption><p>Falloff</p></figcaption></figure>

If you take a look at the last image (Falloff 0) we might want to make the shadow extend a bit more under the product and this is where **Shadow Inner** comes in. Increasing a value a bit, we can see that the shadow extends but the Falloff doesn't change.

<figure><img src="/files/lLAEGAO9mKaDSbLGcdge" alt="" width="563"><figcaption><p>Shadow Inner</p></figcaption></figure>


# Material Range

On the colormass platform, you can add an entire range of materials for renders and for configurators, allowing you to generate many variations of materials within the same range or pattern with a few clicks. To do this please click on *Other* and then *Material Ranges.*

<figure><img src="/files/ToFSjO02Cs0KKjzldBkl" alt="" width="563"><figcaption></figcaption></figure>

Once you click on your *Material Range* it will add a *Config Group* with your materials added as variants.

{% hint style="info" %}
To learn more about what a Config Group is check out the [Create Variants](/building-blocks/products/create-variants) and [Create Material Variants](/building-blocks/products/create-material-variants)pages.
{% endhint %}

To apply these variants, simply drag and drop the last item in the group (indicated by the small arrows) into the desired material slot (see below).

<figure><img src="/files/ltdX5a7rRhRIkqvxO3H2" alt=""><figcaption></figcaption></figure>


# Introduction

{% hint style="warning" %}
This tutorial builds on the [Building Blocks](/building-blocks/products) tutorials. It assumes you already have some **products prepared** (either by colormass staff or by yourself), as they are required to create configurators.
{% endhint %}

In this chapter, we'll start using the 3D assets we created previously in the [Building Blocks](/building-blocks/products) chapter, focusing on **generating configurators** of an existing product.

{% embed url="<https://vimeo.com/1161482433/45c2e9447d?byline=0&portrait=0&title=0>" %}

In this section, we'll show you how to create new configurators that you can publish on your website. With the colormass Single Asset System, you can use the same assets for rendering images as you do for creating configurators or AR, eliminating the need to create different assets for each use case. In this chapter, we will use a simple product to create a configurator, adjust its lighting settings, and upload icons to be used in the UI of the configurator.

It's important to note that the tutorial will demonstrate the default UI of the configurator, which you can use to get started quickly. However, the colormass Configurator also offers an API that allows you to connect configurator functions to your own custom UI.

I hope you find these upcoming tutorials exciting as we begin to use the products created in the first chapter.

{% hint style="info" %}
It is possible to seamlessly integrate the configurators into your website. For more information check out the [Configurator](/dev/configurator/introduction) developer documentation.
{% endhint %}


# Create Your First Configurator


# Add a New Configurator

First navigate to the Pictures tab on the platform and there switch to the Projects tab:

<figure><img src="/files/mVGyxDp56gy9ISLVfAJp" alt="" width="403"><figcaption></figcaption></figure>

If you already see various folders (projects) and sub-folders (sets) then please select a subfolder (set) where you would like to put your configurator. If the folder doesn't exist yet, please create it, by adding a new project and then set:

<figure><img src="/files/a0Sw4b1DFaYBkox3ONPA" alt="" width="233"><figcaption><p>Add a new set</p></figcaption></figure>

Once you selected the set you would like to place it in then press the *+ Create* button and click on *Configurator* like so:

<figure><img src="/files/QX7YG1a3ZRisSlGGscgS" alt="" width="381"><figcaption></figcaption></figure>


# Add a Real-Time Scene and a Product

In order to create a configurator first we need to add a real time scene that can serve as a starting point. Therefore got to the *Scenes* button of the top bar and select a real-time scene:

<figure><img src="/files/VCRpVJlAOefK0z7LsCNe" alt="" width="563"><figcaption><p>Select a real-time scene</p></figcaption></figure>

{% hint style="info" %}
If no such a real-time scene exists in your library, please ask your colormass contact person to add one to your library.
{% endhint %}

Once you added the scene please also go to the *Products* button in the top bar and add a &#x20;

<figure><img src="/files/sjKyiGeBg2nq331DXRei" alt="" width="563"><figcaption></figcaption></figure>

{% hint style="warning" %}
It's very important to note that in these Configurator tutorials we are only showing how to embed a product in an environment and then publish it in a website. Creating variations and product logic is part of the [Products](/building-blocks/products) tutorials and not part of the Configurator tutorials.
{% endhint %}


# Adjust Camera and Lights

If you followed the previous two steps then now you should have the basic setup of a configurator: a real-time scene and a product.&#x20;

You can adjust many things in the configurator to match your exact needs, in this page we will adjust the *Camera* and the *Lights.*&#x20;

## Adjust the Camera

You can freely move around the camera and adjust both the position of the camera and its target. The preview that you can see in the inspector area (left) will be the actual starting point of the published configurator.

<figure><img src="/files/JeHh0SmL4nLtPOFxaw9X" alt=""><figcaption><p>Adjust the camera</p></figcaption></figure>

## Adjust the Lights

The same way as adjusting camera you can also move and adjust the lights to achieve the final light setting that you would like to have for your configurator.

<figure><img src="/files/Pgfa3VTptdFsmFPu3Szw" alt=""><figcaption><p>Adjust the lights</p></figcaption></figure>


# Change Basic UI Settings

If you click on the Scene Properties node in your configurator there are various options that you can do. For the purpose of this tutorial lets simply change the UI style to *Icons:*

<figure><img src="/files/9Ljv99F2iNmc6IcJC5Gf" alt="" width="325"><figcaption><p>UI option</p></figcaption></figure>

and also lets change the *Icon Size* to a bigger size:

<figure><img src="/files/qySbFHfv600PakqyJwEg" alt="" width="320"><figcaption><p>Icon size</p></figcaption></figure>


# Publish the Configurator

Once you saved your scene you can easily publish your scene using the *Publish 3D* button:

<figure><img src="/files/solDg1HyH6n50Kryll1Y" alt=""><figcaption><p>Publish</p></figcaption></figure>

in the top right corner and click on *Copy configurator URL*.

If you’ve followed these steps correctly, opening the link should display a 3D viewer similar to the one shown below, which can easily be embedded into your website.

<figure><img src="/files/a7XPUKCBFnU10KmP9f4K" alt="" width="563"><figcaption><p>First configurator</p></figcaption></figure>

You’ll notice that several elements are missing (e.g., the options don’t have icons uploaded yet), but we’ll cover these details in separate tutorials.


# Upload Icons

As you probably noticed in the [Publish the Configurator](/configurator/create-your-first-configurator/publish-the-configurator) page the configurator by default doesn't include any icons and this would be something that you would need to upload for your own product. To do this you would first need to locate the product whose icon you would like to change.

If you only know the scene of your configurator, you can also find the product by finding your product inside the tree and clicking on its link:

<figure><img src="/files/jRiZomDUp5ckzHRTTYtV" alt="" width="383"><figcaption><p>Link to the template</p></figcaption></figure>

Once you are in the product that you would like to change, simply click on a config variant like so:

<figure><img src="/files/41nfl5svEu0SrZLJogQL" alt="" width="563"><figcaption><p>Config variant</p></figcaption></figure>

and click on the blue Icon field. This will open up a window where you can select a new icon.


# Limit Camera Movements

{% hint style="info" %}
This setting is for configurators only: to limit the angles and zoom levels the user able to explore in the configurator.
{% endhint %}

You can limit the camera movement in the configurators by setting the properties of the camera in the editor. You can set the following two aspect:

* Distance: how far or how close the camera can go
* Angle: how much rotation is allowed

## Distance

You can set the minimum and maximum distance the camera can take if you click on the camera and set the following two values:

<figure><img src="https://colormass.slite.com/api/files/sHhB120S2mI1RS/image.png" alt="image.png" width="375"><figcaption></figcaption></figure>

## Angle

Camera movement in the configurator settings can be limited by setting vertical min/max angles (min and max angle (v)) and horizontal min/max angles (min and max angle (h)). Please note that these angles are in degrees and defined in the spherical coordinate system as the following figure implies:

<figure><img src="https://colormass.slite.com/api/files/Zv7SL4y_hHJ_2V/unbenannt.jpg" alt="Unbenannt.jpg" width="563"><figcaption></figcaption></figure>

To define possible values for the horizontal rotation, the user can set the minimum value of phi by the field *min angle (h)* and the maximum value by the field *max angle (h)*. In the same manner, the set of the possible values for the vertical rotation can be set by the field *min angle (v)* and *max angle (v)*. In this way, the possible viewing angles for those who uses configurator can be defined.

If you click on the camera than you can find these settings here:

<figure><img src="https://colormass.slite.com/api/files/mo2I8G7WgT2-aI/image.png" alt="image.png" width="375"><figcaption></figcaption></figure>

The minimum and maximum vertical angles are from 0 to 180. The screenshot below shows roughly what these values mean:

<figure><img src="https://colormass.slite.com/api/files/moDKsXSXAstqV0/vertical.png" alt="vertical.png" width="563"><figcaption></figcaption></figure>

Values above 180 and below 0 will be clipped. For example you set the maximum vertical angle to 190 degrees, it will be set to 180. Likewise, if you set it to -10 degrees, it will be set to 0.

The horizontal angle goes from 0 to 360 (without any clipping). See screenshot below:

<figure><img src="https://colormass.slite.com/api/files/PHy3Bq7mJuRkbN/horizontal.png" alt="horizontal.png" width="563"><figcaption></figcaption></figure>

The horizontal angle for the camera is 0 degree. If it were 360 degrees, the camera would still be in the same position.

{% hint style="info" %}
Since there is no clipping both setting *min angle (h)* to *0* and *max angle (h)* to 360 and *min angle (h)* to *-180* and *max angle (h)* to 180 will work.
{% endhint %}


# Viewer Settings

There are many other options that you can change in your configurator settings, if you click on the Scene Properties:

* **Features**: Here you can turn on and off features for your configurator. Before turning on features please discuss with your colormass contact person whether your plan includes a certain option to ensure that it will work correctly.
* **Configurator UI Settings:** Here you can select the UI style (unless you connect to the configurator through the API) and also adjust other visual settings like the *Background Color* or the *Icon Size*.
* **Shadow Catcher:** You can adjust how much shadow you would allow in the configurator (so that you can adjust the amount of shadow regardless of your light settings).

<figure><img src="/files/nMgTGx5rg4TsXvCg6HBr" alt="" width="563"><figcaption><p>Scene properties</p></figcaption></figure>


# Integrations


# Webflow

Adding an interactive 3D product configurator to your Webflow site is one of the best ways to increase user engagement. The step-by-step documentation will show you how to embed interactive 3D viewers

In this quick guide, we will walk you through how to embed your configurator `iframe` code into your Webflow project.

<figure><img src="/files/xNXqvYaSCysRPgv7y6Kk" alt=""><figcaption></figcaption></figure>

### Step 1: Open your project

Open your project in the Webflow Designer. Select the existing site or page where you want to integrate the 3D viewer directly.

<figure><img src="/files/Yg6tNjjQjbU2na57wBNk" alt="" width="375"><figcaption></figcaption></figure>

### Step 2: Add an Embed element

Next, you need to add a custom embed block to hold the configurator.

1. Click the Add Elements icon (`+`) in the top left panel or press `A` on your keyboard.
2. Scroll down to the Components section.
3. Drag the Embed element onto your page canvas where you want the 3D viewer to appear.

{% embed url="<https://vimeo.com/1217356078/b1031dbc2c>" %}

### Step 3: Paste the iFrame snippet

Start out by putting this basic iframe code snippet into the code editor of your new Embed element:

```html
<iframe
  src=""
  style="width: 100%; height:100%; border:0"
  allowfullscreen=""
></iframe>
```

#### Get your Configurator URL

Next, open your 3D configurator setup in the colormass platform.

1. Navigate to your project.
2. Click Publish 3D.
3. Select Copy Configurator URL.

<figure><img src="/files/5BOcKjC3QeXHmq54M8su" alt=""><figcaption></figcaption></figure>

#### Add the URL to Webflow

Copy the URL and paste it into the `src=""` attribute of the iframe code in Webflow. Your final code should look something like this:

```html
<iframe
    src="YOUR CONFIGURATOR URL HERE"
    style="width: 100%; height:100%; border:0"
    allowfullscreen=""
></iframe>
```

See the parts of this 3rd step recorded in the video below.

{% embed url="<https://vimeo.com/1217356079/d9333b17eb>" %}

### Step 4: Save and Publish

Once your code is pasted and you are happy with the placement of the embed element, click Save & Close on the embed editor. Finally, click Publish in the top right corner of Webflow to push your site live with the new 3D configurator.


# Notion

Learn how to integrate 3D models into your Notion workspace. Our step-by-step documentation will show you how to embed interactive 3D viewers into your pages

<figure><img src="/files/BUVPBoEwJtaq6FrMPsei" alt=""><figcaption></figcaption></figure>

### Step 1: Open your Notion Page

Start by logging into Notion and opening the specific page or board where you want to showcase your 3D model. Navigate to the exact spot on your canvas where you want the viewer to be placed.

<figure><img src="/files/h120VfZqORsjpvwM8MIM" alt="" width="291"><figcaption></figcaption></figure>

### Step 2: Copy the Link from colormass

Next, you need to get the specific URL for your 3D model.

Open your 3D configurator setup in the colormass platform:

1. Navigate to your project.
2. Click Publish 3D.
3. Select Copy Configurator URL.

<figure><img src="/files/lAXzJrzyGPolklQ9HAuf" alt=""><figcaption></figcaption></figure>

### Step 3: Embed 3D Viewer

Back in Notion, go to your page and type `/embed`, then press Enter to create an embed block.

<figure><img src="/files/dEFDRywdOsl9zOXzC1mI" alt=""><figcaption></figcaption></figure>

Paste your copied colormass link into the field and click Embed link. Once it loads, you can drag the edges to resize the 3D viewer to fit your layout perfectly.

See the screen recording below to see all of these steps together.

{% embed url="<https://vimeo.com/1217356112/dfceb8ad6c>" %}


# Miro

Learn how to integrate 3D models into your Miro workspace. Our step-by-step documentation will show you how to embed interactive 3D viewers into your whiteboards.

<figure><img src="/files/psl0bg622QeN7rLNhLCR" alt=""><figcaption></figcaption></figure>

### Step 1: Open your whiteboard

Open the specific Miro board where you want to showcase your 3D model and navigate to the exact spot on your canvas where you want the viewer to be placed.

<figure><img src="/files/CYK2JcnTO3mcUqn9IqZQ" alt="" width="375"><figcaption></figcaption></figure>

### Step 2: Copy the Link from colormass

Open your 3D configurator setup in the colormass platform:

1. Navigate to your project.
2. Click Publish 3D.
3. Select Copy Configurator URL.

<figure><img src="/files/Fw6lfuNC7xaLuNX1HWhm" alt=""><figcaption></figcaption></figure>

### Step 3: Embed iFrame

Back in Miro, use the following steps to bring your 3D viewer onto your board:

1. Locate the Embed tool from the left-hand toolbar (if you don't see it, click the `...` "More tools" icon).
2. Insert your copied colormass link into the embed field.
3. Your interactive 3D viewer will instantly load onto the canvas.

<figure><img src="/files/3IK5eUUhaywCOnNFJG66" alt=""><figcaption></figcaption></figure>

See the screen recording below to see all of these steps together.

{% embed url="<https://vimeo.com/1217356136/cbe3949cb1>" %}


# Shopify

Learn how to integrate 3D models into your Shopify store. Our step-by-step documentation will show you how to embed interactive 3D viewers directly into your product pages to boost customer engagement

<figure><img src="/files/IFVFn0g3MRPCTLFqBScv" alt=""><figcaption></figcaption></figure>

### Step 1: Copy the Link from colormass

First, you need to get the specific URL for your 3D model.

Open your 3D configurator setup in the colormass platform:

1. Navigate to your project.
2. Click Publish 3D.
3. Select Copy Configurator URL.

<figure><img src="/files/86aIuZuEzbBH6niXHfHr" alt=""><figcaption></figcaption></figure>

### Step 2: Open your Shopify Product

Log into your Shopify Admin dashboard.

1. Click on Products in the left-hand navigation menu.
2. Select the specific product where you want to add the 3D viewer (for example, a "Bose Headphone").

### Step 3: Embed the iFrame in the Description

Once you are on the product edit page, locate the Description text box.

1. Click the Show HTML button (the `</>` icon) located on the far right of the description formatting toolbar.
2. Paste your iframe code snippet into the code editor, placing your copied colormass link inside the `src=""` attribute.

It should look similar to this:

```html
<iframe
  src="YOUR CONFIGURATOR URL HERE"
  style="width: 100%; height:100%; border:0"
  allowfullscreen=""
></iframe>
```

<figure><img src="/files/5H6OUqMJkxPaLDEUE8iR" alt=""><figcaption></figcaption></figure>

### Step 4: Save and Preview

Once you have pasted the code:

1. Click the Save button at the top right of the page to apply your changes.
2. Click the Preview button (or navigate directly to your live storefront) to see the result.

The 3D viewer will now seamlessly load alongside or in place of your traditional product media, allowing your customers to interact with the 3D model in real-time!

<figure><img src="/files/LLQgzWFAPCwDSBVEQlrG" alt=""><figcaption></figcaption></figure>


# Introduction

{% hint style="warning" %}
This tutorial builds on the [Building Blocks](/building-blocks/products) tutorials. It assumes you already have some **products and scenes prepared** (either by colormass staff or by yourself), as they are required to create images.
{% endhint %}

In this chapter, we'll start using the 3D assets we created previously in the [Building Blocks](/building-blocks/products) chapter, focusing on **generating images** of an existing product.

{% embed url="<https://vimeo.com/1161437979/1b1bc6e25c?byline=0&portrait=0&title=0>" %}

Please note, that everything shown here can be done entirely from your browser, making it significantly easier to scale your 3D operations or share scenes with colleagues or clients. This is a key advantage of our system compared to traditional 3D systems, where the 3D scene is typically accessible only to its creator.

While we'll be working with simpler scenes, you can imagine applying the same steps to any type of room or studio scene you prefer. In fact many of our customers create a lot of various environments that are reused for various purposes.

Generating images is just one way to utilize an existing product. With the colormass Single Asset System, the same product can also be used in a configurator and in AR. For more details, refer to the [Configurator](/configurator/introduction) chapter.


# Render Your First Image


# Add a New Picture

First navigate to the Hpme tab on the platform and there switch to the Projects tab:

<figure><img src="/files/2EMZkPJFbsVQpypYRH9Z" alt=""><figcaption></figcaption></figure>

In there you will find that there are various folders (projects) and sub-folders (sets). Please select a subfolder (set) where you would like to put your image. If the folder doesn't exist yet, please create it, by adding a new set:

<figure><img src="/files/a0Sw4b1DFaYBkox3ONPA" alt="" width="233"><figcaption><p>Add a new set</p></figcaption></figure>

Once you selected the set you would like to place it in then press the *+ Create* button and click on *Image* like so:

<figure><img src="/files/6dIYSemcWqdyx3CWnP8J" alt="" width="386"><figcaption><p>Create a new image</p></figcaption></figure>

This will open up a new image scene (which was added to the folder that you had selected).


# Add a Scene

In order to create a new image first we need to add scene that can serve as a starting point. Therefore got to the *Scenes* button of the top bar and select a scene:

<figure><img src="/files/i7PkJXkBjYIxc1Rib9GX" alt="" width="563"><figcaption><p>Select a scene</p></figcaption></figure>

{% hint style="info" %}
If no scene exists in your library, please ask your colormass contact person to add one to your library.
{% endhint %}

Depending on how the scene was prepared it might already include a product but in case it doesn't then don't hesitate to go to the *Products* button and select any of your products:

<figure><img src="/files/HSgRIgyQRZxRz6e7tbz1" alt="" width="563"><figcaption><p>Select a product</p></figcaption></figure>


# Render Image

There are many things that you can change on the scene of course (swap out products, assign new materials, change camera and light settings) but for now we would render out an image as is.

To do that click on the *Render Image* button in the top right corner

<figure><img src="/files/1ATebfr9fDDDwKJg6Ozf" alt=""><figcaption><p>Render Image</p></figcaption></figure>

This should exchange the *3D Editor* that you have seen so far into the image view:

<figure><img src="/files/iEztL4Dx0f7n1pNqNX3Q" alt=""><figcaption><p>Render Image</p></figcaption></figure>

where you can press the *Render this variation* button to submit the image to be rendered on the colormass servers.


# Batch Rendering

Rendering a single image only captures the currently selected variant. To generate all variations simultaneously, you must use specific editor views. The following pages explain the batch generation process.


# View All Variations

In the 3D editor the active view is called *Structure* that shows the structure of the scene, and the currently selected variation that would appear in your render.

<figure><img src="/files/Jc52JNvAN21EfutQS9KQ" alt="" width="308"><figcaption></figcaption></figure>

In the above screenshot you can see that currently a variation called *Romo* is selected, which will be used in the render. If we wanted to generate all variations we would need to click on the *Structure* and change to *All Variations.*&#x20;

In this view all of your variations will be listed (as a flat list), like so:

<figure><img src="/files/sJeFa8QSoIVIcUvtu0to" alt="" width="320"><figcaption></figcaption></figure>

If you click on each variation on the left side, it will show that specific variation on the right side as well in the 3D viewer.

<figure><img src="/files/caFPm8CG8bcz8zlPrtFG" alt=""><figcaption></figcaption></figure>


# Render All Variations

Once you are in the *All Variations* view (check the [View All Variations](/rendering-platform/batch-rendering/view-all-variations) page for more details) you can render all of the variations at once.

<figure><img src="/files/6t5TLXCs6g4oOJdjNsQs" alt="" width="320"><figcaption></figcaption></figure>

To render all of the images at once, press *Render All* and then click *Submit jobs* if the number in the dialog corresponds with the number of images that you would like to have in the end:

<figure><img src="/files/Aj2xlM0s5AbmtA5V8iIN" alt="" width="443"><figcaption></figcaption></figure>

Once you submitted the render jobs on the right side of each list item you will see a progress icon:

<figure><img src="/files/by1egY3XyzAU4c2vcOq0" alt="" width="333"><figcaption></figcaption></figure>

Please see below which icon corresponds to which render status:

* Hourglass: The job is preparing to render.
* Blue Circle: Rendering is currently in progress.
* Green Icon: The render is complete.


# Download All Variations

In order to download all renders, you can press the Download All option here:

<figure><img src="/files/kMmjsmEPgH1867PTmVnd" alt="" width="355"><figcaption></figcaption></figure>

then select the right file format:

<figure><img src="/files/fT6rEvkHbDEXWU7q9yXz" alt="" width="347"><figcaption></figcaption></figure>

and press submit:

<figure><img src="/files/A0lfgMGaeXRfzrPmesJ8" alt="" width="438"><figcaption></figcaption></figure>

After submitting, a progress window will appear in the bottom-left corner while the images are zipped. When finished, a dialog will open allowing you to save the file.

<figure><img src="/files/tEt21NGmgHC712R8vIkK" alt="" width="366"><figcaption></figcaption></figure>


# Delete All Variations

To delete all your images you would need to click on the *Delete All* button:

<figure><img src="/files/GA8zyegU7NDs0HggXOYh" alt="" width="355"><figcaption></figcaption></figure>

and then press *Submit jobs:*

<figure><img src="/files/8ryNB5D6w34BD33G4zmd" alt="" width="446"><figcaption></figcaption></figure>


# Re-render a Variation

If there is a specific variation that you would like to re-render click on the variation you need and then change to the *Render Image* view on the right side.

When you click on each variation the corresponding image will be displayed, like so:

<figure><img src="/files/WXV3wbi57OAs7yhsiCJO" alt=""><figcaption></figcaption></figure>

In order to re-render one, please select the variation that you would need to re-render and then press the little bin button and *Re-render,* like you can see below:

<figure><img src="/files/IFmLol3CaTYMfOavsKVs" alt=""><figcaption></figcaption></figure>


# Scanning

SVBRDF Scanner developed by colormass

<figure><img src="/files/Lr0xiTp4KqmQOPPwlNZ6" alt=""><figcaption></figcaption></figure>

The colormass Scanner is an advanced device designed to capture flat surfaces with exceptional quality, covering a wide range of materials such as fabrics, leathers, woods, plastics, vinyls, and wallpapers, among others. The scanner's primary function is to generate highly accurate texture maps, which are essential for rendering realistic 3D models.

The measurements it takes are used to produce texture maps that align with the Disney Principled BSDF (Bidirectional Scattering Distribution Function) model. By using this method, the colormass scanner ensures that the materials it processes retain a lifelike appearance when rendered in 3D environments, making it a powerful tool for industries like interior design, e-commerce, fashion, and product visualization. The integration with the Disney BSDF model also allows for seamless compatibility with most modern rendering engines, enabling high-quality visuals in real-time applications or pre-rendered imagery. To learn more about the surface digitization process, feel free to read our blog article [here](https://www.colormass.com/resources/blog/the-colormass-textile-scanning-process).

<div align="center" data-full-width="false"><figure><img src="/files/vAI4jRVKTmTJXPOKM4wM" alt=""><figcaption><p>Fabric</p></figcaption></figure> <figure><img src="/files/N20dcoZXtLEJvW4hE11A" alt=""><figcaption><p>Leather</p></figcaption></figure> <figure><img src="/files/4P9J5OWlkTRkcEqWvoDn" alt=""><figcaption><p>Wood</p></figcaption></figure></div>

<div><figure><img src="/files/kC0nmo7UeA6U2mIL1ci8" alt=""><figcaption><p>Wallpaper</p></figcaption></figure> <figure><img src="/files/RcROzwmLPCMiAyzU79Oi" alt=""><figcaption><p>Plastic</p></figcaption></figure> <figure><img src="/files/wITXFoZLZvzq8CCPFNZT" alt=""><figcaption><p>Vinyl</p></figcaption></figure></div>

## Features and Specification

* **Maximum capture area:** approximately 1.8 x 1.8 meters (6 x 6 feet).
* **Maximum resolution:** approximately 800 DPI. For a sample size of 40 x 40 cm (16 x 16 in), this produces texture maps of around 13,000 x 13,000 pixels.
* **Speed:** Approximately 1 minute for every 10 x 10 cm (4 x 4 in) area. Capturing a 40 x 40 cm (16 x 16 in) sample takes about 15 minutes.
* **Color accuracy (Delta E):** 2.49
* **Batch capture:** This feature allows multiple samples to be placed on the scanning table simultaneously, significantly reducing manual effort and optimizing workflow efficiency.
* **Calculated maps:** diffuse, normal, roughness, specular, metalness, anisotropy strength, anisotropy rotation, displacement and transmission (optional). For more details, click [here](broken://pages/qXfSSrSreM7D2Hnztb5w).

{% hint style="info" %}
colormass provides two options for utilizing their scanner technology: you can either use our scanning service, where we handle everything for you, or we can build and supply a scanner for in-house use, allowing you to capture high-quality material textures directly. To see real-life examples of how our customers are using the colormass Scanner, please click [here](https://www.colormass.com/technology/scanning).
{% endhint %}


# PBR Maps

Technical specification of the maps generated by the colormass Scanner.

To better understand the final quality of the maps, download one of the example scans:

* [Leaves - Winter Creeper](https://storage.googleapis.com/cm-platform-prod-media/dfdae760-d2ff-4f84-9c17-d712976047ca)
* [Fabric - Jacquard Woven](https://storage.googleapis.com/cm-platform-prod-media/85ef293a-dd16-4829-9703-57d472cdfb95)
* [Wood Veneer - Dark](https://storage.googleapis.com/cm-platform-prod-media/4f1437e2-e94a-47dd-95d5-2db5cb7c8e4f)
* [Wood Veneer - Light](https://storage.googleapis.com/cm-platform-prod-media/4c2d0cf4-92f5-422c-b36b-fab4e0e3bd75)

Below, you can see the technical specifications demonstrated on the *Fabric - Jacquard Woven* scan.

{% embed url="<https://vimeo.com/1056786431/94173b2e5c>" %}

<table data-card-size="large" data-view="cards" data-full-width="false"><thead><tr><th>Name</th><th>Type</th><th>Colorspace</th><th>Description</th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><strong>Diffuse</strong></td><td>RGB</td><td>sRGB (except EXR: linear)</td><td>RGB map that can contain two types of data: diffuse reflected color for dielectrics and reflectance values for metals. It is devoid of any lighting information such as ambient occlusion.</td><td><a href="/files/bwwl3g9RXiItdRTwkOMm">/files/bwwl3g9RXiItdRTwkOMm</a></td></tr><tr><td><strong>Normal</strong></td><td>RGB</td><td>linear</td><td>A map describing the surface orientation by an RGB encoding. It uses the standard tangent space format, identified by the dominant purple color, corresponding to a vector facing directly away from the surface. Rendering engines differentiate between 2 types of formats: OpenGL (Y+ up) and DirectX (-Y down). We normally provide the OpenGL (Y+ up) format. It can be transformed to DirectX (-Y down) by simply inverting / flipping the green color channel if required.</td><td><a href="/files/xcateYh6mRQpuolXRlED">/files/xcateYh6mRQpuolXRlED</a></td></tr><tr><td><strong>Roughness</strong></td><td>Grayscale</td><td>linear</td><td>Describes the surface irregularities that cause light diffusion. Black represents a completely smooth / shiny surface and white represents a completely rough / diffuse surface. In-between grayscale values allow for different roughness values.</td><td><a href="/files/gRGUOWm58ApQ81iQJW5c">/files/gRGUOWm58ApQ81iQJW5c</a></td></tr><tr><td><strong>Specular</strong></td><td>Grayscale</td><td>linear</td><td>Describes Fresnel reflectance for dielectric materials. Black represents 0% reflectance and white represents 8% reflectance. Most real-world dielectrics have around 4% reflectance, so the values of this map will mostly be around mid-gray.</td><td><a href="/files/tRSTqQcSwsvRQYzfZy5H">/files/tRSTqQcSwsvRQYzfZy5H</a></td></tr><tr><td><strong>Metalness</strong></td><td>Grayscale</td><td>linear</td><td>Describes which parts of the surface are metallic (represented as white) or non-metallic/dielectric (represented as black). Also grayscale values in-between are possible, representing mixtures of metallic and dielectric surfaces.</td><td><a href="/files/eKYdyMPFzoQumZuz96DR">/files/eKYdyMPFzoQumZuz96DR</a></td></tr><tr><td><strong>Anisotropy Strength</strong></td><td>Grayscale</td><td>linear</td><td>Describes the strength of the anisotropic highlight. Black represents a completely isotropic surface (circular, directionally independent highlight), white represents a completely anisotropic surface (elongated, directionally dependent highlight). In-between values define different levels of anisotropy.</td><td><a href="/files/RMv3TOgZQIrhwdhqC9cD">/files/RMv3TOgZQIrhwdhqC9cD</a></td></tr><tr><td><strong>Anisotropy Rotation</strong></td><td>Grayscale</td><td>linear</td><td>Describes the orientation of the anisotropic highlight. It uses a clockwise encoding where black represents a 0°, mid-gray represents a 180° and white represents a 360° rotation of the anisotropic highlight.</td><td><a href="/files/ho7epPFGz3Gjri3Lz4ij">/files/ho7epPFGz3Gjri3Lz4ij</a></td></tr><tr><td><strong>Displacement</strong></td><td>Grayscale</td><td>linear</td><td>Describes small-scale geometric detail of the surface. Black represents zero modification, white represents the surface being fully pulled "outwards". In-between values allows different levels of displacement. The (metric) value of how far the surface should be displaced outwards for a white color value is currently not made available and up to artistic control.</td><td><a href="/files/61lsLnqvCLmoocV9a1FH">/files/61lsLnqvCLmoocV9a1FH</a></td></tr><tr><td><strong>Mask/Alpha (optional)</strong></td><td>Grayscale</td><td>linear</td><td>Describes a simplified version of transparency. Black represents a completely transparent region of the surface, where light passes through unperturbed. White represents a (usually opaque) region where the rest of the maps have full influence over the behavior, and no blending occurs. Intermediate values result in a blending between the shaded surface and full transparency.</td><td></td></tr><tr><td><strong>Transmission (optional)</strong></td><td>RGB</td><td>sRGB (except EXR: linear)</td><td>Describes the amount and color of light transmitted through the surface of a material. When this originates from the colormass scanner, this is assumed to represent diffuse (scattering) transmission. (Since the scanner cannot distinguish between areas that are fully transparent and areas that have very high scattering transmission, this usually needs to be combined with a mask. The mask may be derived from the transmission map by picking a threshold which identifies high-transmission areas as fully transparent.)</td><td></td></tr></tbody></table>

## Frequently Asked Questions (FAQ)

<details>

<summary>What is the maximum scan area and resolution?</summary>

Please find the scanner specifications [here](/scanning-and-tiling/scanning#features-and-specification).

</details>

<details>

<summary>What is the recommended sample size for scanning?</summary>

If the material has a repeating pattern, we require a sample that includes the full pattern in both horizontal and vertical directions, plus an additional 25%. This ensures that the scan can be made tileable. For solid textures with minimal or no pattern, we recommend samples approximately 60 x 60 cm (24 in x 24 in). Although the repeat may be smaller, scanning this larger area allows for a more natural texture, provided there is sufficient variation across the surface.

We understand that larger samples may not always be available or cost-effective, especially when dealing with standard swatch sizes that are only a few centimeters or inches. Therefore, we can accommodate smaller samples if necessary.

For leathers, woods, and other natural materials that do not have a repeat due to their organic nature but still possess distinct patterns, please [contact us](https://www.colormass.com/contact) for a consultation. We can help determine the most appropriate sample sizes for scanning. You can find information about shipping samples [here](/scanning-and-tiling/scanning/shipping-material-samples).

</details>

<details>

<summary>Why is there value in the metalness? This looks like a fabric sample.</summary>

The maps we provide are parameters according to the standard Disney principled BSDF model that were fitted to the observed images captured under different illumination directions. We optimize for all the channels, even though some samples (materials) do not contain metal or are isotropic in a physical sense. However, the fitted model gets closer to what is being observed in the captured images when these maps are also optimized, as the algorithm has more degrees of freedom to tweak its appearance. Depending on the specific material we could also easily constrain these maps to be zero. However, this would yield a slightly larger fitting error (it is never possible to fit the model to the observations 100%). Our goal is to get as close as possible to the visible/observed appearance of the captured sample.

Normally the primary goal is to obtain the most realistic and accurate scans of real-world materials. This aligns perfectly with our approach. Our fitting process employs all available degrees of freedom (PBR maps) to capture the true essence of each sample.

While we provide individual PBR maps for convenience (easy use in different rendering tools), analyzing them in isolation within a traditional 3D workflow might be misleading. Instead, consider the entire set of maps as a unified entity. You should assess the final, rendered results for a comprehensive understanding of the material's appearance by directly plugging the fitted maps into your shader.

</details>

<details>

<summary>Color accuracy is very important for us. Why do you have lighting/shadows/specular components baked into the diffuse map?</summary>

Color accuracy is also one of our top concerns, and we take great care to ensure that we get the best possible data from our scanning system. This is a very deep topic, and there are a huge number of factors to consider when discussing how accuracy is measured and evaluated. Ultimately, what should be judged is the final render, rather than the isolated maps, since there are numerous shading effects that can influence color perception.

Shadows can occur in the diffuse map due to self-occlusions within the 3D structure of the surface. While it may seem strange that these are present in the diffuse/albedo map, they must be accounted for by some parameter in order for the rendered results to match the original sample. In a typical top-down 3D workflow, an artist would have these separated out into different maps for ease of editing, but the final rendered result would be very similar once all the maps are combined in a shader.

</details>

<details>

<summary>Why do you have anisotropy maps for isotropic materials?</summary>

Many seemingly isotropic materials are actually anisotropic when viewed at a small enough scale, and our scanner is able to resolve this. When viewed at a distance, the various anisotropies will average out to give the appearance of isotropy. Rather than have special cases for different types of surfaces, we always calculate anisotropy-related parameters, since their inclusion almost always increases the accuracy of the final render. (It should be noted that if a sample has particularly high roughness or low specularity, then high anisotropy values will contribute less of an effect towards the end result. Therefore, a high anisotropy value should not immediately imply that the material is highly anisotropic—it needs to be taken in context with the other parameters.)

</details>


# Shipping Material Samples

Guidelines for preparing and shipping material samples

* **Sample sizes** should be 60 x 60 cm (24 x 24 in). If the material has a larger pattern, the sample should be the full repeat size in both directions (vertical and horizontal) plus 25%.
* **Never fold** the samples to prevent wrinkles or creases. Please send them either:
  * Rolled, or
  * Laid flat in a 60 x 60 cm (24 x 24 in) box. Ensure the box is fully packed to prevent the samples from moving during transit.
* Clearly **label** each sample you send. We will use the names and article numbers you provide on the colormass Platform. Please mind the following:
  * Indicate the front (or back) side of the sample
  * The direction of the sample (top/bottom)
  * If your labels are 10 x 10 cm (4 x 4 inches) or smaller, place them on the front of the sample
  * If your labels are larger than this, place them on the back to avoid covering a significant portion of the sample, which could interfere with the scanning process
  * For transparent materials, use small labels and place them on the front
* Use the [shipping address](#shipping-address-and-contact-details) provided below.

{% hint style="info" %}
If shipping from outside the European Union, please include a customs declaration (i.e., a pro forma invoice—not an actual invoice) attached to the outside of the package, detailing:

* Your company name and address
* colormass’s company name and address (see below)
* A description of the contents (e.g., "Material samples (textile, fabric, vinyl, etc.) for upholstery furniture")
* The value of the package (ensure the declared value is more than 0 € but under 100 €).
  {% endhint %}

## Shipping Address

colormass GmbH\
Tas Sóti (+49 30 6920 6200)\
Fasanenstr. 7-8\
10623 Berlin\
Germany


# Exports

{% hint style="info" %}
It is possible to integrate exports directly into your website, so that you don't have to manually download and upload files. For more information check out the [Data Exporter](/dev/data-exporter/generating-exports) developer documentation.
{% endhint %}

A big advantage of an online 3D system like colormass is that since you are only storing a single source of truth, you can generate various kinds of export without having to store all those variations separately in the database.

## Types of Exports

On the right side of the screenshot below under *Material outputs* you can see four main outputs.

<figure><img src="/files/AkQOjn9mldx410byRQ3A" alt=""><figcaption><p>Material outputs</p></figcaption></figure>

For fall materials that have an online revision, various outputs can be generated:

* **Flat thumbnails** are images that are generated with a fixed dimension that is visible on the image. On the platform the following predefined sizes are available to be generated:

  <figure><img src="/files/LkIQqb580tQJYSdaDONe" alt="" width="181"><figcaption><p>Thumbnail sizes</p></figcaption></figure>
* **Tileable image** is an image that can be placed next to itself (above, below, or side-by-side) without creating an obvious seam. The size of the repeat (and hence the physical size visible on the image) is included in the name of the file.
* **Map exports** are the PBR exports where the maps can be exported based on the last material revision or texture set. This can mean standard PBR exports but you are also able to change between render engines (Vray, Corona, Cycles), workflows (Metallness/Roughness, Specular/Glossiness), file type and many other settings.

  <figure><img src="/files/7xYID9AiN1oR5rOmvdpm" alt="" width="150"><figcaption><p>PBR export settings</p></figcaption></figure>




---

[Next Page](/llms-full.txt/1)

