mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-20 14:30:41 +00:00
[backport cloud/1.42] fix: resolve incorrect GLSL live preview for non-primitive widget types (#11116)
Backport of #11010 to `cloud/1.42` Automatically created by backport workflow. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-11116-backport-cloud-1-42-fix-resolve-incorrect-GLSL-live-preview-for-non-primitive-widget--33e6d73d365081399958c929458eb840) by [Unito](https://www.unito.io) --------- Co-authored-by: Terry Jia <terryjia88@gmail.com>
This commit is contained in:
@@ -282,7 +282,44 @@ function createInnerPreview(
|
||||
}
|
||||
}
|
||||
|
||||
function getCustomResolution(): [number, number] | null {
|
||||
const gId = graphId.value
|
||||
if (!gId) return null
|
||||
|
||||
const sizeModeNodeId = innerGLSLNode
|
||||
? (innerGLSLNode.id as NodeId)
|
||||
: nodeId.value
|
||||
if (sizeModeNodeId == null) return null
|
||||
|
||||
const sizeMode = widgetValueStore.getWidget(
|
||||
gId,
|
||||
sizeModeNodeId,
|
||||
'size_mode'
|
||||
)
|
||||
if (sizeMode?.value !== 'custom') return null
|
||||
|
||||
const widthWidget = widgetValueStore.getWidget(
|
||||
gId,
|
||||
sizeModeNodeId,
|
||||
'size_mode.width'
|
||||
)
|
||||
const heightWidget = widgetValueStore.getWidget(
|
||||
gId,
|
||||
sizeModeNodeId,
|
||||
'size_mode.height'
|
||||
)
|
||||
if (!widthWidget || !heightWidget) return null
|
||||
|
||||
return clampResolution(
|
||||
normalizeDimension(widthWidget.value),
|
||||
normalizeDimension(heightWidget.value)
|
||||
)
|
||||
}
|
||||
|
||||
function getResolution(): [number, number] {
|
||||
const custom = getCustomResolution()
|
||||
if (custom) return custom
|
||||
|
||||
const node = nodeRef.value
|
||||
if (!node?.inputs) return [DEFAULT_SIZE, DEFAULT_SIZE]
|
||||
|
||||
@@ -325,27 +362,6 @@ function createInnerPreview(
|
||||
}
|
||||
}
|
||||
|
||||
const gId = graphId.value
|
||||
const nId = nodeId.value
|
||||
if (gId && nId != null) {
|
||||
const widthWidget = widgetValueStore.getWidget(
|
||||
gId,
|
||||
nId,
|
||||
'size_mode.width'
|
||||
)
|
||||
const heightWidget = widgetValueStore.getWidget(
|
||||
gId,
|
||||
nId,
|
||||
'size_mode.height'
|
||||
)
|
||||
if (widthWidget && heightWidget) {
|
||||
return clampResolution(
|
||||
normalizeDimension(widthWidget.value),
|
||||
normalizeDimension(heightWidget.value)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return [DEFAULT_SIZE, DEFAULT_SIZE]
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import { useWidgetValueStore } from '@/stores/widgetValueStore'
|
||||
import { isCurveData } from '@/components/curve/curveUtils'
|
||||
import type { CurveData } from '@/components/curve/types'
|
||||
import type { GLSLRendererConfig } from '@/renderer/glsl/useGLSLRenderer'
|
||||
import { hexToInt } from '@/utils/colorUtil'
|
||||
|
||||
interface AutogrowGroup {
|
||||
max: number
|
||||
@@ -20,6 +21,8 @@ interface AutogrowGroup {
|
||||
interface UniformSource {
|
||||
nodeId: NodeId
|
||||
widgetName: string
|
||||
/** Fallback getter for widgets not registered in widgetValueStore (e.g. hidden computed widgets). */
|
||||
directValue: () => unknown
|
||||
}
|
||||
|
||||
interface UniformSources {
|
||||
@@ -78,16 +81,19 @@ export function extractUniformSources(
|
||||
if (!link || link.origin_id === SUBGRAPH_INPUT_ID) continue
|
||||
|
||||
const sourceNode = subgraph.getNodeById(link.origin_id)
|
||||
if (!sourceNode?.widgets?.[0]) continue
|
||||
if (!sourceNode?.widgets?.length) continue
|
||||
|
||||
const inputName = input.name ?? ''
|
||||
const dotIndex = inputName.indexOf('.')
|
||||
if (dotIndex === -1) continue
|
||||
|
||||
const prefix = inputName.slice(0, dotIndex)
|
||||
if (link.origin_slot >= sourceNode.widgets.length) continue
|
||||
const widget = sourceNode.widgets[link.origin_slot]
|
||||
const source: UniformSource = {
|
||||
nodeId: sourceNode.id as NodeId,
|
||||
widgetName: sourceNode.widgets[0].name
|
||||
widgetName: widget.name,
|
||||
directValue: () => widget.value
|
||||
}
|
||||
|
||||
if (prefix === 'floats') floats.push(source)
|
||||
@@ -99,6 +105,11 @@ export function extractUniformSources(
|
||||
return { floats, ints, bools, curves }
|
||||
}
|
||||
|
||||
function toNumber(v: unknown): number {
|
||||
if (typeof v === 'string' && v.startsWith('#')) return hexToInt(v)
|
||||
return Number(v) || 0
|
||||
}
|
||||
|
||||
export function useGLSLUniforms(
|
||||
graphId: ComputedRef<UUID | undefined>,
|
||||
nodeId: ComputedRef<NodeId | undefined>,
|
||||
@@ -120,9 +131,9 @@ export function useGLSLUniforms(
|
||||
if (!gId) return []
|
||||
|
||||
if (subgraphSources) {
|
||||
return subgraphSources.map(({ nodeId: nId, widgetName }) => {
|
||||
return subgraphSources.map(({ nodeId: nId, widgetName, directValue }) => {
|
||||
const widget = widgetValueStore.getWidget(gId, nId, widgetName)
|
||||
return coerce(widget?.value ?? defaultValue)
|
||||
return coerce(widget?.value ?? directValue() ?? defaultValue)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -142,19 +153,24 @@ export function useGLSLUniforms(
|
||||
const slot = node.inputs?.findIndex((inp) => inp.name === inputName)
|
||||
if (slot == null || slot < 0) break
|
||||
|
||||
const link = node.getInputLink(slot)
|
||||
if (!link) break
|
||||
const upstreamNode = node.getInputNode(slot)
|
||||
if (!upstreamNode) break
|
||||
const upstreamWidgets = widgetValueStore.getNodeWidgets(
|
||||
gId,
|
||||
upstreamNode.id as NodeId
|
||||
)
|
||||
if (upstreamWidgets.length === 0) break
|
||||
values.push(coerce(upstreamWidgets[0].value))
|
||||
if (
|
||||
upstreamWidgets.length === 0 ||
|
||||
link.origin_slot >= upstreamWidgets.length
|
||||
)
|
||||
break
|
||||
values.push(coerce(upstreamWidgets[link.origin_slot].value))
|
||||
}
|
||||
return values
|
||||
}
|
||||
|
||||
const toNumber = (v: unknown): number => Number(v) || 0
|
||||
const toBool = (v: unknown): boolean => Boolean(v)
|
||||
|
||||
const floatValues = computed(() =>
|
||||
@@ -197,11 +213,10 @@ export function useGLSLUniforms(
|
||||
const sources = uniformSources.value?.curves
|
||||
if (sources && sources.length > 0) {
|
||||
return sources
|
||||
.map(({ nodeId: nId, widgetName }) => {
|
||||
.map(({ nodeId: nId, widgetName, directValue }) => {
|
||||
const widget = widgetValueStore.getWidget(gId, nId, widgetName)
|
||||
return widget && isCurveData(widget.value)
|
||||
? (widget.value as CurveData)
|
||||
: null
|
||||
const value = widget?.value ?? directValue()
|
||||
return isCurveData(value) ? (value as CurveData) : null
|
||||
})
|
||||
.filter((v): v is CurveData => v !== null)
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import type { ColorAdjustOptions } from '@/utils/colorUtil'
|
||||
import {
|
||||
adjustColor,
|
||||
hexToHsva,
|
||||
hexToInt,
|
||||
hexToRgb,
|
||||
hsbToRgb,
|
||||
hsvaToHex,
|
||||
@@ -95,6 +96,20 @@ describe('colorUtil conversions', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('hexToInt', () => {
|
||||
it('converts 6-digit hex to packed integer', () => {
|
||||
expect(hexToInt('#ff0000')).toBe(0xff0000)
|
||||
expect(hexToInt('#00ff00')).toBe(0x00ff00)
|
||||
expect(hexToInt('#45edf5')).toBe(0x45edf5)
|
||||
expect(hexToInt('#000000')).toBe(0)
|
||||
})
|
||||
|
||||
it('converts 3-digit hex to packed integer', () => {
|
||||
expect(hexToInt('#fff')).toBe(0xffffff)
|
||||
expect(hexToInt('#f00')).toBe(0xff0000)
|
||||
})
|
||||
})
|
||||
|
||||
describe('parseToRgb', () => {
|
||||
it('parses #hex', () => {
|
||||
expect(parseToRgb('#ff0000')).toEqual({ r: 255, g: 0, b: 0 })
|
||||
|
||||
@@ -82,6 +82,11 @@ export function hexToRgb(hex: string): RGB {
|
||||
return { r, g, b }
|
||||
}
|
||||
|
||||
export function hexToInt(hex: string): number {
|
||||
const { r, g, b } = hexToRgb(hex)
|
||||
return (r << 16) | (g << 8) | b
|
||||
}
|
||||
|
||||
export function rgbToHex({ r, g, b }: RGB): string {
|
||||
const toHex = (n: number) =>
|
||||
Math.max(0, Math.min(255, Math.round(n)))
|
||||
|
||||
Reference in New Issue
Block a user