Skip to content

Commit 93b500e

Browse files
authored
Add anisotropy property to renderer and material for configuring it globally and per material respectively (#5309)
Co-authored-by: Noeri Huisman <mrxz@users.noreply.github.com>
1 parent 96a3e7d commit 93b500e

File tree

7 files changed

+60
-2
lines changed

7 files changed

+60
-2
lines changed

docs/components/material.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ Here is an example of using an example custom material:
5454

5555
[flat]: #flat
5656
[standard]: #standard
57+
[renderer]: ./renderer.md
5758

5859
The material component has some base properties. More properties are available
5960
depending on the material type applied.
@@ -74,6 +75,7 @@ depending on the material type applied.
7475
| visible | Whether material is visible. Raycasters will ignore invisible materials. | true |
7576
| blending | The blending mode for the material's RGB and Alpha sent to the WebGLRenderer. Can be one of `none`, `normal`, `additive`, `subtractive` or `multiply`. | normal |
7677
| dithering | Whether material is dithered with noise. Removes banding from gradients like ones produced by lighting. | true |
78+
| anisotropy | The anisotropic filtering sample rate to use for the textures. A value of 0 means the default value will be used, see [renderer][renderer] | 0 |
7779

7880
## Events
7981

docs/components/renderer.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ It also configures presentation attributes when entering WebVR/WebXR.
4141
| alpha | Whether the canvas should contain an alpha buffer. | true |
4242
| toneMapping | Type of toneMapping to use, one of: 'no', 'ACESFilmic', 'linear', 'reinhard', 'cineon' | 'no' |
4343
| exposure | When any toneMapping other than "no" is used this can be used to make the overall scene brighter or darker | 1 |
44+
| anisotropy | Default anisotropic filtering sample rate to use for textures | 1 |
4445

4546
> **NOTE:** Once the scene is initialized, none of these properties may no longer be changed apart from "exposure" and "toneMapping" which can be set dynamically.
4647

src/components/material.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ module.exports.Component = registerComponent('material', {
3232
vertexColorsEnabled: {default: false},
3333
visible: {default: true},
3434
blending: {default: 'normal', oneOf: ['none', 'normal', 'additive', 'subtractive', 'multiply']},
35-
dithering: {default: true}
35+
dithering: {default: true},
36+
anisotropy: {default: 0, min: 0}
3637
},
3738

3839
init: function () {

src/systems/renderer.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ module.exports.System = registerSystem('renderer', {
1919
exposure: {default: 1, if: {toneMapping: ['ACESFilmic', 'linear', 'reinhard', 'cineon']}},
2020
toneMapping: {default: 'no', oneOf: ['no', 'ACESFilmic', 'linear', 'reinhard', 'cineon']},
2121
precision: {default: 'high', oneOf: ['high', 'medium', 'low']},
22+
anisotropy: {default: 1},
2223
sortObjects: {default: false},
2324
colorManagement: {default: true},
2425
alpha: {default: true},
@@ -34,6 +35,7 @@ module.exports.System = registerSystem('renderer', {
3435
renderer.sortObjects = data.sortObjects;
3536
renderer.useLegacyLights = !data.physicallyCorrectLights;
3637
renderer.toneMapping = THREE[toneMappingName + 'ToneMapping'];
38+
THREE.Texture.DEFAULT_ANISOTROPY = data.anisotropy;
3739

3840
THREE.ColorManagement.enabled = data.colorManagement;
3941
renderer.outputColorSpace = data.colorManagement ? THREE.SRGBColorSpace : THREE.LinearSRGBColorSpace;

src/utils/material.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ function setTextureProperties (texture, data) {
1818
var offset = data.offset || {x: 0, y: 0};
1919
var repeat = data.repeat || {x: 1, y: 1};
2020
var npot = data.npot || false;
21+
var anisotropy = data.anisotropy || 0;
2122
// To support NPOT textures, wrap must be ClampToEdge (not Repeat),
2223
// and filters must not use mipmaps (i.e. Nearest or Linear).
2324
if (npot) {
@@ -37,6 +38,11 @@ function setTextureProperties (texture, data) {
3738
if (offset.x !== 0 || offset.y !== 0) {
3839
texture.offset.set(offset.x, offset.y);
3940
}
41+
42+
// Only set anisotropy if it isn't 0, which indicates that the default value should be used.
43+
if (anisotropy !== 0) {
44+
texture.anisotropy = anisotropy;
45+
}
4046
}
4147
module.exports.setTextureProperties = setTextureProperties;
4248

@@ -83,7 +89,7 @@ module.exports.updateMapMaterialFromData = function (materialName, dataName, sha
8389
// Load texture for the new material src.
8490
// (And check if we should still use it once available in callback.)
8591
el.sceneEl.systems.material.loadTexture(src,
86-
{src: src, repeat: data.repeat, offset: data.offset, npot: data.npot},
92+
{src: src, repeat: data.repeat, offset: data.offset, npot: data.npot, anisotropy: data.anisotropy},
8793
checkSetMap);
8894
}
8995

tests/components/material.test.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,4 +344,32 @@ suite('material', function () {
344344
assert.equal(el.components.material.material.blending, THREE.MultiplyBlending);
345345
});
346346
});
347+
348+
suite('anisotropy', function () {
349+
test('defaults to THREE.Texture.DEFAULT_ANISOTROPY', function (done) {
350+
var imageUrl = 'base/tests/assets/test.png';
351+
el.setAttribute('material', '');
352+
assert.notOk(el.components.material.material.texture);
353+
el.setAttribute('material', 'src: url(' + imageUrl + ')');
354+
el.addEventListener('materialtextureloaded', function (evt) {
355+
var loadedTexture = evt.detail.texture;
356+
assert.ok(el.components.material.material.map === loadedTexture);
357+
assert.strictEqual(loadedTexture.anisotropy, THREE.Texture.DEFAULT_ANISOTROPY);
358+
done();
359+
});
360+
});
361+
362+
test('can set specific anisotropic filtering sample rate', function (done) {
363+
var imageUrl = 'base/tests/assets/test.png';
364+
el.setAttribute('material', '');
365+
assert.notOk(el.components.material.material.texture);
366+
el.setAttribute('material', 'src: url(' + imageUrl + '); anisotropy: 8');
367+
el.addEventListener('materialtextureloaded', function (evt) {
368+
var loadedTexture = evt.detail.texture;
369+
assert.ok(el.components.material.material.map === loadedTexture);
370+
assert.strictEqual(loadedTexture.anisotropy, 8);
371+
done();
372+
});
373+
});
374+
});
347375
});

tests/systems/renderer.test.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@ suite('renderer', function () {
1717
assert.strictEqual(rendererSystem.physicallyCorrectLights, false);
1818
assert.strictEqual(rendererSystem.sortObjects, false);
1919
assert.strictEqual(rendererSystem.colorManagement, true);
20+
assert.strictEqual(rendererSystem.anisotropy, 1);
2021

2122
// Verify properties that are transferred from the renderer system to the rendering engine.
2223
var renderingEngine = sceneEl.renderer;
2324
assert.strictEqual(renderingEngine.outputColorSpace, THREE.SRGBColorSpace);
2425
assert.notOk(renderingEngine.sortObjects);
2526
assert.strictEqual(renderingEngine.useLegacyLights, true);
27+
assert.strictEqual(THREE.Texture.DEFAULT_ANISOTROPY, 1);
2628
done();
2729
});
2830
document.body.appendChild(sceneEl);
@@ -81,6 +83,22 @@ suite('renderer', function () {
8183
document.body.appendChild(sceneEl);
8284
});
8385

86+
test('change renderer anisotropy', function (done) {
87+
var sceneEl = createScene();
88+
sceneEl.setAttribute('renderer', 'anisotropy: 16');
89+
sceneEl.addEventListener('loaded', function () {
90+
var rendererSystem = sceneEl.getAttribute('renderer');
91+
assert.strictEqual(rendererSystem.anisotropy, 16);
92+
assert.strictEqual(THREE.Texture.DEFAULT_ANISOTROPY, 16);
93+
94+
// verify that textures inherit it
95+
var texture = new THREE.Texture();
96+
assert.strictEqual(texture.anisotropy, 16);
97+
done();
98+
});
99+
document.body.appendChild(sceneEl);
100+
});
101+
84102
suite('Set WebXR Frame Rates', function () {
85103
var xrTargetFrameRate;
86104
var xrSession;

0 commit comments

Comments
 (0)