Skip to content

Commit

Permalink
3d texture example working
Browse files Browse the repository at this point in the history
  • Loading branch information
tsherif committed Mar 12, 2019
1 parent 7c7bc32 commit 307d199
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 131 deletions.
1 change: 1 addition & 0 deletions .eslintrc
Expand Up @@ -15,6 +15,7 @@
"no-inline-comments": 0,
"camelcase": 0,
"tree-shaking/no-side-effects-in-initialization": 0,
"max-statements": 0,
"luma-gl-custom-rules/check-log-call": 1
}
}
46 changes: 29 additions & 17 deletions examples/core/3d-texture/app.js
@@ -1,6 +1,6 @@
import {AnimationLoop, setParameters, Model, Texture3D } from 'luma.gl';
import {AnimationLoop, setParameters, Model, Texture3D, Buffer} from 'luma.gl';
import {Matrix4, radians} from 'math.gl';
import {StatsWidget} from '@probe.gl/stats-widget'
import {StatsWidget} from '@probe.gl/stats-widget';
import {default as noise3d} from 'noise3d';

const INFO_HTML = `
Expand All @@ -11,7 +11,7 @@ A luma.gl <code>Cube</code>, rendering 65,536 instances in a
single GPU draw call using instanced vertex attributes.
`;

const vs = `
const vs = `\
#version 300 es
in vec3 position;
Expand All @@ -25,7 +25,7 @@ void main() {
gl_PointSize = 2.0;
}`;

const fs = `
const fs = `\
#version 300 es
precision highp float;
precision lowp sampler3D;
Expand All @@ -34,10 +34,12 @@ uniform sampler3D uTexture;
uniform float uTime;
out vec4 fragColor;
void main() {
float alpha = texture(uTexture, vUV + vec3(0.0, 0.0, uTime)).r * 0.03;
float alpha = texture(uTexture, vUV + vec3(0.0, 0.0, uTime)).r * 0.1;
fragColor = vec4(fract(vUV) * alpha, alpha);
}`;

const NEAR = 0.1;
const FAR = 10.0;

class AppAnimationLoop extends AnimationLoop {
constructor() {
Expand All @@ -57,7 +59,7 @@ class AppAnimationLoop extends AnimationLoop {
setParameters(gl, {
clearColor: [0, 0, 0, 1],
blend: true,
blendFunc: [gl.ONE, gl.ONE_MINUE_SRC_ALPHA]
blendFunc: [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]
});

// CREATE POINT CLOUD
Expand All @@ -82,15 +84,21 @@ class AppAnimationLoop extends AnimationLoop {
x += INCREMENT;
}

const positionBuffer = new Buffer(gl, positionData);

// CREATE 3D TEXTURE
const TEXTURE_DIMENSIONS = 16;
const textureData = new Uint8Array(TEXTURE_DIMENSIONS * TEXTURE_DIMENSIONS * TEXTURE_DIMENSIONS);
const NOISE_DIMENSIONS = TEXTURE_DIMENSIONS * 0.07;
const textureData = new Uint8Array(
TEXTURE_DIMENSIONS * TEXTURE_DIMENSIONS * TEXTURE_DIMENSIONS
);
let textureIndex = 0;
for (let i = 0; i < TEXTURE_DIMENSIONS; ++i) {
for (let j = 0; j < TEXTURE_DIMENSIONS; ++j) {
for (let k = 0; k < TEXTURE_DIMENSIONS; ++k) {
let val = perlin(i, j, k) * 255
textureData[textureIndex++] = val;
textureData[textureIndex++] =
(0.5 + 0.5 * perlin(i / NOISE_DIMENSIONS, j / NOISE_DIMENSIONS, k / NOISE_DIMENSIONS)) *
255;
}
}
}
Expand All @@ -99,16 +107,21 @@ class AppAnimationLoop extends AnimationLoop {
const viewMat = new Matrix4().lookAt({eye: [1, 1, 1]});

const texture = new Texture3D(gl, {
width: DIMENSIONS,
height: DIMENSIONS,
depth: DIMENSIONS,
pixels: textureData
width: TEXTURE_DIMENSIONS,
height: TEXTURE_DIMENSIONS,
depth: TEXTURE_DIMENSIONS,
pixels: textureData,
format: gl.RED,
dataFormat: gl.R8
});

const cloud = new Model(gl, {
vs,
fs,
drawMode: gl.POINTS,
vertexCount: positionData.length / 3,
attributes: {
position: positionData
position: positionBuffer
},
uniforms: {
uTexture: texture,
Expand All @@ -127,8 +140,7 @@ class AppAnimationLoop extends AnimationLoop {
}

onRender(animationProps) {

const {gl, cloud, projMat, statsWidget, tick} = animationProps;
const {gl, cloud, projMat, statsWidget, tick, aspect} = animationProps;

projMat.perspective({fov: radians(75), aspect, near: NEAR, far: FAR});

Expand All @@ -143,7 +155,7 @@ class AppAnimationLoop extends AnimationLoop {
gl.clear(gl.COLOR_BUFFER_BIT);
cloud.draw({
uniforms: {
uTime: tick / 1000,
uTime: tick / 100,
uProj: projMat
}
});
Expand Down
77 changes: 4 additions & 73 deletions modules/core/src/webgl/classes/texture-3d.js
@@ -1,87 +1,18 @@
import GL from '@luma.gl/constants';
import Texture from './texture';
import Buffer from './buffer';
import {withParameters} from '../context';
import {isWebGL2, assertWebGL2Context} from '../utils';

export default class Texture3D extends Texture {
static isSupported(gl) {
return isWebGL2(gl);
}

constructor(gl, opts = {}) {
constructor(gl, props = {}) {
assertWebGL2Context(gl);
super(gl, Object.assign({}, opts, {target: opts.target || GL.TEXTURE_3D, is3D: true }));
props = Object.assign({}, props, {target: props.target || GL.TEXTURE_3D, unpackFlipY: false});
super(gl, props);
this.initialize(props);

this.width = null;
this.height = null;
this.depth = null;
Object.seal(this);

this.setImageData(opts);
if (opts.generateMipmap) {
this.generateMipmap();
}
}

initialize(opts = {}) {
this.opts = Object.assign({}, this.opts, opts);
const {pixels, settings} = this.opts;
if (settings) {
withParameters(settings, () => {
if (pixels) {
this.setImage3D(this.opts);
}
});
this.setParameters(opts);
}
}

// WebGL2

// Image 3D copies from Typed Array or WebGLBuffer
setImage3D({
level = 0,
internalformat = GL.RGBA,
width,
height,
depth = 1,
border = 0,
format,
type = GL.UNSIGNED_BYTE,
offset = 0,
pixels
}) {
if (ArrayBuffer.isView(pixels)) {
this.gl.texImage3D(
this.target,
level,
internalformat,
width,
height,
depth,
border,
format,
type,
pixels
);
return;
}
if (pixels instanceof Buffer) {
this.gl.bindBuffer(GL.PIXEL_UNPACK_BUFFER, pixels.handle);
this.gl.texImage3D(
this.target,
level,
internalformat,
width,
height,
depth,
border,
format,
type,
offset
);
this.gl.bindBuffer(GL.PIXEL_UNPACK_BUFFER, pixels.handle);
}
}
}
92 changes: 51 additions & 41 deletions modules/core/src/webgl/classes/texture.js
Expand Up @@ -104,22 +104,24 @@ export default class Texture extends Resource {
data = pixels;
}

let {width, height, depth, dataFormat} = props;
let {width, height, dataFormat} = props;
const {depth = 0} = props;

// Deduce width and height
({width, height, depth, dataFormat} = this._deduceParameters({
({width, height, dataFormat} = this._deduceParameters({
format,
type,
dataFormat,
compressed: false,
data,
width
width,
height
}));

// Store opts for accessors
this.width = width;
this.height = height;
this.depth = depth || 0;
this.depth = depth;
this.format = format;
this.type = type;
this.dataFormat = dataFormat;
Expand Down Expand Up @@ -226,6 +228,10 @@ export default class Texture extends Resource {
*/
/* eslint-disable max-len, max-statements, complexity */
setImageData(options) {
if (this.depth > 0) {
return this.setImage3D(options);
}

const {
target = this.target,
pixels = null,
Expand All @@ -250,23 +256,21 @@ export default class Texture extends Resource {
data = pixels;
}

({type, dataFormat, compressed, width, height, depth} = this._deduceParameters({
({type, dataFormat, compressed, width, height} = this._deduceParameters({
format,
type,
dataFormat,
compressed,
data,
width,
height,
depth,
is3D
height
}));

const {gl} = this;
gl.bindTexture(this.target, this.handle);

let dataType = null;
({data, dataType} = this._getDataType({data, compressed, is3D}));
({data, dataType} = this._getDataType({data, compressed}));

withParameters(this.gl, parameters, () => {
switch (dataType) {
Expand Down Expand Up @@ -493,47 +497,53 @@ export default class Texture extends Resource {
// Image 3D copies from Typed Array or WebGLBuffer
setImage3D({
level = 0,
internalformat = GL.RGBA,
dataFormat = GL.RGBA,
width,
height,
depth = 1,
border = 0,
format,
type = GL.UNSIGNED_BYTE,
offset = 0,
pixels
data,
parameters = {}
}) {
if (ArrayBuffer.isView(pixels)) {
this.gl.texImage3D(
this.target,
level,
internalformat,
width,
height,
depth,
border,
format,
type,
pixels
);
return this;
}
this.gl.bindTexture(this.target, this.handle);

if (pixels instanceof Buffer) {
this.gl.bindBuffer(GL.PIXEL_UNPACK_BUFFER, pixels.handle);
this.gl.texImage3D(
this.target,
level,
internalformat,
width,
height,
depth,
border,
format,
type,
offset
);
}
withParameters(this.gl, parameters, () => {
if (ArrayBuffer.isView(data)) {
this.gl.texImage3D(
this.target,
level,
dataFormat,
width,
height,
depth,
border,
format,
type,
data
);
}

if (data instanceof Buffer) {
this.gl.bindBuffer(GL.PIXEL_UNPACK_BUFFER, data.handle);
this.gl.texImage3D(
this.target,
level,
dataFormat,
width,
height,
depth,
border,
format,
type,
offset
);
}
});

this.loaded = true;

return this;
}
Expand Down

0 comments on commit 307d199

Please sign in to comment.