未验证 提交 53e91323 编写于 作者: M Mr.doob 提交者: GitHub

USDZExporter: Added map transparency support (#22086)

上级 21e72444
......@@ -45,7 +45,10 @@
const texture = textures[ id ];
const color = id.split( '_' )[ 1 ];
files[ 'textures/Texture_' + id + '.jpg' ] = await imgToU8( texture.image, color );
const isRGBA = texture.format === 1023;
const canvas = imageToCanvas( texture.image, color );
const blob = await new Promise( resolve => canvas.toBlob( resolve, isRGBA ? 'image/png' : 'image/jpeg', 1 ) );
files[ `textures/Texture_${id}.${isRGBA ? 'png' : 'jpg'}` ] = new Uint8Array( await blob.arrayBuffer() );
} // 64 byte alignment
// https://github.com/101arrowz/fflate/issues/39#issuecomment-777263109
......@@ -84,7 +87,7 @@
}
async function imgToU8( image, color ) {
function imageToCanvas( image, color ) {
if ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement || typeof OffscreenCanvas !== 'undefined' && image instanceof OffscreenCanvas || typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) {
......@@ -97,14 +100,26 @@
if ( color !== undefined ) {
context.globalCompositeOperation = 'multiply';
context.fillStyle = `#${color}`;
context.fillRect( 0, 0, canvas.width, canvas.height );
const hex = parseInt( color, 16 );
const r = ( hex >> 16 & 255 ) / 255;
const g = ( hex >> 8 & 255 ) / 255;
const b = ( hex & 255 ) / 255;
const imagedata = context.getImageData( 0, 0, canvas.width, canvas.height );
const data = imagedata.data;
for ( let i = 0; i < data.length; i += 4 ) {
data[ i + 0 ] = data[ i + 0 ] * r;
data[ i + 1 ] = data[ i + 1 ] * g;
data[ i + 2 ] = data[ i + 2 ] * b;
}
context.putImageData( imagedata, 0, 0 );
}
const blob = await new Promise( resolve => canvas.toBlob( resolve, 'image/jpeg', 1 ) );
return new Uint8Array( await blob.arrayBuffer() );
return canvas;
}
......@@ -314,6 +329,7 @@ ${array.join( '' )}
function buildTexture( texture, mapType, color ) {
const id = texture.id + ( color ? '_' + color.getHexString() : '' );
const isRGBA = texture.format === 1023;
textures[ id ] = texture;
return `
def Shader "Transform2d_${mapType}" (
......@@ -332,7 +348,7 @@ ${array.join( '' )}
def Shader "Texture_${texture.id}_${mapType}"
{
uniform token info:id = "UsdUVTexture"
asset inputs:file = @textures/Texture_${id}.jpg@
asset inputs:file = @textures/Texture_${id}.${isRGBA ? 'png' : 'jpg'}@
float2 inputs:st.connect = </Materials/Material_${material.id}/Transform2d_${mapType}.outputs:result>
token inputs:wrapS = "repeat"
token inputs:wrapT = "repeat"
......
......@@ -52,8 +52,12 @@ class USDZExporter {
const texture = textures[ id ];
const color = id.split( '_' )[ 1 ];
const isRGBA = texture.format === 1023;
files[ 'textures/Texture_' + id + '.jpg' ] = await imgToU8( texture.image, color );
const canvas = imageToCanvas( texture.image, color );
const blob = await new Promise( resolve => canvas.toBlob( resolve, isRGBA ? 'image/png' : 'image/jpeg', 1 ) );
files[ `textures/Texture_${ id }.${ isRGBA ? 'png' : 'jpg' }` ] = new Uint8Array( await blob.arrayBuffer() );
}
......@@ -90,7 +94,7 @@ class USDZExporter {
}
async function imgToU8( image, color ) {
function imageToCanvas( image, color ) {
if ( ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement ) ||
( typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement ) ||
......@@ -108,14 +112,28 @@ async function imgToU8( image, color ) {
if ( color !== undefined ) {
context.globalCompositeOperation = 'multiply';
context.fillStyle = `#${ color }`;
context.fillRect( 0, 0, canvas.width, canvas.height );
const hex = parseInt( color, 16 );
const r = ( hex >> 16 & 255 ) / 255;
const g = ( hex >> 8 & 255 ) / 255;
const b = ( hex & 255 ) / 255;
const imagedata = context.getImageData( 0, 0, canvas.width, canvas.height );
const data = imagedata.data;
for ( let i = 0; i < data.length; i += 4 ) {
data[ i + 0 ] = data[ i + 0 ] * r;
data[ i + 1 ] = data[ i + 1 ] * g;
data[ i + 2 ] = data[ i + 2 ] * b;
}
context.putImageData( imagedata, 0, 0 );
}
const blob = await new Promise( resolve => canvas.toBlob( resolve, 'image/jpeg', 1 ) );
return new Uint8Array( await blob.arrayBuffer() );
return canvas;
}
......@@ -334,6 +352,7 @@ function buildMaterial( material, textures ) {
function buildTexture( texture, mapType, color ) {
const id = texture.id + ( color ? '_' + color.getHexString() : '' );
const isRGBA = texture.format === 1023;
textures[ id ] = texture;
......@@ -354,7 +373,7 @@ function buildMaterial( material, textures ) {
def Shader "Texture_${ texture.id }_${ mapType }"
{
uniform token info:id = "UsdUVTexture"
asset inputs:file = @textures/Texture_${ id }.jpg@
asset inputs:file = @textures/Texture_${ id }.${ isRGBA ? 'png' : 'jpg' }@
float2 inputs:st.connect = </Materials/Material_${ material.id }/Transform2d_${ mapType }.outputs:result>
token inputs:wrapS = "repeat"
token inputs:wrapT = "repeat"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册