Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add shader textureBias #4088

Merged
merged 16 commits into from
Mar 8, 2022
88 changes: 38 additions & 50 deletions src/graphics/grab-pass.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,33 @@ import { Texture } from "./texture.js";
* A class used by the graphics device to handle the capture of the current framebuffer into a
* texture to be used by following draw calls to implement refraction.
*
* @ignore
*/
class GrabPass {
/**
* Create a new GrabPass instance.
*
* @param {GraphicsDevice} graphicsDevice - The graphics device used to manage this grab pass.
* @param {boolean} useAlpha - Whether the grab pass should have an alpha channel.
* @param {boolean} useMipmaps - Whether to generate mipmaps. Only compatible under webgl2.
*/
constructor(device, useAlpha) {
constructor(device, useAlpha, useMipmaps = true, name = "texture_grabPass") {
slimbuck marked this conversation as resolved.
Show resolved Hide resolved
this.device = device;
this.useAlpha = useAlpha;

// for now we only support mipmaps on webgl2 devices due to the support for mipmaps for textures of any dimension
// (captured framebuffer is usually not power of 2). See TODO in generateMipmaps function.
this.useMipmaps = device.webgl2;
this.useMipmaps = useMipmaps && device.webgl2;
this.name = name;

this.texture = null;
this.renderTarget = null;
this.textureId = null;

const handler = () => {
this.destroy();
};

device.once('destroy', handler);
device.on('devicelost', handler);
slimbuck marked this conversation as resolved.
Show resolved Hide resolved
}

/**
Expand All @@ -51,52 +58,53 @@ class GrabPass {
* Create the texture and render target used by the grab pass.
*/
create() {
if (!this.texture) {

const texture = new Texture(this.device, {
name: 'texture_grabPass',
format: this.useAlpha ? PIXELFORMAT_R8_G8_B8_A8 : PIXELFORMAT_R8_G8_B8,
minFilter: this.useMipmaps ? FILTER_LINEAR_MIPMAP_LINEAR : FILTER_LINEAR,
magFilter: FILTER_LINEAR,
addressU: ADDRESS_CLAMP_TO_EDGE,
addressV: ADDRESS_CLAMP_TO_EDGE,
mipmaps: this.useMipmaps
});

this.texture = texture;

this.renderTarget = new RenderTarget({
colorBuffer: texture,
depth: false
});

this.textureId = this.device.scope.resolve(texture.name);
this.textureId.setValue(texture);
}
const texture = new Texture(this.device, {
name: this.name,
format: this.useAlpha ? PIXELFORMAT_R8_G8_B8_A8 : PIXELFORMAT_R8_G8_B8,
minFilter: this.useMipmaps ? FILTER_LINEAR_MIPMAP_LINEAR : FILTER_LINEAR,
magFilter: FILTER_LINEAR,
addressU: ADDRESS_CLAMP_TO_EDGE,
addressV: ADDRESS_CLAMP_TO_EDGE,
mipmaps: this.useMipmaps
});

this.texture = texture;

this.renderTarget = new RenderTarget({
colorBuffer: texture,
depth: false
});

this.textureId = this.device.scope.resolve(texture.name);
this.textureId.setValue(texture);
}

/**
* Resolve/copy the backbuffer into the grab pass render target.
*
* @returns {boolean} - Whether the grab pass was successfully resolved or not.
*/
update() {
prepareTexture() {
const device = this.device;
const gl = device.gl;

// print error if we cannot grab framebuffer at this point
if (!device.grabPassAvailable) {
Debug.error("texture_grabPass cannot be used when rendering shadows and similar passes, exclude your object from rendering to them");
return false;
}

if (!this.texture) {
this.create();
}

// render target currently being rendered to (these are null if default framebuffer is active)
const renderTarget = device.renderTarget;
const resolveRenderTarget = renderTarget && renderTarget._glResolveFrameBuffer;

const texture = this.texture;
const width = device.width;
const height = device.height;
const gl = device.gl;

DebugGraphics.pushGpuMarker(device, "grabPass");

Expand Down Expand Up @@ -141,36 +149,16 @@ class GrabPass {
}
}

DebugGraphics.popGpuMarker(device);

return true;
}

/**
* Generate mipmaps for the grab pass texture.
*/
generateMipmaps() {
// TODO: implement support for WebGL 1, which requires the texture to be a power of two, by
// first downscaling the captured framebuffer texture to smaller power of 2 texture, and
// then generate mipmaps and use it for rendering
if (this.useMipmaps) {
this.device.gl.generateMipmap(this.texture.impl._glTarget);
}
}

/**
* Grab a copy of the frame buffer to a texture and generate mipmaps for it.
*
* @returns {boolean} - Whether the grab pass was successfully updated or not.
*/
prepareTexture() {
// capture the framebuffer
const updated = this.update();
if (updated) {
this.generateMipmaps();
}
DebugGraphics.popGpuMarker(device);

return updated;
return true;
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/graphics/program-lib/chunks/ao.frag.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ void applyAO() {
dAo = 1.0;

#ifdef MAPTEXTURE
dAo *= texture2D(texture_aoMap, $UV).$CH;
dAo *= texture2D(texture_aoMap, $UV, globalTextureBias).$CH;
#endif

#ifdef MAPVERTEX
Expand Down
2 changes: 2 additions & 0 deletions src/graphics/program-lib/chunks/base.frag.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ uniform vec3 view_position;

uniform vec3 light_globalAmbient;

uniform float globalTextureBias;
slimbuck marked this conversation as resolved.
Show resolved Hide resolved

float square(float x) {
return x*x;
}
Expand Down
2 changes: 1 addition & 1 deletion src/graphics/program-lib/chunks/diffuse.frag.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ void getAlbedo() {
#endif

#ifdef MAPTEXTURE
dAlbedo *= gammaCorrectInput(addAlbedoDetail(texture2D(texture_diffuseMap, $UV).$CH));
dAlbedo *= gammaCorrectInput(addAlbedoDetail(texture2D(texture_diffuseMap, $UV, globalTextureBias).$CH));
#endif

#ifdef MAPVERTEX
Expand Down
2 changes: 1 addition & 1 deletion src/graphics/program-lib/chunks/metalness.frag.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ void getSpecularity() {
#endif

#ifdef MAPTEXTURE
metalness *= texture2D(texture_metalnessMap, $UV).$CH;
metalness *= texture2D(texture_metalnessMap, $UV, globalTextureBias).$CH;
#endif

#ifdef MAPVERTEX
Expand Down
2 changes: 1 addition & 1 deletion src/graphics/program-lib/chunks/normalDetailMap.frag.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ vec3 blendNormals(vec3 n1, vec3 n2) {

vec3 addNormalDetail(vec3 normalMap) {
#ifdef MAPTEXTURE
vec3 normalDetailMap = unpackNormal(texture2D(texture_normalDetailMap, $UV));
vec3 normalDetailMap = unpackNormal(texture2D(texture_normalDetailMap, $UV, globalTextureBias));
normalDetailMap = normalize(mix(vec3(0.0, 0.0, 1.0), normalDetailMap, material_normalDetailMapBumpiness));
return blendNormals(normalMap, normalDetailMap);
#else
Expand Down
2 changes: 1 addition & 1 deletion src/graphics/program-lib/chunks/normalMap.frag.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ uniform sampler2D texture_normalMap;
uniform float material_bumpiness;

void getNormal() {
vec3 normalMap = unpackNormal(texture2D(texture_normalMap, $UV));
vec3 normalMap = unpackNormal(texture2D(texture_normalMap, $UV, globalTextureBias));
normalMap = normalize(mix(vec3(0.0, 0.0, 1.0), normalMap, material_bumpiness));
dNormalMap = addNormalDetail(normalMap);
dNormalW = dTBN * dNormalMap;
Expand Down
2 changes: 1 addition & 1 deletion src/graphics/program-lib/chunks/normalMapFast.frag.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ export default /* glsl */`
uniform sampler2D texture_normalMap;

void getNormal() {
vec3 normalMap = unpackNormal(texture2D(texture_normalMap, $UV));
vec3 normalMap = unpackNormal(texture2D(texture_normalMap, $UV, globalTextureBias));
dNormalMap = addNormalDetail(normalMap);
dNormalW = dTBN * dNormalMap;
}
Expand Down
2 changes: 1 addition & 1 deletion src/graphics/program-lib/chunks/opacity.frag.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ void getOpacity() {
#endif

#ifdef MAPTEXTURE
dAlpha *= texture2D(texture_opacityMap, $UV).$CH;
dAlpha *= texture2D(texture_opacityMap, $UV, globalTextureBias).$CH;
#endif

#ifdef MAPVERTEX
Expand Down
2 changes: 1 addition & 1 deletion src/graphics/program-lib/chunks/parallax.frag.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ uniform float material_heightMapFactor;
void getParallax() {
float parallaxScale = material_heightMapFactor;

float height = texture2D(texture_heightMap, $UV).$CH;
float height = texture2D(texture_heightMap, $UV, globalTextureBias).$CH;
height = height * parallaxScale - parallaxScale*0.5;
vec3 viewDirT = dViewDirW * dTBN;

Expand Down
2 changes: 1 addition & 1 deletion src/graphics/program-lib/chunks/reflectionEnv.frag.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ float shinyMipLevel(vec2 uv) {
// calculate min of both sets of dF to handle discontinuity at the azim edge
float maxd = min(max(dot(dx, dx), dot(dy, dy)), max(dot(dx2, dx2), dot(dy2, dy2)));

return clamp(0.5 * log2(maxd) - 1.0, 0.0, 6.0);
return clamp(0.5 * log2(maxd) - 1.0 + globalTextureBias, 0.0, 6.0);
}

vec3 calcReflection(vec3 tReflDirW, float tGlossiness) {
Expand Down
2 changes: 1 addition & 1 deletion src/graphics/program-lib/chunks/specular.frag.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ void getSpecularity() {
#endif

#ifdef MAPTEXTURE
dSpecularity *= texture2D(texture_specularMap, $UV).$CH;
dSpecularity *= texture2D(texture_specularMap, $UV, globalTextureBias).$CH;
#endif

#ifdef MAPVERTEX
Expand Down
12 changes: 3 additions & 9 deletions src/graphics/webgl/webgl-graphics-device.js
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,9 @@ class WebglGraphicsDevice extends GraphicsDevice {
}

this.constantTexSource = this.scope.resolve("source");
this.globalTextureBias = this.scope.resolve("globalTextureBias");

this.globalTextureBias.setValue(0.0);

if (this.extTextureFloat) {
if (this.webgl2) {
Expand Down Expand Up @@ -608,9 +611,7 @@ class WebglGraphicsDevice extends GraphicsDevice {

// set to false during rendering when grabTexture is unavailable (when rendering shadows ..)
this.grabPassAvailable = true;

this.grabPass = new GrabPass(this, options.alpha);
this.grabPass.create();

// area light LUT format - order of preference: half, float, 8bit
this.areaLightLutFormat = PIXELFORMAT_R8_G8_B8_A8;
Expand All @@ -628,8 +629,6 @@ class WebglGraphicsDevice extends GraphicsDevice {
super.destroy();
const gl = this.gl;

this.grabPass.destroy();

if (this.webgl2 && this.feedback) {
gl.deleteTransformFeedback(this.feedback);
}
Expand Down Expand Up @@ -1004,9 +1003,6 @@ class WebglGraphicsDevice extends GraphicsDevice {
shader.loseContext();
}

// grab pass
this.grabPass.destroy();

slimbuck marked this conversation as resolved.
Show resolved Hide resolved
// release textures
for (const texture of this.textures) {
texture.loseContext();
Expand Down Expand Up @@ -1045,8 +1041,6 @@ class WebglGraphicsDevice extends GraphicsDevice {
for (const buffer of this.buffers) {
buffer.unlock();
}

this.grabPass.create();
slimbuck marked this conversation as resolved.
Show resolved Hide resolved
}

/**
Expand Down
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export { shFromCubemap } from './graphics/prefilter-cubemap.js';
export { reprojectTexture } from './graphics/reproject-texture.js';
export { programlib } from './graphics/program-lib/program-lib.js';
export { shaderChunks } from './graphics/program-lib/chunks/chunks.js';
export { GrabPass } from './graphics/grab-pass.js';
export { GraphicsDevice } from './graphics/graphics-device.js';
export { EnvLighting } from './graphics/env-lighting.js';
export { IndexBuffer } from './graphics/index-buffer.js';
Expand Down
6 changes: 3 additions & 3 deletions src/resources/parser/glb-parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -899,7 +899,7 @@ const createMaterial = function (gltfMaterial, textures) {
"#endif",
"",
"#ifdef MAPTEXTURE",
" dGlossiness *= texture2D(texture_glossMap, $UV).$CH;",
" dGlossiness *= texture2D(texture_glossMap, $UV, globalTextureBias).$CH;",
"#endif",
"",
"#ifdef MAPVERTEX",
Expand Down Expand Up @@ -929,7 +929,7 @@ const createMaterial = function (gltfMaterial, textures) {
" #endif",
"",
" #ifdef MAPTEXTURE",
" vec3 srgb = texture2D(texture_specularMap, $UV).$CH;",
" vec3 srgb = texture2D(texture_specularMap, $UV, globalTextureBias).$CH;",
" dSpecularity *= vec3(pow(srgb.r, 2.2), pow(srgb.g, 2.2), pow(srgb.b, 2.2));",
" #endif",
"",
Expand All @@ -956,7 +956,7 @@ const createMaterial = function (gltfMaterial, textures) {
"#endif",
"",
"#ifdef MAPTEXTURE",
" ccGlossiness *= texture2D(texture_clearCoatGlossMap, $UV).$CH;",
" ccGlossiness *= texture2D(texture_clearCoatGlossMap, $UV, globalTextureBias).$CH;",
"#endif",
"",
"#ifdef MAPVERTEX",
Expand Down