Skip to content

Commit

Permalink
Merge pull request #37 from ux3d/feature/ibl_sampler
Browse files Browse the repository at this point in the history
Feature/ibl sampler
  • Loading branch information
UX3D-becher authored Dec 24, 2020
2 parents 43345d0 + 54416b1 commit 05e8d00
Show file tree
Hide file tree
Showing 16 changed files with 1,180 additions and 36 deletions.
2 changes: 1 addition & 1 deletion example/assets/environments
2 changes: 1 addition & 1 deletion example/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default {
}
],
plugins: [
glslify({include: ['../src/Renderer/shaders/*']}),
glslify({include: ['../src/Renderer/shaders/*', '../src/shaders/*']}),
resolve({
browser: true,
preferBuiltins: true
Expand Down
4 changes: 2 additions & 2 deletions example/src/drag_input.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getIsGltf, getIsGlb } from 'gltf-sample-viewer';
import { getIsGltf, getIsGlb, getIsHdr } from 'gltf-sample-viewer';

class gltfDragInput
{
Expand Down Expand Up @@ -114,7 +114,7 @@ class gltfDragInput
let additionalFiles = [];
for (let file of files)
{
if (getIsGltf(file.name) || getIsGlb(file.name))
if (getIsGltf(file.name) || getIsGlb(file.name) || getIsHdr(file.name))
{
mainFile = file;
}
Expand Down
29 changes: 19 additions & 10 deletions example/src/main.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { gltfInput } from './input.js';

import { GltfView, computePrimitiveCentroids, loadGltf, loadPrefilteredEnvironmentFromPath, initKtxLib, initDracoLib } from 'gltf-sample-viewer';
import { GltfView, computePrimitiveCentroids, loadGltf, loadEnvironment, initKtxLib, initDracoLib } from 'gltf-sample-viewer';

import { UIModel } from './logic/uimodel.js';
import { app } from './ui/ui.js';
Expand All @@ -17,7 +17,7 @@ async function main()
initDracoLib();
initKtxLib(view);

loadPrefilteredEnvironmentFromPath("assets/environments/footprint_court", view).then( (environment) => {
loadEnvironment("assets/environments/footprint_court_512.hdr", view).then( (environment) => {
state.environment = environment;
});

Expand Down Expand Up @@ -110,14 +110,23 @@ async function main()
state.userCamera.updatePosition();
};
input.onDropFiles = (mainFile, additionalFiles) => {
loadGltf(mainFile, view, additionalFiles).then( gltf => {
state.gltf = gltf;
computePrimitiveCentroids(state.gltf);
state.userCamera.fitViewToScene(state.gltf, state.sceneIndex);
state.userCamera.updatePosition();
state.animationIndices = [0];
state.animationTimer.start();
});
if (mainFile.name.endsWith(".hdr"))
{
loadEnvironment(mainFile, view).then( (environment) => {
state.environment = environment;
});
}
if (mainFile.name.endsWith(".gltf") || mainFile.name.endsWith(".glb"))
{
loadGltf(mainFile, view, additionalFiles).then( gltf => {
state.gltf = gltf;
computePrimitiveCentroids(state.gltf);
state.userCamera.fitViewToScene(state.gltf, state.sceneIndex);
state.userCamera.updatePosition();
state.animationIndices = [0];
state.animationTimer.start();
});
}
};

await view.startRendering(state);
Expand Down
3 changes: 2 additions & 1 deletion src/Renderer/webgl.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ class gltfWebGl
}

const image = gltf.images[gltfTex.source];
if (image.mimeType === ImageMimeType.KTX2)
if (image.mimeType === ImageMimeType.KTX2 ||
image.mimeType === ImageMimeType.GLTEXTURE)
{
gltfTex.glTexture = image.image;
gltfTex.initialized = true;
Expand Down
3 changes: 2 additions & 1 deletion src/ResourceLoader/image_processor.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ class gltfImageProcessor
{
const image = gltfImage.image;

if (gltfImage.mimeType === ImageMimeType.KTX2)
if (gltfImage.mimeType === ImageMimeType.KTX2 ||
gltfImage.mimeType === ImageMimeType.GLTEXTURE)
{
continue;
}
Expand Down
147 changes: 132 additions & 15 deletions src/ResourceLoader/resource_loader.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

import { axios } from '@bundled-es-modules/axios';
import { glTF } from '../gltf/gltf.js';
import { getIsGlb, getContainingFolder } from '../gltf/utils.js';
Expand All @@ -7,11 +8,16 @@ import { gltfImage, ImageMimeType } from "../gltf/image.js";
import { gltfTexture, gltfTextureInfo } from '../gltf/texture.js';
import { gltfSampler } from '../gltf/sampler.js';

import { iblSampler } from '../ibl_sampler.js';


import { AsyncFileReader } from './async_file_reader.js';

import { DracoDecoder } from './draco.js';
import { KtxDecoder } from './ktx.js';

import { HDRImage } from '../libs/hdrpng.js';

function initKtxLib(view, ktxlib)
{
view.ktxDecoder = new KtxDecoder(view.context,ktxlib);
Expand Down Expand Up @@ -81,12 +87,34 @@ async function loadGltf(file, view, additionalFiles)
return gltf;
}

async function loadPrefilteredEnvironmentFromPath(filteredEnvironmentsDirectoryPath, view)

async function loadEnvironment(file, view)
{
let image = new HDRImage();
if (typeof file === "string")
{
await image.loadHDR(file);
await new Promise((resolve, reject) => {
image.onload = () => resolve(image);
image.onerror = reject;
});
}
else
{
const imageData = await AsyncFileReader.readAsArrayBuffer(file).catch( () => {
console.error("Could not load image with FileReader");
});
await image.loadHDR(new Uint8Array(imageData));
}
return loadEnvironmentFromImage(image, view);
}


async function loadEnvironmentFromImage(imageHDR, view)
{
// The environment uses the same type of samplers, textures and images as used in the glTF class
// so we just use it as a template
const environment = new glTF();
environment.ktxDecoder = view.ktxDecoder;

//
// Prepare samplers.
Expand All @@ -110,22 +138,105 @@ async function loadPrefilteredEnvironmentFromPath(filteredEnvironmentsDirectoryP
// Prepare images and textures.
//

let textureIdx = environment.images.length;
let imageIdx = environment.images.length;

let environmentFiltering = new iblSampler(view);

environmentFiltering.init(imageHDR);
environmentFiltering.filterAll();

// Diffuse

const diffuseGltfImage = new gltfImage(
undefined,
WebGL2RenderingContext.TEXTURE_CUBE_MAP,
0,
undefined,
"Diffuse",
ImageMimeType.GLTEXTURE,
environmentFiltering.lambertianTextureID
);

environment.images.push(diffuseGltfImage);

const diffuseTexture = new gltfTexture(
diffuseCubeSamplerIdx,
[imageIdx++],
WebGL2RenderingContext.TEXTURE_CUBE_MAP,
environmentFiltering.lambertianTextureID);

environment.textures.push(diffuseTexture);

environment.diffuseEnvMap = new gltfTextureInfo(environment.textures.length - 1, 0, true);
environment.diffuseEnvMap.generateMips = false;



// Specular
const specularGltfImage = new gltfImage(
undefined,
WebGL2RenderingContext.TEXTURE_CUBE_MAP,
0,
undefined,
"Specular",
ImageMimeType.GLTEXTURE,
environmentFiltering.ggxTextureID
);

environment.images.push(specularGltfImage);

const specularTexture = new gltfTexture(
specularCubeSamplerIdx,
[imageIdx++],
WebGL2RenderingContext.TEXTURE_CUBE_MAP,
environmentFiltering.ggxTextureID);

environment.textures.push(specularTexture);

environment.specularEnvMap = new gltfTextureInfo(environment.textures.length - 1, 0, true);
environment.specularEnvMap.generateMips = false;


// Sheen
const sheenGltfImage = new gltfImage(
undefined,
WebGL2RenderingContext.TEXTURE_CUBE_MAP,
0,
undefined,
"Sheen",
ImageMimeType.GLTEXTURE,
environmentFiltering.ggxTextureID
);

environment.images.push(sheenGltfImage);

const sheenTexture = new gltfTexture(
sheenCubeSamplerIdx,
[imageIdx++],
WebGL2RenderingContext.TEXTURE_CUBE_MAP,
environmentFiltering.sheenTextureID);

environment.textures.push(sheenTexture);

environment.sheenEnvMap = new gltfTextureInfo(environment.textures.length - 1, 0, true);
environment.sheenEnvMap.generateMips = false;

/*
// Diffuse
const lambertian = new gltfImage(filteredEnvironmentsDirectoryPath + "/lambertian/diffuse.ktx2", WebGL2RenderingContext.TEXTURE_CUBE_MAP);
lambertian.mimeType = ImageMimeType.KTX2;
environment.images.push(lambertian);
environment.textures.push(new gltfTexture(diffuseCubeSamplerIdx, [textureIdx++], WebGL2RenderingContext.TEXTURE_CUBE_MAP));
environment.textures.push(new gltfTexture(diffuseCubeSamplerIdx, [imageIdx++], WebGL2RenderingContext.TEXTURE_CUBE_MAP));
environment.diffuseEnvMap = new gltfTextureInfo(environment.textures.length - 1, 0, true);
environment.diffuseEnvMap.generateMips = false;
// Specular
const specular = new gltfImage(filteredEnvironmentsDirectoryPath + "/ggx/specular.ktx2", WebGL2RenderingContext.TEXTURE_CUBE_MAP);
specular.mimeType = ImageMimeType.KTX2;
environment.images.push(specular);
environment.textures.push(new gltfTexture(specularCubeSamplerIdx, [textureIdx++], WebGL2RenderingContext.TEXTURE_CUBE_MAP));
environment.textures.push(new gltfTexture(specularCubeSamplerIdx, [imageIdx++], WebGL2RenderingContext.TEXTURE_CUBE_MAP));
environment.specularEnvMap = new gltfTextureInfo(environment.textures.length - 1, 0, true);
environment.specularEnvMap.generateMips = false;
Expand All @@ -136,40 +247,46 @@ async function loadPrefilteredEnvironmentFromPath(filteredEnvironmentsDirectoryP
const sheen = new gltfImage(filteredEnvironmentsDirectoryPath + "/charlie/sheen.ktx2", WebGL2RenderingContext.TEXTURE_CUBE_MAP);
sheen.mimeType = ImageMimeType.KTX2;
environment.images.push(sheen);
environment.textures.push(new gltfTexture(sheenCubeSamplerIdx, [textureIdx++], WebGL2RenderingContext.TEXTURE_CUBE_MAP));
environment.textures.push(new gltfTexture(sheenCubeSamplerIdx, [imageIdx++], WebGL2RenderingContext.TEXTURE_CUBE_MAP));
environment.sheenEnvMap = new gltfTextureInfo(environment.textures.length - 1, 0, true);
environment.sheenEnvMap.generateMips = false;
environment.sheenEnvMap.generateMips = false;*/

//
// Look Up Tables.
//

// GGX
environment.images.push(new gltfImage("../assets/images/lut_ggx.png", WebGL2RenderingContext.TEXTURE_2D));
environment.textures.push(new gltfTexture(lutSamplerIdx, [textureIdx++], WebGL2RenderingContext.TEXTURE_2D));

environment.images.push(new gltfImage("assets/images/lut_ggx.png", WebGL2RenderingContext.TEXTURE_2D));
environment.textures.push(new gltfTexture(lutSamplerIdx, [imageIdx++], WebGL2RenderingContext.TEXTURE_2D));

environment.lut = new gltfTextureInfo(environment.textures.length - 1);
environment.lut.generateMips = false;

// Sheen
// Charlie
environment.images.push(new gltfImage("../assets/images/lut_charlie.png", WebGL2RenderingContext.TEXTURE_2D));
environment.textures.push(new gltfTexture(lutSamplerIdx, [textureIdx++], WebGL2RenderingContext.TEXTURE_2D));

environment.images.push(new gltfImage("assets/images/lut_charlie.png", WebGL2RenderingContext.TEXTURE_2D));
environment.textures.push(new gltfTexture(lutSamplerIdx, [imageIdx++], WebGL2RenderingContext.TEXTURE_2D));

environment.sheenLUT = new gltfTextureInfo(environment.textures.length - 1);
environment.sheenLUT.generateMips = false;

// Sheen E LUT
environment.images.push(new gltfImage("../assets/images/lut_sheen_E.png", WebGL2RenderingContext.TEXTURE_2D));
environment.textures.push(new gltfTexture(lutSamplerIdx, [textureIdx++], WebGL2RenderingContext.TEXTURE_2D));

environment.images.push(new gltfImage("assets/images/lut_sheen_E.png", WebGL2RenderingContext.TEXTURE_2D));
environment.textures.push(new gltfTexture(lutSamplerIdx, [imageIdx++], WebGL2RenderingContext.TEXTURE_2D));

environment.sheenELUT = new gltfTextureInfo(environment.textures.length - 1);
environment.sheenELUT.generateMips = false;

await gltfLoader.loadImages(environment).then(() => gltfLoader.processImages(environment));

environment.initGl(view.context);

environment.mipCount = specularImage.image.levels;
environment.mipCount = environmentFiltering.mipmapLevels;

return environment;
}

export { loadGltf, loadPrefilteredEnvironmentFromPath, initKtxLib, initDracoLib};
export { loadGltf, loadEnvironment, initKtxLib, initDracoLib};
14 changes: 11 additions & 3 deletions src/gltf-sample-viewer.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
import { GltfView } from './GltfView/gltf_view.js';
import { computePrimitiveCentroids } from './gltf/gltf_utils.js';
import { loadGltf, loadPrefilteredEnvironmentFromPath, initDracoLib, initKtxLib } from './ResourceLoader/resource_loader.js';

import {
loadGltf,
loadEnvironment,
initDracoLib,
initKtxLib
} from './ResourceLoader/resource_loader.js';

import {
getIsGltf,
getIsGlb,
getIsHdr,
getContainingFolder,
combinePaths,
getFileNameWithoutExtension
Expand All @@ -17,13 +24,14 @@ export {
GltfView,
getIsGltf,
getIsGlb,
getIsHdr,
computePrimitiveCentroids,
loadGltf,
loadPrefilteredEnvironmentFromPath,
loadEnvironment,
initKtxLib,
initDracoLib,
getContainingFolder,
combinePaths,
getFileNameWithoutExtension,
glTF,
};
};
7 changes: 5 additions & 2 deletions src/gltf/image.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { GltfObject } from './gltf_object.js';
import { isPowerOf2 } from './math_utils.js';
import { AsyncFileReader } from '../ResourceLoader/async_file_reader.js';

const ImageMimeType = {JPEG: "image/jpeg", PNG: "image/png", HDR: "image/vnd.radiance", KTX2: "image/ktx2"};
const ImageMimeType = {JPEG: "image/jpeg", PNG: "image/png", HDR: "image/vnd.radiance", KTX2: "image/ktx2", GLTEXTURE: "image/texture"};

class gltfImage extends GltfObject
{
Expand Down Expand Up @@ -46,7 +46,10 @@ class gltfImage extends GltfObject
{
if (this.image !== undefined)
{
console.error("image has already been loaded");
if (this.mimeType !== ImageMimeType.GLTEXTURE)
{
console.error("image has already been loaded");
}
return;
}

Expand Down
6 changes: 6 additions & 0 deletions src/gltf/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,11 @@ function getIsGltf(filename)
return getExtension(filename) == "gltf";
}

function getIsHdr(filename)
{
return getExtension(filename) == "hdr";
}

function getExtension(filename)
{
const split = filename.toLowerCase().split(".");
Expand Down Expand Up @@ -272,6 +277,7 @@ export {
clamp,
getIsGlb,
getIsGltf,
getIsHdr,
getExtension,
getFileName,
getFileNameWithoutExtension,
Expand Down
Loading

0 comments on commit 05e8d00

Please sign in to comment.