Skip to content

Commit e913570

Browse files
committedJan 5, 2013
Texture mapping for surfaces
1 parent f8a4505 commit e913570

16 files changed

+278
-57
lines changed
 

‎.gitmodules

+3
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,6 @@
77
[submodule "vendor/ThreeRTT.js"]
88
path = vendor/ThreeRTT.js
99
url = https://github.com/unconed/ThreeRTT.js
10+
[submodule "vendor/console-extras"]
11+
path = vendor/console-extras
12+
url = https://github.com/unconed/console-extras.js.git

‎README.md

+4
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,8 @@ Bezier Surface
326326
doubleSided: true, // Whether the mesh is double sided
327327
flipSided: false, // Whether to flip a single sided mesh
328328
shaded: true, // Whether to shade the surface
329+
map: null, // Texture Map (pass in THREE.Texture)
330+
mapOpacity: 0, // Opacity of texture map
329331
})
330332
```
331333

@@ -370,6 +372,8 @@ Surface
370372
doubleSided: true, // Whether the mesh is double sided
371373
flipSided: false, // Whether to flip a single sided mesh
372374
shaded: true, // Whether to shade the surface
375+
map: null, // Texture Map (pass in THREE.Texture)
376+
mapOpacity: 0, // Opacity of texture map
373377
})
374378
```
375379

‎build/MathBox-bundle.js

+12-2
Original file line numberDiff line numberDiff line change
@@ -43488,6 +43488,8 @@ MathBox.Style.prototype = {
4348843488
worldRotation: new THREE.Vector3(),
4348943489
worldPosition: new THREE.Vector3(),
4349043490
zIndex: 0.0,
43491+
43492+
mapOpacity: 0,
4349143493
};
4349243494
},
4349343495

@@ -44579,6 +44581,7 @@ MathBox.Surface.prototype = _.extend(new MathBox.Primitive(null), {
4457944581
doubleSided: true,
4458044582
flipSided: false,
4458144583
shaded: true,
44584+
map: null,
4458244585
style: {}//,
4458344586
};
4458444587
},
@@ -44621,7 +44624,8 @@ MathBox.Surface.prototype = _.extend(new MathBox.Primitive(null), {
4462144624
doubleSided: options.doubleSided,
4462244625
flipSided: options.flipSided,
4462344626
shaded: options.shaded,
44624-
dynamic: options.live
44627+
dynamic: options.live,
44628+
map: options.map,
4462544629
}, style);
4462644630
this.line = new MathBox.Renderable.Mesh(geometry, {
4462744631
type: 'mesh',
@@ -44795,6 +44799,7 @@ MathBox.BezierSurface.prototype = _.extend(new MathBox.Surface(null), {
4479544799
doubleSided: true,
4479644800
flipSided: false,
4479744801
shaded: true,
44802+
map: null,
4479844803
style: {}//,
4479944804
};
4480044805
},
@@ -45015,9 +45020,14 @@ MathBox.Renderable.prototype = {
4501545020
}
4501645021

4501745022
if (this.material) {
45023+
options = this.get();
45024+
45025+
// Apply texture
45026+
if (options.map) {
45027+
this.material.uniforms.texture.value = options.map;
45028+
}
4501845029

4501945030
// Set double sided / culling order.
45020-
options = this.get();
4502145031
this.material.side = options.doubleSided ? THREE.DoubleSide :
4502245032
THREE.FrontSide;
4502345033
options = { flipSided: (options.doubleSided && options.flipSided) ? -1 : 1 };

‎build/MathBox-bundle.min.js

+15-15
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎build/MathBox-core.js

+12-2
Original file line numberDiff line numberDiff line change
@@ -1641,6 +1641,8 @@ MathBox.Style.prototype = {
16411641
worldRotation: new THREE.Vector3(),
16421642
worldPosition: new THREE.Vector3(),
16431643
zIndex: 0.0,
1644+
1645+
mapOpacity: 0,
16441646
};
16451647
},
16461648

@@ -2732,6 +2734,7 @@ MathBox.Surface.prototype = _.extend(new MathBox.Primitive(null), {
27322734
doubleSided: true,
27332735
flipSided: false,
27342736
shaded: true,
2737+
map: null,
27352738
style: {}//,
27362739
};
27372740
},
@@ -2774,7 +2777,8 @@ MathBox.Surface.prototype = _.extend(new MathBox.Primitive(null), {
27742777
doubleSided: options.doubleSided,
27752778
flipSided: options.flipSided,
27762779
shaded: options.shaded,
2777-
dynamic: options.live
2780+
dynamic: options.live,
2781+
map: options.map,
27782782
}, style);
27792783
this.line = new MathBox.Renderable.Mesh(geometry, {
27802784
type: 'mesh',
@@ -2948,6 +2952,7 @@ MathBox.BezierSurface.prototype = _.extend(new MathBox.Surface(null), {
29482952
doubleSided: true,
29492953
flipSided: false,
29502954
shaded: true,
2955+
map: null,
29512956
style: {}//,
29522957
};
29532958
},
@@ -3168,9 +3173,14 @@ MathBox.Renderable.prototype = {
31683173
}
31693174

31703175
if (this.material) {
3176+
options = this.get();
3177+
3178+
// Apply texture
3179+
if (options.map) {
3180+
this.material.uniforms.texture.value = options.map;
3181+
}
31713182

31723183
// Set double sided / culling order.
3173-
options = this.get();
31743184
this.material.side = options.doubleSided ? THREE.DoubleSide :
31753185
THREE.FrontSide;
31763186
options = { flipSided: (options.doubleSided && options.flipSided) ? -1 : 1 };

‎build/MathBox-core.min.js

+15-15
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎build/MathBox.glsl.html

+16-2
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,11 @@
312312
// Fragment shader: render a shaded surface fragment.
313313
uniform vec3 color;
314314
uniform float opacity;
315+
uniform float mapOpacity;
316+
317+
uniform sampler2D texture;
318+
varying vec2 vUV;
319+
315320
varying vec3 vNormal;
316321
varying vec3 vViewPosition;
317322
uniform float flipSided;
@@ -337,18 +342,27 @@
337342
float dotNormalHalf = max(dot(normal, halfVector), 0.0);
338343
float specular = max(pow(dotNormalHalf, shininess), 0.0);
339344

340-
gl_FragColor = vec4(color * diffuse + specular * .3, opacity);
345+
vec4 sample = texture2D(texture, vUV);
346+
vec3 textured = color + (color * sample.xyz - color) * mapOpacity * sample.w;
347+
gl_FragColor = vec4(textured * diffuse + specular * .3, opacity);
341348
}
342349
</script>
343350

344351
<script type="application/x-glsl" id="fragmentSolid">
345352
// Fragment shader: render a solid surface fragment.
346353
uniform vec3 color;
347354
uniform float opacity;
355+
uniform float mapOpacity;
356+
357+
uniform sampler2D texture;
358+
varying vec2 vUV;
348359

349360
void fragmentSolid() {
350361
if (opacity < 0.01) discard;
351-
gl_FragColor = vec4(color, opacity);
362+
363+
vec4 sample = texture2D(texture, vUV);
364+
vec3 textured = color + (color * sample.xyz - color) * mapOpacity * sample.w;
365+
gl_FragColor = vec4(textured, opacity);
352366
}
353367
</script>
354368

‎build/MathBox.js

+12-2
Original file line numberDiff line numberDiff line change
@@ -4612,6 +4612,8 @@ MathBox.Style.prototype = {
46124612
worldRotation: new THREE.Vector3(),
46134613
worldPosition: new THREE.Vector3(),
46144614
zIndex: 0.0,
4615+
4616+
mapOpacity: 0,
46154617
};
46164618
},
46174619

@@ -5703,6 +5705,7 @@ MathBox.Surface.prototype = _.extend(new MathBox.Primitive(null), {
57035705
doubleSided: true,
57045706
flipSided: false,
57055707
shaded: true,
5708+
map: null,
57065709
style: {}//,
57075710
};
57085711
},
@@ -5745,7 +5748,8 @@ MathBox.Surface.prototype = _.extend(new MathBox.Primitive(null), {
57455748
doubleSided: options.doubleSided,
57465749
flipSided: options.flipSided,
57475750
shaded: options.shaded,
5748-
dynamic: options.live
5751+
dynamic: options.live,
5752+
map: options.map,
57495753
}, style);
57505754
this.line = new MathBox.Renderable.Mesh(geometry, {
57515755
type: 'mesh',
@@ -5919,6 +5923,7 @@ MathBox.BezierSurface.prototype = _.extend(new MathBox.Surface(null), {
59195923
doubleSided: true,
59205924
flipSided: false,
59215925
shaded: true,
5926+
map: null,
59225927
style: {}//,
59235928
};
59245929
},
@@ -6139,9 +6144,14 @@ MathBox.Renderable.prototype = {
61396144
}
61406145

61416146
if (this.material) {
6147+
options = this.get();
6148+
6149+
// Apply texture
6150+
if (options.map) {
6151+
this.material.uniforms.texture.value = options.map;
6152+
}
61426153

61436154
// Set double sided / culling order.
6144-
options = this.get();
61456155
this.material.side = options.doubleSided ? THREE.DoubleSide :
61466156
THREE.FrontSide;
61476157
options = { flipSided: (options.doubleSided && options.flipSided) ? -1 : 1 };

‎build/MathBox.min.js

+15-15
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎examples/TextureMap.html

+145
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<title>MathBox - Example: Texture map on surface.</title>
6+
7+
<!--
8+
This example shows how to apply a texture map to a surface.
9+
-->
10+
11+
<style type="text/css" media="screen">
12+
html, body { height: 100%; }
13+
body { margin: 0; padding: 0 }
14+
canvas { display: block }
15+
</style>
16+
17+
<script type="text/javascript" charset="utf-8" src="../vendor/domready.js"></script>
18+
<script type="text/javascript" charset="utf-8" src="../vendor/console-extras/dist/console-extras.min.js"></script>
19+
<script type="text/javascript" charset="utf-8" src="../build/MathBox-bundle.js"></script>
20+
21+
<script type="text/javascript" charset="utf-8">
22+
DomReady.ready(function () {
23+
if (location.href.match(/^file:/)) {
24+
document.getElementById('info').style.opacity = 1;
25+
document.getElementById('info').innerHTML = "Sorry. This example does not work when accessed using file://. Please use an http:// host and try again.";
26+
}
27+
});
28+
</script>
29+
30+
<style type="text/css" media="screen">
31+
#info {
32+
position: absolute;
33+
left: 50%;
34+
bottom: 50px;
35+
z-index: 20;
36+
37+
width: 300px;
38+
margin-left: -150px;
39+
40+
padding: 25px;
41+
background: rgba(0, 0, 0, .3);
42+
color: #fff;
43+
44+
font-family: "Lucida Grande", sans-serif;
45+
font-size: 16px;
46+
text-align: center;
47+
48+
border-radius: 3px;
49+
text-shadow: 0px 1px 0px rgba(0, 0, 0, .4);
50+
51+
opacity: 0;
52+
}
53+
54+
#info kbd {
55+
background: #ccc;
56+
box-shadow: 0px 1px 1px rgba(0, 0, 0, .3);
57+
border-radius: 3px;
58+
padding: 3px;
59+
margin: 3px;
60+
61+
font-family: inherit;
62+
}
63+
</style>
64+
65+
<script type="text/javascript" charset="utf-8">
66+
/**
67+
* Bootstrap
68+
*/
69+
DomReady.ready(function() {
70+
ThreeBox.preload([
71+
'../shaders/snippets.glsl.html',
72+
'../resources/texture.png',
73+
], function (assets) {
74+
75+
// MathBox boilerplate
76+
var mathbox = window.mathbox = mathBox({
77+
cameraControls: true,
78+
cursor: true,
79+
controlClass: ThreeBox.OrbitControls,
80+
elementResize: true,
81+
fullscreen: true,
82+
screenshot: true,
83+
stats: false,
84+
scale: 1,
85+
}).start();
86+
87+
// Viewport camera/setup
88+
mathbox
89+
// Polar viewport
90+
.viewport({
91+
type: 'cartesian',
92+
})
93+
.camera({
94+
orbit: 4,
95+
phi: τ/4-.8,
96+
theta: 1.1,
97+
})
98+
.transition(300)
99+
100+
// Surface function
101+
.surface({
102+
n: [192, 192],
103+
color: 0xffffff,
104+
shaded: true,
105+
map: assets['texture'], // Asset name is the filename without extension
106+
mapOpacity: 1,
107+
domain: [[-1.5, 1.5], [-1.5, 1.5]],
108+
n: [48, 32],
109+
expression: surfaceFunc,
110+
})
111+
112+
// Animate viewport between polar and cartesian
113+
mathbox.world().loop().hookPreRender(function () {
114+
var t = +new Date() * .0003;
115+
mathbox.set('viewport', { polar: Math.sin(t) * .5 + .5 });
116+
});
117+
});
118+
});
119+
</script>
120+
121+
<script type="text/javascript" charset="utf-8">
122+
/**
123+
* Custom helpers
124+
*/
125+
126+
// Clock that starts as soon as it is first called (per id).
127+
var clocks = {};
128+
window.clock = function (id) {
129+
if (!clocks[id]) clocks[id] = +new Date();
130+
return (+new Date() - clocks[id]) * .001;
131+
}
132+
133+
// Arbitrary function
134+
function surfaceFunc(x, y) {
135+
136+
return [x, -.15 + (Math.cos(x*3.41+Math.sin(y*1.9)) + Math.cos(y*3.7-Math.cos(x*4.1)))*.25, y];
137+
}
138+
139+
</script>
140+
141+
</head>
142+
<body>
143+
<div id="info"></div>
144+
</body>
145+
</html>

‎shaders/snippets.glsl.html

+16-2
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,11 @@
312312
// Fragment shader: render a shaded surface fragment.
313313
uniform vec3 color;
314314
uniform float opacity;
315+
uniform float mapOpacity;
316+
317+
uniform sampler2D texture;
318+
varying vec2 vUV;
319+
315320
varying vec3 vNormal;
316321
varying vec3 vViewPosition;
317322
uniform float flipSided;
@@ -337,18 +342,27 @@
337342
float dotNormalHalf = max(dot(normal, halfVector), 0.0);
338343
float specular = max(pow(dotNormalHalf, shininess), 0.0);
339344

340-
gl_FragColor = vec4(color * diffuse + specular * .3, opacity);
345+
vec4 sample = texture2D(texture, vUV);
346+
vec3 textured = color + (color * sample.xyz - color) * mapOpacity * sample.w;
347+
gl_FragColor = vec4(textured * diffuse + specular * .3, opacity);
341348
}
342349
</script>
343350

344351
<script type="application/x-glsl" id="fragmentSolid">
345352
// Fragment shader: render a solid surface fragment.
346353
uniform vec3 color;
347354
uniform float opacity;
355+
uniform float mapOpacity;
356+
357+
uniform sampler2D texture;
358+
varying vec2 vUV;
348359

349360
void fragmentSolid() {
350361
if (opacity < 0.01) discard;
351-
gl_FragColor = vec4(color, opacity);
362+
363+
vec4 sample = texture2D(texture, vUV);
364+
vec3 textured = color + (color * sample.xyz - color) * mapOpacity * sample.w;
365+
gl_FragColor = vec4(textured, opacity);
352366
}
353367
</script>
354368

‎src/Style.js

+2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ MathBox.Style.prototype = {
2525
worldRotation: new THREE.Vector3(),
2626
worldPosition: new THREE.Vector3(),
2727
zIndex: 0.0,
28+
29+
mapOpacity: 0,
2830
};
2931
},
3032

‎src/primitives/BezierSurface.js

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ MathBox.BezierSurface.prototype = _.extend(new MathBox.Surface(null), {
3131
doubleSided: true,
3232
flipSided: false,
3333
shaded: true,
34+
map: null,
3435
style: {}//,
3536
};
3637
},

‎src/primitives/Surface.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ MathBox.Surface.prototype = _.extend(new MathBox.Primitive(null), {
2323
doubleSided: true,
2424
flipSided: false,
2525
shaded: true,
26+
map: null,
2627
style: {}//,
2728
};
2829
},
@@ -65,7 +66,8 @@ MathBox.Surface.prototype = _.extend(new MathBox.Primitive(null), {
6566
doubleSided: options.doubleSided,
6667
flipSided: options.flipSided,
6768
shaded: options.shaded,
68-
dynamic: options.live
69+
dynamic: options.live,
70+
map: options.map,
6971
}, style);
7072
this.line = new MathBox.Renderable.Mesh(geometry, {
7173
type: 'mesh',

‎src/renderables/Renderable.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,14 @@ MathBox.Renderable.prototype = {
8181
}
8282

8383
if (this.material) {
84+
options = this.get();
85+
86+
// Apply texture
87+
if (options.map) {
88+
this.material.uniforms.texture.value = options.map;
89+
}
8490

8591
// Set double sided / culling order.
86-
options = this.get();
8792
this.material.side = options.doubleSided ? THREE.DoubleSide :
8893
THREE.FrontSide;
8994
options = { flipSided: (options.doubleSided && options.flipSided) ? -1 : 1 };

‎vendor/console-extras

Submodule console-extras added at 61c0608

0 commit comments

Comments
 (0)
Please sign in to comment.