Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions editor/js/Menubar.Add.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as THREE from 'three';
import { UIPanel, UIRow } from './libs/ui.js';

import { AddObjectCommand } from './commands/AddObjectCommand.js';
import { MultiCmdsCommand } from './commands/MultiCmdsCommand.js';

import { FontLoader } from 'three/addons/loaders/FontLoader.js';
import { TextGeometry } from 'three/addons/geometries/TextGeometry.js';
Expand Down Expand Up @@ -419,7 +420,10 @@ function MenubarAdd( editor ) {

light.position.set( 5, 10, 7.5 );

editor.execute( new AddObjectCommand( editor, light ) );
editor.execute( new MultiCmdsCommand( editor, [
new AddObjectCommand( editor, light.target ),
new AddObjectCommand( editor, light )
] ) );

} );
lightSubmenu.add( option );
Expand Down Expand Up @@ -483,7 +487,10 @@ function MenubarAdd( editor ) {

light.position.set( 5, 10, 7.5 );

editor.execute( new AddObjectCommand( editor, light ) );
editor.execute( new MultiCmdsCommand( editor, [
new AddObjectCommand( editor, light.target ),
new AddObjectCommand( editor, light )
] ) );

} );
lightSubmenu.add( option );
Expand Down
12 changes: 11 additions & 1 deletion editor/js/Menubar.Edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { clone } from 'three/addons/utils/SkeletonUtils.js';
import { UIPanel, UIRow, UIHorizontalRule, UIText } from './libs/ui.js';

import { AddObjectCommand } from './commands/AddObjectCommand.js';
import { MultiCmdsCommand } from './commands/MultiCmdsCommand.js';
import { RemoveObjectCommand } from './commands/RemoveObjectCommand.js';
import { SetPositionCommand } from './commands/SetPositionCommand.js';

Expand Down Expand Up @@ -129,7 +130,16 @@ function MenubarEdit( editor ) {

const object = editor.selected;

if ( object !== null && object.parent !== null ) {
if ( object === null || object.parent === null ) return;

if ( object.isSpotLight || object.isDirectionalLight ) {

editor.execute( new MultiCmdsCommand( editor, [
new RemoveObjectCommand( editor, object ),
new RemoveObjectCommand( editor, object.target )
] ) );

} else {

editor.execute( new RemoveObjectCommand( editor, object ) );

Expand Down
17 changes: 14 additions & 3 deletions editor/js/Sidebar.Settings.Shortcuts.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { UIPanel, UIText, UIRow, UIInput } from './libs/ui.js';

import { MultiCmdsCommand } from './commands/MultiCmdsCommand.js';
import { RemoveObjectCommand } from './commands/RemoveObjectCommand.js';

function SidebarSettingsShortcuts( editor ) {
Expand Down Expand Up @@ -109,10 +110,20 @@ function SidebarSettingsShortcuts( editor ) {

const object = editor.selected;

if ( object === null ) return;
if ( object === null || object.parent === null ) return;

const parent = object.parent;
if ( parent !== null ) editor.execute( new RemoveObjectCommand( editor, object ) );
if ( object.isSpotLight || object.isDirectionalLight ) {

editor.execute( new MultiCmdsCommand( editor, [
new RemoveObjectCommand( editor, object ),
new RemoveObjectCommand( editor, object.target )
] ) );

} else {

editor.execute( new RemoveObjectCommand( editor, object ) );

}

break;

Expand Down
14 changes: 14 additions & 0 deletions editor/js/Viewport.js
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,20 @@ function Viewport( editor ) {

}

// update light helper when light target is changed

for ( const id in editor.helpers ) {

const helper = editor.helpers[ id ];

if ( helper.light && helper.light.target === object ) {

helper.update();

}

}

initPT();
render();

Expand Down
22 changes: 16 additions & 6 deletions examples/jsm/exporters/USDZExporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -284,11 +284,14 @@ class USDZExporter {
texture.flipY,
options.maxTextureSize
);

const mimeType = ( texture.userData.mimeType === 'image/jpeg' ) ? 'image/jpeg' : 'image/png';

const blob = await new Promise( ( resolve ) =>
canvas.toBlob( resolve, 'image/png', 1 )
canvas.toBlob( resolve, mimeType )
);

files[ `textures/Texture_${id}.png` ] = new Uint8Array(
files[ `textures/Texture_${id}.${getTextureExtension( texture )}` ] = new Uint8Array(
await blob.arrayBuffer()
);

Expand Down Expand Up @@ -363,6 +366,12 @@ function getName( object, namesSet ) {

}

function getTextureExtension( texture ) {

return texture.userData.mimeType === 'image/jpeg' ? 'jpg' : 'png';

}

function imageToCanvas( image, flipY, maxTextureSize ) {

if (
Expand Down Expand Up @@ -839,14 +848,15 @@ function buildMaterial( material, textures, quickLookCompatible = false ) {
'Shader'
);
textureNode.addProperty( 'uniform token info:id = "UsdUVTexture"' );
textureNode.addProperty( `asset inputs:file = @textures/Texture_${id}.png@` );
textureNode.addProperty( `asset inputs:file = @textures/Texture_${id}.${getTextureExtension( texture )}@` );
textureNode.addProperty(
`float2 inputs:st.connect = </Materials/Material_${material.id}/Transform2d_${mapType}.outputs:result>`
);

if ( color !== undefined ) {

textureNode.addProperty( `float4 inputs:scale = ${buildColor4( color )}` );
const alpha = ( mapType === 'diffuse' ) ? material.opacity : 1;
textureNode.addProperty( `float4 inputs:scale = ${buildColor4( color, alpha )}` );

}

Expand Down Expand Up @@ -1137,9 +1147,9 @@ function buildColor( color ) {

}

function buildColor4( color ) {
function buildColor4( color, alpha = 1 ) {

return `(${color.r}, ${color.g}, ${color.b}, 1.0)`;
return `(${color.r}, ${color.g}, ${color.b}, ${alpha})`;

}

Expand Down
21 changes: 16 additions & 5 deletions examples/jsm/loaders/usd/USDAParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -675,12 +675,23 @@ class USDAParser {
// Parse value based on type
const parsedValue = this._parseAttributeValue( valueType, rawValue );

// Store as attribute spec
// Store as attribute spec, preserving any existing fields
// (e.g. connectionPaths set by an earlier `.connect` form)
const attrPath = path + '.' + attrName;
specsByPath[ attrPath ] = {
specType: SpecType.Attribute,
fields: { default: parsedValue, typeName: valueType }
};

if ( specsByPath[ attrPath ] ) {

specsByPath[ attrPath ].fields.default = parsedValue;
specsByPath[ attrPath ].fields.typeName = valueType;

} else {

specsByPath[ attrPath ] = {
specType: SpecType.Attribute,
fields: { default: parsedValue, typeName: valueType }
};

}

}

Expand Down
4 changes: 2 additions & 2 deletions examples/jsm/tsl/display/DepthOfFieldNode.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { TempNode, NodeMaterial, NodeUpdateType, RenderTarget, Vector2, HalfFloatType, RedFormat, QuadMesh, RendererUtils } from 'three/webgpu';
import { convertToTexture, nodeObject, Fn, uniform, smoothstep, step, texture, max, uniformArray, outputStruct, property, vec4, vec3, uv, Loop, min, mix } from 'three/tsl';
import { convertToTexture, nodeObject, Fn, uniform, smoothstep, step, texture, max, uniformArray, outputStruct, property, vec4, vec3, uv, Loop, min, mix, float } from 'three/tsl';
import { gaussianBlur } from './GaussianBlurNode.js';

const _quadMesh = /*@__PURE__*/ new QuadMesh();
Expand Down Expand Up @@ -368,7 +368,7 @@ class DepthOfFieldNode extends TempNode {
nearField.assign( step( signedDist, 0 ).mul( CoC ) );
farField.assign( step( 0, signedDist ).mul( CoC ) );

return vec4( 0 );
return float( 0 );

} );

Expand Down
2 changes: 1 addition & 1 deletion src/materials/nodes/NodeMaterial.js
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,7 @@ class NodeMaterial extends Material {

if ( fragmentNode.isOutputStructNode !== true ) {

fragmentNode = vec4( fragmentNode );
fragmentNode = fragmentNode.convert( builder.getOutputType() );

}

Expand Down
5 changes: 3 additions & 2 deletions src/nodes/core/MRTNode.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import OutputStructNode from './OutputStructNode.js';
import { nodeProxy, vec4 } from '../tsl/TSLBase.js';
import { nodeProxy } from '../tsl/TSLBase.js';
import { MaterialBlending, NoBlending } from '../../constants.js';
import BlendMode from '../../renderers/common/BlendMode.js';

Expand Down Expand Up @@ -170,8 +170,9 @@ class MRTNode extends OutputStructNode {
for ( const name in outputNodes ) {

const index = getTextureIndex( textures, name );
const type = builder.getOutputType( index );

members[ index ] = vec4( outputNodes[ name ] );
members[ index ] = outputNodes[ name ].convert( type );

}

Expand Down
65 changes: 59 additions & 6 deletions src/nodes/core/NodeBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import CubeRenderTarget from '../../renderers/common/CubeRenderTarget.js';

import BindGroup from '../../renderers/common/BindGroup.js';

import { REVISION, IntType, UnsignedIntType, LinearFilter, LinearMipmapNearestFilter, NearestMipmapLinearFilter, LinearMipmapLinearFilter, NormalBlending } from '../../constants.js';
import { REVISION, IntType, UnsignedIntType, LinearFilter, LinearMipmapNearestFilter, NearestMipmapLinearFilter, LinearMipmapLinearFilter, NormalBlending, RedFormat, RGFormat, RGBFormat, RedIntegerFormat, RGIntegerFormat, RGBIntegerFormat } from '../../constants.js';
import { RenderTarget } from '../../core/RenderTarget.js';
import { Color } from '../../math/Color.js';
import { Vector2 } from '../../math/Vector2.js';
Expand Down Expand Up @@ -535,6 +535,61 @@ class NodeBuilder {

}

/**
* Returns the type of the color output based on the renderer's render target.
*
* @param {number} [index=0] - The index of the render target texture.
* @return {string} The type.
*/
getOutputType( index = 0 ) {

let type = 'vec4';

const renderTarget = this.renderer.getRenderTarget();

if ( renderTarget !== null ) {

const renderTargetType = renderTarget.textures[ index ].type;
const renderTargetFormat = renderTarget.textures[ index ].format;

let typeStr = 'vec';

if ( renderTargetType === IntType ) {

typeStr = 'ivec';

} else if ( renderTargetType === UnsignedIntType ) {

typeStr = 'uvec';

}

if ( renderTargetFormat === RedFormat || renderTargetFormat === RedIntegerFormat ) {

if ( renderTargetType === IntType ) type = 'int';
else if ( renderTargetType === UnsignedIntType ) type = 'uint';
else type = 'float';

} else if ( renderTargetFormat === RGFormat || renderTargetFormat === RGIntegerFormat ) {

type = `${ typeStr }2`;

} else if ( renderTargetFormat === RGBFormat || renderTargetFormat === RGBIntegerFormat ) {

type = `${ typeStr }3`;

} else {

type = `${ typeStr }4`;

}

}

return type;

}

/**
* Returns the output struct name which is required by
* {@link OutputStructNode}.
Expand Down Expand Up @@ -1469,12 +1524,10 @@ class NodeBuilder {

const type = texture.type;

if ( texture.isDataTexture ) {
if ( texture.isDepthTexture === true ) return 'float';

if ( type === IntType ) return 'int';
if ( type === UnsignedIntType ) return 'uint';

}
if ( type === IntType ) return 'int';
if ( type === UnsignedIntType ) return 'uint';

return 'float';

Expand Down
2 changes: 1 addition & 1 deletion src/nodes/core/OutputStructNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class OutputStructNode extends Node {

for ( let i = 0; i < members.length; i ++ ) {

const snippet = members[ i ].build( builder );
const snippet = members[ i ].build( builder, nodeData.membersLayout[ i ].type );

builder.addLineFlowCode( `${ structPrefix }m${ i } = ${ snippet }`, this );

Expand Down
16 changes: 15 additions & 1 deletion src/nodes/core/PropertyNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,20 @@ class PropertyNode extends Node {

}

getNodeType( builder ) {

const nodeType = super.getNodeType( builder );

if ( nodeType === 'output' ) {

return builder.getOutputType();

}

return nodeType;

}

customCacheKey() {

return hashString( this.type + ':' + ( this.name || '' ) + ':' + ( this.varying ? '1' : '0' ) );
Expand Down Expand Up @@ -292,7 +306,7 @@ export const shininess = /*@__PURE__*/ nodeImmutable( PropertyNode, 'float', 'Sh
* @tsl
* @type {PropertyNode<vec4>}
*/
export const output = /*@__PURE__*/ nodeImmutable( PropertyNode, 'vec4', 'Output' );
export const output = /*@__PURE__*/ nodeImmutable( PropertyNode, 'output', 'Output' );

/**
* TSL object that represents the shader variable `dashSize`.
Expand Down
6 changes: 3 additions & 3 deletions src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -1075,7 +1075,7 @@ ${ flowData.code }

if ( shaderStage === 'fragment' && outputSnippet.length === 0 ) {

outputSnippet.push( 'layout( location = 0 ) out vec4 fragColor;' );
outputSnippet.push( `layout( location = 0 ) out ${ this.getOutputType() } fragColor;` );

}

Expand Down Expand Up @@ -1633,14 +1633,14 @@ void main() {
if ( shaderStage === 'vertex' ) {

flow += 'gl_Position = ';
flow += `${ flowSlotData.result };`;
flow += `${ this.format( flowSlotData.result, mainNode.getNodeType( this ), 'vec4' ) };`;

} else if ( shaderStage === 'fragment' ) {

if ( ! node.outputNode.isOutputStructNode ) {

flow += 'fragColor = ';
flow += `${ flowSlotData.result };`;
flow += `${ this.format( flowSlotData.result, mainNode.getNodeType( this ), this.getOutputType() ) };`;

}

Expand Down
Loading